/* IterTools(Test) - building combined and filtering iterators based on the Iterator tools Copyright (C) Lumiera.org 2009, Hermann Vosseler This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *****************************************************/ #include "lib/test/run.hpp" #include "lib/util.hpp" #include "lib/itertools.hpp" #include #include #include namespace lib { namespace test{ using ::Test; using boost::lexical_cast; using util::for_each; using util::isnil; using std::vector; using std::cout; using std::endl; namespace { // Test data uint NUM_ELMS = 10; struct TestSource { vector data_; TestSource(uint num) { while (num) data_.push_back(num--); } typedef vector::iterator sourceIter; typedef RangeIter iterator; iterator begin() { return iterator(data_.begin(),data_.end()); } iterator end() { return iterator(); } }; } // (END) Test data /******************************************************************************* * @test build combined and filtering iterators with the help of lib::IterTool. * Check correct behaviour of the resulting iterators and * verify they fulfil the Lumiera Forward Iterator concept * * @todo implement more iterator tools.... see Ticket #347 */ class IterTools_test : public Test { typedef TestSource::iterator Iter; virtual void run (Arg arg) { if (0 < arg.size()) NUM_ELMS = lexical_cast (arg[0]); TestSource source(NUM_ELMS); pullOut (source.begin()); verifyComparisons (source.begin()); buildFilterIterator (source.begin()); Iter ii (source.begin()); ++++++ii; buildFilterIterator (ii); buildTransformingIterator (source.begin()); } template void pullOut (IT const& ii) { for (IT iter(ii) ; iter; ++iter ) cout << "::" << *iter; cout << endl; } static bool takeAll (int) { return true; } static bool takeOdd (int i) { return 0 != i % 2; } static bool takeEve (int i) { return 0 == i % 2; } void buildFilterIterator (Iter const& ii) { pullOut (filterIterator (ii, takeAll)); // note: using the convenient builder function pullOut (filterIterator (ii, takeEve)); pullOut (filterIterator (ii, takeOdd)); FilterIter all (ii, takeAll); FilterIter odd (ii, takeOdd); verifyComparisons (all); verifyComparisons (odd); while (++all && ++odd) ASSERT (all != odd); while (++all) { } ASSERT (isnil (odd)); ASSERT (all == odd); } static ulong addTwo (int i) { return i+2; } static int negate (int i) { return -i; } static int idFunc (int i) { return i; } void buildTransformingIterator (Iter const& ii) { pullOut (transformIterator(ii, idFunc)); pullOut (transformIterator(ii, negate)); pullOut (transformIterator(ii, addTwo)); // note: changing output type to unsigned TransformIter idi (ii, idFunc); TransformIter neg (ii, negate); verifyComparisons (idi); verifyComparisons (neg); ASSERT (idi); ASSERT (neg); for ( ;idi&&neg; ++idi,++neg) ASSERT (idi != neg); ASSERT (!idi && !neg); ASSERT (idi == neg); } /** @test verify equality handling and NIL detection * for the given iterator/wrapper handed in */ template void verifyComparisons (IT const& ii) { IT i1(ii); IT i2(ii); IT iN; ASSERT ( isnil (iN)); ASSERT (!isnil (i1)); ASSERT (!isnil (i2)); ASSERT (i1 == i2); ASSERT (i2 == i1); ASSERT (i1 != iN); ASSERT (iN != i1); ASSERT (i2 != iN); ASSERT (iN != i2); ++i1; ASSERT (i1 != i2); ASSERT (i1 != iN); ++i2; ASSERT (i1 == i2); ASSERT (i1 != iN); ASSERT (i2 != iN); while (++i1) { } ASSERT (isnil(i1)); ASSERT (i1 != i2); ASSERT (i1 == iN); while (++i2) { } ASSERT (isnil(i2)); ASSERT (i2 == i1); ASSERT (i2 == iN); } }; LAUNCHER (IterTools_test, "unit common"); }} // namespace lib::test