/*****************************************************************************
 * $LastChangedDate: 2009-12-28 02:30:09 -0500 (Mon, 28 Dec 2009) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Iterator classes.
 *//*
 * LEGAL:   COPYRIGHT (C) 2004 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef BASE_ITERATOR_HH
#define BASE_ITERATOR_HH 1

namespace base {

////////////////////////////////////////////////////////////////////////////////
/// @brief Abstract class for Iterator objects.
///
/// In itself, an abstract Iterator class is useless, because Iterator objects
/// are returned by value which precludes polymorphism.
/// Rather, its purpose is to be a reference for writing concrete Iterators
/// that all have a compatible interface.
///
/// By using Iterator as a facade, classes such as Dlist, STL containers, Array
/// can be transparently substituted without changing clients of Iterator.
///
template<typename T>
class AbstractIterator
{
public:
                    AbstractIterator( void ) { }
    virtual         ~AbstractIterator() { }

    virtual         operator bool() = 0;
    virtual T       Next( void ) = 0;
};

////////////////////////////////////////////////////////////////////////////////
/// @brief Iterator object for STL vectors.
///
/// Pass CONTAINER as "vector<Class>", not just "vector".
///
template<typename T,typename CONTAINER>
class STLIterator : public base::AbstractIterator<T>
{
public:
    explicit    STLIterator( CONTAINER& cont ) : mCont(cont), mIter(cont.begin()) { }
                operator bool() { return mIter != mCont.end(); }
    T           Next( void ) { return *mIter++; }
private:
    CONTAINER&                      mCont;
    typename CONTAINER::iterator    mIter;
};

} // namespace base

#endif // BASE_ITERATOR_HH
