#ifndef TCG_ANY_ITERATOR_H #define TCG_ANY_ITERATOR_H #include "base.h" /* \file any_iterator.h \brief This file contains the implementation of a type-erased iterator template class. \details Type erasure is a C++ idiom about allocating an interface to an object who is then hidden as the interface's implementation detail. The cost of using a type-erased object instead of its actual type is typically measured in a heap access at construction and destruction, and one virtual function call per method invocation. A type-erased iterator can be useful to hide implementation details about container choices, yet providing an iterator-like interface to access the stored data. */ #ifndef TCG_RVALUES_SUPPORT #include #ifdef BOOST_NO_RVALUE_REFERENCES #define TCG_RVALUES_SUPPORT 0 #else #define TCG_RVALUES_SUPPORT 1 #endif #endif namespace tcg { //**************************************************************************** // any_iterator_concept (ie the interface) //**************************************************************************** template class any_iterator_concept { public: virtual ~any_iterator_concept() {} virtual any_iterator_concept *clone() const = 0; virtual ValRef operator*() const = 0; virtual ValPtr operator->() const = 0; virtual bool operator==(const any_iterator_concept &other) const = 0; virtual bool operator!=(const any_iterator_concept &other) const = 0; virtual void operator++() = 0; virtual any_iterator_concept *operator++(int) { assert(false); return 0; } virtual void operator--() { assert(false); } virtual any_iterator_concept *operator--(int) { assert(false); return 0; } virtual bool operator<(const any_iterator_concept &) const { assert(false); return false; } virtual bool operator>(const any_iterator_concept &) const { assert(false); return false; } virtual bool operator<=(const any_iterator_concept &) const { assert(false); return false; } virtual bool operator>=(const any_iterator_concept &) const { assert(false); return false; } virtual any_iterator_concept *operator+(Dist) const { assert(false); return 0; } virtual void operator+=(Dist d) { assert(false); } virtual any_iterator_concept *operator-(Dist) const { assert(false); return 0; } virtual void operator-=(Dist d) { assert(false); } virtual Dist operator-(const any_iterator_concept &) const { assert(false); return 0; } virtual ValRef operator[](Dist) const { assert(false); return *(Val *)0; } }; //**************************************************************************** // any_iterator_model (ie the concrete interface implementations) //**************************************************************************** template class any_iterator_model : public any_iterator_concept { typedef any_iterator_concept any_it_concept; public: any_iterator_model() : m_it() {} any_iterator_model(const It &it) : m_it(it) {} any_it_concept *clone() const { return new any_iterator_model(*this); } ValRef operator*() const { return m_it.operator*(); } ValPtr operator->() const { return m_it.operator->(); } bool operator==(const any_it_concept &other) const { return m_it == static_cast(other).m_it; } bool operator!=(const any_it_concept &other) const { return m_it != static_cast(other).m_it; } void operator++() { ++m_it; } any_it_concept *operator++(int) { return new any_iterator_model(m_it++); } protected: It m_it; }; template class any_iterator_model : public any_iterator_model { typedef any_iterator_concept any_it_concept; using any_iterator_model::m_it; public: any_iterator_model() {} any_iterator_model(const It &it) : any_iterator_model(it) {} any_it_concept *clone() const { return new any_iterator_model(*this); } void operator--() { --m_it; } any_it_concept *operator--(int) { return new any_iterator_model(m_it--); } }; template class any_iterator_model : public any_iterator_model { typedef any_iterator_concept any_it_concept; using any_iterator_model::m_it; public: any_iterator_model() {} any_iterator_model(const It &it) : any_iterator_model(it) {} any_it_concept *clone() const { return new any_iterator_model(*this); } bool operator<(const any_it_concept &other) const { return m_it < static_cast(other).m_it; } bool operator>(const any_it_concept &other) const { return m_it > static_cast(other).m_it; } bool operator<=(const any_it_concept &other) const { return m_it <= static_cast(other).m_it; } bool operator>=(const any_it_concept &other) const { return m_it >= static_cast(other).m_it; } any_it_concept *operator+(Dist d) const { return new any_iterator_model(m_it + d); } void operator+=(Dist d) { m_it += d; } any_it_concept *operator-(Dist d) const { return new any_iterator_model(m_it - d); } void operator-=(Dist d) { m_it -= d; } Dist operator-(const any_it_concept &other) const { return m_it - static_cast(other).m_it; } ValRef operator[](Dist d) const { return m_it[d]; } }; //**************************************************************************** // any_iterator (ie the wrapper to the interface) //**************************************************************************** template class any_iterator : public std::iterator { any_iterator_concept *m_model; public: any_iterator() : m_model(0) {} any_iterator(any_iterator_concept *model) : m_model(model) {} template any_iterator(const It &it) : m_model(new any_iterator_model(it)) {} any_iterator(const any_iterator &other) : m_model(other.m_model->clone()) {} any_iterator &operator=(any_iterator other) { swap(*this, other); return *this; } ~any_iterator() { delete m_model; } friend void swap(any_iterator &a, any_iterator &b) { std::swap(a.m_model, b.m_model); } ValRef operator*() const { return m_model->operator*(); } ValPtr operator->() const { return m_model->operator->(); } bool operator==(const any_iterator &other) const { return m_model->operator==(*other.m_model); } bool operator!=(const any_iterator &other) const { return m_model->operator!=(*other.m_model); } any_iterator &operator++() { ++*m_model; return *this; } any_iterator operator++(int) { return any_iterator((*m_model)++); } any_iterator &operator--() { --*m_model; return *this; } any_iterator operator--(int) { return any_iterator((*m_model)--); } bool operator<(const any_iterator &other) const { return m_model->operator<(*other.m_model); } bool operator>(const any_iterator &other) const { return m_model->operator>(*other.m_model); } bool operator<=(const any_iterator &other) const { return m_model->operator<=(*other.m_model); } bool operator>=(const any_iterator &other) const { return m_model->operator>=(*other.m_model); } any_iterator operator+(Dist d) const { return any_iterator((*m_model) + d); } any_iterator &operator+=(Dist d) { (*m_model) += d; return *this; } any_iterator operator-(Dist d) const { return any_iterator((*m_model) - d); } any_iterator &operator-=(Dist d) { (*m_model) -= d; return *this; } Dist operator-(const any_iterator &other) const { return m_model->operator-(*other.m_model); } ValRef operator[](Dist d) const { return m_model->operator[](d); } #if (TCG_RVALUES_SUPPORT > 0) any_iterator(any_iterator &&other) : m_model(other.m_model) { other.m_model = 0; } #endif }; //------------------------------------------------------------------------------- template any_iterator operator+( Dist d, const any_iterator &it) { return it + d; } //**************************************************************************** // Additional typedefs to the actual types //**************************************************************************** template struct any_iterator { typedef any_iterator input; typedef any_iterator output; typedef any_iterator forward; typedef any_iterator bidirectional; typedef any_iterator random; }; template struct any_it { typedef any_iterator input; typedef any_iterator output; typedef any_iterator forward; typedef any_iterator bidirectional; typedef any_iterator random; }; } // namespace tcg #endif // TCG_ANY_ITERATOR_H