PLearn 0.1
PPTest.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines