#pragma once #include /** * \brief This class provides a generic interface for iterators and implements the * function which are required by iterators. * * The class is inspired by boost's iterator facade and probably offers less * functionality. See here for details: * http://www.boost.org/doc/libs/1_54_0/libs/iterator/doc/index.html#iterator-facade-and-adaptor * * Derived classes must implement the functions * * bool equal(const Derived&) * difference_type distance_to(const Derived&) * reference dereference() * void increment() * void decrement() * void advance(difference_type offset) * * for a bidirectional iterator. * * So far, this class has only been evaluated for bidirection iterators. The implementation * is based on the curiously recurring template pattern (CRTP) and therefore needs to know * the type of the derived class. * */ template < typename Derived, typename Value, typename Categroy > class IteratorFacade : public std::iterator< Categroy, Value > { Derived& derived() { return *static_cast(this); } Derived const& derived() const { return *static_cast(this); } public: /// Equality comparison. bool operator==(const IteratorFacade& other) const { return derived().equal(other.derived()); } /// Inequality comparison. bool operator!=(const IteratorFacade& other) const { return !derived().equal(other.derived()); } // Relations bool operator<(const IteratorFacade& other) const { return derived().distance_to(other.derived()) > 0; } bool operator>(const IteratorFacade& other) const { return derived().distance_to(other.derived()) < 0; } bool operator<=(const IteratorFacade& other) const { return derived().distance_to(other.derived()) >= 0; } bool operator>=(const IteratorFacade& other) const { return derived().distance_to(other.derived()) <= 0; } /// Pre-increment. Derived& operator++() { derived().increment(); return derived(); } /// Post-increment. Derived operator++(int) { Derived tmp(derived()); derived().increment(); return tmp; } /// Pre-decrement. Derived& operator--() { derived().decrement(); return derived(); } /// Post-decrement. Derived operator--(int) { Derived tmp(derived()); derived().decrement(); return tmp; } /// Dereference operator. reference operator*() const { return derived().dereference(); } /// Pointer access operator. pointer operator->() const { return &derived().dereference(); } /// Advances the iterator by the given offset. Derived& operator+=(difference_type offset) { derived().advance(offset); return derived(); } /// Move the iterator backwards by the given offset. Derived& operator-=(difference_type offset) { derived().advance(-offset); return derived(); } /// Adds an offset to the iterator (on the right hand side). Derived operator+(difference_type offset) const { Derived tmp(derived()); tmp += offset; return tmp; } /// Subtracts an offset from the iterator (on the right hand side). Derived operator-(difference_type offset) const { Derived tmp(derived()); tmp -= offset; return tmp; } /// Computes the distance between two iterators. difference_type operator-(const IteratorFacade& other) const { return other.derived().distance_to(derived()); } /// Array access to iterator elements. reference operator[](difference_type offset) const { return (*(*this + offset)); } /// Adds an offset to the iterator (on the left hand side, thus its a friend). friend Derived operator+(difference_type offset, const IteratorFacade& other) { Derived tmp(other.derived()); tmp += offset; return tmp; } };