PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // PPTest.cc 00004 // 00005 // Copyright (C) 2005 Olivier Delalleau 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: .pyskeleton_header 544 2003-09-01 00:05:31Z plearner $ 00037 ******************************************************* */ 00038 00039 // Authors: Olivier Delalleau 00040 00044 #include "PPTest.h" 00045 00046 #define T_ERR(_Type__, _The_Message__)\ 00047 cerr << "\n============================================================" << endl;\ 00048 cerr << "" << _Type__ << " " << flush;\ 00049 cerr << "At " << __FILE__ << ":" << __LINE__; \ 00050 cerr << endl << _The_Message__ << endl;\ 00051 cerr << "============================================================\n" << endl;\ 00052 exit(1); 00053 00054 #define T_ASSERT(__Test_, __Message_)\ 00055 if( !(__Test_) ){\ 00056 T_ERR("T_ASSERT", (__Message_) )}; 00057 00058 bool __result = false; 00059 #define DO_TEST(__name, __testFunction)\ 00060 __result = false;\ 00061 cout << endl;\ 00062 cout << "Step:\t " << __name << endl;\ 00063 cout << "Doing ..." << endl << endl;\ 00064 __result = __testFunction;\ 00065 if(__result){ cout << "PASSED" << endl; }\ 00066 else{ PLERROR("****FAIL****"); }\ 00067 cout << endl << endl; 00068 00069 #define MAX_SIZE 11 00070 00071 namespace PLearn { 00072 using namespace std; 00073 00074 00075 PLEARN_IMPLEMENT_OBJECT( 00076 PPTest, 00077 "Does basic manipulations with smart pointers -- PP", 00078 "" 00079 ); 00080 00082 // PPTest // 00084 PPTest::PPTest() 00085 /* ### Initialize all fields to their default value */ 00086 { 00087 // ... 00088 00089 // ### You may (or not) want to call build_() to finish building the object 00090 // ### (doing so assumes the parent classes' build_() have been called too 00091 // ### in the parent classes' constructors, something that you must ensure) 00092 } 00093 00095 // build // 00097 void PPTest::build() 00098 { 00099 inherited::build(); 00100 build_(); 00101 } 00102 00104 // makeDeepCopyFromShallowCopy // 00106 void PPTest::makeDeepCopyFromShallowCopy(CopiesMap& copies) 00107 { 00108 inherited::makeDeepCopyFromShallowCopy(copies); 00109 00110 // ### Call deepCopyField on all "pointer-like" fields 00111 // ### that you wish to be deepCopied rather than 00112 // ### shallow-copied. 00113 // ### ex: 00114 // deepCopyField(trainvec, copies); 00115 00116 // ### Remove this line when you have fully implemented this method. 00117 PLERROR("PPTest::makeDeepCopyFromShallowCopy not fully (correctly) implemented yet!"); 00118 } 00119 00121 // declareOptions // 00123 void PPTest::declareOptions(OptionList& ol) 00124 { 00125 // ### Declare all of this object's options here 00126 // ### For the "flags" of each option, you should typically specify 00127 // ### one of OptionBase::buildoption, OptionBase::learntoption or 00128 // ### OptionBase::tuningoption. Another possible flag to be combined with 00129 // ### is OptionBase::nosave 00130 00131 // ### ex: 00132 // declareOption(ol, "myoption", &PPTest::myoption, OptionBase::buildoption, 00133 // "Help text describing this option"); 00134 // ... 00135 00136 // Now call the parent class' declareOptions 00137 inherited::declareOptions(ol); 00138 } 00139 00141 // build_ // 00143 void PPTest::build_() 00144 { 00145 // ### This method should do the real building of the object, 00146 // ### according to set 'options', in *any* situation. 00147 // ### Typical situations include: 00148 // ### - Initial building of an object from a few user-specified options 00149 // ### - Building of a "reloaded" object: i.e. from the complete set of all serialised options. 00150 // ### - Updating or "re-building" of an object after a few "tuning" options have been modified. 00151 // ### You should assume that the parent class' build_() has already been called. 00152 } 00153 00154 class ChildA; 00155 class ChildB; 00156 00157 class Parent : public PPointable 00158 { 00159 public: 00161 int i_par; 00163 string s_par; 00164 PP<ChildA> childAPP; 00165 PP<ChildB> childBPP; 00166 Parent(int ipp=0, string spp="parent") : i_par(ipp), s_par(spp) {} 00167 void print(ostream& out) { out << "* Parent:\ti_par= " << i_par << "\ts_par= " << s_par << endl; } 00168 00169 Parent(const Parent& other) : i_par(other.i_par), s_par(other.s_par), 00170 childAPP(other.childAPP), childBPP(other.childBPP){} 00171 00172 Parent* deepCopy(CopiesMap& copies) const 00173 { 00174 CopiesMap::iterator it = copies.find(this); 00175 if(it!=copies.end()) 00176 return (Parent*) it->second; 00177 00179 Parent* dcopy = new Parent(*this); 00180 dcopy->childAPP = PLearn::deepCopy( childAPP ); 00181 dcopy->childBPP = PLearn::deepCopy( childBPP ); 00182 00184 if (usage() > 1) 00185 copies[this] = dcopy; 00186 00187 return dcopy; 00188 } 00189 }; 00190 00191 class ChildA : public Parent 00192 { 00193 public: 00195 int i_child_a; 00196 PP<Parent> parentPP; 00197 PP<ChildB> childBPP; 00198 ChildA(int pp=0, string sp="zero_hundred", int cc=0) : Parent(pp, sp), i_child_a(cc) {} 00199 void print(ostream& out) { out << "* ChildA:\ti_child_a= " << i_child_a << "\t\t\t" << flush; Parent::print(out); } 00200 00201 ChildA(const ChildA& other) : 00202 Parent(other.i_par, other.s_par), 00203 i_child_a(other.i_child_a), 00204 parentPP(other.parentPP), childBPP(other.childBPP){} 00205 00206 ChildA* deepCopy(CopiesMap& copies) const 00207 { 00208 CopiesMap::iterator it = copies.find(this); 00209 if(it!=copies.end()) 00210 return (ChildA*) it->second; 00211 00213 ChildA* dcopy = new ChildA(*this); 00214 dcopy->parentPP = PLearn::deepCopy( parentPP ); 00215 dcopy->childBPP = PLearn::deepCopy( childBPP ); 00216 00218 if (usage() > 1) 00219 copies[this] = dcopy; 00220 00221 return dcopy; 00222 } 00223 }; 00224 00225 00226 class ChildB : public Parent 00227 { 00228 public: 00230 string s_child_b; 00231 PP<ChildA> childAPP; 00232 ChildB(string schildb="childB") : s_child_b(schildb) {} 00233 void print(ostream& out) { out << "* ChildB:\ts_child_b= " << s_child_b << "\t\t" << flush; Parent::print(out); } 00234 00235 ChildB(const ChildB& other) : Parent(other.i_par, other.s_par), childAPP(other.childAPP){} 00236 00237 ChildB* deepCopy(CopiesMap& copies) const 00238 { 00239 CopiesMap::iterator it = copies.find(this); 00240 if(it!=copies.end()) 00241 return (ChildB*) it->second; 00242 00244 ChildB* dcopy = new ChildB(*this); 00245 dcopy->childAPP = PLearn::deepCopy( childAPP ); 00246 00248 if (usage() > 1) 00249 copies[this] = dcopy; 00250 00251 return dcopy; 00252 } 00253 }; 00254 00255 class Other : public PPointable 00256 { 00257 public: 00258 int i_other; 00259 string s_other; 00260 Other(int iother=0, string sother="other") : i_other(iother), s_other(sother) {} 00261 }; 00262 00263 00264 class Test_PP 00265 { 00266 public: 00267 PP<ChildA>* child_a_array; 00268 PP<ChildB>* child_b_array; 00269 PP<Parent>* parent_array; 00270 PP<Other> otherPP; 00271 int size_a; 00272 int size_b; 00273 int size_p; 00274 00275 Test_PP() 00276 { 00277 child_a_array = new PP<ChildA>[MAX_SIZE]; 00278 child_b_array = new PP<ChildB>[MAX_SIZE]; 00279 parent_array = new PP<Parent>[MAX_SIZE]; 00280 otherPP = new Other(99, "ninety-nine"); 00281 cout << endl << "***** STARTING TEST_PP *****" << endl << endl; 00282 size_a = 0; 00283 size_b = 0; 00284 size_p = 0; 00285 } 00286 00290 bool emptyCons(); 00291 bool copieConsOrdinaryPtr(); 00292 bool copieConsSameTypePP(); 00293 bool copieConsChildPP(); 00294 bool illegalCopieCons(); 00295 00296 00298 bool conversionOrdinaryPtr(); // tests: PP::operator T*() const 00299 bool accessPointedObject(); // tests: T& PP:operator*() const 00300 bool affectationFromOrdPtr(); // tests: void PP::operator=(const T* otherptr) 00301 bool affectationFromPP(); // tests: void PP::operator=(const PP<T>& other) 00302 bool tryDeepCopy(); // tests; inline T* deepCopy(PP<T> source) 00303 00304 private: 00307 void invariants(int oddIndex, int evenIndex); 00309 bool conversionOPchildA(); 00310 bool conversionOPchildB(); 00311 bool conversionOPparent(); 00312 }; 00313 00314 00315 // ----------------- tests on constructors -------------------------------------- 00317 bool Test_PP::emptyCons() 00318 { 00320 PP<ChildA> childAPP0; 00321 child_a_array[0] = childAPP0; 00322 size_a++; 00323 cout << " - Empty constructor verified for class ChildA " << endl; 00324 00326 PP<ChildB> childBPP0; 00327 child_b_array[0] = childBPP0; 00328 size_b++; 00329 cout << " - Empty constructor verified for class ChildB " << endl; 00330 00332 PP<Parent> parentPP0; 00333 parent_array[0] = parentPP0; 00334 size_p++; 00335 cout << " - Empty constructor verified for class Parent " << endl; 00336 cout << "--- Empty constructor verified ---" << endl << endl; 00337 return true; 00338 } 00339 00341 bool Test_PP::copieConsOrdinaryPtr() 00342 { 00344 PP<ChildA> childAPP1 = new ChildA(1, "one_hundred", 100); 00345 T_ASSERT(childAPP1->usage()==1 , 00346 "Error in call to ->usage() while testing ChildA's \n" 00347 "copie constructors with ordinary ptr"); 00348 child_a_array[1] = childAPP1; 00349 size_a++; 00350 00351 ChildA childA2; 00352 childA2.i_child_a = 2; 00353 childA2.i_par = 200; 00354 childA2.s_par = "two_hundred"; 00355 ChildA* ptr2= new ChildA(childA2); 00356 PP<ChildA> childAPP2(ptr2); 00357 T_ASSERT(childAPP2->usage()==1 ,"Error in call to ->usage() while testing ChildA's \ncopie constructors with ordinary ptr"); 00358 child_a_array[2] = childAPP2; 00359 size_a++; 00360 cout << " - Copie constructor with ordinary pointers verified for class ChildA" << endl; 00361 00362 00364 PP<ChildB> childBPP1 = new ChildB("one"); 00365 T_ASSERT(childBPP1->usage()==1 ,"Error in call to ->usage() while testing ChildB's \ncopie constructors with ordinary ptr"); 00366 child_b_array[1] = childBPP1; 00367 size_b++; 00368 00369 ChildB childB2; 00370 childB2.s_child_b = "two__"; 00371 childB2.i_par = 200; 00372 childB2.s_par = "two_hundred"; 00373 ChildB* ptr22 = new ChildB(childB2); 00374 PP<ChildB> childBPP2(ptr22); 00375 T_ASSERT(childBPP2->usage()==1 ,"Error in call to ->usage() while testing ChildB's \ncopie constructors with ordinary ptr"); 00376 child_b_array[2] = childBPP2; 00377 size_b++; 00378 cout << " - Copie constructor with ordinary pointers verified for class ChildB" << endl; 00379 00381 PP<Parent> parentPP1 = new Parent(100, "one_hundred" ); 00382 T_ASSERT(parentPP1->usage()==1 ,"Error in call to ->usage() while testing Parent's \ncopie constructors with ordinary ptr"); 00383 parent_array[1] = parentPP1; 00384 size_p++; 00385 00386 Parent parent2; 00387 parent2.i_par=200; 00388 parent2.s_par="two_hundred"; 00389 Parent* ptr200 = new Parent(parent2); 00390 PP<Parent> parentPP2(ptr200); 00391 T_ASSERT(parentPP2->usage()==1 ,"Error in call to ->usage() while testing Parent's \ncopie constructors with ordinary ptr"); 00392 parent_array[2] = parentPP2; 00393 size_p++; 00394 cout << " - Copie constructor with ordinary pointers verified for class Parent" << endl; 00395 00396 cout << "--- Copie constructor with ordinary pointers verified ---" << endl << endl; 00397 return true; 00398 } 00399 00401 bool Test_PP::copieConsSameTypePP(){ 00403 PP<ChildA> childAPP3(child_a_array[1]); 00404 T_ASSERT(child_a_array[1]->usage()==2 && childAPP3->usage()==2 , 00405 "Error in call to ->usage() while testing ChildA's \ncopie constructors with same type of PP"); 00406 child_a_array[3] = childAPP3; 00407 size_a++; 00408 00409 PP<ChildA> childAPP4(child_a_array[2]); 00410 T_ASSERT(child_a_array[2]->usage()==2 && childAPP4->usage()==2 , 00411 "Error in call to ->usage() while testing ChildA's \ncopie constructors with same type of PP"); 00412 child_a_array[4] = childAPP4; 00413 size_a++; 00414 cout << " - Copie constructor with same type of PP verified for class ChildA " << endl; 00415 00417 PP<ChildB> childBPP3(child_b_array[1]); 00418 T_ASSERT(child_b_array[1]->usage()==2 && childBPP3->usage()==2, 00419 "Error in call to ->usage() while testing ChildB's \ncopie constructors with same type of PP"); 00420 child_b_array[3] = childBPP3; 00421 size_b++; 00422 00423 PP<ChildB> childBPP4(child_b_array[2]); 00424 T_ASSERT(child_b_array[2]->usage()==2 && childBPP4->usage()==2, 00425 "Error in call to ->usage() while testing ChildB's \ncopie constructors with same type of PP"); 00426 child_b_array[4] = childBPP4; 00427 size_b++; 00428 cout << " - Copie constructor with same type of PP verified for class ChildB" << endl; 00429 00431 PP<Parent> parentPP3(parent_array[1]); 00432 T_ASSERT(parent_array[1]->usage()==2 && parentPP3->usage()==2, 00433 "Error in call to ->usage() while testing Parent's \ncopie constructors with same type of PP"); 00434 parent_array[3] = parentPP3; 00435 size_p++; 00436 00437 PP<Parent> parentPP4(parent_array[2]); 00438 T_ASSERT(parent_array[2]->usage()==2 && parentPP4->usage()==2 , 00439 "Error in call to ->usage() while testing Parent's \ncopie constructors with same type of PP"); 00440 parent_array[4] = parentPP4; 00441 size_p++; 00442 cout << " - Copie constructor with same type of PP verified for class Parent" << endl; 00443 cout << "--- Copie constructor with other PPs verified ---" << endl << endl; 00444 return true; 00445 } 00446 00447 00449 bool Test_PP::copieConsChildPP() 00450 { 00452 PP<Parent> parentPP5(child_a_array[1]); 00453 T_ASSERT(child_a_array[1]->usage()==3 && child_a_array[3]->usage()==3 && parentPP5->usage()==3 , 00454 "Error in call to ->usage() while testing Parent's \ncopie constructors with other type of PP"); 00455 parent_array[5]= parentPP5; 00456 size_p++; 00457 00458 PP<Parent> parentPP6(child_b_array[2]); 00459 T_ASSERT(child_b_array[2]->usage()==3 && child_b_array[4]->usage()==3 && parentPP6->usage()==3 , 00460 "Error in call to ->usage() while testing Parent's \ncopie constructors with other type of PP"); 00461 parent_array[6]= parentPP6; 00462 size_p++; 00463 00464 cout << "--- Copie constructor with other PP type verified (for class Parent)---" << endl << endl; 00465 return true; 00466 } 00467 00468 00470 bool Test_PP::illegalCopieCons() 00471 { 00472 #ifdef CHECK_COMPILATION 00473 00474 PP<ChildA> childAPP4(parent_array[2]); 00475 child_a_array[4] = childAPP4; 00476 00478 PP<ChildA> childAPP4(child_a__array[2]); 00479 child_a_array[4] = childAPP4; 00480 00482 PP<Parent> parentPP4(otherPP); 00483 parent_array[4] = parentPP4; 00484 cout << "--- Illegal Copie constructors should not be verified: error has occured!---" << endl << endl; 00485 #endif 00486 return true; 00487 } 00488 00489 00490 // ----------------- tests on methods ---------------------------------------------- 00491 00492 00494 // tests: PP::operator T*() const 00495 bool Test_PP::conversionOrdinaryPtr() 00496 { 00497 bool result = conversionOPchildA(); 00498 invariants(3,2); 00499 00500 result = result && conversionOPchildB(); 00501 invariants(3,2); 00502 00503 result = result && conversionOPparent(); 00504 invariants(3,2); 00505 00506 cout << "--- Conversion to ordinary ptr verified ---" << endl << endl; 00507 return true; 00508 } 00509 00512 // tests: T& PP:operator*() const 00513 bool Test_PP::accessPointedObject() 00514 { 00515 int i; 00516 // for ChildA 00517 cout << "Printing child_a_array:" << endl; 00518 for( i=1; i< size_a; i++) 00519 { 00520 cout << "child_a_array[" << i << "]: " << flush; 00521 (*child_a_array[i]).print(cout); 00522 } 00523 00524 // for ChildB 00525 cout << endl << "Printing child_b_array:" << endl; 00526 for( i=1; i< size_b; i++) 00527 { 00528 cout << "child_b_array[" << i << "]: " << flush; 00529 (*child_b_array[i]).print(cout); 00530 } 00531 00532 // for Parent 00533 cout << endl << "Printing parent_array:" << endl; 00534 for( i=1; i< size_p; i++) 00535 { 00536 cout << "parent_array[" << i << "]: " << flush; 00537 (*parent_array[i]).print(cout); 00538 } 00539 cout << endl; 00540 00541 return true; 00542 } 00543 00545 // tests: void PP::operator=(const T* otherptr) 00546 bool Test_PP::affectationFromOrdPtr() 00547 { 00548 ChildA* aPtr = new ChildA(400, "four_hundred", 4); 00549 child_a_array[4] = aPtr; 00550 T_ASSERT( child_a_array[4]->i_par==400 && child_a_array[2]->i_par==200, 00551 "Error in affectationFromOrdPtr(): wrong ptr links in child_a_array" ); 00552 00553 ChildB* bPtr = new ChildB("one__"); 00554 child_b_array[1] = bPtr; 00555 (*child_b_array[1]).i_par = 100; 00556 child_b_array[1]->s_par = "one_hundred"; 00557 T_ASSERT( child_b_array[1]->i_par==100 && child_b_array[3]->i_par==300, 00558 "Error in affectationFromOrdPtr(): wrong ptr links in child_b_array" ); 00559 00560 Parent* pPtr = new Parent(400, "four_hundred"); 00561 parent_array[4] = pPtr; 00562 T_ASSERT( parent_array[4]->i_par==400 && parent_array[2]->i_par==200, 00563 "Error in affectationFromOrdPtr(): wrong ptr links in parent_array" ); 00564 pPtr = new Parent(300, "three_hundred"); 00565 parent_array[3] = pPtr; 00566 T_ASSERT( parent_array[1]->i_par==100 && parent_array[3]->i_par==300, 00567 "Error in affectationFromOrdPtr(): wrong ptr links in parent_array" ); 00568 pPtr = new Parent(600, "six_hundred"); 00569 parent_array[6]= pPtr; 00570 T_ASSERT( child_b_array[2]->i_par!=600 && child_b_array[4]->i_par!=600, 00571 "Error in affectationFromOrdPtr(): wrong ptr links between child_b_array and parent_array" ); 00572 00573 parent_array[6]= child_b_array[2]; 00574 00575 00576 // after affectationFromOrdPtr()... 00577 // a: {[1][3]p[5], [2], [4]} 00578 // b:{[1], [3], [2][4]p[6]} 00579 // p: {[1], [2], [3], [4], [5]a[1][3], [6]b[2][4]} 00580 accessPointedObject(); 00581 invariants(3,1); 00582 00583 return true; 00584 } 00585 00586 00587 // tests: void PP::operator=(const PP<T>& other) 00588 bool Test_PP::affectationFromPP() 00589 { 00590 // for ChildA 00591 parent_array[7]= new Parent(700, "seven_hundred"); 00592 size_p++; 00593 parent_array[8]= new Parent(800, "eight_hundred"); 00594 size_p++; 00595 parent_array[8]= child_a_array[4]; 00596 parent_array[7]= child_a_array[4]; 00597 child_a_array[2] = child_a_array[4]; 00598 T_ASSERT( child_a_array[2]->i_par==child_a_array[4]->i_par , 00599 "1-Error in affectationFromPP(): wrong ptr links in child_a_array" ); 00600 T_ASSERT( child_a_array[4]->i_par==parent_array[7]->i_par && parent_array[7]->i_par==parent_array[8]->i_par, 00601 "2-Error in affectationFromPP(): wrong ptr links in child_a_array" ); 00602 00603 // for ChildB 00604 parent_array[10]= new Parent(10, "ten_hundred!!"); 00605 parent_array[9]=new Parent(900, "nine_hundred"); 00606 size_p+=2; 00607 parent_array[10]= child_b_array[3]; 00608 parent_array[9]= child_b_array[3]; 00609 child_b_array[1] = child_b_array[3]; 00610 T_ASSERT( child_b_array[1]->i_par==child_b_array[3]->i_par && child_b_array[1]->i_par==parent_array[9]->i_par 00611 && parent_array[9]->i_par==parent_array[10]->i_par, 00612 "3-Error in affectationFromPP(): wrong ptr links in child_b_array" ); 00613 00614 // for Parent 00615 parent_array[4] = parent_array[1]; 00616 parent_array[3] = parent_array[4]; 00617 parent_array[2] = parent_array[4]; 00618 T_ASSERT( parent_array[1]->i_par==parent_array[2]->i_par, 00619 "4-Error in affectationFromPP(): wrong ptr links in parent_array" ); 00620 T_ASSERT( parent_array[2]->i_par==parent_array[3]->i_par && parent_array[3]->i_par==parent_array[4]->i_par, 00621 "5-Error in affectationFromPP(): wrong ptr links in parent_array" ); 00622 00623 accessPointedObject(); 00624 invariants(3,4); 00625 00626 return true; 00627 } 00628 00629 00633 bool Test_PP::tryDeepCopy() 00634 { 00635 /* creating the pattern: 00636 : -parentPP --> : -parentPP --> 00637 child_a_array[i] | child_a_array[i+1} | etc. && parentPP: ->childBPP 00638 : -childBB --> : -childBB --> 00639 */ 00640 cout << "- creating pattern..." << endl; 00641 child_a_array[1] = new ChildA(100, "one_hundred", 1); 00642 child_a_array[2] = new ChildA(300, "three_hundred", 3); 00643 00644 child_a_array[1]->parentPP = new Parent(200,"two_hundred"); 00645 child_a_array[1]->childBPP = new ChildB("two"); 00646 child_a_array[1]->parentPP->childAPP = child_a_array[2]; 00647 child_a_array[1]->childBPP->childAPP = child_a_array[2]; 00648 child_a_array[1]->parentPP->childBPP = child_a_array[1]->childBPP; 00649 00650 00651 cout << "- deep copying..." << endl; 00653 ChildA* t = PLearn::deepCopy(child_a_array[1]); 00654 PP<ChildA> root_copy = t; 00655 00656 cout << "- verifying different levels of the deep copy..." << endl; 00659 PP<ChildA> root_copy2 = root_copy->parentPP->childAPP; 00660 root_copy2->i_child_a = 2; 00661 T_ASSERT(root_copy2->i_child_a == root_copy->childBPP->childAPP->i_child_a, 00662 "Error, the copy does not respect the initial map - root_copy1, i_child_a"); 00663 PP<ChildB> root_copy3 = root_copy->parentPP->childBPP; 00664 root_copy3->s_child_b = "two"; 00665 T_ASSERT(root_copy3->s_child_b == root_copy->childBPP->s_child_b, 00666 "Error, the copy does not respect the initial map - root copy1, s_child_b"); 00667 00668 // int i, j; 00669 // for(i=2; i<size_a && i<size_b; i++) 00670 // { 00671 // j = 2*(i-1); 00672 // child_a_array[i-1]->parentPP = new Parent(j*100, tostring(j)+(string)"_hundred"); 00673 // child_a_array[i-1]->childBPP = new ChildB( tostring(j)+(string)"s"); 00674 // child_a_array[i-1]->parentPP->childAPP = child_a_array[i]; 00675 // child_a_array[i-1]->childBPP->childAPP = child_a_array[i]; 00676 // child_a_array[i-1]->parentPP->childBPP = child_a_array[i-1]->childBPP; 00677 // } 00678 00679 // cout << "- deep copying the root..." << endl; 00680 // //! deep copying the root 00681 // ChildA* test = PLearn::deepCopy(child_a_array[3]); 00682 // PP<ChildA> root_copy = test; 00683 00684 // cout << "- verifying different levels of the deep copy..." << endl; 00685 // //! 1rst T_ASSERT :asserts that the changes applied to childA through parent are respected within ChildB 00686 // //! 2nd T_ASSERT :asserts that the changes applied to childB through parent are respected within ChildA 00687 // PP<ChildA> root_copy2 = root_copy->parentPP->childAPP; 00688 // root_copy2->i_child_a = 2; 00689 // T_ASSERT(root_copy2->i_child_a == root_copy->childBPP->childAPP->i_child_a, 00690 // "Error, the copy does not respect the initial map - root_copy1, i_child_a"); 00691 // root_copy->parentPP->childBPP->s_child_b = "two"; 00692 // T_ASSERT(root_copy->parentPP->childBPP->s_child_b == root_copy->childBPP->s_child_b, 00693 // "Error, the copy does not respect the initial map - root copy1, s_child_b"); 00694 00695 // cout << "- root_copy1 done" << endl; 00696 00697 // PP<ChildA> root_copy3 = root_copy2->parentPP->childAPP; 00698 // root_copy3->i_child_a = 4; 00699 // T_ASSERT(root_copy3->i_child_a == root_copy2->childBPP->childAPP->i_child_a, 00700 // "Error, the copy does not respect the initial map - root_copy2, i_child_a"); 00701 // root_copy2->parentPP->childBPP->s_child_b = "four"; 00702 // T_ASSERT(root_copy->parentPP->childBPP->s_child_b == root_copy->childBPP->s_child_b, 00703 // "Error, the copy does not respect the initial map - root copy2, s_child_b"); 00704 00705 // cout << "- root_copy2 done" << endl; 00706 00707 // PP<ChildA> root_copy4 = root_copy3->parentPP->childAPP; 00708 // root_copy4->i_child_a = 6; 00709 // T_ASSERT(root_copy4->i_child_a == root_copy3->childBPP->childAPP->i_child_a, 00710 // "Error, the copy does not respect the initial map - root_copy3, i_child_a"); 00711 // root_copy3->parentPP->childBPP->s_child_b = "six"; 00712 // T_ASSERT(root_copy->parentPP->childBPP->s_child_b == root_copy->childBPP->s_child_b, 00713 // "Error, the copy does not respect the initial map - root copy3, s_child_b"); 00714 00715 // cout << "- root_copy3 done" << endl; 00716 00717 return true; 00718 } 00719 00720 00721 00722 00723 00724 00725 // ------------ private methods --------------------------------------------------------- 00726 00728 void Test_PP::invariants(int nb1, int nb2) 00729 { 00730 T_ASSERT(child_a_array[1]->usage()==nb1 && child_a_array[3]->usage()==nb1 && parent_array[5]->usage()==nb1, 00731 "1-Error in call to ->usage() in invariants()"); 00732 T_ASSERT(child_a_array[2]->usage()==nb2 && child_a_array[4]->usage()==nb2, 00733 "2-Error in call to ->usage() in invariants()"); 00734 T_ASSERT(child_b_array[1]->usage()==nb2 && child_b_array[3]->usage()==nb2, 00735 "3-Error in call to ->usage() in invariants() " + tostring(child_b_array[1]->usage())); 00736 T_ASSERT(child_b_array[2]->usage()==nb1 && child_b_array[4]->usage()==nb1 && parent_array[6]->usage()==nb1 , 00737 "4-Error in call to ->usage() in invariants()"); 00738 T_ASSERT(parent_array[1]->usage()==nb2 && parent_array[3]->usage()==nb2, 00739 "5-Error in call to ->usage() in invariants()"); 00740 T_ASSERT(parent_array[2]->usage()==nb2 && parent_array[4]->usage()==nb2 , 00741 "6-Error in call to ->usage() in invariants()"); 00742 } 00743 00745 bool Test_PP::conversionOPchildA() 00746 { 00747 string key = "hundred"; 00748 // for class ChildA 00749 ChildA* a = child_a_array[3]; 00750 int sum = (*a).i_child_a + a->i_par; 00751 T_ASSERT(sum==101, "The value of the integer fields in class ChildA are wrong:\n\t\tsum=" 00752 + tostring(sum) + " ,!=101"); 00753 int pos = (*a).s_par.find (key,0); // one_hundred: "hundred" in 4th pos 00754 T_ASSERT(pos==4,"The value of the string fields in class ChildA are wrong:\n\t\t pos=" 00755 + tostring(pos) + " ,!=4"); 00756 00757 //after modifiying the fields 00758 a->i_child_a=3; 00759 (*a).i_par=300; 00760 a->s_par="three_hundred"; 00761 sum = a->i_child_a + (*a).i_par; 00762 T_ASSERT(sum==303, "The value of the integer fields in class ChildA are wrong:\n\t\tsum=" 00763 + tostring(sum) + " ,!=303"); 00764 pos = (*a).s_par.find (key,0); // three_hundred: "hundred" in 6th pos 00765 T_ASSERT(pos==6,"The value of the string fields in class ChildA are wrong:\n\t\t pos=" 00766 + tostring(pos) + " ,!=6"); 00767 cout << " - Conversion to ordinary ptr verified for class ChildA" << endl; 00768 return true; 00769 } 00770 00772 bool Test_PP::conversionOPchildB() 00773 { 00774 string key = "hundred"; 00775 // for class ChildB 00776 ChildB* b = child_b_array[1]; 00777 string key2 = "e"; 00778 int pos = (*b).s_child_b.find(key2,0); // one: "e" in 2nd pos 00779 T_ASSERT(pos==2,"The value of the string fields in class ChildB are wrong:\n\t\t pos=" 00780 + tostring(pos)+ " ,!=2"); 00781 b->i_par = 100; 00782 b->s_par = "one_hundred"; 00783 T_ASSERT( b->i_par==100,"The value of the integer fields in class ChildB are wrong:\n\t\ti_par=" 00784 + tostring(b->i_par)+ " ,!=100"); 00785 00786 // after modifiying the fields 00787 b->i_par = 300; 00788 b->s_par = "three_hundred"; 00789 b->s_child_b = "three"; 00790 T_ASSERT( b->i_par==300,"The value of the integer fields in class ChildB are wrong:\n\t\ti_par=" 00791 + tostring(b->i_par) + " ,!=300"); 00792 pos = (*b).s_par.find(key2,0); // three_hundred: "hundred" in 6th pos 00793 T_ASSERT(pos==3,"The value of the string fields in class ChildB are wrong:\n\t\t pos=" 00794 +tostring(pos) + " ,!=3"); 00795 pos = (*b).s_child_b.find(key2,0); // three_hundred: "e" in 3rd pos 00796 T_ASSERT(pos==3,"The value of the string fields in class ChildB are wrong:\n\t\t pos=" 00797 + tostring(pos)+ " ,!=3"); 00798 00799 cout << " - Conversion to ordinary ptr verified for class ChildB" << endl; 00800 return true; 00801 } 00802 00804 bool Test_PP::conversionOPparent() 00805 { 00806 string key = "hundred"; 00807 // for class Parent 00808 Parent* p = parent_array[5]; 00809 00810 //p->i_par should have value 300 because of it's connection to [3] 00811 T_ASSERT( p->i_par==300,"The value of the integer fields in class Parent are wrong:\n\t\ti_par=" 00812 + tostring(p->i_par) + " ,!=300"); 00813 int pos = p->s_par.find(key,0); // three_hundred: "hundred" in 6th pos 00814 T_ASSERT(pos==6,"The value of the string fields in class Parent are wrong:\n\t\tpos=" 00815 + tostring(pos)+ " ,!=6"); 00816 00817 // after modifiying the fields 00818 p->s_par="five_hundred"; 00819 p->i_par=500; 00820 pos = p->s_par.find(key,0); // five_hundred: "hundred" in 5th pos 00821 T_ASSERT(pos==5,"The value of the string fields in class Parent are wrong:\n\t\tpos=" 00822 + tostring(pos)+ " ,!=5"); 00823 T_ASSERT( p->i_par==500,"The value of the integer fields in class Parent are wrong:\n\t\ti_par=" 00824 + tostring(p->i_par) + " ,!=500"); 00825 00826 p = child_a_array[3]; //p->i_par should have value 500 because of it's connection to [3]and[5] 00827 T_ASSERT( p->i_par==500,"The value of the integer fields in class Parent are wrong:\n\t\ti_par=" 00828 + tostring(p->i_par) + " ,!=500"); 00829 00830 p = child_a_array[1]; //p->i_par should have value 500 because of it's connection to [3]and[5] 00831 T_ASSERT( p->i_par==500,"IciThe value of the integer fields in class Parent are wrong:\n\t\ti_par=" 00832 + tostring(p->i_par) + " ,!=500"); 00833 00834 00835 cout << " - Conversion to ordinary ptr verified for class Parent" << endl; 00836 return true; 00837 } 00838 00840 // perform // 00842 void PPTest::perform() 00843 { 00844 Test_PP tpp; 00845 00846 cout << "Launching Test_TVec..." << endl; 00847 00848 DO_TEST("Empty Constructors", tpp.emptyCons()); 00849 DO_TEST("Copie Constructors with Ordinary Pointers", tpp.copieConsOrdinaryPtr()); 00850 DO_TEST("Copie Constructors with same PP type pointers",tpp.copieConsSameTypePP()); 00851 DO_TEST("Copie Constructors with other(child) PP type pointers",tpp.copieConsChildPP()); 00852 #ifdef CHECK_COMPILATION 00853 DO_TEST("Illegal Copie Constructors",tpp.illegalCopieCons()); 00854 #endif 00855 DO_TEST("Conversion to ordinary pointers",tpp.conversionOrdinaryPtr()); 00856 DO_TEST("Access pointed objects",tpp.accessPointedObject()); 00857 DO_TEST("Affectation from ordinary pointers", tpp.affectationFromOrdPtr()); 00858 DO_TEST("Affectation between PP pointers",tpp.affectationFromPP()); 00860 //DO_TEST("Deep Copy of a PP<childA> root",tpp.tryDeepCopy()); 00861 00862 cout << "Quitting Test_TVec..." << endl; 00863 } 00864 00865 } // end of namespace PLearn 00866 00867 00868 /* 00869 Local Variables: 00870 mode:c++ 00871 c-basic-offset:4 00872 c-file-style:"stroustrup" 00873 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00874 indent-tabs-mode:nil 00875 fill-column:79 00876 End: 00877 */ 00878 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :