// test_iterJava.cpp (c) 2009 adolfo@di-mare.com /** \file test_iterJava.cpp \brief Test ==> class iterJava<>. \author Adolfo Di Mare <adolfo@di-mare.com> \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 <list> /// 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<long> makeList_long(const char* V); // forward declaration /// Test ==> \c iterJava<> ==> \c example(). void test_iterJava::test_example() { {{ // test::example() std::list<long> Lfwd, Lbck, L; assertTrue( Lfwd.empty() && L.empty() ); L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::iterator > itFwd( L.begin(), L.end() ); iterJava< std::list<long>::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<long> Lcp, L; { // L.empty() L = makeList_long( "" ); iterJava< std::list<long>::iterator > iter( L.begin(), L.end() ); assertTrue( ! iter.hasNext() ); } { // L.size() == 1 L = makeList_long( " 1 " ); iterJava< std::list<long>::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<long>::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<long> Lcp; L = makeList_long( " 5 4 3 2 1 " ); iterJava< std::list<long>::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<long> 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<long> Lcp, L; assertTrue( Lcp.empty() ); L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::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<long>::const_iterator > IT = iter; assertTrue( IT == iter && !( IT.hasNext() ) && !( IT != iter ) ); #undef const_error }} { // const list<>& std::list<long> Lcp, L; assertTrue( Lcp.empty() ); L = longlist( "( 1 2 3 4 5 )" ); const std::list<long> & L_const = L; iterJava< std::list<long>::const_iterator > iter( L_const.begin(),L_const.end() ); while ( iter.hasNext() ) { Lcp.push_back( iter.next() ); } assertTrue( L == Lcp ); iterJava< std::list<long>::const_iterator > IT = iter; assertTrue( IT == iter && !( IT.hasNext() ) && !( IT != iter ) ); } } #include <cassert> #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<long> &L ) { typedef iterJava< std::list<long>::const_iterator > Iter; Iter iter( L.begin(),L.end() ); while ( iter.hasNext() ) { // L.erase(iter); // forbidden for const_iterator } assert( L.empty() ); } template <typename C> 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<long> L = makeList_long( "( 1 2 3 2 1 )" ); typedef std::list<long>::const_iterator IterFwd; typedef std::reverse_iterator<IterFwd> 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<long> L = makeList_long( "( 1 2 3 2 1 )" ); typedef std::list<long>::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<long> L = makeList_long( "( 1 2 3 4 5 )" ); typedef std::list<long>::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 <typename C> 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 <typename C> bool isPalindrome( const C& CCC ) {{ typedef typename C::const_iterator IterFwd; typedef typename std::reverse_iterator<IterFwd> 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<long> L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::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<long> L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::iterator > itFwd( L.begin(), L.end() ); iterJava< std::list<long>::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<long> L1 = makeList_long( "( 1 2 3 4 5 )" ); std::list<long> L2 = makeList_long( "( 6 7 8 9 )" ); iterJava< std::list<long>::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<long> L1 = makeList_long( "( 1 2 3 4 5 )" ); std::list<long> L2 = makeList_long( "( 6 7 8 9 )" ); iterJava< std::list<long>::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<long> L, Lcp; L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::const_iterator > iter123; iterJava< std::list<long>::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<long> L, Lcp; L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::iterator > iter123; iterJava< std::list<long>::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<long> L = makeList_long( "( 1 2 3 4 5 )" ); iterJava< std::list<long>::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<char> & T); // forward declaration {{ // test::Tree_BF() TL::Tree<char> T; make_a_o(T); Tree_BF<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> S = iter.next(); L.push_back( *S ); } assertTrue( L == "abcdefghijklmno" && "Tree_BF" ); }} if (false) { // T.empty() && 1 == T.Count() TL::Tree<char> T; Tree_BF<char> 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<char> T; Tree_BF<char> 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<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_0_6(T); Tree_BF<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_H(T); Tree_BF<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_O(T); Tree_BF<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); {{ // test::Tree_PLR() TL::Tree<char> T; make_a_o(T); Tree_PLR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> S = iter.next(); L.push_back( *S ); } assertTrue( L == "abfghcdeijlmnok" && "Tree_PLR" ); }} if (true) { // T.empty() && 1 == T.Count() TL::Tree<char> T; Tree_PLR<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_0_6(T); Tree_PLR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_H(T); Tree_PLR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_O(T); Tree_PLR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); {{ // test::Tree_LPR() TL::Tree<char> T; make_a_o(T); Tree_LPR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> S = iter.next(); L.push_back( *S ); } assertTrue( L == "fbghacdieljnmok" && "Tree_LPR" ); }} if (false) { // T.empty() && 1 == T.Count() // WABE !!! TL::Tree<char> T; Tree_LPR<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_0_6(T); Tree_LPR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_H(T); assertTrue( check_ok(T) ); Tree_LPR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_O(T); Tree_LPR<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); {{ // test::Tree_LRP() TL::Tree<char> T; make_a_o(T); Tree_LRP<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> S = iter.next(); L.push_back( *S ); } assertTrue( L == "fghbcdilnomjkea" && "Tree_LRP" ); }} if (false) { // T.empty() && 1 == T.Count() // WABE !!! TL::Tree<char> T; Tree_LRP<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_0_6(T); Tree_LRP<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_H(T); Tree_LRP<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> 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<char> & T); // forward declaration { TL::Tree<char> T; make_A_O(T); Tree_LRP<char> iter; std::string L; iter.set(T); while ( iter.hasNext() ) { TL::Tree<char> S = iter.next(); L.push_back( *S ); } assertTrue( L == "HIDJKEBLMFNOGCA" && "Tree_LRP [Wabe]" ); assertTrue( L != "HIDJKEBLMFNOGA" && "Tree_LRP [ C missing ]" ); } } /** <code>T = ( a ( b ( f g h ) c d e ( i j ( l m ( n o ) ) k ) )</code>. \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<char> & T) { TL::Tree<char> 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 } /** <code>T = ( 0 ( 1 ( 3 4 ) 2 ( 5 6 ) ) )</code>. \code T = 0 T = 0 |--1 ./ \. | |--3 1 2 | +--4 ./ \ / \. +--2 3 4 5 6 |--5 +--6 \endcode */ void make_0_6(TL::Tree<char> & T) { TL::Tree<char> 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 } /** <code>T = ( F ( B ( A ( C E ) D ) ) G ( I ( H ) ) )</code>. \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<char> & T) { TL::Tree<char> 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 } /** <code>T = ( A ( B ( D ( H I) E ( J K ) ) C ( F ( L M ) G ( N O ) ) ) )</code>. \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<char> & T) { TL::Tree<char> 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 <cmath> // 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 <iostream> #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 <class Collection> 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<long> L = makeList_long( "( 1 2 3 4 5 )" ); std::cout << "useIterator( L ); ==> "; useIterator( L ); assert( L.empty() ); } if (false) { generateRandom( ); } #ifdef ZTREE TL::Tree<char> ZT; make_A_O( ZT ); Ztree_Print( ZT ); #endif } // EOF: test_iterJava.cpp