#include #include void assertWellFormedHandleList( int maxLen ) { // with(HeapArea) // HandleNode *n; // int limit1 = maxLen; // for ( n = Header.flink; (limit1-- > 0) && n != &Header; n = n->flink ) {} // assert (n == &Header); // int limit2 = maxLen; // for ( n = Header.blink; (limit2-- > 0) && n != &Header; n = n->blink ) {} // assert (n == &Header); // assert (limit1 == limit2); } // The given string is reachable. void assertOnHandleList( string & q ) { // with(HeapArea) // HandleNode *n; // for ( n = Header.flink; n != &Header; n = n->flink ) { // if ( n == & q.inner->Handle ) return; // } // assert( false ); } // Purpose: call each function in string.hfa, top to bottom int main () { #ifdef STRING_SHARING_OFF string_sharectx c = { NO_SHARING }; #endif string s = "hello"; string s2 = "hello"; string s3 = "world"; string frag = "ell"; // IO operator, x2 sout | s | s | s; // hello hello hello // empty ctor then assign string sxx; sout | sxx; // (blank line) sxx = s; sout | sxx; // hello // Comparisons // all print "true false" sout | (s == s2) | (s == s3); sout | (s != s3) | (s != s2); sout | (s == "hello") | (s == "world"); sout | (s != "world") | (s != "hello"); sout | ( frag == s(1,3) ) | ( s3 == s(1,3) ); sout | ( s3 != s(1,3) ) | ( frag != s(1,3) ); sout | ( s2(1,3) == s(1,3) ) | ( s3(1,3) == s(1,3) ); sout | ( s3(1,3) != s(1,3) ) | ( s2(1,3) != s(1,3) ); sout | ( s(1,3) == frag ) | ( s(1,3) == s3 ); sout | ( s(1,3) != s3 ) | ( s(1,3) != frag ); sout | ( s(1,3) == "ell" ) | ( s(1,3) == "world" ); sout | ( s(1,3) != "world" ) | ( s(1,3) != "ell" ); assertWellFormedHandleList( 10 ); // // breadth Constructors // { string b1 = "1234567"; sout | b1; // 1234567 string b1x = { "1234567", 3 }; sout | b1x; // 123 string b2 = s; sout | b2; // hello string b2x = { s, 4 }; sout | b2x; // hell // todo: a plain string & const string & s_ref = s; string b3 = s_ref; sout | b3; // hello & s_ref = & s3; b3 = s_ref; sout | b3; // world const string & s_constref = s; string b4 = s_constref; sout | b4; // hello & s_constref = & s3; b4 = s_constref; sout | b4; // world string b5 = 'Q'; sout | b5; // Q string b6 = 42; sout | b6; // 42 string b7 = -42; sout | b7; // -42 string b8 = 5.5; sout | b8; // 5.5 string b9 = 5.5L; sout | b9; // 5.5 string b10 = 5.5+3.4i; sout | b10; // 5.5+3.4i string b11 = 5.5L+3.4Li; sout | b11; // 5.5+3.4i } assertWellFormedHandleList( 10 ); // // Assignments // { string b = "xxx"; b = "1234567"; sout | b; // 1234567 b = "xxx"; b = s; sout | b; // hello b = "xxx"; b = 'Q'; sout | b; // Q b = "xxx"; assign( b, "1234567", 3 ); sout | b; // 123 b = "xxx"; assign( b, s, 4 ); sout | b; // hell b = "xxx"; strcpy(b, "1234567"); sout | b; // 1234567 b = "xxx"; strcpy(b, s); sout | b; // hello b = "xxx"; strncpy( b, "1234567", 3 ); sout | b; // 123 b = "xxx"; strncpy( b, s, 4 ); sout | b; // hell b = 42; sout | b; // 42 b = -42; sout | b; // -42 b = 5.5; sout | b; // 5.5 b = 5.5L; sout | b; // 5.5 b = 5.5+3.4i; sout | b; // 5.5+3.4i b = 5.5L+3.4Li; sout | b; // 5.5+3.4i } assertWellFormedHandleList( 10 ); sout | size(s); // 5 // // concatenation/append // string sx = s + s3; assertWellFormedHandleList( 10 ); sout | sx; // helloworld assertWellFormedHandleList( 10 ); sx = "xx"; assertWellFormedHandleList( 10 ); sx = s + s3; assertWellFormedHandleList( 10 ); sout | sx; // helloworld assertWellFormedHandleList( 10 ); sx += '!'; sout | sx; // helloworld! sx = s + '!'; sout | sx; // hello! sx = s; sx += s; sout | sx; // hellohello assertWellFormedHandleList( 10 ); sx += ", friend"; sout | sx; // hellohello, friend sx = s + ", friend"; sout | sx; // hello, friend sx = "bye, " + "friend"; sout | sx; // bye, friend sx = "o"; strcat( sx, s ); sout | sx; // ohello sx = "o"; append( sx, s, 4 ); sout | sx; // ohell sx = "o"; strncat( sx, s, 4 ); sout | sx; // ohell sx = "o"; strcat( sx, "mydarling" ); sout | sx; // omydarling sx = "o"; append( sx, "mydarling", 2 ); sout | sx; // omy sx = "o"; strncat( sx, "mydarling", 2 ); sout | sx; // omy // // repetition // sx = s; sx *= 4; sout | sx; // hellohellohellohello sx = s * 3; sout | sx; // hellohellohello sx = 'Q' * (size_t)3; sout | sx; // QQQ sx = "asdf" * 3; sout | sx; // asdfasdfasdf // // slicing // // Range cases treated thoroughly in "string-overwrite" test. // Composability with comparison and search are demoed above and below. // Coverage here adds the single-argument ("rest of string") overload. sx = s; sout | sx(3); // lo sx(3) = "iocentric"; sout | s | sx; // hello heliocentric // // character access // char c = s[1]; sout | c; // e s[3] = "p!!!"; sout | s; // help!!!o s[7] = '!'; sout | s; // help!!!! s[7] = ""; sout | s; // help!!! sout | s[3]; // p // // search // s += '?'; // already tested sout | contains( s, 'h' ) | contains( s, '?' ) | contains( s, 'o' ); // true true false sout | find( s, 'h' ) // 0 | find( s, '!' ) // 4 | find( s, '?' ) // 7 | find( s, 'o' ); // 8, not found string alphabet = "abcdefghijklmnopqrstuvwxyz"; sout | find( alphabet, "" ) // 0 | find( alphabet, "a" ) // 0 | find( alphabet, "z" ) // 25 | find( alphabet, "abc" ) // 0 | find( alphabet, "abq" ) // 26, not found | find( alphabet, "def"); // 3 sout | includes( alphabet, "" ) // true | includes( alphabet, "a" ) // true | includes( alphabet, "z" ) // true | includes( alphabet, "abc" ) // true | includes( alphabet, "abq" ) // false | includes( alphabet, "def"); // true { char *empty_c = ""; char *a_c = "a"; char *z_c = "z"; char *dex_c = "dex"; sout | find( alphabet, empty_c ) // 0 | find( alphabet, a_c ) // 0 | find( alphabet, dex_c ) // 26, not found | find( alphabet, dex_c, 2 ); // 3 sout | includes( alphabet, empty_c ) // true | includes( alphabet, a_c ) // true | includes( alphabet, dex_c ) // false | includes( alphabet, dex_c, 2 ); // true sout | startsWith( alphabet, a_c) // true | endsWith ( alphabet, a_c) // false | startsWith( alphabet, z_c) // false | endsWith ( alphabet, z_c); // true string empty = empty_c; string a = a_c; string z = z_c; string dex = dex_c; sout | find( alphabet, empty ) // 0 | find( alphabet, a ) // 0 | find( alphabet, dex ) // 26, not found | find( alphabet, dex(0,2) ); // 3 sout | includes( alphabet, empty ) // true | includes( alphabet, a ) // true | includes( alphabet, dex ) // false | includes( alphabet, dex(0,2) ); // true sout | startsWith( alphabet, a) // true | endsWith ( alphabet, a) // false | startsWith( alphabet, z) // false | endsWith ( alphabet, z); // true } sout | find( alphabet , "def") // 3 | find( alphabet( 0, 26), "def") // 3 | find( alphabet( 2, 24), "def") // 1 | find( alphabet( 3, 23), "def") // 0 | find( alphabet( 4, 22), "def") // 22, not found | find( alphabet( 4, 22), "ef") // 0 | find( alphabet( 0, 6), "def") // 3 | find( alphabet( 0, 5), "def") // 5, not found | find( alphabet( 0, 5), "de" ); // 3 sout | includes( alphabet , "def") // true | includes( alphabet( 0, 26), "def") // true | includes( alphabet( 2, 24), "def") // true | includes( alphabet( 3, 23), "def") // true | includes( alphabet( 4, 22), "def") // false | includes( alphabet( 4, 22), "ef") // true | includes( alphabet( 0, 6), "def") // true | includes( alphabet( 0, 5), "def") // false | includes( alphabet( 0, 5), "de" ); // true sout | startsWith( alphabet , "abc") // true | startsWith( alphabet( 0, 26), "abc") // true | startsWith( alphabet( 1, 25), "abc") // false | startsWith( alphabet( 1, 25), "bc") // true | startsWith( alphabet( 0, 26), "abc") // true | startsWith( alphabet( 0, 4), "abc") // true | startsWith( alphabet( 0, 3), "abc") // true | startsWith( alphabet( 0, 3), "ab" ) // true | startsWith( alphabet , "xyz"); // false sout | endsWith( alphabet , "xyz") // true | endsWith( alphabet , "xyzz") // false | endsWith( alphabet( 0, 26), "xyz") // true | endsWith( alphabet( 0, 25), "xyz") // false | endsWith( alphabet( 0, 25), "xy" ) // true | endsWith( alphabet( 0, 26), "xyz") // true | endsWith( alphabet(23, 3), "xyz") // true | endsWith( alphabet(24, 2), "xyz") // false | endsWith( alphabet(24, 2), "yz") // true | endsWith( alphabet , "abc"); // false charclass cc_cba = {"cba"}; charclass cc_onml = {"onml"}; charclass cc_alphabet = {alphabet}; // include (rest of the) numbers: tell me where the numbers stop // exclude (until) numbers: tell me where the numbers start (include rest of the non-numbers) sout | include( alphabet, cc_cba ) // 3 | exclude( alphabet, cc_cba ) // 0 | include( alphabet, cc_onml ) // 0 | exclude( alphabet, cc_onml ) // 11 | include( alphabet, cc_alphabet ) // 26 | exclude( alphabet, cc_alphabet ); // 0 }