Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members

StringTest.C

Go to the documentation of this file.
00001 
00065 #include <stdio.h>
00066 #include <string.h>
00067 
00068 #include "String.h"
00069 
00074 void checkRefCntVal( String s, size_t shouldBe, const char *prefix )
00075 {
00076   if (s.getRefCnt() != shouldBe)
00077     printf("%s refCnt = %d (should be %d)\n", 
00078            prefix, s.getRefCnt(), shouldBe );
00079 } // checkRefCntVal
00080 
00081 
00087 void checkRefCnt( String &s, size_t shouldBe, const char *prefix )
00088 {
00089   if (s.getRefCnt() != shouldBe)
00090     printf("%s refCnt = %d (should be %d)\n", 
00091            prefix, s.getRefCnt(), shouldBe );
00092 } // checkRefCnt
00093 
00094 
00098 void test_constructors()
00099 {
00100   String a( "abcd" );
00101   String b( a );
00102 
00103   printf("Test String constructors\n");
00104 
00105   if (b.getRefCnt() != 2)
00106     printf("1. Reference count is wrong: refCnt = %d (should be 2)\n",
00107            b.getRefCnt() );
00108 
00109   String c = a;
00110   if (b.getRefCnt() != 3)
00111     printf("2. Reference count is wrong: refCnt = %d (should be 3)\n",
00112            b.getRefCnt() );
00113 
00114   if (a.getRefCnt() != 3)
00115     printf("3. Reference count is wrong: refCnt = %d (should be 3)\n",
00116            b.getRefCnt() );
00117 
00118   checkRefCntVal( a, 4, "4. ");
00119 
00120   if (a.getRefCnt() != 3)
00121     printf("4. Reference count is wrong: refCnt = %d (should be 3)\n",
00122            b.getRefCnt() );
00123 
00124   checkRefCnt( a, 3, "5. ");
00125 
00126   String d( 'd' );
00127 
00128   // test for construction with an empty string
00129   String e;
00130   String f( e );
00131   checkRefCnt( f, 2, "6. ");
00132   checkRefCntVal( f, 3, "7. ");
00133 
00134   // test of a pointer containing null
00135   const char *nullPtr = 0;
00136   String g( nullPtr );
00137 
00138   // test of a null address
00139   String h( (const char *)0 );
00140 
00141   String i( '\0' );
00142   if (i.strlen() != 0) {
00143     printf("8. Adding a null character should not increase length\n");
00144   }
00145 } // test_constructors
00146 
00147 
00151 void test_char_cast()
00152 {
00153   printf("Test character cast\n");
00154 
00155   const char *testStr = "the quick brown fox";
00156   String a( testStr );
00157   const char *tmp = a;
00158 
00159   if (tmp == 0)
00160     printf("1. error: result of cast is null\n");
00161   else if (strcmp(testStr, tmp) != 0)
00162     printf("2. error: strings are not equal\n");
00163 
00164 } // test_char_cast
00165 
00166 
00167 /*
00168  * test_assign
00169  *
00170 
00171    The privious version of the String class created a new copy when
00172    ever the index operator ([]) was used.  I was surprised to 
00173    discover that this was the case even with the index operator
00174    was on the right hand size.  This function includes a test
00175    which checks that copy on read does not take place in this
00176    version.
00177    
00178  */
00179 void test_assign()
00180 {
00181   printf("Test assignment\n");
00182 
00183   const char *testStr = "my girl is the best";
00184   String a = "abcd";
00185 
00186   const char *tmp = a;
00187 
00188   if (strcmp(tmp, "abcd") != 0)
00189     printf("1. Assignment in declaration failed\n");
00190 
00191   const char *init_b = "this is not it";
00192   String b(init_b);
00193   String original_b;
00194 
00195   original_b = b;
00196 
00197   b = testStr;
00198   if (b.getRefCnt() != 1)
00199     printf("2. reference count for b is wrong\n");
00200 
00201   tmp = b;
00202   if (strcmp(tmp, testStr) != 0)
00203     printf("3. String has incorrect contents\n");
00204 
00205   if (original_b.getRefCnt() != 1)
00206      printf("4. reference count for original_b is wrong\n");
00207 
00208   if (original_b != init_b)
00209      printf("5. modification of b improperly changed original_b\n");
00210 
00211   String c( testStr );
00212   c = b;
00213   if (b.getRefCnt() != 2)
00214     printf("6. reference count is wrong\n");
00215 
00216   const char *nullPtr = 0;
00217   String d;
00218 
00219   if (d != "") {
00220     printf("7. comparision to a null string failed\n");
00221   }
00222 
00223   d = nullPtr;
00224   if (d != "") {
00225     printf("8. assignment of a null C-string failed\n");
00226   }
00227 
00228   d = testStr;
00229   tmp = d;
00230   if (strcmp(tmp, testStr) != 0)
00231     printf("9. String has incorrect contents\n");
00232 
00233   String e = String( testStr );
00234   tmp = e;
00235   if (strcmp(tmp, testStr) != 0)
00236     printf("10. String has incorrect contents\n");
00237 
00238   if (e.getRefCnt() != 1)
00239     printf("11. refCnt is wrong: refCnt = %d, should be 1\n",
00240            e.getRefCnt() );
00241 
00242   const char *constCStr = "1234567890";
00243   const size_t len = sizeof(constCStr) / sizeof(char);
00244   String foo = constCStr;
00245   String bar = foo;
00246   if (foo.getRefCnt() != 2) {
00247     printf("12. refcnt is wrong: refCnt = %d, should be 2\n",
00248            foo.getRefCnt() );
00249   }
00250 
00251   // This makes sure that the [] operator is implemented properly
00252   // and does not cause a "copy-on-write" on a read operation.
00253   bool contentOK = true;
00254   for (size_t i = 0; i < len; i++) {
00255     if (constCStr[i] != foo[i]) {
00256       contentOK = false;
00257       break;
00258     }
00259   }
00260   if (!contentOK) {
00261     printf("13: content is wrong\n");
00262   }
00263   // make sure refCnt is still OK
00264   if (bar.getRefCnt() != 2) {
00265     printf("14. refcnt is wrong: refCnt = %d, should be 2\n",
00266            bar.getRefCnt() );
00267   }
00268 
00269   const char *testStr2 = "null is a lonely number";
00270   String r = testStr2;
00271   String r2 = r;
00272   r = '\0';
00273   if (r != "") {
00274     printf("15. assignment of null character did not result in empty str\n");
00275   }
00276 
00277   if (r2 != testStr2) {
00278     printf("16. null character assignment changed a shared string\n");
00279   }
00280 
00281   if (r2.getRefCnt() != 1) {
00282     printf("17. reference count is wrong\n");
00283   }
00284 
00285   const char *testStr3 = "\"Writing tests is hard!\" said Barbie";
00286   String s = testStr3;
00287   String s2 = s;
00288   s = "";
00289   if (s != "") {
00290     printf("18. assignment of empty string did not result in empty str\n");
00291   }
00292 
00293   if (s2 != testStr3) {
00294     printf("19. empty string assignment changed a shared string\n");
00295   }
00296 
00297   if (s2.getRefCnt() != 1) {
00298     printf("17. reference count is wrong\n");
00299   }
00300 
00301   // Test chained assignment
00302   const char *testStr4 = "working on the chain gang";
00303   String w, x, y;
00304   w = x = y = testStr4;
00305 
00306   if (w != testStr4 ||
00307       x != testStr4 ||
00308       y != testStr4) {
00309     printf("18. chained assignment failed\n");
00310   }
00311 
00312   if (y.getRefCnt() != 3) {
00313     printf("19. reference count in chained assignment is wrong\n");
00314   }
00315 
00316   String z = "still working on the gang";
00317   w = x = y = z;
00318   if (w != x &&
00319       x != y &&
00320       y != z) {
00321     printf("20. chained assignment failed\n");
00322   }
00323 
00324   if (y.getRefCnt() != 4) {
00325     printf("21. reference count in chained assignment is wrong\n");
00326   }
00327 } // test_assign
00328 
00329 
00333 void test_plus_equal()
00334 {
00335   const char *firstHalf = "abcd";
00336   const char *secondHalf = " efgh";
00337   const char *concatStr = "abcd efgh";
00338 
00339   printf("Test += operator\n");
00340 
00341   String a( firstHalf );
00342 
00343   a += secondHalf;
00344 
00345   const char *tmp = a;
00346 
00347   if (strcmp(tmp, concatStr) != 0)
00348     printf("1. Strings did not match: str = %s (should be [%s]\n",
00349            tmp, concatStr );
00350 
00351   String b;
00352 
00353   b += firstHalf;
00354   tmp = b;
00355   if (strcmp(tmp, firstHalf) != 0)
00356     printf("2. Strings did not match: str = %s (should be [%s]\n",
00357            tmp, firstHalf );
00358 
00359   String d, c;
00360 
00361   c += d;
00362   if (c.getRefCnt() != 1)
00363     printf("3. refCnt should (still) be 1\n");
00364 
00365   if (d != "" || c != "") {
00366     printf("4. Strings c and d should be the empty string, but are not\n");
00367   }
00368 
00369   c += secondHalf;
00370   tmp = c;
00371   if (strcmp(tmp, secondHalf) != 0)
00372     printf("5. Strings did not match: str = %s (should be [%s]\n",
00373            tmp, secondHalf );
00374 
00375   String e("1234");
00376 
00377   for (size_t i = 5; i < 10; i++) {
00378     e += (char)(i + (char)'0');
00379   }
00380   if (e != "123456789") {
00381     tmp = e;
00382     printf("6. Character concat failed: d = %s, should be 123456789\n",
00383            tmp );
00384   }
00385 
00386   const char *testStr1 = "metal jacket";
00387   String empty;
00388   String full(testStr1);
00389 
00390   empty += full;
00391 
00392   if (empty.getRefCnt() != 1) {
00393     printf("7. empty.getRefCnt() = %d, should be 1\n", empty.getRefCnt() );
00394   }
00395 
00396   if (empty != testStr1) {
00397     printf("8. empty string += String failed\n");
00398   }
00399 
00400   const char *testStr2 = "foo";
00401   String empty2;
00402   const char *str = testStr2;
00403 
00404   empty2 += str;
00405   if (empty2.getRefCnt() != 1) {
00406     printf("9. empty2.getRefCnt() = %d, should be 1\n", empty2.getRefCnt() );
00407   }
00408 
00409   if (empty2 != testStr2) {
00410     printf("10. empty string += C-string failed\n");
00411   }
00412 
00413   // test chained assignment
00414   const char *testStr3 = "twas brillig";
00415   String s1 = "twas ";
00416   String s2 = "brillig";
00417   String s3 = s1 += s2;
00418 
00419   if (s3 != s1 && s1 != testStr3) {
00420     printf("11. chained assignment with += failed\n");
00421   }
00422 
00423   if (s3.getRefCnt() != 2 &&
00424       s1.getRefCnt() != 2 &&
00425       s2.getRefCnt() != 1) {
00426     printf("12. reference count for chained assignment with += failed\n");
00427   }
00428 } // test_plus_equal
00429 
00430 
00431 
00435 void test_plus()
00436 {
00437   printf("Test + operator\n");
00438 
00439   const char *firstHalf = "abcd";
00440   const char *secondHalf = " efgh";
00441   const char *concatStr = "abcd efgh";
00442 
00443   //
00444   // Test String + String
00445   //
00446   String t1( firstHalf );
00447   String t2( secondHalf );
00448   String a = t1 + t2;
00449   if (a.getRefCnt() != 1) {
00450     printf("1. refCnt is wrong: refCnt = %d, should be 1\n",
00451            a.getRefCnt() );
00452   }
00453 
00454   if (strcmp((const char *)a, concatStr) != 0)
00455     printf("2. String contents are not correct: a = %s (should be [%s])\n",
00456            (const char *)a, concatStr );
00457 
00458   //
00459   // Test String + const char *
00460   //
00461   String b = t1 + secondHalf;
00462 
00463   if (b.getRefCnt() != 1) {
00464     printf("3. refCnt is wrong: refCnt = %d, should be 1\n",
00465            b.getRefCnt() );
00466   }
00467 
00468   const char *tmp = b;
00469   if (strcmp(tmp, concatStr) != 0)
00470     printf("4. String contents are not correct: b = %s (should be [%s])\n",
00471            tmp, concatStr );
00472 
00473   //
00474   // test the global String addition operator const char * + String
00475   //
00476   String c = firstHalf + t2;
00477   tmp = c;
00478   if (strcmp(tmp, concatStr) != 0)
00479     printf("5. String contents are not correct: c = %s (should be [%s])\n",
00480            tmp, concatStr );
00481 
00482   //
00483   // Make sure that the operands of the addition are not altered by
00484   // the addition
00485   //
00486   String first( firstHalf );
00487   String second( secondHalf );
00488   String d = first + second;
00489   tmp = first;
00490   if (strcmp(tmp, firstHalf) != 0)
00491     printf("6. first has been altered: first = %s (should be [%s])\n",
00492            tmp, firstHalf );
00493 
00494   tmp = second;
00495   if (strcmp(tmp, secondHalf) != 0)
00496     printf("7. second has been altered: second = %s (should be [%s])\n",
00497            tmp, secondHalf );
00498 
00499   tmp = d;
00500   if (strcmp(tmp, concatStr) != 0)
00501     printf("8. String contents are not correct: d = %s (should be [%s])\n",
00502            tmp, concatStr );
00503 
00504   //
00505   // Test character concatenation.  Here the character operands
00506   // are converted to String objects.
00507   //
00508   String e("12345");
00509   String f;
00510   String g;
00511 
00512   f = e + '6' + '7' + '8' + '9';
00513   g = 'a' + f;
00514 
00515   if (e != "12345")
00516     printf("9. String e changed\n");
00517 
00518   if (f != "123456789") {
00519      const char *tmp = f;
00520      printf("10. String f is %s, it should be \"123456789\"\n", tmp);
00521   }
00522 
00523   if (g != "a123456789")
00524     printf("11. g is incorrect\n");
00525 
00526   // Test addition with chained assignment and string operands
00527   String w( "foo" );
00528   String x( "bar" );
00529   String y;
00530   String z = y = w + x;
00531 
00532   if (y != "foobar") {
00533      const char *tmp = y;
00534      printf("12. String y is %s, it should be \"foobar\"\n", tmp );
00535   }
00536 
00537   if (z != "foobar") {
00538      const char *tmp = z;
00539      printf("13. String z is %s, it should be \"foobar\"\n", tmp );
00540   }
00541 
00542   // The reference counts for w and x should both be 1
00543   if (w.getRefCnt() != 1) {
00544      printf("14. w.getRefCnt() = %d, it should be 1\n", w.getRefCnt() );
00545   }
00546   if (x.getRefCnt() != 1) {
00547      printf("15. x.getRefCnt() = %d, it should be 1\n", x.getRefCnt() );
00548   }
00549 
00550   if (y.getRefCnt() != 2) {
00551      printf("16. y.getRefCnt() = %d, it should be 2\n", y.getRefCnt() );
00552   }
00553   if (z.getRefCnt() != 2) {
00554      printf("17. z.getRefCnt() = %d, it should be 2\n", z.getRefCnt() );
00555   }
00556 } // test_plus
00557 
00558 
00559 
00567 void test_relops()
00568 {
00569   printf("Test relational operators\n");
00570 
00571   const char *less = "abcd";
00572   const char *greater = "wxyz";
00573   const char *equal = "abcd";
00574   String lessString( less );
00575   String greaterString( greater );
00576   String equalString( equal );  // note that equalString == lessString == less
00577   String same;
00578 
00579   same = less;
00580 
00581   //
00582   // ==
00583   //
00584   // String String
00585   //
00586   // Check the case where both strings contain no data
00587   // (and so are equal).
00588   String x, y;  // two empty strings
00589   if (x != y)
00590     printf("0. empty strings are not equal\n");
00591 
00592   if (x != "") {
00593     printf("0.5: String not equal to empty C string\n");
00594   }
00595 
00596   if (! (lessString == equalString))
00597     printf("1. String == String failed\n");
00598 
00599   // String const char *
00600   if (! (lessString == equal))
00601     printf("2. String == const char * failed\n");
00602 
00603   // const char *  String
00604   if (! (equal == lessString))
00605     printf("3. const char * == String failed\n");
00606 
00607   if (! (same == less))
00608     printf("String == String failed for String objs w/same shared data\n");
00609 
00610   //
00611   // !=
00612   //
00613   // String String
00614   if (! (lessString != greaterString))
00615     printf("4. String != String failed\n");
00616 
00617   // String const char *
00618   if (! (lessString != greater))
00619     printf("5. String != const char * failed\n");
00620 
00621   // const char *  String
00622   if (! (less != greaterString))
00623     printf("6. const char * != String failed\n");
00624 
00625   //
00626   // >=
00627   //
00628   // String String
00629   if (! (greaterString >= lessString))
00630     printf("7. String >= String failed for >\n");
00631 
00632   if (! (lessString >= equalString))
00633     printf("8. String >= String failed for ==\n");
00634 
00635   // String const char *
00636   if (! (greaterString >= less))
00637     printf("9. String >= const char * failed for >\n");
00638 
00639   if (! (lessString >= equal))
00640     printf("10. String >= const char * failed ==\n");
00641 
00642   // const char *  String
00643   if (! (greater >= lessString))
00644     printf("11. const char * >= String failed for >\n");
00645 
00646   if (! (equal >= lessString))
00647     printf("12. const char * >= String failed for ==\n");
00648 
00649   //
00650   // <=
00651   //
00652   // String String
00653   if (! (lessString <= greaterString))
00654     printf("13. String <= String failed for <\n");
00655 
00656   if (! (lessString <= equalString))
00657     printf("14. String <= String failed for ==\n");
00658 
00659   // String const char *
00660   if (! (lessString <= greater))
00661     printf("15. String <= const char * failed for <\n");
00662 
00663   if (! (lessString <= equal))
00664     printf("16. String <= const char * failed for ==\n");
00665 
00666   // const char *  String
00667   if (! (less <= greaterString))
00668     printf("17. const char * <= String failed for <\n");
00669 
00670   if (! (equal <= lessString))
00671     printf("18. const char * <= String failed for ==\n");
00672 
00673   //
00674   // >
00675   //
00676   // String String
00677   if (! (greaterString > lessString))
00678     printf("19. String > String failed\n");
00679 
00680   // String const char *
00681   if (! (greaterString > less))
00682     printf("20. String > const char * failed\n");
00683 
00684   // const char *  String
00685   if (! (greater > lessString))
00686     printf("21. const char * > String failed\n");
00687 
00688   //
00689   // <
00690   //
00691   // String String
00692   if (! (lessString < greaterString))
00693     printf("22. String < String failed\n");
00694 
00695   // String const char *
00696   if (! (lessString < greater))
00697     printf("23. String < const char * failed\n");
00698 
00699   // const char *  String
00700   if (! (less < greaterString))
00701     printf("24. const char * < String failed\n");
00702 
00703 } // test_relops
00704 
00705 
00706 
00718 void test_arrayop()
00719 {
00720   const char *jabbar     = "He took his vorpal sword in hand";
00721   const char *newJabbar1 = "He took her vorpal sword in hand";
00722   //     index 9   -----------------^
00723   const char *newJabbar2 = "He took her vorpal ruler in hand";
00724   //     index 19  ----------------------------^
00725   const char *newWord = "ruler";
00726 
00727   const size_t len = strlen( jabbar );
00728   String jabbarString( jabbar );
00729   String jabbarRefStr = jabbarString;
00730 
00731   //
00732   // Make sure that integer operators on the RHS work properly
00733   //
00734   if (jabbarString[3] != 't') {
00735     printf("0. string index failed\n");
00736   }
00737 
00738   // make sure than in index operation does not cause a copy
00739   if (jabbarRefStr.getRefCnt() != 2) {
00740     printf("0.5. string index seems to have caused a copy\n");
00741   }
00742 
00743   for (size_t i = 0; i < len; i++) {
00744     char lhsCh = jabbarString[i];
00745     char rhsCh = jabbar[i];
00746     if (lhsCh != rhsCh) {
00747       printf("1. mismatch on rhs String index\n");
00748     }
00749   }
00750 
00751   // references are jabbarString, jabbarRefStr and now, "a"
00752   String a = jabbarString;
00753   if (a.getRefCnt() != 3)
00754     printf("2. reference count is wrong\n");
00755 
00756   a[9] = 'e';
00757   a[10] = 'r';
00758 
00759   // The string has been changed, so a "copy on write" should 
00760   // have taken place.  Now there is a single copy, with the
00761   // change.
00762   if (a.getRefCnt() != 1)
00763     printf("3. 'a' reference count is wrong\n");
00764 
00765   if (jabbarString.getRefCnt() != 2)
00766     printf("4. jabbarString reference count is wrong\n");
00767   
00768   const char *tmp = a;
00769   if (strcmp(tmp, newJabbar1) != 0) {
00770     printf("5. strings don't match: a = %s, should be %s\n",
00771            tmp, newJabbar1 );
00772   }
00773 
00774   // make sure that the original string is unchanged
00775   tmp = jabbarString;
00776   if (strcmp(tmp, jabbar) != 0) {
00777     printf("6. strings don't match: a = %s, should be %s\n",
00778            tmp, jabbar );
00779   }
00780 
00781 } // test_arrayop
00782 
00783 
00784 
00785 
00800 void test_insert()
00801 {
00802   printf("Test string insert\n");
00803 
00804   const char *origA = "abcdefgh";
00805   const char *rslt1 = "abcd1234efgh";
00806   String a(origA);
00807   String b("1234");
00808   String c = a;
00809 
00810   // test insert of a String into a String
00811 
00812   // reference count should be 2, since a and c have the
00813   // same shared data
00814   if (a.getRefCnt() != 2)
00815     printf("1. reference count is wrong\n");
00816 
00817   a(4,0) = b;
00818   // make sure a is "abcd1234efgh"
00819   if (a != rslt1) {
00820     printf("2. insert failed. a = [%s], should be [%s]\n",
00821            (const char *)a, rslt1 );
00822   }
00823 
00824   // a should be unique
00825   if (a.getRefCnt() != 1)
00826     printf("3. reference count in a is wrong\n");
00827 
00828   // c should be unique
00829   if (c.getRefCnt() != 1)
00830     printf("4. reference count in c is wrong\n");
00831 
00832   // The contents of c should be unchanged
00833   if (c != origA)
00834     printf("5. contents of c is wrong\n");
00835 
00836   // test insert of C-string into a String
00837   String d = c;
00838   d(4,0) = "1234";
00839   // make sure d is "abcd1234efgh"
00840   if (d != rslt1) {
00841     printf("6. insert failed. d = [%s], should be [%s]\n",
00842            (const char *)d, rslt1 );
00843   }  
00844 
00845   String c_prime = c;  // reference count is 2
00846 
00847   // test insert of a zero length C string into a String
00848   // (remember, c is still "abcdefgh")
00849   c(4, 0) = "";
00850   // make sure c is "abcdefgh" (e.g., nothing happened)
00851   if (c != origA) {
00852     printf("7. insert failed. c = [%s], should be [%s]\n",
00853            (const char *)c, origA );
00854   }
00855 
00856   // Insert a null string into a String object (should do nothing)
00857   c_prime(4, 0) = (const char *)0;
00858   // make sure that reference count is still 2
00859   if (c.getRefCnt() != 2)
00860     printf("8. c.getRefCnt() = %d, should be 2\n", c.getRefCnt());
00861 
00862   if (c_prime.getRefCnt() != 2)
00863     printf("9. c_prime.getRefCnt() = %d, should be 2\n", c_prime.getRefCnt());
00864 
00865   if (c_prime != origA) {
00866     printf("10. insert failed. c_prime = [%s], should be [%s]\n",
00867            (const char *)c_prime, origA );
00868   }
00869 
00870   // test insert of an empty String into "c", an non-empty string.
00871   String emptyString;
00872 
00873   // try insert at index 0
00874   c(0,0) = emptyString;
00875   // make sure c is "abcdefgh" (e.g., nothing happened)
00876   if (c != origA) {
00877     printf("11. insert failed. c = [%s], should be [%s]\n",
00878            (const char *)c, origA );
00879   }
00880 
00881   // try insert at index 4
00882   c(4,0) = emptyString;
00883   // make sure c is "abcdefgh" (e.g., nothing happened)
00884   if (c != origA) {
00885     printf("12. insert failed. c = [%s], should be [%s]\n",
00886            (const char *)c, origA );
00887   }
00888 } // test_insert
00889 
00890 
00893 void test_substr_func_valarg( SubString sub, size_t errorNum )
00894 {
00895   if (sub.getRefCnt() != 1) {
00896     printf("%d. sub.getRefCnt() = %d, should be 1\n", 
00897            errorNum, sub.getRefCnt() );
00898   }
00899 
00900   if (sub != "de") {
00901     printf("%d. sub.string = %s, should be \"de\"\n",
00902            errorNum + 1, (const char *)((String)sub) );
00903   }
00904 } // test_substr_func_valarg
00905 
00906 
00917 void test_substring()
00918 {
00919   printf("Test sub-string operations\n");
00920   const char *init_a = "abcdefgh";
00921   String a(init_a);
00922 
00923   if (a(3, 4).getRefCnt() != 1) {
00924     printf("1. reference count is wrong\n");
00925   }
00926 
00927   test_substr_func_valarg( a(3, 2 ), 2 );
00928 
00929   String b = a;
00930 
00931   // b is "abcdefgh
00932   // insert "1234" at position 3
00933   b(3, 4) = "1234";
00934 
00935   if (a != init_a) {
00936     printf("3. \"a\" was altered when b(3, 4) was changed\n");
00937   }
00938 
00939   if (b != "abc1234h") {
00940     printf("4. b = %s, should be \"abc1234h\"\n", (const char *)b);
00941   }
00942 
00943   if (a.getRefCnt() != 1 || b.getRefCnt() != 1) {
00944     printf("5. a.getRefCnt() = %d, b.getRefCnt() = %d (both should be 1)\n",
00945            a.getRefCnt(), b.getRefCnt() );
00946   }
00947 
00948   String c;
00949   c = b(3, 4);
00950   if (c != "1234") {
00951     printf("6. c = %s, should be \"1234\"\n", (const char *)c);
00952   }
00953 
00954   if (c.strlen() != 4) {
00955     printf("7. c.strlen() = %d, should be 4\n", c.strlen());
00956   }
00957 
00958   String d("1234abcdefgh");
00959   String e;
00960 
00961   e = d(4, 8) + d(0, 4); // e = d << 4
00962   if (e != "abcdefgh1234") {
00963     printf("8. e = %s, should be \"abcdefgh1234\"\n", (const char *)e );
00964   }
00965 
00966   if (d != "1234abcdefgh") {
00967     printf("9. d was changed by the SubString operations\n");
00968   }
00969 
00970   if (d.getRefCnt() != 1) {
00971     printf("10. d.getRefCnt() = %d, it should be 1\n", d.getRefCnt());
00972   }
00973 
00974   //
00975   // According to 10.4.10 Temporary Objects in "The C++ Programming
00976   // Language", Third Edition, by Stroustrup:
00977   //
00978   //   Unless bound to a reference or used to initialize a named
00979   //   object, a temporary object is destroyed at the end of teh full
00980   //   expression in which it was created.  A full expression is an
00981   //   expression that is not a subexpression of some other
00982   //   expression.
00983   //
00984   // Stroustrup goes on to provide an example using the Standard
00985   // Template Library (STL) "string" class.  Here the c_str()
00986   // function returns a "C" language string.
00987   //
00988   //    const char* cs = (s1 + s2).c_str().
00989   //
00990   //    A temporary object of class string is created to hold s1+s2.
00991   //    Next, a pointer to a C-style string is extracted from the
00992   //    object.  Then - at the end of the expression - the temporary
00993   //    object is deleted.  Now, where was the C-style string
00994   //    allocated?  Probably as part of the temporary object holding
00995   //    s1+s2, and that storage is not guaranteed to exist after that
00996   //    temporary is destroyted.  Consequently, cs points to
00997   //    deallocated storage.
00998   //
00999   // In the case of the String container, the expression
01000   //
01001   //     e = d(4, 8) + d(0, 4);
01002   // 
01003   // creates a String object temporary, which is assigned to "e"
01004   //
01005   //   <allocate String temporary object CompilerTemp>
01006   //   <CompilerTemp> = d(4, 8) + d(0, 4);
01007   //   e = <CompilerTemp>     Note: at this point getRefCnt = 2
01008   //   <destructor called for CompilerTemp> Note: refCnt decremented
01009   //   next statement
01010   //
01011   // By the time we reach "next statement" the destructor is called
01012   // and the reference counter for "e" is 1, which is what we would
01013   // expect.
01014   //
01015   // If this example does not convience you that C++ is a complicated
01016   // language, nothing will.
01017   //
01018   if (e.getRefCnt() != 1) {
01019     printf("11. e.getRefCnt() = %d, it should be 1\n", e.getRefCnt());
01020   }
01021 
01022   //
01023   // Note that the SubString object created by the () operator is
01024   // a new object and so has a reference count of 1, although the
01025   // String associated with it has a reference count of two.
01026   String z = "lost Z-man";
01027   String y = z; // refCnt is now 2
01028   if (z(5, 5).getRefCnt() != 1) {
01029     printf("12. z(8, 4).getRefCnt() = %d, should be 1\n",
01030            z(8, 4).getRefCnt() );
01031   }
01032 
01033   String f("chopsock");
01034 
01035   f(4, 4) = f(0, 4);
01036   
01037   if (f != "chopchop") {
01038     printf("13. f = %s, should be \"chopchop\"\n", (const char *)f );
01039   }
01040 } // test_substring
01041 
01042 
01043 
01051 void test_resize()
01052 {
01053   const char *init_a = "01234567890123456789";
01054   String a( init_a );
01055   String b = a;
01056   const char *tmp;
01057 
01058   printf("Test resize\n");
01059 
01060   b.resize(10);  // set size of String b to 10
01061   if (b.strlen() != 10)
01062     printf("1. b.strlen() = %d, should be 10\n", b.strlen() );
01063 
01064   if (b != "0123456789") {
01065     tmp = b;
01066     printf("2. b = %s, should be \"0123456789\"\n", tmp );
01067   }
01068 
01069   if (a != init_a)
01070     printf("3. a was improperly modified by resizing b\n");
01071 
01072   if (a.strlen() != 20)
01073     printf("4. a.strlen() = %d, should be 20\n", a.strlen() );
01074 
01075   b.resize(20);
01076   if (b != "0123456789          ") {
01077     tmp = b;
01078     printf("5. b = %s, should be \"0123456789          \"\n", tmp );
01079   }
01080   if (b.strlen() != 20)
01081     printf("6. b.strlen() = %d, should be 20\n", b.strlen() );
01082 
01083   if (a != init_a)
01084     printf("8. resizing b modified a\n");
01085 
01086   b.resize( 0 );
01087 
01088   String empty;
01089 
01090   if (b != empty)
01091     printf("9. b is not the same as the empty string\n");
01092 
01093   if (a != init_a)
01094     printf("10. resizing b modified a\n");
01095 
01096   if (b.strlen() != 0)
01097     printf("11. b.strlen() = %d, should be 0\n", b.strlen() );
01098 
01099   if (b != "") {
01100     printf("12. b should be the same as the empty string\n");
01101   }
01102 
01103 } // test_resize
01104 
01105 
01108 main()
01109 {
01110   test_constructors();
01111   test_char_cast();
01112   test_assign();
01113   test_plus_equal();
01114   test_plus();
01115   test_relops();
01116   test_arrayop();
01117   test_insert();
01118   test_substring();
01119   test_resize();
01120   return 0;
01121 }

Generated on Mon Sep 22 20:22:58 2003 by doxygen 1.3.3