From c33ae70d1366a03d09a452d75bc0c0266dd9c155 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sun, 25 Nov 2012 01:05:11 +0900 Subject: [PATCH] add compost stereo, left_channel, right_channel, effected_xxx --- sprout/compost/effects/superposed.hpp | 2 + sprout/compost/formats.hpp | 4 + .../compost/formats/effected_each_cannel.hpp | 107 ++++++ .../compost/formats/effected_left_cannel.hpp | 71 ++++ .../compost/formats/effected_right_cannel.hpp | 71 ++++ sprout/compost/formats/stereo.hpp | 22 ++ sprout/iterator/adaptor.hpp | 1 + sprout/iterator/alternate_iterator.hpp | 329 ++++++++++++++++++ sprout/range/adaptor.hpp | 1 + sprout/range/adaptor/adapted_dropped.hpp | 2 +- sprout/range/adaptor/adapted_dropped_end.hpp | 2 +- sprout/range/adaptor/adapted_taken.hpp | 2 +- sprout/range/adaptor/adapted_taken_end.hpp | 2 +- sprout/range/adaptor/alternated.hpp | 151 ++++++++ 14 files changed, 763 insertions(+), 4 deletions(-) create mode 100644 sprout/compost/formats/effected_each_cannel.hpp create mode 100644 sprout/compost/formats/effected_left_cannel.hpp create mode 100644 sprout/compost/formats/effected_right_cannel.hpp create mode 100644 sprout/compost/formats/stereo.hpp create mode 100644 sprout/iterator/alternate_iterator.hpp create mode 100644 sprout/range/adaptor/alternated.hpp diff --git a/sprout/compost/effects/superposed.hpp b/sprout/compost/effects/superposed.hpp index 2eb093c6..e92a27d1 100644 --- a/sprout/compost/effects/superposed.hpp +++ b/sprout/compost/effects/superposed.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include namespace sprout { diff --git a/sprout/compost/formats.hpp b/sprout/compost/formats.hpp index a292ad3f..53e3ccd8 100644 --- a/sprout/compost/formats.hpp +++ b/sprout/compost/formats.hpp @@ -5,5 +5,9 @@ #include #include #include +#include +#include +#include +#include #endif // #ifndef SPROUT_COMPOST_FORMATS_HPP diff --git a/sprout/compost/formats/effected_each_cannel.hpp b/sprout/compost/formats/effected_each_cannel.hpp new file mode 100644 index 00000000..bb6bc4e1 --- /dev/null +++ b/sprout/compost/formats/effected_each_cannel.hpp @@ -0,0 +1,107 @@ +#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP +#define SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + namespace formats { + // + // effect_each_channel_holder + // + template + class effect_each_channel_holder { + public: + typedef LAdaptor left_adaptor_type; + typedef RAdaptor right_adaptor_type; + private: + left_adaptor_type left_adaptor_; + right_adaptor_type right_adaptor_; + public: + SPROUT_CONSTEXPR effect_each_channel_holder(left_adaptor_type const& left_adaptor, right_adaptor_type const& right_adaptor) + : left_adaptor_(left_adaptor), right_adaptor_(right_adaptor) + {} + SPROUT_CONSTEXPR left_adaptor_type const& left_adaptor() const { + return left_adaptor_; + } + SPROUT_CONSTEXPR right_adaptor_type const& right_adaptor() const { + return right_adaptor_; + } + }; + template + class effect_each_channel_holder { + public: + typedef Adaptor adaptor_type; + private: + adaptor_type adaptor_; + public: + explicit SPROUT_CONSTEXPR effect_each_channel_holder(adaptor_type const& adaptor) + : adaptor_(adaptor) + {} + SPROUT_CONSTEXPR adaptor_type const& adaptor() const { + return adaptor_; + } + }; + + // + // effected_each_cannel_forwarder + // + class effected_each_cannel_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::formats::effect_each_channel_holder + operator()(LAdaptor const& left_adaptor, RAdaptor const& right_adaptor) { + return sprout::compost::formats::effect_each_channel_holder(left_adaptor, right_adaptor); + } + template + SPROUT_CONSTEXPR sprout::compost::formats::effect_each_channel_holder + operator()(Adaptor const& adaptor) { + return sprout::compost::formats::effect_each_channel_holder(adaptor); + } + }; + + // + // effected_each_cannel + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_each_cannel_forwarder effected_each_cannel{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::formats::effect_each_channel_holder const& rhs) + -> decltype( + sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.left_adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.right_adaptor()) + ) + { + return sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.left_adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.right_adaptor()) + ; + } + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::formats::effect_each_channel_holder const& rhs) + -> decltype( + sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.adaptor()) + ) + { + return sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.adaptor()) + ; + } + } // namespace formats + + using sprout::compost::formats::effected_each_cannel; + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP diff --git a/sprout/compost/formats/effected_left_cannel.hpp b/sprout/compost/formats/effected_left_cannel.hpp new file mode 100644 index 00000000..202fbf9e --- /dev/null +++ b/sprout/compost/formats/effected_left_cannel.hpp @@ -0,0 +1,71 @@ +#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP +#define SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + namespace formats { + // + // effect_left_channel_holder + // + template + class effect_left_channel_holder { + public: + typedef Adaptor adaptor_type; + private: + adaptor_type adaptor_; + public: + explicit SPROUT_CONSTEXPR effect_left_channel_holder(adaptor_type const& adaptor) + : adaptor_(adaptor) + {} + SPROUT_CONSTEXPR adaptor_type const& adaptor() const { + return adaptor_; + } + }; + + // + // effected_left_cannel_forwarder + // + class effected_left_cannel_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::formats::effect_left_channel_holder + operator()(Adaptor const& adaptor) { + return sprout::compost::formats::effect_left_channel_holder(adaptor); + } + }; + + // + // effected_left_cannel + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_left_cannel_forwarder effected_left_cannel{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::formats::effect_left_channel_holder const& rhs) + -> decltype( + sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel) + ) + { + return sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel | rhs.adaptor() + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel) + ; + } + } // namespace formats + + using sprout::compost::formats::effected_left_cannel; + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP diff --git a/sprout/compost/formats/effected_right_cannel.hpp b/sprout/compost/formats/effected_right_cannel.hpp new file mode 100644 index 00000000..162839fe --- /dev/null +++ b/sprout/compost/formats/effected_right_cannel.hpp @@ -0,0 +1,71 @@ +#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP +#define SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + namespace formats { + // + // effect_right_channel_holder + // + template + class effect_right_channel_holder { + public: + typedef Adaptor adaptor_type; + private: + adaptor_type adaptor_; + public: + explicit SPROUT_CONSTEXPR effect_right_channel_holder(adaptor_type const& adaptor) + : adaptor_(adaptor) + {} + SPROUT_CONSTEXPR adaptor_type const& adaptor() const { + return adaptor_; + } + }; + + // + // effected_right_cannel_forwarder + // + class effected_right_cannel_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::formats::effect_right_channel_holder + operator()(Adaptor const& adaptor) { + return sprout::compost::formats::effect_right_channel_holder(adaptor); + } + }; + + // + // effected_right_cannel + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_right_cannel_forwarder effected_right_cannel{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::formats::effect_right_channel_holder const& rhs) + -> decltype( + sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.adaptor()) + ) + { + return sprout::lvalue_forward(lhs) | sprout::compost::formats::left_channel + | sprout::compost::formats::stereo(sprout::lvalue_forward(lhs) | sprout::compost::formats::right_channel | rhs.adaptor()) + ; + } + } // namespace formats + + using sprout::compost::formats::effected_right_cannel; + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP diff --git a/sprout/compost/formats/stereo.hpp b/sprout/compost/formats/stereo.hpp new file mode 100644 index 00000000..0489f844 --- /dev/null +++ b/sprout/compost/formats/stereo.hpp @@ -0,0 +1,22 @@ +#ifndef SPROUT_COMPOST_FORMATS_STEREO_HPP +#define SPROUT_COMPOST_FORMATS_STEREO_HPP + +#include +#include + +namespace sprout { + namespace compost { + namespace formats { + // + // stereo + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::alternated_forwarder stereo{}; + } // anonymous-namespace + } // namespace formats + + using sprout::compost::formats::stereo; + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_FORMATS_STEREO_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index ba4dff42..c36574c1 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/sprout/iterator/alternate_iterator.hpp b/sprout/iterator/alternate_iterator.hpp new file mode 100644 index 00000000..bda8c619 --- /dev/null +++ b/sprout/iterator/alternate_iterator.hpp @@ -0,0 +1,329 @@ +#ifndef SPROUT_ITERATOR_ALTERNATE_ITERATOR_HPP +#define SPROUT_ITERATOR_ALTERNATE_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + // + // alternate_iterator + // + template + class alternate_iterator + : public std::iterator< + typename sprout::common_iterator_category::type, + typename sprout::common_iterator_value_type::type, + typename sprout::common_iterator_difference_type::type, + typename sprout::common_iterator_pointer::type, + typename sprout::common_iterator_reference::type + > + { + public: + typedef LIterator iterator_type; + typedef RIterator iterator2_type; + typedef typename sprout::common_iterator_category::type iterator_category; + typedef typename sprout::common_iterator_value_type::type value_type; + typedef typename sprout::common_iterator_difference_type::type difference_type; + typedef typename sprout::common_iterator_pointer::type pointer; + typedef typename sprout::common_iterator_reference::type reference; + protected: + iterator_type current1; + iterator2_type current2; + bool in_left; + private: + SPROUT_CONSTEXPR alternate_iterator advance_impl_1(difference_type n) const { + return alternate_iterator(sprout::next(current1, n / 2), sprout::next(current2, n / 2), n % 2); + } + SPROUT_CONSTEXPR alternate_iterator advance_impl(difference_type n) const { + return advance_impl_1(n + (!is_in_left() ? 1 : 0)); + } + SPROUT_CONSTEXPR alternate_iterator(iterator_type it1, iterator2_type it2, bool in_left) + : current1(it1), current2(it2), in_left(in_left) + {} + public: + alternate_iterator() + : current1(), current2(), in_left(true) + {} + alternate_iterator(alternate_iterator const&) = default; + SPROUT_CONSTEXPR alternate_iterator(iterator_type it1, iterator2_type it2) + : current1(it1), current2(it2), in_left(true) + {} + template + SPROUT_CONSTEXPR alternate_iterator(alternate_iterator const& it) + : current1(it.base()), current2(it.base2()), in_left(it.is_in_left()) + {} + template + alternate_iterator& operator=(alternate_iterator const& it) { + alternate_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current1; + } + SPROUT_CONSTEXPR iterator2_type base2() const { + return current2; + } + SPROUT_CONSTEXPR bool is_in_left() const { + return in_left; + } + SPROUT_CONSTEXPR reference operator*() const { + return is_in_left() ? *current1 : *current2; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*(*this); + } + alternate_iterator& operator++() { + if (is_in_left()) { + in_left = false; + } else { + in_left = true; + ++current1; + ++current2; + } + return *this; + } + alternate_iterator operator++(int) { + alternate_iterator result(*this); + if (is_in_left()) { + in_left = false; + } else { + in_left = true; + ++current1; + ++current2; + } + return result; + } + alternate_iterator& operator--() { + if (is_in_left()) { + in_left = false; + --current1; + --current2; + } else { + in_left = true; + } + return *this; + } + alternate_iterator operator--(int) { + alternate_iterator temp(*this); + if (is_in_left()) { + in_left = false; + --current1; + --current2; + } else { + in_left = true; + } + return temp; + } + SPROUT_CONSTEXPR alternate_iterator operator+(difference_type n) const { + return advance_impl(n); + } + SPROUT_CONSTEXPR alternate_iterator operator-(difference_type n) const { + return advance_impl(-n); + } + alternate_iterator& operator+=(difference_type n) { + alternate_iterator temp(*this + n); + temp.swap(*this); + return *this; + } + alternate_iterator& operator-=(difference_type n) { + alternate_iterator temp(*this - n); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return *(*this + n); + } + SPROUT_CONSTEXPR alternate_iterator next() const { + return is_in_left() ? alternate_iterator(current1, current2, false) + : alternate_iterator(sprout::next(current1), sprout::next(current2), true) + ; + } + SPROUT_CONSTEXPR alternate_iterator prev() const { + return is_in_left() ? alternate_iterator(sprout::prev(current1), sprout::prev(current2), false) + : alternate_iterator(current1, current2, true) + ; + } + void swap(alternate_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(sprout::swap(current1, other.current1)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(current2, other.current2)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(in_left, other.in_left)) + ) + { + sprout::swap(current1, other.current1); + sprout::swap(current2, other.current2); + sprout::swap(in_left, other.in_left); + } + }; + + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator==( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return lhs.base() == rhs.base() && (lhs.is_in_left() == rhs.is_in_left()); + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator!=( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return !(lhs == rhs); + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator<( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return lhs.base() < rhs.base() || (lhs.base() == rhs.base() && lhs.is_in_left() && !rhs.is_in_left()); + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator>( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return rhs < lhs; + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator<=( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return !(rhs < lhs); + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR bool operator>=( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return !(lhs < rhs); + } + template< + typename LIterator1, typename RIterator1, + typename LIterator2, typename RIterator2 + > + inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) + operator-( + sprout::alternate_iterator const& lhs, + sprout::alternate_iterator const& rhs + ) + { + return lhs.base() - rhs.base() + (lhs.is_in_left() ? (rhs.is_in_left() ? 0 : 1) : (rhs.is_in_left() ? 1 : 0)); + } + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator operator+( + typename sprout::alternate_iterator::difference_type n, + sprout::alternate_iterator const& it + ) + { + return it + n; + } + + // + // make_alternate_iterator + // + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator + make_alternate_iterator(LIterator it1, RIterator it2) { + return sprout::alternate_iterator(it1, it2); + } + + // + // swap + // + template + inline void + swap( + sprout::alternate_iterator& lhs, + sprout::alternate_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( + sprout::alternate_iterator first, + sprout::alternate_iterator last + ) + { + return last - first; + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator + iterator_next(sprout::alternate_iterator const& it) { + return it.next(); + } + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator + iterator_next( + sprout::alternate_iterator const& it, + typename sprout::alternate_iterator::difference_type n + ) + { + return it + n; + } + + // + // iterator_prev + // + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator + iterator_prev(sprout::alternate_iterator const& it) { + return it.prev(); + } + template + inline SPROUT_CONSTEXPR sprout::alternate_iterator + iterator_prev( + sprout::alternate_iterator const& it, + typename sprout::alternate_iterator::difference_type n + ) + { + return it - n; + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_ALTERNATE_ITERATOR_HPP diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp index 8ddb79d7..fc727800 100644 --- a/sprout/range/adaptor.hpp +++ b/sprout/range/adaptor.hpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/range/adaptor/adapted_dropped.hpp b/sprout/range/adaptor/adapted_dropped.hpp index 0baa42b9..03e59132 100644 --- a/sprout/range/adaptor/adapted_dropped.hpp +++ b/sprout/range/adaptor/adapted_dropped.hpp @@ -21,7 +21,7 @@ namespace sprout { adaptor_type adaptor_; difference_type distance_; public: - explicit SPROUT_CONSTEXPR adapt_drop_holder(adaptor_type const& adaptor, difference_type distance) + SPROUT_CONSTEXPR adapt_drop_holder(adaptor_type const& adaptor, difference_type distance) : adaptor_(adaptor), distance_(distance) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { diff --git a/sprout/range/adaptor/adapted_dropped_end.hpp b/sprout/range/adaptor/adapted_dropped_end.hpp index 56a90ab0..94c65313 100644 --- a/sprout/range/adaptor/adapted_dropped_end.hpp +++ b/sprout/range/adaptor/adapted_dropped_end.hpp @@ -21,7 +21,7 @@ namespace sprout { adaptor_type adaptor_; difference_type distance_; public: - explicit SPROUT_CONSTEXPR adapt_drop_end_holder(adaptor_type const& adaptor, difference_type distance) + SPROUT_CONSTEXPR adapt_drop_end_holder(adaptor_type const& adaptor, difference_type distance) : adaptor_(adaptor), distance_(distance) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { diff --git a/sprout/range/adaptor/adapted_taken.hpp b/sprout/range/adaptor/adapted_taken.hpp index 1fc85fe1..b3e0de14 100644 --- a/sprout/range/adaptor/adapted_taken.hpp +++ b/sprout/range/adaptor/adapted_taken.hpp @@ -21,7 +21,7 @@ namespace sprout { adaptor_type adaptor_; difference_type distance_; public: - explicit SPROUT_CONSTEXPR adapt_take_holder(adaptor_type const& adaptor, difference_type distance) + SPROUT_CONSTEXPR adapt_take_holder(adaptor_type const& adaptor, difference_type distance) : adaptor_(adaptor), distance_(distance) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { diff --git a/sprout/range/adaptor/adapted_taken_end.hpp b/sprout/range/adaptor/adapted_taken_end.hpp index eb609190..4cc7a819 100644 --- a/sprout/range/adaptor/adapted_taken_end.hpp +++ b/sprout/range/adaptor/adapted_taken_end.hpp @@ -21,7 +21,7 @@ namespace sprout { adaptor_type adaptor_; difference_type distance_; public: - explicit SPROUT_CONSTEXPR adapt_take_end_holder(adaptor_type const& adaptor, difference_type distance) + SPROUT_CONSTEXPR adapt_take_end_holder(adaptor_type const& adaptor, difference_type distance) : adaptor_(adaptor), distance_(distance) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { diff --git a/sprout/range/adaptor/alternated.hpp b/sprout/range/adaptor/alternated.hpp new file mode 100644 index 00000000..2a22792c --- /dev/null +++ b/sprout/range/adaptor/alternated.hpp @@ -0,0 +1,151 @@ +#ifndef SPROUT_RANGE_ADAPTOR_ALTERNATED_HPP +#define SPROUT_RANGE_ADAPTOR_ALTERNATED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + namespace adaptors { + // + // alternated_range + // + template + class alternated_range + : public sprout::range::range_container< + sprout::alternate_iterator< + typename sprout::container_traits::iterator, + typename sprout::container_traits::iterator + > + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef LRange range_type; + typedef RRange range2_type; + typedef sprout::range::range_container< + sprout::alternate_iterator< + typename sprout::container_traits::iterator, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::iterator iterator; + public: + alternated_range() = default; + alternated_range(alternated_range const&) = default; + SPROUT_CONSTEXPR alternated_range(range_type& range1, range2_type& range2) + : base_type( + iterator(sprout::begin(range1), sprout::begin(range2)), + iterator( + sprout::next(sprout::begin(range1), NS_SSCRISK_CEL_OR_SPROUT::min(sprout::size(range1), sprout::size(range2))), + sprout::next(sprout::begin(range2), NS_SSCRISK_CEL_OR_SPROUT::min(sprout::size(range1), sprout::size(range2))) + ) + ) + {} + }; + + // + // alternate_holder + // + template + class alternate_holder { + public: + typedef RRange range2_type; + private: + sprout::value_holder range_; + public: + alternate_holder() = default; + alternate_holder(alternate_holder const&) = default; + explicit SPROUT_CONSTEXPR alternate_holder(range2_type& range) + : range_(range) + {} + SPROUT_CONSTEXPR range2_type& range() const { + return range_; + } + }; + + // + // alternated_forwarder + // + class alternated_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::alternate_holder< + typename std::remove_reference::type>::type + > + operator()(RRange&& range) { + return sprout::adaptors::alternate_holder< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(range) + ); + } + }; + + // + // alternated + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::alternated_forwarder alternated{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::alternated_range< + typename std::remove_reference::type>::type, + RRange + > + operator|(LRange&& lhs, sprout::adaptors::alternate_holder const& rhs) { + return sprout::adaptors::alternated_range< + typename std::remove_reference::type>::type, + RRange + >( + sprout::lvalue_forward(lhs), + rhs.range() + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_ALTERNATED_HPP