/*============================================================================= Copyright (c) 2011-2019 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 SPROUT_ITERATOR_MOVE_ITERATOR_HPP #define SPROUT_ITERATOR_MOVE_ITERATOR_HPP #include #include #include #include #include #include #include #include #include namespace sprout { // // move_iterator // template class move_iterator : public sprout::detail::iterator_base< Iterator, sprout::use_default, sprout::use_default, sprout::use_default, Iterator, typename iterator_traits::value_type&& >::type { private: typedef typename sprout::detail::iterator_base< Iterator, sprout::use_default, sprout::use_default, sprout::use_default, Iterator, typename iterator_traits::value_type&& >::type base_type; public: typedef Iterator iterator_type; typedef typename base_type::iterator_category iterator_category; typedef typename base_type::value_type value_type; typedef typename base_type::difference_type difference_type; typedef typename base_type::pointer pointer; typedef typename base_type::reference reference; protected: iterator_type current; public: SPROUT_CONSTEXPR move_iterator() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL SPROUT_CONSTEXPR move_iterator(move_iterator const& other) : current(other.current) {} explicit SPROUT_CONSTEXPR move_iterator(iterator_type it) : current(it) {} template SPROUT_CONSTEXPR move_iterator(move_iterator const& it) : current(it.base()) {} template SPROUT_CXX14_CONSTEXPR move_iterator& operator=(move_iterator const& it) { move_iterator temp(it); temp.swap(*this); return *this; } SPROUT_CONSTEXPR iterator_type base() const { return current; } SPROUT_CONSTEXPR reference operator*() const { return sprout::move(*current); } SPROUT_CONSTEXPR pointer operator->() const { return current; } SPROUT_CXX14_CONSTEXPR move_iterator& operator++() { ++current; return *this; } SPROUT_CXX14_CONSTEXPR move_iterator operator++(int) { move_iterator result(*this); ++current; return result; } SPROUT_CXX14_CONSTEXPR move_iterator& operator--() { --current; return *this; } SPROUT_CXX14_CONSTEXPR move_iterator operator--(int) { move_iterator temp(*this); --current; return temp; } SPROUT_CONSTEXPR move_iterator operator+(difference_type n) const { return move_iterator(current + n); } SPROUT_CONSTEXPR move_iterator operator-(difference_type n) const { return move_iterator(current - n); } SPROUT_CXX14_CONSTEXPR move_iterator& operator+=(difference_type n) { move_iterator temp(current + n); temp.swap(*this); return *this; } SPROUT_CXX14_CONSTEXPR move_iterator& operator-=(difference_type n) { move_iterator temp(current - n); temp.swap(*this); return *this; } SPROUT_CONSTEXPR reference operator[](difference_type n) const { return sprout::move(current[n]); } SPROUT_CONSTEXPR move_iterator next() const { return move_iterator(sprout::next(current)); } SPROUT_CONSTEXPR move_iterator prev() const { return move_iterator(sprout::prev(current)); } SPROUT_CXX14_CONSTEXPR void swap(move_iterator& other) SPROUT_NOEXCEPT_IF( SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) ) { swap(current, other.current); } }; template inline SPROUT_CONSTEXPR bool operator==(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return lhs.base() == rhs.base(); } template inline SPROUT_CONSTEXPR bool operator!=(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return !(lhs == rhs); } template inline SPROUT_CONSTEXPR bool operator<(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return lhs.base() < rhs.base(); } template inline SPROUT_CONSTEXPR bool operator>(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return rhs < lhs; } template inline SPROUT_CONSTEXPR bool operator<=(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return !(rhs < lhs); } template inline SPROUT_CONSTEXPR bool operator>=(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return !(lhs < rhs); } template inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) operator-(sprout::move_iterator const& lhs, sprout::move_iterator const& rhs) { return lhs.base() - rhs.base(); } template inline SPROUT_CONSTEXPR sprout::move_iterator operator+( typename sprout::move_iterator::difference_type n, sprout::move_iterator const& it ) { return it + n; } // // make_move_iterator // template inline SPROUT_CONSTEXPR sprout::move_iterator make_move_iterator(Iterator it) { return sprout::move_iterator(it); } // // swap // template inline SPROUT_CXX14_CONSTEXPR void swap(sprout::move_iterator& lhs, sprout::move_iterator& rhs) SPROUT_NOEXCEPT_IF_EXPR(lhs.swap(rhs)) { lhs.swap(rhs); } // // iterator_next // template inline SPROUT_CONSTEXPR sprout::move_iterator iterator_next(sprout::move_iterator const& it) { return it.next(); } // // iterator_prev // template inline SPROUT_CONSTEXPR sprout::move_iterator iterator_prev(sprout::move_iterator const& it) { return it.prev(); } // // is_const_iterator_cast_convertible // template struct is_const_iterator_cast_convertible, sprout::move_iterator > : public sprout::is_const_iterator_cast_convertible {}; // // const_iterator_conversion // template< typename T, typename Iterator, typename sprout::enabler_if, T>::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR T const_iterator_conversion(sprout::move_iterator const& it) { return T(sprout::const_iterator_cast(it.base())); } } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_MOVE_ITERATOR_HPP