// test_iterJava.cpp (c) 2009 adolfo@di-mare.com /** \file test_iterJava.cpp \brief Test ==> class iterJava<>. \author Adolfo Di Mare \date 2009 - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04 */ #include "iterJava.h" #include "str2list.h" #include "BUnit.h" #include /// Test ==> \c iterJava<>. class test_iterJava : public TestCase { public: bool run(); private: void test_example(); void test_const_example(); void test_examplePtr(); void test_assign(); void test_set_CCC(); void test_next(); void test_erase(); void test_palindrome(); void test_palindromo(); void test_setReverse(); void test_isPalindrome(); void test_Tree_BF(); void test_Tree_PLR(); void test_Tree_LPR(); void test_Tree_LRP(); }; // test_iterJava /// Test ==> \c iterJava<> ==> \c run(). bool test_iterJava::run() { test_example(); test_const_example(); test_examplePtr(); test_assign(); test_set_CCC(); test_next(); test_erase(); test_palindrome(); test_palindromo(); test_setReverse(); test_isPalindrome(); test_Tree_BF(); test_Tree_PLR(); test_Tree_LPR(); test_Tree_LRP(); return wasSuccessful(); } std::list makeList_long(const char* V); // forward declaration /// Test ==> \c iterJava<> ==> \c example(). void test_iterJava::test_example() { {{ // test::example() std::list Lfwd, Lbck, L; assertTrue( Lfwd.empty() && L.empty() ); L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::iterator > itFwd( L.begin(), L.end() ); iterJava< std::list::iterator > itBck( L.begin(), L.end() ); itBck.setReverse(); while ( itFwd.hasNext() && itBck.hasNext() ) { Lfwd.push_back( itFwd.next() ); Lbck.push_back( itBck.next() ); } assertTrue( Lfwd == makeList_long( "( 1 2 3 4 5 )" ) ); assertTrue( Lbck == makeList_long( "( 5 4 3 2 1 )" ) ); }} { std::list Lcp, L; { // L.empty() L = makeList_long( "" ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); assertTrue( ! iter.hasNext() ); } { // L.size() == 1 L = makeList_long( " 1 " ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); assertTrue( iter.hasNext() ); assertTrue( iter.next() == 1 ); assertTrue( ! iter.hasNext() ); } { // L.size() == 2 L = makeList_long( " 1 2 " ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); assertTrue( iter.hasNext() ); assertTrue( iter.next() == 1 ); assertTrue( iter.hasNext() ); assertTrue( iter.next() == 2 ); assertTrue( ! iter.hasNext() ); iter.set( L ); assertTrue( iter.next() == 1 ); L.erase(iter); assertTrue( iter.next() == 2 ); assertTrue( ! iter.hasNext() ); } { // L.empty() std::list Lcp; L = makeList_long( " 5 4 3 2 1 " ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); iter.setReverse(); while ( iter.hasNext() ) { Lcp.push_back( iter.next() ); } assertTrue( Lcp == makeList_long( "( 1 2 3 4 5 )" ) ); } } } /// Test ==> \c iterJava<> ==> \c examplePtr(). void test_iterJava::test_examplePtr() { {{ // test::examplePtr() #define dim(V) ( sizeof(V)/sizeof(*V) ) std::list L; int VEC[] = { 1, 2, 3, 4, 5 }; iterJava< int* > iter( VEC, VEC+dim(VEC) ); while ( iter.hasNext() ) { L.push_back( iter.next() ); } assertTrue( L == makeList_long( "( 1 2 3 4 5 )" ) ); }} #undef dim } /// Test ==> \c iterJava<> ==> \c const_example(). void test_iterJava::test_const_example() { #ifdef const_error #warning Macro [const_error] already defined #endif {{ // test::const_example() #define const_error #undef const_error std::list Lcp, L; assertTrue( Lcp.empty() ); L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::const_iterator > iter( L.begin(),L.end() ); while ( iter.hasNext() ) { Lcp.push_back( iter.next() ); #ifdef const_error L.erase(iter); // forbidden for const_iterator #endif } assertTrue( L == Lcp ); iterJava< std::list::const_iterator > IT = iter; assertTrue( IT == iter && !( IT.hasNext() ) && !( IT != iter ) ); #undef const_error }} { // const list<>& std::list Lcp, L; assertTrue( Lcp.empty() ); L = longlist( "( 1 2 3 4 5 )" ); const std::list & L_const = L; iterJava< std::list::const_iterator > iter( L_const.begin(),L_const.end() ); while ( iter.hasNext() ) { Lcp.push_back( iter.next() ); } assertTrue( L == Lcp ); iterJava< std::list::const_iterator > IT = iter; assertTrue( IT == iter && !( IT.hasNext() ) && !( IT != iter ) ); } } #include #ifdef English_dox /// Implementation to show that const_iterator cannot be used to erase values. #endif #ifdef Spanish_dox /// Implementación en la que se muestra que un \c const_iterator no se puede usar para eliminar valores. #endif void const_compile_error( std::list &L ) { typedef iterJava< std::list::const_iterator > Iter; Iter iter( L.begin(),L.end() ); while ( iter.hasNext() ) { // L.erase(iter); // forbidden for const_iterator } assert( L.empty() ); } template bool isPalindrome( const C& CCC ); /// Test ==> \c iterJava<> ==> \c isPalindrome(). void test_iterJava::test_isPalindrome() { {{ // test::isPalindrome() assertFalse( isPalindrome( makeList_long( "( 1 2 3 4 5 )" ) ) ); assertTrue( isPalindrome( makeList_long( "( 1 2 3 2 1 )" ) ) ); assertTrue( isPalindrome( makeList_long( "( 1 )" ) ) ); assertTrue( isPalindrome( makeList_long( "( 1 2 1 )" ) ) ); assertTrue( isPalindrome( makeList_long( "( )" ) ) ); }} } /// Test ==> \c iterJava<> ==> \c palindrome(). void test_iterJava::test_palindrome() { {{ // test::palindrome() std::list L = makeList_long( "( 1 2 3 2 1 )" ); typedef std::list::const_iterator IterFwd; typedef std::reverse_iterator IterBck; iterJava< IterFwd > itFwd( L.begin(), L.end() ); iterJava< IterBck > itBck( L.rbegin(), L.rend() ); while ( itFwd.hasNext() && itBck.hasNext() ) { if ( itFwd.next() != itBck.next() ) { assertTrue( "palindrome error" && false ); } } assertTrue( !itFwd.hasNext() && !itBck.hasNext() ); }} { std::list L = makeList_long( "( 1 2 3 2 1 )" ); typedef std::list::const_iterator Iter; iterJava< Iter > itFwd, itBck; itFwd.set(L); itBck.set(L); itBck.setReverse(); while ( itFwd.hasNext() && itBck.hasNext() ) { if ( itFwd.next() != itBck.next() ) { assertTrue( "palindrome error" && false ); } } assertTrue( !itFwd.hasNext() && !itBck.hasNext() ); } } /// Test ==> \c iterJava<> ==> \c setReverse(). void test_iterJava::test_setReverse() { {{ // test::setReverse() std::list L = makeList_long( "( 1 2 3 4 5 )" ); typedef std::list::const_iterator Iter; iterJava< Iter > itFwd, itBck; itFwd.set(L); assertTrue( itFwd.next() == 1 ); // next() ! itFwd.setReverse(); // NOP !!! assertTrue( itFwd.isForward() ); itBck.set(L); itBck.setReverse(); assertTrue( !itBck.isForward() ); assertTrue( itBck.isBackward() && itBck.isReverse() ); assertTrue( itBck.next() == 5 ); itFwd.set(L); itFwd.setReverse(); assertTrue( ! itFwd.isForward() && itFwd.isReverse() ); }} { } } #if 1 template bool isPalindrome( const C& CCC ) {{ typedef typename C::const_iterator Iter; iterJava< Iter > itFwd, itBck; itFwd.set(CCC); itBck.set(CCC); itBck.setReverse(); while ( itFwd.hasNext() && itBck.hasNext() ) { if ( itFwd.next() != itBck.next() ) { return false; } } return ( !itFwd.hasNext() && !itBck.hasNext() ); }} #else template bool isPalindrome( const C& CCC ) {{ typedef typename C::const_iterator IterFwd; typedef typename std::reverse_iterator IterBck; iterJava< IterFwd > itFwd( CCC.begin(), CCC.end() ); iterJava< IterBck > itBck( CCC.rbegin(), CCC.rend() ); while ( itFwd.hasNext() && itBck.hasNext() ) { if ( itFwd.next() != itBck.next() ) { return false; } } return ( !itFwd.hasNext() && !itBck.hasNext() ); }} #endif #ifdef English_dox /** \fn isPalindrome( const C& CCC ) Returns \c true when \c CCC is a palindrome. - Traversing a palindrome forward yields the same secuence of values as traversing it backwards. \dontinclude test_iterJava.cpp \skipline test::palindrome() \until }} \dontinclude test_iterJava.cpp \skipline isPalindrome( const C& CCC ) {{ \until }} \dontinclude test_iterJava.cpp \skipline test::isPalindrome() \until }} \see test_iterJava::test_palindrome() \see test_iterJava::test_isPalindrome() */ #endif #ifdef Spanish_dox /** \fn isPalindrome( const C& CCC ) Retorna \c true si \c CCC es un palíndromo. - Al recorrer un palíndromo hacia adelante se obtienen los mismo valors que al recorrerlo hacia atrás. \dontinclude test_iterJava.cpp \skipline test::palindrome() \until }} \dontinclude test_iterJava.cpp \skipline isPalindrome( const C& CCC ) {{ \until }} \dontinclude test_iterJava.cpp \skipline test::isPalindrome() \until }} \see test_iterJava::test_palindrome() \see test_iterJava::test_isPalindrome() */ #endif /// Test ==> \c iterJava<> ==> \c palindrome(). void test_iterJava::test_palindromo() { bool palindromo(const std::list< std::string >& L); {{ // test::palindromo() assertTrue( palindromo( str2list( "[ 1 2 3 2 1 ]") ) ); assertFalse( palindromo( str2list( "[ 1 2 3 2 0 ]") ) ); assertTrue( palindromo( str2list( "[ r a d a r ]") ) ); assertFalse( palindromo( str2list( "[ M A J E M ]") ) ); }} } /** Regresa true si al recorrer el contenedor "L" hacia adelante se obtiene el mismo resultado que al recorrerlo hacia atrás. Un palíndromo es una palabra que se lee igual al derecho que al revés. \dontinclude test_iterJava.cpp \skipline test::palindromo() \until }} */ bool palindromo(const std::list< std::string >& L) { return isPalindrome(L); } /// Test ==> \c iterJava<> ==> \c next(). void test_iterJava::test_next() { {{ // test::next() std::list L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); int trngl = 3; while ( iter.hasNext() ) { switch (trngl++ % 3) { case 0: { // reference long & l = iter.next(); l++; break; } case 1: { // pointer long * p = & iter.next(); (*p)++; break; } case 2: { // direct iter.next()++; break; } } } assertTrue( L == makeList_long( "( 2 3 4 5 6 )" ) ); }} if (false) { // cannot erase with 2 iterators over the same container std::list L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::iterator > itFwd( L.begin(), L.end() ); iterJava< std::list::iterator > itBck( L.begin(), L.end() ); itBck.setReverse(); int n=0; while ( itFwd.hasNext() && itBck.hasNext() ) { ++n; L.push_back( itFwd.next() ); L.push_back( itBck.next() ); if ( itFwd.current() == itBck.current() ) { break; } L.erase(itFwd); L.erase(itBck); } assertTrue( L.size() != 7 ); assertTrue( n == 3 ); assertTrue( itFwd.next() == 3 ); assertTrue( itBck.next() == 3 ); } } /// Test ==> \c iterJava<> ==> \c set(CCC). void test_iterJava::test_set_CCC() { {{ // test::set_CCC() std::list L1 = makeList_long( "( 1 2 3 4 5 )" ); std::list L2 = makeList_long( "( 6 7 8 9 )" ); iterJava< std::list::iterator > iter( L1.begin(), L1.end() ); int i = 0; while ( iter.hasNext() ) { // L1 i++; assertTrue( i == iter.next() ); L1.erase( iter ); } iter.set( L2 ); while ( iter.hasNext() ) { // L2 i++; assertTrue( i == iter.next() ); } assertTrue( L1.empty() ); }} { // same but reversed std::list L1 = makeList_long( "( 1 2 3 4 5 )" ); std::list L2 = makeList_long( "( 6 7 8 9 )" ); iterJava< std::list::iterator > iter; iter.set( L2 ); iter.setReverse(); int i = 10; while ( iter.hasNext() ) { // L2 i--; assertTrue( i == iter.next() ); } iter.set( L1 ); iter.setReverse(); while ( iter.hasNext() ) { // L1 i--; assertTrue( i == iter.next() ); } } } /// Test ==> \c iterJava<> ==> \c assign(CCC). void test_iterJava::test_assign() { {{ // test::assign() std::list L, Lcp; L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::const_iterator > iter123; iterJava< std::list::const_iterator > iter45; iter123.set( L.begin(), L.end() ); // full range int i=1; while ( i<=3 ) { assertTrue( i == iter123.next() ); Lcp.push_back( i ); ++i; } iter45 = iter123; // iter45 <==> iter123 while ( i<=5 ) { assertTrue( i == iter45.next() ); Lcp.push_back( i ); ++i; } assertTrue( Lcp == makeList_long( "( 1 2 3 4 5 )" ) ); }} { // non-const test std::list L, Lcp; L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::iterator > iter123; iterJava< std::list::iterator > iter45; iter123.set( L.begin(), L.end() ); // full range int i=1; while ( i<=3 ) { assertTrue( i == iter123.next() ); Lcp.push_back( i ); L.erase( iter123 ); ++i; } iter45 = iter123; while ( i<=5 ) { // iter45 <==> iter123 assertTrue( i == iter45.next() ); Lcp.push_back( i ); L.erase( iter45 ); ++i; } assertTrue( Lcp == makeList_long( "( 1 2 3 4 5 )" ) ); assertTrue( L.empty() ); } } /// Test ==> \c iterJava<> ==> \c erase(). void test_iterJava::test_erase() { {{ // test::erase() std::list L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list::iterator > iter( L.begin(), L.end() ); int i = 0; while ( iter.hasNext() ) { assertTrue( ! L.empty() ); long *pL = & iter.next(); i++; assertTrue( i == *pL ); L.erase( iter ); // L.erase( iter.current() ); } assertTrue( L.empty() ); }} { } } #include "Tree_BF.h" // test multiple inclusion #include "Tree_LRP.h" #include "Tree_LPR.h" #include "Tree_PLR.h" #include "Tree_BF.h" #include "Tree_LRP.h" #include "Tree_LPR.h" #include "Tree_PLR.h" /// Test ==> \c iterJava<> ==> \c Tree_BF(). void test_iterJava::test_Tree_BF() { void make_a_o(TL::Tree & T); // forward declaration {{ // test::Tree_BF() TL::Tree T; make_a_o(T); Tree_BF iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "abcdefghijklmno" && "Tree_BF" ); }} if (false) { // T.empty() && 1 == T.Count() TL::Tree T; Tree_BF iter; iter.set(T); assertTrue( ! iter.hasNext() && "Tree_BF" ); T = 'A'; iter.set(T); assertTrue( iter.hasNext() && "Tree_BF" ); assertTrue( 'A' == iter.next().Data() && "Tree_BF" ); assertTrue( ! iter.hasNext() && "Tree_BF" ); } { TL::Tree T; Tree_BF iter; std::string L; T = 'A'; T.Change_Child(1,'1'); T.Child(1).Change_Child(2,'2'); T.Child(1).Child(2).Change_Child(3,'3'); iter.set(T); L.clear(); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "A123" && "Tree_BF" ); } // T = 0 // ./ \. // 1 2 // ./ \ / \. // 3 4 5 6 void make_0_6(TL::Tree & T); // forward declaration { TL::Tree T; make_0_6(T); Tree_BF iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "0123456" && "Tree_BF" ); } // T = F // ./ \. // B G // ./ \ \. // A D I // ./ \ /. // C E H void make_A_H(TL::Tree & T); // forward declaration { TL::Tree T; make_A_H(T); Tree_BF iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "FBGADICEH" && "Tree_BF" ); } // T = A // ./ \. // ./ \. // ./ \. // B C // ./ \ / \. // D E F G // ./ \ / \ / \ / \. // H I J K L M N O void make_A_O(TL::Tree & T); // forward declaration { TL::Tree T; make_A_O(T); Tree_BF iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "ABCDEFGHIJKLMNO" && "Tree_BF" ); } } /// Test ==> \c iterJava<> ==> \c Tree_PLR(). void test_iterJava::test_Tree_PLR() { void make_a_o(TL::Tree & T); {{ // test::Tree_PLR() TL::Tree T; make_a_o(T); Tree_PLR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "abfghcdeijlmnok" && "Tree_PLR" ); }} if (true) { // T.empty() && 1 == T.Count() TL::Tree T; Tree_PLR iter; iter.set(T); assertTrue( ! iter.hasNext() && "Tree_PLR" ); T = 'A'; iter.set(T); assertTrue( iter.hasNext() && "Tree_PLR" ); assertTrue( 'A' == iter.next().Data() && "Tree_PLR" ); assertTrue( ! iter.hasNext() && "Tree_PLR" ); } // T = 0 // ./ \. // 1 2 // ./ \ / \. // 3 4 5 6 void make_0_6(TL::Tree & T); // forward declaration { TL::Tree T; make_0_6(T); Tree_PLR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "0134256" && "Tree_PLR" ); } // T = F // ./ \. // B G // ./ \ \. // A D I // ./ \ /. // C E H void make_A_H(TL::Tree & T); // forward declaration { TL::Tree T; make_A_H(T); Tree_PLR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "FBACEDGIH" && "Tree_PLR" ); } // T = A // ./ \. // ./ \. // ./ \. // B C // ./ \ / \. // D E F G // ./ \ / \ / \ / \. // H I J K L M N O void make_A_O(TL::Tree & T); // forward declaration { TL::Tree T; make_A_O(T); Tree_PLR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "ABDHIEJKCFLMGNO" && "Tree_PLR" ); } } /// Test ==> \c iterJava<> ==> \c Tree_LPR(). void test_iterJava::test_Tree_LPR() { void make_a_o(TL::Tree & T); {{ // test::Tree_LPR() TL::Tree T; make_a_o(T); Tree_LPR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "fbghacdieljnmok" && "Tree_LPR" ); }} if (false) { // T.empty() && 1 == T.Count() // WABE !!! TL::Tree T; Tree_LPR iter; iter.set(T); assertTrue( ! iter.hasNext() && "Tree_LPR" ); T = 'A'; iter.set(T); assertTrue( iter.hasNext() && "Tree_LPR" ); assertTrue( 'A' == iter.next().Data() && "Tree_LPR" ); assertTrue( ! iter.hasNext() && "Tree_LPR" ); } // T = 0 // ./ \. // 1 2 // ./ \ / \. // 3 4 5 6 void make_0_6(TL::Tree & T); // forward declaration { TL::Tree T; make_0_6(T); Tree_LPR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "3140526" && "Tree_LPR" ); assertTrue( L != "314526" && "Tree_LPR [T.Root() missing]" ); } // T = F // ./ \. // B G // ./ \ \. // A D I // ./ \ /. // C E H void make_A_H(TL::Tree & T); // forward declaration { TL::Tree T; make_A_H(T); assertTrue( check_ok(T) ); Tree_LPR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "CAEBDFGHI" && "Tree_LPR" ); assertTrue( L != "CAEDHI" && "Tree_LPR [ BFG missing ]" ); assertTrue( L != "CAEBDFGHIH" && "Tree_LPR [Extra H]" ); assertTrue( L != "CAEBDFG" && "Tree_LPR [ HI missing ]" ); } // T = A // ./ \. // ./ \. // ./ \. // B C // ./ \ / \. // D E F G // ./ \ / \ / \ / \. // H I J K L M N O void make_A_O(TL::Tree & T); // forward declaration { TL::Tree T; make_A_O(T); Tree_LPR iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "HDIBJEKALFMCNGO" && "Tree_LPR" ); assertTrue( L != "HDIJEKLFMNGO" && "Tree_LPR [ BAC missing ]" ); } } /// Test ==> \c iterJava<> ==> \c Tree_LRP(). void test_iterJava::test_Tree_LRP() { void make_a_o(TL::Tree & T); {{ // test::Tree_LRP() TL::Tree T; make_a_o(T); Tree_LRP iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "fghbcdilnomjkea" && "Tree_LRP" ); }} if (false) { // T.empty() && 1 == T.Count() // WABE !!! TL::Tree T; Tree_LRP iter; iter.set(T); assertTrue( ! iter.hasNext() && "Tree_LRP" ); T = 'A'; iter.set(T); assertTrue( iter.hasNext() && "Tree_LRP" ); assertTrue( 'A' == iter.next().Data() && "Tree_LRP" ); assertTrue( ! iter.hasNext() && "Tree_LRP" ); } // T = 0 // ./ \. // 1 2 // ./ \ / \. // 3 4 5 6 void make_0_6(TL::Tree & T); // forward declaration { TL::Tree T; make_0_6(T); Tree_LRP iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "3415620" && "Tree_LRP" ); } // T = F // ./ \. // B G // ./ \ \. // A D I // ./ \ /. // C E H void make_A_H(TL::Tree & T); // forward declaration { TL::Tree T; make_A_H(T); Tree_LRP iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "CEADBHIGF" && "Tree_LRP [Wabe]" ); assertTrue( L != "CEADBHIF" && "Tree_LRP [ G missing ]" ); } // T = A // ./ \. // ./ \. // ./ \. // B C // ./ \ / \. // D E F G // ./ \ / \ / \ / \. // H I J K L M N O void make_A_O(TL::Tree & T); // forward declaration { TL::Tree T; make_A_O(T); Tree_LRP iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree S = iter.next(); L.push_back( *S ); } assertTrue( L == "HIDJKEBLMFNOGCA" && "Tree_LRP [Wabe]" ); assertTrue( L != "HIDJKEBLMFNOGA" && "Tree_LRP [ C missing ]" ); } } /** T = ( a ( b ( f g h ) c d e ( i j ( l m ( n o ) ) k ) ). \code T = a |--b | |--f T = a | |--g /|\ | +--h / / \ \ |--c b c d e |--d /|\ /|\ +--e f g h i j k |--i / \ |--j l m | |--l / \ | +--m n o | |--n | +--o +--k \endcode */ void make_a_o(TL::Tree & T) { TL::Tree Th; T.Erase(); T = 'a'; // inserta la raiz 'A' /***********************************/ T.Change_Child(0, 'b'); // a T.Change_Child(1, 'c'); // ./|\. T.Change_Child(2, 'd'); // ./ / \ \. T.Change_Child(3, 'e'); // b c d e /***********************************/ Th = T.Child(0); // 'b' Th.Change_Child(0, 'f'); // b Th.Change_Child(1, 'g'); // ./|\. Th.Change_Child(2, 'h'); // f g h /***********************************/ Th = T.Child(3); // 'e' Th.Change_Child(0, 'i'); // e Th.Change_Child(1, 'j'); // ./|\. Th.Change_Child(2, 'k'); // i j k /***********************************/ Th = Th.Child(1); // 'j' Th.Change_Child(0, 'l'); // ./ \. Th.Change_Child(1, 'm'); // l m Th = Th.Child(1); // 'm' Th.Change_Child(0, 'n'); // ./ \. Th.Change_Child(1, 'o'); // n o } /** T = ( 0 ( 1 ( 3 4 ) 2 ( 5 6 ) ) ). \code T = 0 T = 0 |--1 ./ \. | |--3 1 2 | +--4 ./ \ / \. +--2 3 4 5 6 |--5 +--6 \endcode */ void make_0_6(TL::Tree & T) { TL::Tree Th; T.Erase(); T = '0'; // inserta la raiz '0' /***********************************/ // 0 T.Change_Child(0, '1'); // ./ \. T.Change_Child(1, '2'); // 1 2 /***********************************/ Th = T.Child(0); // '1' Th.Change_Child(0, '3'); // ./ \. Th.Change_Child(1, '4'); // 3 4 /***********************************/ Th = T.Child(1); // '2' Th.Change_Child(0, '5'); // ./ \. Th.Change_Child(1, '6'); // 5 6 } /** T = ( F ( B ( A ( C E ) D ) ) G ( I ( H ) ) ). \code F T = F |--B ./ \. | |--A B G | | |--C ./ \ \. | | +--E A D I | +--D ./ \ /. +--G C E H +--I \endcode +--H */ void make_A_H(TL::Tree & T) { TL::Tree A, B, G, I; T.Erase(); /***********************************/ A = 'A'; // A A.Change_Child(0, 'C'); // ./ \. A.Change_Child(1, 'E'); // C E /***********************************/ I = 'I'; // I I.Change_Child(0, 'H'); // ./. // H /***********************************/ B = 'B'; // B B.Graft(0, A); // ./ \. B.Change_Child(1, 'D'); // A D /***********************************/ G = 'G'; // G // \. G.Graft(1, I); // I /***********************************/ T = 'F'; // F T.Graft(0, B); // ./ \. T.Graft(1, G); // B G } /** T = ( A ( B ( D ( H I) E ( J K ) ) C ( F ( L M ) G ( N O ) ) ) ). \code T = A |--B | |--D T = A | | |--H ./ \. | | +--I ./ \. | +--E ./ \. | |--J B C | +--K ./ \ / \. +--C D E F G |--F ./ \ / \ / \ / \. | |--L H I J K L M N O | +--M \endcode +--G |--N +--O */ void make_A_O(TL::Tree & T) { TL::Tree B, D, E, C, F, G; T.Erase(); /***********************************/ D = 'D'; // D D.Change_Child(0, 'H'); // ./ \. D.Change_Child(1, 'I'); // H I /***********************************/ E = 'E'; // E E.Change_Child(0, 'J'); // ./ \. E.Change_Child(1, 'K'); // J K /***********************************/ F = 'F'; // F F.Change_Child(0, 'L'); // ./ \. F.Change_Child(1, 'M'); // L M /***********************************/ G = 'G'; // G G.Change_Child(0, 'N'); // ./ \. G.Change_Child(1, 'O'); // N O /***********************************/ B = 'B'; // B B.Graft(0, D); // ./ \. B.Graft(1, E); // N O /***********************************/ C = 'C'; // B C.Graft(0, F); // ./ \. C.Graft(1, G); // F G /***********************************/ T = 'A'; // A T.Graft(0, B); // ./ \. T.Graft(1, C); // B C } #include // rand() && srand() #ifdef English_dox /// C++ encapsulation of a generator as a Java iterator. #endif #ifdef Spanish_dox /// Encapsulamiento C++ de un generador como una iteración Java. #endif class Random { unsigned m_qty; ///< #. unsigned m_last; ///< Max. long m_val; ///< current(). public: /// \c Iterator::init() Random( unsigned n=1 , long seed=3145159 ) : m_qty(0), m_last(n) { srand(seed); } /// \c Iterator::hastNext() bool hasNext() const { return m_qty < m_last; } /// \c Iterator::next() const long& next() { m_qty++; return (m_val = rand()) ; } }; #include #ifdef English_dox /// Example usage of Java iterators as generators. #endif #ifdef Spanish_dox /// Ejemplo de uso de iteraciones Java como generadores. #endif void generateRandom( ) { Random iter( 15, 271828 ); while ( iter.hasNext() ) { std::cout << iter.next() << std::endl; } } #ifdef English_dox /// Example usage of the \c iterJava<> iterator class. #endif #ifdef Spanish_dox /// Ejemplo de uso de la clase de iteración \c iterJava<>. #endif template void useIterator( Collection& C ) { // iterJava< typename Collection::iterator > iter( C.begin(), C.end() ); typedef iterJava< typename Collection::iterator > ITER; ITER iter( C.begin(), C.end() ); while ( iter.hasNext() ) { std::cout << iter.next(); C.erase( iter ); // C.erase( iter.current() ); } } #undef ZTREE #ifdef ZTREE using namespace TL; // avoid errors within Tree_Ex.h #include "Tree_Ex.h" #endif /// Test ==> \c main() ==> \c iterJava(). int main() { test_iterJava tester; tester.setUp(); tester.run(); std::cout << tester.report(); if (false) { std::list L = makeList_long( "( 1 2 3 4 5 )" ); std::cout << "useIterator( L ); ==> "; useIterator( L ); assert( L.empty() ); } if (false) { generateRandom( ); } #ifdef ZTREE TL::Tree ZT; make_A_O( ZT ); Ztree_Print( ZT ); #endif } // EOF: test_iterJava.cpp