| #pragma once |
| |
| #ifndef TCG_ANY_ITERATOR_H |
| #define TCG_ANY_ITERATOR_H |
| |
| #include "base.h" |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef TCG_RVALUES_SUPPORT |
| #include <boost/config.hpp> |
| |
| #ifdef BOOST_NO_RVALUE_REFERENCES |
| #define TCG_RVALUES_SUPPORT 0 |
| #else |
| #define TCG_RVALUES_SUPPORT 1 |
| #endif |
| #endif |
| |
| namespace tcg { |
| |
| |
| |
| |
| |
| template <typename Val, typename ValRef, typename ValPtr, typename Dist> |
| 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; |
| } |
| }; |
| |
| |
| |
| |
| |
| template <typename It, typename iterator_cat, typename Val, typename ValRef, |
| typename ValPtr, typename Dist> |
| class any_iterator_model |
| : public any_iterator_concept<Val, ValRef, ValPtr, Dist> { |
| typedef any_iterator_concept<Val, ValRef, ValPtr, Dist> 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<It, iterator_cat, Val, ValRef, ValPtr, Dist>( |
| *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<const any_iterator_model &>(other).m_it; |
| } |
| bool operator!=(const any_it_concept &other) const { |
| return m_it != static_cast<const any_iterator_model &>(other).m_it; |
| } |
| |
| void operator++() { ++m_it; } |
| any_it_concept *operator++(int) { |
| return new any_iterator_model<It, iterator_cat, Val, ValRef, ValPtr, Dist>( |
| m_it++); |
| } |
| |
| protected: |
| It m_it; |
| }; |
| |
| template <typename It, typename Val, typename ValRef, typename ValPtr, |
| typename Dist> |
| class any_iterator_model<It, std::bidirectional_iterator_tag, Val, ValRef, |
| ValPtr, Dist> |
| : public any_iterator_model<It, std::forward_iterator_tag, Val, ValRef, |
| ValPtr, Dist> { |
| typedef any_iterator_concept<Val, ValRef, ValPtr, Dist> any_it_concept; |
| |
| using any_iterator_model<It, std::forward_iterator_tag, Val, ValRef, ValPtr, |
| Dist>::m_it; |
| |
| public: |
| any_iterator_model() {} |
| any_iterator_model(const It &it) |
| : any_iterator_model<It, std::forward_iterator_tag, Val, ValRef, ValPtr, |
| Dist>(it) {} |
| |
| any_it_concept *clone() const { |
| return new any_iterator_model<It, std::bidirectional_iterator_tag, Val, |
| ValRef, ValPtr, Dist>(*this); |
| } |
| |
| void operator--() { --m_it; } |
| any_it_concept *operator--(int) { |
| return new any_iterator_model<It, std::bidirectional_iterator_tag, Val, |
| ValRef, ValPtr, Dist>(m_it--); |
| } |
| }; |
| |
| template <typename It, typename Val, typename ValRef, typename ValPtr, |
| typename Dist> |
| class any_iterator_model<It, std::random_access_iterator_tag, Val, ValRef, |
| ValPtr, Dist> |
| : public any_iterator_model<It, std::bidirectional_iterator_tag, Val, |
| ValRef, ValPtr, Dist> { |
| typedef any_iterator_concept<Val, ValRef, ValPtr, Dist> any_it_concept; |
| |
| using any_iterator_model<It, std::forward_iterator_tag, Val, ValRef, ValPtr, |
| Dist>::m_it; |
| |
| public: |
| any_iterator_model() {} |
| any_iterator_model(const It &it) |
| : any_iterator_model<It, std::bidirectional_iterator_tag, Val, ValRef, |
| ValPtr, Dist>(it) {} |
| |
| any_it_concept *clone() const { |
| return new any_iterator_model<It, std::random_access_iterator_tag, Val, |
| ValRef, ValPtr, Dist>(*this); |
| } |
| |
| bool operator<(const any_it_concept &other) const { |
| return m_it < static_cast<const any_iterator_model &>(other).m_it; |
| } |
| bool operator>(const any_it_concept &other) const { |
| return m_it > static_cast<const any_iterator_model &>(other).m_it; |
| } |
| bool operator<=(const any_it_concept &other) const { |
| return m_it <= static_cast<const any_iterator_model &>(other).m_it; |
| } |
| bool operator>=(const any_it_concept &other) const { |
| return m_it >= static_cast<const any_iterator_model &>(other).m_it; |
| } |
| |
| any_it_concept *operator+(Dist d) const { |
| return new any_iterator_model<It, std::random_access_iterator_tag, Val, |
| ValRef, ValPtr, Dist>(m_it + d); |
| } |
| void operator+=(Dist d) { m_it += d; } |
| |
| any_it_concept *operator-(Dist d) const { |
| return new any_iterator_model<It, std::random_access_iterator_tag, Val, |
| ValRef, ValPtr, Dist>(m_it - d); |
| } |
| void operator-=(Dist d) { m_it -= d; } |
| |
| Dist operator-(const any_it_concept &other) const { |
| return m_it - static_cast<const any_iterator_model &>(other).m_it; |
| } |
| |
| ValRef operator[](Dist d) const { return m_it[d]; } |
| }; |
| |
| |
| |
| |
| |
| template <typename Val, typename iterator_cat = tcg::empty_type, |
| typename ValRef = Val &, typename ValPtr = Val *, |
| typename Dist = std::ptrdiff_t> |
| class any_iterator |
| : public std::iterator<iterator_cat, Val, Dist, ValPtr, ValRef> { |
| any_iterator_concept<Val, ValRef, ValPtr, Dist> *m_model; |
| |
| public: |
| any_iterator() : m_model(0) {} |
| any_iterator(any_iterator_concept<Val, ValRef, ValPtr, Dist> *model) |
| : m_model(model) {} |
| |
| template <typename It> |
| any_iterator(const It &it) |
| : m_model( |
| new any_iterator_model<It, iterator_cat, Val, ValRef, ValPtr, Dist>( |
| 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 <typename Val, typename iterator_cat, typename ValRef, typename ValPtr, |
| typename Dist> |
| any_iterator<Val, iterator_cat, ValRef, ValPtr, Dist> operator+( |
| Dist d, const any_iterator<Val, iterator_cat, ValRef, ValPtr, Dist> &it) { |
| return it + d; |
| } |
| |
| |
| |
| |
| |
| template <typename Val> |
| struct any_iterator<Val, tcg::empty_type> { |
| typedef any_iterator<Val, std::input_iterator_tag> input; |
| typedef any_iterator<Val, std::output_iterator_tag> output; |
| typedef any_iterator<Val, std::forward_iterator_tag> forward; |
| typedef any_iterator<Val, std::bidirectional_iterator_tag> bidirectional; |
| typedef any_iterator<Val, std::random_access_iterator_tag> random; |
| }; |
| |
| template <typename Val, typename ValRef = Val &, typename ValPtr = Val *, |
| typename Dist = std::ptrdiff_t> |
| struct any_it { |
| typedef any_iterator<Val, std::input_iterator_tag, ValRef, ValPtr, Dist> |
| input; |
| typedef any_iterator<Val, std::output_iterator_tag, ValRef, ValPtr, Dist> |
| output; |
| typedef any_iterator<Val, std::forward_iterator_tag, ValRef, ValPtr, Dist> |
| forward; |
| typedef any_iterator<Val, std::bidirectional_iterator_tag, ValRef, ValPtr, |
| Dist> |
| bidirectional; |
| typedef any_iterator<Val, std::random_access_iterator_tag, ValRef, ValPtr, |
| Dist> |
| random; |
| }; |
| |
| } |
| |
| #endif |