+Jun 11, 2020 - Release 0.3.1
+============================
+
+ - Introduction of class SuperString
+
Feb 07, 2020 - Release 0.3
============================
- UTC: Convert to and from time_t, struct tm
- xml: Add access to attributes
+- xml: Xinclude processing
.obj.eps:
tgif -print -eps -color $<
-XMLS = manual.xml string.xml date.xml hour.xml utc.xml Integer.xml xml.xml
+XMLS = manual.xml string.xml superstring.xml date.xml hour.xml utc.xml Integer.xml xml.xml
IMAGES=
PICTURES=
+++ /dev/null
-<html>
-<head>
-<title>UTC - ANDROMEDA CLASS LIBRARY</title>
-</head>
-<body bgcolor=white>
-
-<h2> NAME</h2>
-UTC - Universal Time Coordinated class
-<h2> SYNOPSIS</h2>
-<pre>
-#include <date.h>
-
-UTC clock;
-</pre>
-<h2> DESCRIPTION</h2>
-
-
-<h3>Construction</h3>
-
-<h5>UTC()</h5>
-<h5>UTC(date d, hour t)</h5>
-<h5>UTC(string)</h5>
-
-<h3>Assignment</h3>
-
-<h5>operator=(string &)</h5>
-
-<h3>Conversion</h3>
-
-<h5>string()</h5>
-
-<h3>Relational operations</h3>
-
-<h5>operator==(UTC &)</h5>
-<h5>operator!=(UTC &)</h5>
-<h5>operator<(UTC &)</h5>
-<h5>operator<=(UTC &)</h5>
-<h5>operator>(UTC &)</h5>
-<h5>operator>=(UTC &)</h5>
-
-<h3>Attributes</h3>
-
-<h5>date day()</h5>
-<h5>hour hour()</h5>
-
-<h3>Arithmetic</h3>
-
-<h5>UTC operator+(UTC &t1, UTC &t2)</h5>
-<h5>UTC operator-(UTC &t1, UTC &t2)</h5>
-<h5>UTC &operator+=(UTC &t)</h5>
-<h5>UTC &operator-=(UTC &t)</h5>
-<h5>UTC &operator++()</h5>
-<h5>UTC &operator--()</h5>
-
-<h3>Stream I/O</h3>
-
-<h5>ostream &operator<<(ostream &str, UTC &t)</h5>
-<h5>istream &operator>>(istream &str, UTC &t)</h5>
-
-<h2> SEE ALSO</h2>
-
-<a href="date.html">date</a>
-<a href="hour.html">hour</a>
-
-<h2> DIAGNOSTICS</h2>
-
-</body>
-</html>
+++ /dev/null
-<HTML>
-<HEAD>
-<TITLE>complex - ANDROMEDA CLASS LIBRARY</TITLE>
-<!--Created by Applixware HTML Authoring System, Release 4.3 on Fri Jun 19 13:20:00 1998-->
-</HEAD>
-<BODY BGCOLOR="#ffffff">
-<H2>NAME</H2>
-<P>complex - Complex number arithmetic</P>
-<H2>SYNOPSIS</H2>
-<P>complex z;</P>
-<H2>DESCRIPTION</H2>
-<P>The <I>complex</I> class encapsulates a comples number consisting of a real
-and an imaginary part.</P>
-<H3>Construction</H3>
-<H3>Assignment</H3>
-<H3>Conversion</H3>
-<H3>Relational Operators</H3>
-<H3>Attributes</H3>
-<H3>Arithmetic</H3>
-<H3>Mathematical operations</H3>
-<H3>Stream I/O</H3>
-<H2>SEE ALSO</H2>
-<H2>DIAGNOSTICS</H2>
-</BODY>
-</HTML>
+++ /dev/null
-<html>
-<head>
-<title>hour - ANDROMEDA CLASS LIBRARY</title>
-</head>
-<body bgcolor=white>
-
-<h2> NAME</h2>
-hour - Time class
-<h2> SYNOPSIS</h2>
-<pre>
-#include <date.h>
-
-hour t;
-</pre>
-<h2> DESCRIPTION</h2>
-
-The <em>hour</em> class encapsulates a time in hours, minutes and seconds.
-
-<h3>Construction</h3>
-
-<h5>hour()</h5>
-<h5>hour(int hour, short minute, short second)</h5>
-<h5>hour(string)</h5>
-
-Format is HH:MM:SS
-
-<h5>hour(long)</h5>
-
-A number of seconds.
-
-<h3>Assignment</h3>
-
-<h5>operator=(hour &)</h5>
-<h5>operator=(string &)</h5>
-<h5>operator=(long)</h5>
-
-<h3>Conversion</h3>
-
-<h5>long()</h5>
-
-Converts to a number of seconds.
-
-<h5>string()</h5>
-
-<h3>Relational operations</h3>
-
-<h5>operator==(hour &)</h5>
-<h5>operator!=(hour &)</h5>
-<h5>operator<(hour &)</h5>
-<h5>operator<=(hour &)</h5>
-<h5>operator>(hour &)</h5>
-<h5>operator>=(hour &)</h5>
-
-<h3>Attributes</h3>
-
-<h5>int hour()</h5>
-<h5>short minute()</h5>
-<h5>short second()</h5>
-
-<h3>Arithmetic</h3>
-
-<h5>hour operator+(hour &t1, hour &t2)</h5>
-<h5>hour operator-(hour &t1, hour &t2)</h5>
-<h5>hour &operator+=(hour &t)</h5>
-<h5>hour &operator-=(hour &t)</h5>
-<h5>hour &operator++()</h5>
-<h5>hour &operator--()</h5>
-
-<h3>Stream I/O</h3>
-
-<h5>ostream &operator<<(ostream &str, hour &t)</h5>
-<h5>istream &operator>>(istream &str, hour &t)</h5>
-
-<h2> SEE ALSO</h2>
-
-<a href="date.html">date</a>
-<a href="UTC.html">UTC</a>
-
-<h2> DIAGNOSTICS</h2>
-
-</body>
-</html>
+++ /dev/null
-<HTML>
-<HEAD>
-<TITLE>ANDROMEDA CLASS LIBRARY Class index</TITLE>
-<!--Created by Applixware HTML Authoring System, Release 4.3 on Mon Jun 22 10:51:41 1998-->
-</HEAD>
-<BODY BGCOLOR="#ffffff">
-<UL>
-<LI><A HREF="string.html">string</A>
-<LI><A HREF="date.html">date</A>
-<LI><A HREF="hour.html">hour</A>
-<LI><A HREF="UTC.html">UTC</A>
-<LI><A HREF="complex.html">complex</A>
-<LI><A HREF="../GNU/index.html">GNU Standard C++ library</A>
-<LI>???</UL>
-</BODY>
-</HTML>
<toc/>
<xi:include href="string.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="superstring.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="date.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="hour.xml"
+++ /dev/null
-<HTML>
-<HEAD>
-<TITLE>string - ANDROMEDA CLASS LIBRARY</TITLE>
-<!--Created by Applixware HTML Authoring System, Release 4.3 on Fri Jun 19 11:53:50 1998-->
-</HEAD>
-<BODY BGCOLOR="#ffffff">
-<H1>class string</H1>
-<CENTER>
-<HR ALIGN=CENTER SIZE=1>
-</CENTER>
-<H2>NAME</H2>
-<P>String - C++ string class</P>
-<H2>SYNOPSIS</H2>
-<PRE>
-<P>#include <Stringc.h></P>
-</PRE>
-<H2>DESCRIPTION</H2>
-<P>The C++ String class can be used to represent character strings and perform
-operation upon them. Many operations are defined for normal operators but may
-have different semantics. E.g. the + operator is used to concatenate (add)
-strings together.</P>
-<P>Substrings may be selected from strings to create other strings. Also,
-substrings have lvalue semantics, meaning a string may be assigned to a
-substring expression.</P>
-<H3>Construction and assignment.</H3>
-<P><B>String()</B></P>
-<P>The default constructor creates an empty string.</P>
-<P><B>String(const char *)</B></P>
-<P><B>String(char)</B></P>
-<P><B>String(const String &)</B></P>
-<P>Other constructors are provided to initialize strings from character
-pointers, single characters or other strings. These constuctors also take care
-of typecasting:</P>
-<PRE>
-<P>String x; // Contruct an empty string
-String abc("abc"); // Convert a char * to a string
-String p('p'); // A string with one character in it.
-</P>
-</PRE>
-<P>Another string (or string expression), a char* or a single character can be
-assigned to a string:</P>
-<PRE>
-<P>String x, y;
-
-x = "abc";
-y = x;
-x = 'p';</P>
-</PRE>
-<H3>Relational operators.</H3>
-<P>All relational operators (==, != , <, <=, > and >=) are
-available to compare strings alphabethically. Note that the comparison is done
-in the local character set, which will be ASCII in most cases. This also means
-that case is significant.</P>
-<H3>Adding strings together.</H3>
-<P>String can be added together, i.e. concatenated, with the <B>+</B>
-operator. Of course, the <B>+= </B>operator can be used as well. Example:
-</P>
-<PRE>
-<P>String x, y, z;
-
-x = "abc"
-y = "def"
-z = x + y; // z = "abcdef"
-y += x; // y = "defabc"</P>
-</PRE>
-<H3>String length, testing and character access</H3>
-<P>The length of a string can be determined with the <B>~ </B>operator. Do not
-confuse this with the bit-wise inversion operator !</P>
-<PRE>
-<P>String x = "Hello";
-int l = ~x; // l = 5</P>
-</PRE>
-<P>The test for an empty string is done with the <B>! </B>operator. Note that
-there is no test for a non-empty string.</P>
-<PRE>
-<P>if (!x)
- cout << "String x is empty\n";</P>
-</PRE>
-<P>Access to individual characters is provided like in ordinary C strings. The
-<B>[] </B>operator selects an individual character for both read and write access:
-</P>
-<PRE>
-<P>String x = "Hello";
-
-char c = x[1]; // c = 'e'
-x[2] = 'L'; // x = "HeLlo"</P>
-</PRE>
-<H3>Substring expressions.</H3>
-<P>A substring is a part of a string denoted by its start index and its
-length. The start index is counted from zero. To extract a substring from a
-string use:</P>
-<PRE>
-<P>String x = "abcdefghijkl";
-String y = x(3,5); // y = "defgh"</P>
-</PRE>
-<P>A substring expression can also be used as an lvalue. This means that a
-string can be assigned to a substring. The length of the substring does not
-need to be equal to the length of the string that is assigned to it.</P>
-<PRE>
-<P>String x = "abcdefghijkl";
-String y = "12345678";
-
-x(3,5) = y; // x = "abc12345678ijkl"</P>
-</PRE>
-<P>Note that assigning a string to a zero-length substring will simply insert
-the a string into another string. Reversely, assigning an empty string to a
-substring will remove the characters from the original string. This property
-can be used to truncate a string to its first n characters by:</P>
-<PRE>
-<P>x(n, ~x-n) = "";</P>
-</PRE>
-<H3>Numerical Conversion</H3>
-<P>Strings are coverted to and from numerical types (integer or floating
-point) by constructors and conversion operators. A numerical value is
-converted to a string with the number constructor:</P>
-<PRE>
-<P>String n(12); // n = "12"</P>
-<P>String x(2.32); // x = "2.32"</P>
-</PRE>
-<P>These functions use a default format to convert the number to a string.
-Specifically, an integer is converted with the "%d" format from
-printf and a floating point is converted with the "%g" format.
-</P>
-<P>A string is converted to a number with the type-casting operators: operator
-long() and operator double(). The conversion to a long integer recognizes C
-syntax for numerical literals. Numbers starting with '0' are regarded as octal
-and numbers starting with '0x' are regarded as hexadecimal.</P>
-<P>Special member functions allow conversion of strings to and from numbers in
-a specific format. The functions dec(), oct() and hex() convert the string
-using decimal, octal and hexadecimal, respectively.</P>
-<H3>Shifting</H3>
-<P>Shifting a string moves all characters in the string a number of places to
-the left or to the right. Characters on the other end of the string simply
-fall off. Unlike shifting a binary number, shifting a string does not pad the
-string. Rather, shifting a string <I>n</I> places either to the left or to the
-right, renders the string <I>n</I> characters shorter. Example:</P>
-<PRE>
-<P>"abcdefgh" << 3 = "defgh"</P>
-<P>"abcdefgh" >> 3 = "abcde"</P>
-</PRE>
-<P>The shift operators << and >> can be combined with assignment:
-<<= and >>=.</P>
-<P>Do not confuse these shift operators with stream I/O operators.</P>
-<H3>Operations</H3>
-<H5>String upper(void)</H5>
-<P>Convert the string to all upper-case characters.</P>
-<H5>String lower(void)</H5>
-<P>Convert the string to all lower-case characters.</P>
-<H3>Pattern matching</H3>
-<H5>int in(String &x)</H5>
-<P>Find the string x within the string. Returns the index where <I>x</I> was
-found. Returns -1 if x was not found in the string. see also strstr().
-</P>
-<H3>Stream I/O.</H3>
-<P>A string can be written to a stream like any other type with the <B><<
-</B>operator. The left hand side of the expression must be a stream. To read a
-string from a stream, use the <B>>> </B>operator, with a stream on the
-left hand side:</P>
-<PRE>
-<P>String x;
-
-cin >> x;
-cout << x;</P>
-</PRE>
-<P>Note that reading a string from a istream behaves like reading a character
-array from an istream. I.e., characters are read from the stream until the
-first whitespace character.</P>
-<H2>SEE ALSO</H2>
-<P>Bjarne Stroustrup, Section 6.9,<BR>
-DDJ October 1991, pg 24</P>
-<H2>DIAGNOSTICS</H2>
-</BODY>
-</HTML>
x[2] = 'L'; // x = "HeLlo"
</example>
</section>
+
<section>
<heading>Substring expressions.</heading>
--- /dev/null
+<?xml version="1.0"?>
+<chapter>
+<heading>class SuperString</heading>
+<para>
+A SuperString is a sequence of Strings, just like a String is a sequence of characters.
+A SuperString is in fact a string of Strings.
+Many operations that can be applied to String objects are also available for SuperSting objects,
+for example realtional operators, adding to SuperString objects, access to individual characters
+and 'substring' expressions.
+
+Split and join operations convert Strings into SuperStrings and vice versa.
+In that sense, split and join are complementary operations.
+The split() method of a string creates a SuperString.
+Conversily, the join() method of a SuperString creates a String.
+</para>
+
+<section>
+<heading>Construction and assignment.</heading>
+<para>
+The default constructor creates an empty superstring, one that does not contain any strings.
+A superstring constructed from a string creates a superstring with one element.
+Other contructors can create a SuperString from STL collectors (list and vector) of strings.
+</para>
+<description>
+<item tag="SuperString()">
+ The default constructor creates an empty string.
+</item>
+<item tag="SuperString(const String &s)">
+Create a SuperSting with one element.
+</item>
+<item tag="SuperString(const int n)">
+Create a SuperSting with n empty elements.
+</item>
+</description>
+
+<para>
+Another SuperString, String or SuperString expression can be
+assigned to a SuperString:
+</para>
+<example>
+SuperString x, y;
+String z("abc");
+
+x = z; // Create a SuperString with one element
+y = x;
+</example>
+</section>
+
+<section>
+<heading>SuperString length, testing and element access</heading>
+
+<para>
+The length of a SuperString can be determined with the <strong>~ </strong>operator.
+This is the number of Strings in the SuperString.
+Do not confuse this with the bit-wise inversion operator !
+</para>
+<example>
+
+SuperString xx(5);
+int l = ~xx; // l = 5
+
+</example>
+<para>
+The test for an empty string is done with the <strong>bool</strong>operator.
+This operator returns true if the SuperString object contains 1 or more Strings.
+It does not mean, however, that the String objects inside the SuperSting are not empty.
+</para>
+<example>
+if (!x)
+ cout << "String x is empty\n";
+</example>
+<para>
+Access to individual String elements is provided like in ordinary arrays. The
+<strong>[] </strong>operator selects an individual String for both read and write access:
+</para>
+<example>
+SuperString xx(3);
+
+String s = "Hello";
+xx[2] = s;
+</example>
+<para>
+Access out of range will throw a std::out_of_range exception.
+</para>
+</section>
+
+<section>
+<heading>Adding to SuperStrings</heading>
+
+<para>
+SuperString objects can be added together, i.e. concatenated, with the <strong>+</strong>
+operator. Of course, the <strong>+= </strong>operator can be used as well. Example:
+</para>
+<example>
+SuperString x, y, z;
+
+SuperString x("abc");
+SuperString y("def");
+
+z = x + y; // z = [ "abc", "def" ]
+y += z; // y = [ "def", "abc", "def" ]
+</example>
+</section>
+<para>
+ split on a regex ? how to split on an empty string ?
+
+split and join for csv formats. quoting and escape , ?
+
+
+
+the + operater can add strings and superstrings to append or prepend the one to the other. the result us always a superstring.
+
+add characters and strings ? -> TODO
+
+stream io is not possible. the split and join functions must be used instead
+
+the substring expression creates a selection of strings of the superstring just like the substring expression of a string creates a selection of characters.
+a substring expression with regex argument selects all strings that match the expression. implements a sort of grep function. this means the substring may not be a consequitive subset of the superstring.
+
+assigning to a substring repleces all strings in the substring
+
+convert to and from a std vector or list
+</para>
+</chapter>
lib_LTLIBRARIES = libACL.la
-libACL_la_SOURCES = string.cpp regex.cpp date.cpp parsedate.c dateyacc.y datelex.c \
+libACL_la_SOURCES = string.cpp regex.cpp superstring.cpp date.cpp parsedate.c dateyacc.y datelex.c \
hour.cpp utc.cpp \
Integer.cpp \
xml.cpp \
#include <stdlib.h>
#include <iostream>
+#include <vector>
#include <string.h>
#include <regex.h>
// Forward declarations.
class substring;
class regex;
+class SuperString;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
** NAME : String - Character String class.
friend bool operator == (const String &s, const regex &r);
friend bool operator == (const regex &r, const String &s);
// TODO: The != operator
+
+ SuperString split(const String &separator);
+
};
/*
* Other operators to think about...
}
};
+class SuperString
+{
+ std::vector<String> _ss;
+
+public:
+
+ SuperString() {};
+
+ SuperString(const String &s)
+ {
+ std::vector<String> __ss(1, s);
+ _ss = __ss;
+ }
+
+ SuperString(const int n)
+ {
+ std::vector<String> __ss(n);
+ _ss = __ss;
+ }
+
+ operator bool() // Test for empty SuperString
+ {
+ return _ss.size() != 0;
+ }
+
+ int operator~() const // Length of the SuperString
+ {
+ return _ss.size();
+ }
+
+ String& operator[](size_t i) // Individual String access
+ {
+ return _ss.at(i);
+ }
+
+ // Adding Strings and SuperStrings
+
+ friend SuperString operator+(const SuperString&, const String&);
+ SuperString& operator+=(const String&);
+};
+
#endif /* STRING_H */
* The subscript operator is provided for access to individual characters
*/
-// TODO: boundary check.
// TODO: Assignment to an individual character does not decouple references (BUG)
char& String::operator[](size_t i)
else
return -1;
}
+
+SuperString String::split(const String &separator)
+{
+ SuperString splitted;
+ char *sep, *part;
+
+ part = p->s;
+ sep = strstr(p->s, separator.p->s);
+
+ while (sep != NULL)
+ {
+ // Create a new string from the part until the separator
+
+ int len = sep - part;
+ char *str = new char[len + 1];
+
+ strncpy(str, part, len);
+ str[len] = '\0';
+ splitted += String(str);
+
+ // Look for the next separator
+
+ sep += ~separator;
+ part = sep;
+ sep = strstr(sep, separator.p->s);
+ }
+
+ // Add the leftover after the last separator.
+
+ splitted += String(part);
+
+ return splitted;
+}
--- /dev/null
+/**************************************************************************
+** (c) Copyright 1997, Andromeda Technology & Automation
+***************************************************************************
+** MODULE INFORMATION *
+***********************
+** FILE NAME : superstring.cpp
+** SYSTEM NAME : Andromeda X-Windows Encapsulation
+** VERSION NUMBER : $Revision: 1.5 $
+**
+** DESCRIPTION : SuperString class implementation.
+**
+** EXPORTED OBJECTS :
+** LOCAL OBJECTS :
+** MODULES USED :
+***************************************************************************
+** ADMINISTRATIVE INFORMATION *
+********************************
+** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
+** CREATION DATE : Jun 10, 2020
+** LAST UPDATE : Jun 10, 2020
+** MODIFICATIONS :
+**************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include "String.h"
+
+// Addition operators
+
+SuperString operator+(const SuperString& ss, const String& s)
+{
+ SuperString SS(ss);
+
+ SS._ss.push_back(s);
+
+ return SS;
+}
+
+SuperString& SuperString::operator+=(const String& x)
+{
+ _ss.push_back(x);
+
+ return *this;
+}
LDADD = ../src/.libs/libACL.la
check_PROGRAMS = string_assign string_basics string_compare string_cat string_convert string_modify \
string_shift string_substring string_regex \
+ superstring_assign superstring_basics superstring_cat string_split_join \
date_assign date_parse date_compare date_arithmetic date_attributes date_check_today \
hour_assign hour_parse hour_compare hour_arithmetic hour_check_now \
utc_assign utc_parse utc_compare utc_arithmetic utc_convert \
string_substring_SOURCES = string_substring.cpp
string_regex_SOURCES = string_regex.cpp
+superstring_assign_SOURCES = superstring_assign.cpp
+superstring_basics_SOURCES = superstring_basics.cpp
+superstring_cat_SOURCES = superstring_cat.cpp
+string_split_join_SOURCES = string_split_join.cpp
+
date_assign_SOURCES = date_assign.cpp
date_parse_SOURCES = date_parse.cpp
date_compare_SOURCES = date_compare.cpp
/*******************************************************
* Unit test for the String class
*
- * test relational operators
+ * test addition operators
******************************************************
*
*/
--- /dev/null
+/*******************************************************
+ * Unit test for the SuperString class
+ *
+ * test split and join of String and SuperString
+ ******************************************************
+ *
+ */
+
+#include "String.h"
+#include <assert.h>
+
+void print_ss(SuperString ss)
+{
+ std::cout << "[";
+ for (int i = 0; i < ~ss; i++)
+ {
+ if (i != 0)
+ std::cout << ",";
+ std::cout << "\"" << ss[i] << "\"";
+ }
+ std::cout << "]";
+}
+
+int main()
+{
+ String s0("The_String_To_Split");
+ SuperString ss0;
+
+ ss0 = s0.split("_");
+
+ std::cout << "The string " << s0 << " split on \"_\":\n";
+ print_ss(ss0);
+ std::cout << "\n";
+
+ assert(ss0[0] == "The");
+ assert(ss0[1] == "String");
+ assert(ss0[2] == "To");
+ assert(ss0[3] == "Split");
+
+ return 0;
+}
+
--- /dev/null
+/*******************************************************
+ * Unit test for the SuperString class
+ *
+ * test contrustor and assignment of SuperSting objects
+ ******************************************************
+ *
+ */
+
+#include "String.h"
+#include <assert.h>
+
+int main()
+{
+ // Default contructor: empty string
+ SuperString s0;
+
+ std::cout << "The default contructor makes an empty superstring.\n";
+ assert(~s0 == 0);
+
+ String s1("abc");
+ SuperString ss1(s1);
+
+ std::cout << "Contructor from a String makes a superstring with 1 element.\n";
+ assert(~ss1 == 1);
+
+ SuperString ss2(4);
+
+ std::cout << "Contructor with an integer argument makes a superstring with n elements.\n";
+ assert(~ss2 == 4);
+
+ // The copy contructor
+
+ SuperString ss3(ss2);
+
+ std::cout << "The copy contructor makes a bitwise copy.\n";
+ assert(~ss3 == 4);
+
+ // Assignment to a SuperSting with n elements should remove the old elements.
+
+ return 0;
+
+ // A string from a literal string
+ String s2("abc");
+
+ std::cout << "A string from a literal string \"abc\": \"" << s2 << "\"\n";
+ assert(~s2 == 3);
+
+ // The copy constructor
+ String s3(s2);
+
+ std::cout << "A string copied from the previous string \"abc\": \"" << s3 << "\"\n";
+ assert(~s3 == 3);
+
+ // Assign a single character
+ String s4;
+ s4 = 'q';
+ std::cout << "A string assigned a single charater 'q': \"" << s4 << "\"\n";
+ assert(~s4 == 1);
+
+ // Initialized with a single character
+ String s5 = 'r';
+
+ std::cout << "A string initialized with a single charater 'r': \"" << s5 << "\"\n";
+ assert(~s5 == 1);
+
+ // Assign a literal string
+ String s6;
+ s6 = "ijk";
+ std::cout << "A string assigned a literal string \"ijk\": \"" << s6 << "\"\n";
+ assert(~s6 == 3);
+
+ // Initialized a literal string
+ String s7 = "lmn";
+
+ std::cout << "A string initialized with a literal string \"lmn\": \"" << s7 << "\"\n";
+ assert(~s7 == 3);
+
+ // Assign a String object
+ String s8;
+ s8 = s6;
+ std::cout << "A string assigned a String object \"ijk\": \"" << s8 << "\"\n";
+ assert(~s8 == 3);
+
+ // Initialized a String object
+ String s9 = s7;
+
+ std::cout << "A string initialized with a String object \"lmn\": \"" << s9 << "\"\n";
+ assert(~s9 == 3);
+
+ return 0;
+}
+
--- /dev/null
+The default contructor makes an empty superstring.
+Contructor from a String makes a superstring with 1 element.
+Contructor with an integer argument makes a superstring with n elements.
+The copy contructor makes a bitwise copy.
+PASS superstring_assign (exit status: 0)
--- /dev/null
+/*******************************************************
+ * Unit test for the SuperString class
+ *
+ * test basic SuperString operations
+ ******************************************************
+ *
+ */
+
+#include "String.h"
+#include <assert.h>
+
+int main()
+{
+ // Default contructor: empty SuperString
+ SuperString ss0;
+
+ assert(~ss0 == 0);
+
+ // The length of a string with the ~ operator
+ String s1("abcde");
+ SuperString ss1(s1);
+
+ // check boolean opareations that check for empty strings
+
+ if (ss0)
+ {
+ std::cout << " ss0 is not empty.\n";
+ }
+ else
+ {
+ std::cout << " ss0 is empty.\n";
+ }
+ if (!ss0)
+ {
+ std::cout << " ss0 is empty.\n";
+ }
+ else
+ {
+ std::cout << " ss0 is not empty.\n";
+ }
+
+ if (ss1)
+ {
+ std::cout << " ss1 is not empty.\n";
+ }
+ else
+ {
+ std::cout << " ss1 is empty.\n";
+ }
+ if (!ss1)
+ {
+ std::cout << " ss1 is empty.\n";
+ }
+ else
+ {
+ std::cout << " ss1 is not empty.\n";
+ }
+
+ int length;
+ SuperString ss2(5);
+ length = ~ss2;
+ std::cout << "The length of ss2 is " << length << "\n";
+ assert(length == 5);
+
+ // test String access, also outside boundaries (e.g. -1, 666)
+
+ String s2;
+ s2 = ss1[0];
+ std::cout << "First string of ss1 is \"" << s2 << "\"\n";
+ assert(s2 == "abcde");
+
+ // An out of bounds index throws an exception
+
+ try
+ {
+ s2 = ss1[3];
+ std::cout << "Fourth string of ss1 is \"" << s2 << "\"\n";
+ }
+ catch (std::out_of_range e)
+ {
+ std::cout << "SuperString exception: " << e.what() << "\n";
+ }
+
+ // Fill up a SuperSting with some content.
+
+ SuperString ss3(4);
+ ss3[0] = "abc";
+ ss3[1] = "def";
+ ss3[3] = "xyz";
+
+ for (int i = 0; i < ~ss3; i++)
+ {
+ std::cout << "ss3[" << i << "] = " << ss3[i] << "\n";
+ }
+ return 0;
+
+}
+
--- /dev/null
+ ss0 is empty.
+ ss0 is empty.
+ ss1 is not empty.
+ ss1 is not empty.
+The length of ss2 is 5
+First string of ss1 is "abcde"
+SuperString exception: vector::_M_range_check: __n (which is 3) >= this->size() (which is 1)
+ss3[0] = abc
+ss3[1] = def
+ss3[2] =
+ss3[3] = xyz
+PASS superstring_basics (exit status: 0)
--- /dev/null
+/*******************************************************
+ * Unit test for the SuperString class
+ *
+ * test addition operators
+ ******************************************************
+ *
+ */
+
+#include "String.h"
+#include <assert.h>
+
+void print_ss(SuperString ss)
+{
+ std::cout << "[";
+ for (int i = 0; i < ~ss; i++)
+ {
+ if (i != 0)
+ std::cout << ",";
+ std::cout << "\"" << ss[i] << "\"";
+ }
+ std::cout << "]";
+}
+
+int main()
+{
+ // Add a String to a SuperString, + operator
+
+ SuperString ss0;
+
+ String s1("abc");
+ String s2("def");
+ SuperString ss1(s1);
+
+ ss0 = ss1 + s2;
+
+ print_ss(ss1);
+ std::cout << " + " << s2 << " = ";
+ print_ss(ss0);
+ std::cout << "\n";
+
+ // Add a String to a SuperString, += operator
+
+ SuperString ss2;
+
+ String s3("uvw");
+ String s4("xyz");
+
+ ss2 += s3;
+ print_ss(ss2);
+ std::cout << "\n";
+
+ ss2 += s4;
+ print_ss(ss2);
+ std::cout << "\n";
+
+ return 0;
+}
+