trying to implement a simple iterator adapter working
(oops, didn't expect this to be so difficult...)
This commit is contained in:
parent
fa3d596a59
commit
60cf9e8c9e
10 changed files with 369 additions and 105 deletions
|
|
@ -123,6 +123,8 @@ namespace lumiera {
|
|||
|
||||
/* generic error situations */
|
||||
LUMIERA_ERROR_DECLARE (WRONG_TYPE); ///< runtime type mismatch
|
||||
LUMIERA_ERROR_DECLARE (ITER_EXHAUST); ///< end of sequence reached
|
||||
|
||||
|
||||
/** Macro for creating derived exception classes properly
|
||||
* integrated into Lumiera's exception hierarchy. Using
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ namespace lumiera {
|
|||
|
||||
/* some further generic error situations */
|
||||
LUMIERA_ERROR_DEFINE (WRONG_TYPE, "runtime type mismatch");
|
||||
LUMIERA_ERROR_DEFINE (ITER_EXHAUST, "end of sequence reached");
|
||||
|
||||
} // namespace error
|
||||
|
||||
|
|
|
|||
|
|
@ -43,32 +43,172 @@
|
|||
|
||||
|
||||
//#include "include/logging.h"
|
||||
//#include "lib/error.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
//#include <vector>
|
||||
//#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
||||
// using util::for_each;
|
||||
using boost::remove_pointer;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* simple ptr-to-object based implementation of the lumiera forward iterator concept.
|
||||
* Basically such an PtrIter behaves like the similar concept from STL, but
|
||||
* - it is not just a disguised pointer (meaning, its more expensive)
|
||||
* - it checks validity on every operation and may throw
|
||||
* - it has a distinct back-link to the source container
|
||||
* - the source container needs to implement iterStart() and iterInc()
|
||||
* - we need friendship to and from the container class
|
||||
* - the end-of-iteration can be detected by bool check
|
||||
*
|
||||
* @see scoped-ptrvect.hpp usage example
|
||||
* @see iter-adaptor-test.cpp
|
||||
*/
|
||||
template<class T, class CON>
|
||||
class PtrIter
|
||||
template<class POS, class CON>
|
||||
class IterAdapter
|
||||
: public lib::BoolCheckable<IterAdapter<POS,CON> >
|
||||
{
|
||||
const CON* source_;
|
||||
POS pos_;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////TODO: implement empty test
|
||||
/////////////////////////////////////////////////////////////////////////TODO: implement comparisons
|
||||
|
||||
public:
|
||||
typedef typename POS::pointer pointer; //////////////////TODO: do we really need all those typedefs???
|
||||
typedef typename POS::reference reference;
|
||||
typedef typename POS::value_type value_type;
|
||||
|
||||
IterAdapter (const CON* src, const POS& startpos)
|
||||
: source_(src)
|
||||
, pos_(startpos)
|
||||
{ }
|
||||
|
||||
IterAdapter ()
|
||||
: source_(0)
|
||||
, pos_(0)
|
||||
{ }
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
_maybe_throw();
|
||||
return *pos_;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
_maybe_throw();
|
||||
return pos_;
|
||||
}
|
||||
|
||||
IterAdapter&
|
||||
operator++()
|
||||
{
|
||||
_maybe_throw();
|
||||
CON::iterNext (source_,pos_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IterAdapter
|
||||
operator++(int)
|
||||
{
|
||||
_maybe_throw();
|
||||
IterAdapter oldPos(*this);
|
||||
CON::iterNext (source_,pos_);
|
||||
return oldPos;
|
||||
}
|
||||
|
||||
bool
|
||||
isValid () const
|
||||
{
|
||||
return (source_ && CON::iterValid(source_,pos_));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
_maybe_throw() const
|
||||
{
|
||||
if (!isValid())
|
||||
throw lumiera::error::Invalid ("Can't iterate further",
|
||||
lumiera::error::LUMIERA_ERROR_ITER_EXHAUST);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
|
||||
|
||||
|
||||
/** wrapper for an existing Iterator type,
|
||||
* automatically dereferencing the former's output.
|
||||
* For this to work, the "source" iterator is expected
|
||||
* to be declared on \em pointers rather than on values.
|
||||
* @note bool checkable if and only if source is...
|
||||
*/
|
||||
template<class T, class CON>
|
||||
template<class IT>
|
||||
class PtrDerefIter
|
||||
: public lib::BoolCheckable<PtrDerefIter<IT> >
|
||||
{
|
||||
IT i_;
|
||||
|
||||
public:
|
||||
typedef typename IT::value_type pointer;
|
||||
typedef typename remove_pointer<pointer>::type & reference;
|
||||
|
||||
|
||||
PtrDerefIter (IT srcIter)
|
||||
: i_(srcIter)
|
||||
{ }
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *(*i_);
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return *i_;
|
||||
}
|
||||
|
||||
PtrDerefIter&
|
||||
operator++()
|
||||
{
|
||||
++i_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PtrDerefIter
|
||||
operator++(int)
|
||||
{
|
||||
return PtrDerefIter (i_++);
|
||||
}
|
||||
|
||||
bool
|
||||
isValid () const
|
||||
{
|
||||
return bool(i_);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
|
||||
#include "include/logging.h"
|
||||
#include "lib/iter-adaptor.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -101,25 +102,25 @@ namespace lib {
|
|||
T&
|
||||
manage (T* obj)
|
||||
{
|
||||
if (obj)
|
||||
try
|
||||
{
|
||||
push_back (obj);
|
||||
return *obj;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete obj;
|
||||
throw;
|
||||
} }
|
||||
REQUIRE (obj);
|
||||
try
|
||||
{
|
||||
push_back (obj);
|
||||
return *obj;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
delete obj;
|
||||
throw;
|
||||
} }
|
||||
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
typedef typename _Vec::iterator VIter;
|
||||
VIter e = this->end();
|
||||
for (VIter i = this->begin(); i!=e; ++i)
|
||||
VIter e = _Vec::end();
|
||||
for (VIter i = _Vec::begin(); i!=e; ++i)
|
||||
{
|
||||
if (*i)
|
||||
try
|
||||
|
|
@ -143,8 +144,8 @@ namespace lib {
|
|||
return *get(i);
|
||||
}
|
||||
|
||||
typedef PtrDerefIter<reference, _Vec> iterator;
|
||||
typedef PtrDerefIter<const_reference, _Vec> const_iterator;
|
||||
typedef PtrDerefIter<typename _Vec::iterator> iterator;
|
||||
typedef PtrDerefIter<typename _Vec::const_iterator> const_iterator;
|
||||
|
||||
iterator begin() { return iterator (_Vec::begin()); }
|
||||
const_iterator begin() const { return const_iterator (_Vec::begin()); }
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@
|
|||
|
||||
|
||||
#include "include/symbol.hpp"
|
||||
#include "lib/lumitime.hpp"
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
|
||||
|
|
@ -36,7 +38,9 @@ namespace lib {
|
|||
namespace test{
|
||||
|
||||
using lumiera::Symbol;
|
||||
using lumiera::Time;
|
||||
using std::string;
|
||||
using std::rand;
|
||||
|
||||
|
||||
|
||||
|
|
@ -48,7 +52,7 @@ namespace test{
|
|||
* type identification as implemented by the compiler.
|
||||
*/
|
||||
template<typename T>
|
||||
const char*
|
||||
inline const char*
|
||||
showType (T const& obj, Symbol name=0)
|
||||
{
|
||||
return name? name : typeid(obj).name();
|
||||
|
|
@ -61,7 +65,7 @@ namespace test{
|
|||
* type identification as implemented by the compiler.
|
||||
*/
|
||||
template<typename T>
|
||||
const char*
|
||||
inline const char*
|
||||
showType (Symbol name=0)
|
||||
{
|
||||
return name? name : typeid(T).name();
|
||||
|
|
@ -75,21 +79,21 @@ namespace test{
|
|||
|
||||
/** for printing sizeof(), trying to figure out the type name automatically */
|
||||
template<typename T>
|
||||
string
|
||||
inline string
|
||||
showSizeof(Symbol name=0)
|
||||
{
|
||||
return showSizeof (sizeof (T), showType<T> (name));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string
|
||||
inline string
|
||||
showSizeof(T const& obj, Symbol name=0)
|
||||
{
|
||||
return showSizeof (sizeof (obj), showType (obj,name));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string
|
||||
inline string
|
||||
showSizeof(T *obj, Symbol name=0)
|
||||
{
|
||||
return obj? showSizeof (*obj, name)
|
||||
|
|
@ -97,6 +101,16 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/** create a random but not insane Time value */
|
||||
inline Time
|
||||
randTime ()
|
||||
{
|
||||
return Time (500 * (rand() % 2), (rand() % 600));
|
||||
}
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,45 +23,14 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
//#include "proc/asset/media.hpp"
|
||||
//#include "proc/mobject/session.hpp"
|
||||
//#include "proc/mobject/session/edl.hpp"
|
||||
//#include "proc/mobject/session/testclip.hpp"
|
||||
//#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
//#include "lib/p.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-index.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/control/argument-tuple-accept.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
|
||||
//#include "lib/scoped-ptrvect.hpp"
|
||||
//#include "lib/lumitime-fmt.hpp"
|
||||
//#include "lib/meta/typelist.hpp"
|
||||
//#include "lib/meta/tuple.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/lumitime-fmt.hpp"
|
||||
|
||||
#include <tr1/functional>
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
//#include <strstream>
|
||||
//#include <cstdlib>
|
||||
//#include <string>
|
||||
|
||||
//using std::tr1::bind;
|
||||
//using std::tr1::placeholders::_1;
|
||||
//using std::tr1::placeholders::_2;
|
||||
using std::tr1::function;
|
||||
//using util::isnil;
|
||||
//using util::and_all;
|
||||
//using boost::format;
|
||||
//using lumiera::Time;
|
||||
//using util::contains;
|
||||
//using std::string;
|
||||
//using std::rand;
|
||||
//using std::ostream;
|
||||
//using std::ostrstream;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
|
@ -70,15 +39,12 @@ namespace control {
|
|||
namespace test {
|
||||
|
||||
using lib::test::showSizeof;
|
||||
using lib::test::randTime;
|
||||
|
||||
using lumiera::Time;
|
||||
using std::tr1::function;
|
||||
using lumiera::typelist::FunctionSignature;
|
||||
using lumiera::typelist::Tuple;
|
||||
// using session::test::TestClip;
|
||||
// using lumiera::P;
|
||||
// using namespace lumiera::typelist;
|
||||
// using lumiera::typelist::Tuple;
|
||||
|
||||
// using control::CmdClosure;
|
||||
|
||||
|
||||
|
||||
|
|
@ -98,36 +64,32 @@ namespace test {
|
|||
template<typename SIG>
|
||||
class TestClass
|
||||
: public ArgumentTupleAccept< SIG // to derive the desired signature
|
||||
, TestClass // the target class providing the implementation
|
||||
, TestClass<SIG> // the target class providing the implementation
|
||||
, typename Tup<SIG>::Ty // base class to inherit from
|
||||
>
|
||||
{
|
||||
typedef typename Tup<SIG>::Ty ATuple;
|
||||
|
||||
public:
|
||||
|
||||
void
|
||||
bind (typename Tup<SIG>::Ty const& tuple)
|
||||
bindArg (ATuple const& tuple)
|
||||
{
|
||||
*this = tuple;
|
||||
static_cast<ATuple&> (*this) = tuple;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Time
|
||||
randTime ()
|
||||
{
|
||||
UNIMPLEMENTED ("create a random but not insane Time value");
|
||||
}
|
||||
|
||||
|
||||
} // test-helper implementation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef lib::ScopedPtrVect<CmdClosure> ArgTuples;
|
||||
|
||||
/***************************************************************
|
||||
* @test Build test object, which accepts a bind(...) call with
|
||||
* specifically typed arguments.
|
||||
/*************************************************************
|
||||
* @test Build a test object, which accepts a bind(...) call
|
||||
* with specifically typed arguments.
|
||||
*
|
||||
* @see control::CommandArgumentHolder
|
||||
*/
|
||||
|
|
@ -144,10 +106,10 @@ namespace test {
|
|||
testTime.bind(randTime(),23);
|
||||
|
||||
cout << showSizeof(testVoid) << endl;
|
||||
cout << showSizeof(testITim) << endl;
|
||||
cout << showSizeof(testTime) << endl;
|
||||
|
||||
cout << testITim.getHead() << endl;
|
||||
ASSERT (23 == testITim.getTail().getHead());
|
||||
cout << testTime.getHead() << endl;
|
||||
ASSERT (23 == testTime.getTail().getHead());
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
//#include <tr1/functional>
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include <strstream>
|
||||
#include <sstream>
|
||||
//#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ using lumiera::Time;
|
|||
using std::string;
|
||||
//using std::rand;
|
||||
using std::ostream;
|
||||
using std::ostrstream;
|
||||
using std::ostringstream;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
|
@ -67,6 +67,7 @@ namespace control {
|
|||
namespace test {
|
||||
|
||||
using lib::test::showSizeof;
|
||||
using lib::test::randTime;
|
||||
|
||||
// using session::test::TestClip;
|
||||
// using lumiera::P;
|
||||
|
|
@ -82,7 +83,7 @@ namespace test {
|
|||
|
||||
namespace { // test helpers
|
||||
|
||||
ostrstream protocol; ///< used to verify the test function calls
|
||||
ostringstream protocol; ///< used to verify the test function calls
|
||||
|
||||
|
||||
template<typename TY>
|
||||
|
|
@ -103,7 +104,7 @@ namespace test {
|
|||
}
|
||||
|
||||
TY&
|
||||
operator* () const
|
||||
operator* ()
|
||||
{
|
||||
return element_;
|
||||
}
|
||||
|
|
@ -111,7 +112,7 @@ namespace test {
|
|||
friend ostream&
|
||||
operator<< (ostream& out, const Tracker& tra)
|
||||
{
|
||||
return out << element_;
|
||||
return out << tra.element_;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -128,13 +129,13 @@ namespace test {
|
|||
}
|
||||
|
||||
Tracker<string>
|
||||
captureState (Tracker<Time> time, Tracker<string> str, int rand)
|
||||
captureState (Tracker<Time>, Tracker<string>, int)
|
||||
{
|
||||
return protocol.str();
|
||||
}
|
||||
|
||||
void
|
||||
undoIt (Tracker<Time> time, Tracker<string> str, int rand, Tracker<string> memento)
|
||||
undoIt (Tracker<Time> time, Tracker<string>, int, Tracker<string> memento)
|
||||
{
|
||||
protocol << "undoIt(time="<<time<<")---state-was-:"<< *memento;
|
||||
}
|
||||
|
|
@ -156,12 +157,6 @@ namespace test {
|
|||
// serialise, then de-serialise into a new instance and compare both
|
||||
}
|
||||
|
||||
Time
|
||||
randTime ()
|
||||
{
|
||||
UNIMPLEMENTED ("create a random but not insane Time value");
|
||||
}
|
||||
|
||||
|
||||
} // test-helper implementation
|
||||
|
||||
|
|
@ -183,6 +178,7 @@ namespace test {
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
#if false ////////////////////////////////////////////////////////////////////////////TODO.....
|
||||
ArgTuples testTuples;
|
||||
Tracker<Time>::instanceCnt = 0;
|
||||
Tracker<string>::instanceCnt = 0;
|
||||
|
|
@ -323,6 +319,7 @@ namespace test {
|
|||
|
||||
bound_undoFun();
|
||||
cout << protocol.str() << endl;
|
||||
#endif ////////////////////////////////////////////////////////////////////////////TODO.....
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -77,14 +77,14 @@ namespace mobject {
|
|||
// TODO: how to handle insufficiently determinated Placement? Throw?
|
||||
FixedLocation & fixloc = pc.chain(Time(1)); // TODO: the track??
|
||||
ExplicitPlacement expla = pc.resolve();
|
||||
ASSERT (expla.time == 1);
|
||||
ASSERT (expla.time == Time(1));
|
||||
ASSERT (!expla.chain.isOverdetermined());
|
||||
//ASSERT (*expla == *pc); ////////////////////////TODO: define equality on placements (Trac #119)
|
||||
|
||||
// now overconstraining with another Placement
|
||||
pc.chain(Time(2));
|
||||
ExplicitPlacement expla2 = pc.resolve();
|
||||
ASSERT (expla2.time == 2); // the latest addition wins
|
||||
ASSERT (expla2.time == Time(2)); // the latest addition wins
|
||||
ASSERT (expla2.chain.isOverdetermined());
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ namespace test {
|
|||
ASSERT (1 == ref1.use_count());
|
||||
ASSERT (1 == ref2.use_count());
|
||||
ExplicitPlacement exPla = refX.resolve();
|
||||
ASSERT (exPla.time == 2); // indeed get back the time we set on p2 above
|
||||
ASSERT (exPla.time == Time(2)); // indeed get back the time we set on p2 above
|
||||
ASSERT (2 == ref2.use_count()); // exPla shares ownership with p2
|
||||
|
||||
ASSERT (index->contains(ref1)); // ref can stand-in for a placement-ID
|
||||
|
|
@ -144,9 +144,9 @@ namespace test {
|
|||
ASSERT (ref2 != refX);
|
||||
|
||||
// resolution is indeed "live", we see changes to the referred placement
|
||||
ASSERT (refX.resolve().time == 0);
|
||||
ASSERT (refX.resolve().time == Time(0));
|
||||
p1 = p2;
|
||||
ASSERT (refX.resolve().time == 2); // now we get the time tie we originally set on p2
|
||||
ASSERT (refX.resolve().time == Time(2)); // now we get the time tie we originally set on p2
|
||||
ASSERT (3 == ref2.use_count()); // p1, p2 and exPla share ownership
|
||||
|
||||
// actually, the assignment has invalidated ref1, because of the changed ID
|
||||
|
|
|
|||
|
|
@ -26,14 +26,93 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
//#include "lib/scoped-ptrvect.hpp"
|
||||
#include "lib/iter-adaptor.hpp"
|
||||
//#include "testdummy.hpp"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
using ::Test;
|
||||
using util::isnil;
|
||||
// using util::isnil;
|
||||
using boost::lexical_cast;
|
||||
using util::for_each;
|
||||
using std::vector;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
uint NUM_ELMS = 10;
|
||||
|
||||
|
||||
class TestContainer
|
||||
{
|
||||
typedef vector<int *> _Vec;
|
||||
|
||||
_Vec numberz_;
|
||||
|
||||
static void killIt (int *it) { delete it; }
|
||||
|
||||
public:
|
||||
TestContainer (uint count)
|
||||
: numberz_(count)
|
||||
{
|
||||
for (uint i=0; i<count; ++i)
|
||||
numberz_[i] = new int(i);
|
||||
}
|
||||
|
||||
~TestContainer ()
|
||||
{
|
||||
for_each (numberz_, killIt);
|
||||
}
|
||||
|
||||
typedef int * value_type;
|
||||
typedef int ** pointer;
|
||||
typedef int *& reference;
|
||||
|
||||
typedef IterAdapter<_Vec::iterator, TestContainer> iterator;
|
||||
typedef IterAdapter<_Vec::const_iterator, TestContainer> const_iterator;
|
||||
typedef PtrDerefIter<iterator > ref_iterator;
|
||||
typedef PtrDerefIter<const_iterator> const_ref_iter;
|
||||
|
||||
|
||||
iterator begin () { return iterator (this, numberz_.begin()); }
|
||||
const_iterator begin () const { return const_iterator (this, numberz_.begin()); }
|
||||
ref_iterator begin_ref () { return ref_iterator (begin()); }
|
||||
const_ref_iter begin_ref () const { return const_ref_iter (begin()); }
|
||||
|
||||
iterator end () { return iterator(); }
|
||||
const_iterator end () const { return const_iterator(); }
|
||||
|
||||
protected:
|
||||
|
||||
friend class IterAdapter<_Vec::iterator, TestContainer>;
|
||||
friend class IterAdapter<_Vec::const_iterator,TestContainer>;
|
||||
|
||||
|
||||
template<class ITER>
|
||||
static void
|
||||
iterNext (const TestContainer* src, ITER& pos)
|
||||
{
|
||||
if (iterValid(src,pos))
|
||||
++pos;
|
||||
}
|
||||
|
||||
template<class ITER>
|
||||
static bool
|
||||
iterValid (const TestContainer* src, ITER& pos)
|
||||
{
|
||||
REQUIRE (src);
|
||||
return pos != src->numberz_.end();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -47,21 +126,89 @@ namespace test{
|
|||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
run (Arg arg)
|
||||
{
|
||||
UNIMPLEMENTED ("build a simple lumiera forward iterator");
|
||||
simpleUsage();
|
||||
// iterating();
|
||||
// detaching();
|
||||
if (0 < arg.size()) NUM_ELMS = lexical_cast<uint> (arg[0]);
|
||||
|
||||
TestContainer testElms (NUM_ELMS);
|
||||
simpleUsage (testElms);
|
||||
iterTypeVariations (testElms);
|
||||
}
|
||||
|
||||
|
||||
static void showIt (int* elm) { cout << "::" << *elm; }
|
||||
|
||||
|
||||
void
|
||||
simpleUsage()
|
||||
simpleUsage (TestContainer& elms)
|
||||
{
|
||||
for_each (elms, showIt);
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
iterTypeVariations (TestContainer& elms)
|
||||
{
|
||||
TestContainer const& const_elms (elms);
|
||||
|
||||
int i = 0;
|
||||
for (TestContainer::iterator iter = elms.begin();
|
||||
iter; ++iter, ++i
|
||||
)
|
||||
{
|
||||
ASSERT (iter);
|
||||
ASSERT (iter != elms.end());
|
||||
ASSERT (**iter == i);
|
||||
--(**iter);
|
||||
ASSERT (**iter == i-1);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (TestContainer::const_iterator iter = const_elms.begin();
|
||||
iter; ++iter, ++i
|
||||
)
|
||||
{
|
||||
ASSERT (iter);
|
||||
// ASSERT (iter != elms.end()); ////////////////////////////TODO: implement comparison
|
||||
ASSERT (**iter == i-1);
|
||||
|
||||
// note: the previous run indeed modified
|
||||
// the element within the container.
|
||||
|
||||
// --(**iter); // doesn't compile, because it's const
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (TestContainer::ref_iterator iter = elms.begin_ref();
|
||||
iter; ++iter, ++i
|
||||
)
|
||||
{
|
||||
ASSERT (iter);
|
||||
ASSERT ((*iter) == i-1);
|
||||
++(*iter);
|
||||
ASSERT ((*iter) == i);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (TestContainer::const_ref_iter iter = const_elms.begin_ref();
|
||||
iter; ++iter, ++i
|
||||
)
|
||||
{
|
||||
ASSERT (iter);
|
||||
ASSERT ((*iter) == i);
|
||||
}
|
||||
|
||||
ASSERT (TestContainer::iterator() == elms.end());
|
||||
ASSERT (!(TestContainer::iterator()));
|
||||
ASSERT (!(elms.end()));
|
||||
// ASSERT (isnil (elms.end())); ////////////////////////////TODO: implement empty test
|
||||
|
||||
ASSERT (elms.begin());
|
||||
// ASSERT (!isnil (elms.begin())); ////////////////////////////TODO: implement empty test
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
LAUNCHER (IterAdaptor_test, "unit common");
|
||||
|
|
|
|||
Loading…
Reference in a new issue