/*============================================================================= Copyright (c) 2011-2014 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef TESTSPR_ITERATOR_HPP #define TESTSPR_ITERATOR_HPP #include #include #include #include #include #include #include namespace testspr { // // reduct_iterator // template::iterator_category> class reduct_iterator : public std::iterator< Category, typename std::iterator_traits::value_type, typename std::iterator_traits::difference_type, typename std::iterator_traits::pointer, typename std::iterator_traits::reference > { public: typedef Iterator iterator_type; typedef Category iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef typename std::iterator_traits::pointer pointer; typedef typename std::iterator_traits::reference reference; protected: iterator_type current; public: SPROUT_CONSTEXPR reduct_iterator() {}; SPROUT_CONSTEXPR reduct_iterator(reduct_iterator const& other) = default; explicit SPROUT_CONSTEXPR reduct_iterator(iterator_type it) : current(it) {} template SPROUT_CONSTEXPR reduct_iterator(reduct_iterator const& it) : current(it.base()) {} template reduct_iterator& operator=(reduct_iterator const& it) { reduct_iterator temp(it); temp.swap(*this); return *this; } SPROUT_CONSTEXPR iterator_type base() const { return current; } SPROUT_CONSTEXPR reference operator*() const { return *current; } SPROUT_CONSTEXPR pointer operator->() const { return &*current; } reduct_iterator& operator++() { ++current; return *this; } reduct_iterator operator++(int) { reduct_iterator result(*this); ++current; return result; } reduct_iterator& operator--() { --current; return *this; } reduct_iterator operator--(int) { reduct_iterator temp(*this); --current; return temp; } SPROUT_CONSTEXPR reduct_iterator operator+(difference_type n) const { return reduct_iterator(current + n); } SPROUT_CONSTEXPR reduct_iterator operator-(difference_type n) const { return reduct_iterator(current - n); } reduct_iterator& operator+=(difference_type n) { reduct_iterator temp(current + n); temp.swap(*this); return *this; } reduct_iterator& operator-=(difference_type n) { reduct_iterator temp(current - n); temp.swap(*this); return *this; } SPROUT_CONSTEXPR reference operator[](difference_type n) const { return current[n]; } SPROUT_CONSTEXPR reduct_iterator next() const { return reduct_iterator(sprout::next(current)); } SPROUT_CONSTEXPR reduct_iterator prev() const { return reduct_iterator(sprout::prev(current)); } void swap(reduct_iterator& other) SPROUT_NOEXCEPT_EXPR( SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) ) { using std::swap; swap(current, other.current); } }; template inline SPROUT_CONSTEXPR bool operator==(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return lhs.base() == rhs.base(); } template inline SPROUT_CONSTEXPR bool operator!=(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return !(lhs == rhs); } template inline SPROUT_CONSTEXPR bool operator<(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return lhs.base() < rhs.base(); } template inline SPROUT_CONSTEXPR bool operator>(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return rhs < lhs; } template inline SPROUT_CONSTEXPR bool operator<=(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return !(rhs < lhs); } template inline SPROUT_CONSTEXPR bool operator>=(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return !(lhs < rhs); } template inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) operator-(testspr::reduct_iterator const& lhs, testspr::reduct_iterator const& rhs) { return lhs.base() - rhs.base(); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator operator+( typename testspr::reduct_iterator::difference_type n, testspr::reduct_iterator const& it ) { return it + n; } // // make_reduct_iterator // template inline SPROUT_CONSTEXPR testspr::reduct_iterator make_reduct_iterator(Iterator it) { return testspr::reduct_iterator(it); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator make_reduct_iterator(Iterator it) { return testspr::reduct_iterator(it); } // // reduct_input // reduct_forward // reduct_bidirectional // reduct_random_access // template inline SPROUT_CONSTEXPR testspr::reduct_iterator reduct_input(Iterator it) { return testspr::reduct_iterator(it); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator reduct_forward(Iterator it) { return testspr::reduct_iterator(it); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator reduct_bidirectional(Iterator it) { return testspr::reduct_iterator(it); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator reduct_random_access(Iterator it) { return testspr::reduct_iterator(it); } // // swap // template inline void swap(testspr::reduct_iterator& lhs, testspr::reduct_iterator& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) { lhs.swap(rhs); } // // iterator_distance // template inline SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type iterator_distance(testspr::reduct_iterator first, testspr::reduct_iterator last) { return sprout::distance(first.base(), last.base()); } // // iterator_next // template inline SPROUT_CONSTEXPR testspr::reduct_iterator iterator_next(testspr::reduct_iterator const& it) { return it.next(); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator iterator_next( testspr::reduct_iterator const& it, typename testspr::reduct_iterator::difference_type n ) { return testspr::reduct_iterator(sprout::next(it.base(), n)); } // // iterator_prev // template inline SPROUT_CONSTEXPR testspr::reduct_iterator iterator_prev(testspr::reduct_iterator const& it) { return it.prev(); } template inline SPROUT_CONSTEXPR testspr::reduct_iterator iterator_prev( testspr::reduct_iterator const& it, typename testspr::reduct_iterator::difference_type n ) { return testspr::reduct_iterator(sprout::next(it.base(), n)); } } // namespace testspr #endif // #ifndef TESTSPR_ITERATOR_HPP