#include <stdio.h>
#include <string.h>
#include "String.h"
Include dependency graph for StringTest.C:
Go to the source code of this file.
Functions | |
void | checkRefCntVal (String s, size_t shouldBe, const char *prefix) |
checkRefCntVal: pass by value, where reference count gets incremented by one on entry and decremented by one on exit. | |
void | checkRefCnt (String &s, size_t shouldBe, const char *prefix) |
checkRefCnt: pass by reference. | |
void | test_constructors () |
test_constructors | |
void | test_char_cast () |
test_char_cast | |
void | test_assign () |
void | test_plus_equal () |
test_plus_equal | |
void | test_plus () |
test_plus | |
void | test_relops () |
test_relops | |
void | test_arrayop () |
Array reference [] operator tests. | |
void | test_insert () |
test_insert() | |
void | test_substr_func_valarg (SubString sub, size_t errorNum) |
void | test_substring () |
test_substring | |
void | test_resize () |
test_resize | |
main () |
No errors should be printed when this code runs.
You really need to run these regression tests before using this code on your system. This code has been tested on a variety of platforms. Although C++ compilers are getting more standard conformant, this the String class uses C++ features which historically been supported differently by different compilers.
Note that the existence of these regression tests does not change that statement this code is provided without waranty. You use this code at your own risk.
I also recommend verifying this code using Purify or a similar memory usage verification tool. This level of pain and difficulty should not be necessary, but hey, its C++.
In an earlier version of the String class the SubString class was included in the same .h file, with some function implementations in String.C.
This version separates the two classes. A set of regression tests (SubStrTest.C) was written for the SubString class. However, for historical reasons, this file also include some tests for SubString, which overlap with the tests in SubStrTest.C.
Compiling this code:
This code is written to compile on Microsoft Visual C++ 6.0 and higher. It will also compile on GNU C++ and Sun's 6.0 and later C++ compilers. To compile under Microsoft VC++:
The -GX flag is needed to support exceptions, which are used rather than the assert() functions in the earlier versions.
Copyright and Use
You may use this source code without limitation and without fee as long as you include:
This software was written and is copyrighted by Ian Kaplan, Bear Products International, www.bearcave.com, 2001.This software is provided "as is", without any warrenty or claim as to its usefulness. Anyone who uses this source code uses it at their own risk. Nor is any support provided by Ian Kaplan and Bear Products International.
Please send any bug fixes or suggested source changes to:
Definition in file StringTest.C.
Function Documentation
|
checkRefCnt: pass by reference. The reference count in the String object is unchanged, since the object is passed by reference. Definition at line 87 of file StringTest.C. References String::getRefCnt(). Referenced by test_constructors().
|
|
checkRefCntVal: pass by value, where reference count gets incremented by one on entry and decremented by one on exit.
Definition at line 74 of file StringTest.C. References String::getRefCnt(). Referenced by test_constructors().
|
|
Definition at line 1108 of file StringTest.C. References test_arrayop(), test_assign(), test_char_cast(), test_constructors(), test_insert(), test_plus(), test_plus_equal(), test_relops(), test_resize(), and test_substring().
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 } |
|
Array reference [] operator tests. There are two versions: left hand size and right hand size array operators. The right hand side version returns a value, the left hand size operator returns an address (to which a value can be assigned). Definition at line 718 of file StringTest.C. References String::getRefCnt(). Referenced by main().
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 |
|
Definition at line 179 of file StringTest.C. References String::getRefCnt(). Referenced by main().
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 |
|
test_char_cast
Definition at line 151 of file StringTest.C. Referenced by main().
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 |
|
test_constructors
Definition at line 98 of file StringTest.C. References checkRefCnt(), checkRefCntVal(), String::getRefCnt(), and String::strlen(). Referenced by main().
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 |
|
In an earlier version of the String object used an explicit insert function to insert a string into another string. This is very much like assigning to a SubString. In the case of an insert the length of the section being replaced is 0. This code attempts to not only make sure that insert works, but also that insert works for various corner cases (e.g., insert of an empty string or a null C string). Definition at line 800 of file StringTest.C. References String::getRefCnt(). Referenced by main().
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 |
|
test_plus
Definition at line 435 of file StringTest.C. References String::getRefCnt(). Referenced by main().
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 |
|
test_plus_equal
Definition at line 333 of file StringTest.C. References String::getRefCnt(). Referenced by main().
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 |
|
test_relops Test relational operators Definition at line 567 of file StringTest.C. Referenced by main().
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 |
|
test_resize Test the String object resize function. Definition at line 1051 of file StringTest.C. References String::resize(), and String::strlen(). Referenced by main().
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 |
|
Definition at line 893 of file StringTest.C. References SubString::getRefCnt(). Referenced by test_substring().
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 |
|
test_substring Test operations on SubStrings via the String() operator. These test overlap the SubString class tests. They are here for historical reasons. Definition at line 917 of file StringTest.C. References String::getRefCnt(), String::strlen(), and test_substr_func_valarg(). Referenced by main().
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 |