From 3fb83e0fbe03fd801c89c18f7a8eccaea0fc09f1 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 20 Mar 2014 23:52:08 +0900 Subject: [PATCH] add move_iterator --- sprout/iterator/adaptor.hpp | 1 + sprout/iterator/move_iterator.hpp | 228 +++++++++++++++++++++++++++++ sprout/range/adaptor/modifying.hpp | 1 + sprout/range/adaptor/moved.hpp | 88 +++++++++++ 4 files changed, 318 insertions(+) create mode 100644 sprout/iterator/move_iterator.hpp create mode 100644 sprout/range/adaptor/moved.hpp diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index f5851010..42b8ddde 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/sprout/iterator/move_iterator.hpp b/sprout/iterator/move_iterator.hpp new file mode 100644 index 00000000..2e78eeb9 --- /dev/null +++ b/sprout/iterator/move_iterator.hpp @@ -0,0 +1,228 @@ +/*============================================================================= + 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 SPROUT_ITERATOR_MOVE_ITERATOR_HPP +#define SPROUT_ITERATOR_MOVE_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // move_iterator + // + template + class move_iterator + : public std::iterator< + typename std::iterator_traits::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 typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef Iterator pointer; + typedef value_type&& 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_EXPR( + 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_EXPR(SPROUT_NOEXCEPT_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 diff --git a/sprout/range/adaptor/modifying.hpp b/sprout/range/adaptor/modifying.hpp index 6121d104..5cf2354a 100644 --- a/sprout/range/adaptor/modifying.hpp +++ b/sprout/range/adaptor/modifying.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/sprout/range/adaptor/moved.hpp b/sprout/range/adaptor/moved.hpp new file mode 100644 index 00000000..83a35987 --- /dev/null +++ b/sprout/range/adaptor/moved.hpp @@ -0,0 +1,88 @@ +/*============================================================================= + 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 SPROUT_RANGE_ADAPTOR_MOVED_HPP +#define SPROUT_RANGE_ADAPTOR_MOVED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // moved_range + // + template + class moved_range + : public sprout::adaptors::detail::adapted_range_default< + Range, + sprout::move_iterator::iterator> + > + { + public: + typedef sprout::adaptors::detail::adapted_range_default< + Range, + sprout::move_iterator::iterator> + > base_type; + typedef typename base_type::range_type range_type; + typedef typename base_type::iterator iterator; + public: + SPROUT_CONSTEXPR moved_range() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL + moved_range(moved_range const&) = default; + explicit SPROUT_CONSTEXPR moved_range(range_type& range) + : base_type( + iterator(sprout::end(range)), + iterator(sprout::begin(range)) + ) + {} + }; + + // + // moved_forwarder + // + class moved_forwarder {}; + + // + // moved + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::moved_forwarder moved = {}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::moved_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::moved_forwarder) { + return sprout::adaptors::moved_range< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > + : public sprout::container_construct_traits::base_type> + {}; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_MOVED_HPP