From 1cfec16e52382f1c0e2cdeb8c8aa75b83f3c36fd Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sun, 27 Jan 2013 16:56:14 +0900 Subject: [PATCH] add range adaptors adjacent_filtered, uniqued --- sprout/algorithm/fixed/unique_copy.hpp | 82 +++++++- sprout/iterator/adaptor.hpp | 12 +- sprout/iterator/adjacent_filter_iterator.hpp | 177 ++++++++++++++++++ sprout/iterator/filter_iterator.hpp | 21 +-- sprout/iterator/unique_iterator.hpp | 50 +++++ sprout/range/adaptor/adjacent_filtered.hpp | 118 ++++++++++++ sprout/range/adaptor/alternated.hpp | 1 - sprout/range/adaptor/amplitude_spectrum.hpp | 1 - sprout/range/adaptor/blanked.hpp | 1 - sprout/range/adaptor/clamped.hpp | 1 - sprout/range/adaptor/counting.hpp | 1 - sprout/range/adaptor/dft.hpp | 1 - sprout/range/adaptor/filled.hpp | 1 - sprout/range/adaptor/filtered.hpp | 1 - sprout/range/adaptor/idft.hpp | 1 - sprout/range/adaptor/indexed.hpp | 1 - sprout/range/adaptor/jointed.hpp | 1 - sprout/range/adaptor/merged.hpp | 1 - sprout/range/adaptor/modifying.hpp | 2 + sprout/range/adaptor/outdirected.hpp | 1 - sprout/range/adaptor/phase_spectrum.hpp | 1 - sprout/range/adaptor/removed.hpp | 1 - sprout/range/adaptor/removed_if.hpp | 1 - sprout/range/adaptor/replaced.hpp | 1 - sprout/range/adaptor/replaced_if.hpp | 1 - sprout/range/adaptor/reversed.hpp | 1 - sprout/range/adaptor/sawtooth_wave.hpp | 1 - sprout/range/adaptor/set_difference.hpp | 1 - sprout/range/adaptor/set_intersection.hpp | 1 - .../adaptor/set_symmetric_difference.hpp | 1 - sprout/range/adaptor/set_union.hpp | 1 - sprout/range/adaptor/sinusoidal.hpp | 1 - sprout/range/adaptor/size_enumed.hpp | 1 - sprout/range/adaptor/sized.hpp | 1 - sprout/range/adaptor/square_wave.hpp | 1 - sprout/range/adaptor/steps.hpp | 1 - sprout/range/adaptor/transformed.hpp | 1 - sprout/range/adaptor/triangle_wave.hpp | 1 - sprout/range/adaptor/uniqued.hpp | 135 +++++++++++++ sprout/range/adaptor/valued.hpp | 1 - 40 files changed, 571 insertions(+), 58 deletions(-) create mode 100644 sprout/iterator/adjacent_filter_iterator.hpp create mode 100644 sprout/iterator/unique_iterator.hpp create mode 100644 sprout/range/adaptor/adjacent_filtered.hpp create mode 100644 sprout/range/adaptor/uniqued.hpp diff --git a/sprout/algorithm/fixed/unique_copy.hpp b/sprout/algorithm/fixed/unique_copy.hpp index a61e1f5c..87d6b43c 100644 --- a/sprout/algorithm/fixed/unique_copy.hpp +++ b/sprout/algorithm/fixed/unique_copy.hpp @@ -1,11 +1,13 @@ #ifndef SPROUT_ALGORITHM_FIXED_UNIQUE_COPY_HPP #define SPROUT_ALGORITHM_FIXED_UNIQUE_COPY_HPP +#include #include #include #include #include #include +#include #include #include #include @@ -48,6 +50,41 @@ namespace sprout { : sprout::detail::container_complate(result, args..., head) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + unique_copy(InputIterator first, InputIterator last, Result const& result) { + return first != last + ? sprout::fixed::detail::unique_copy_impl(sprout::next(first), last, result, sprout::size(result), *first) + : sprout::detail::container_complate(result) + ; + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unique_copy_dyn( + InputIterator first, InputIterator last, Result const& result, + std::forward_iterator_tag* + ) + { + return sprout::remake( + result, sprout::size(result), + sprout::make_unique_iterator(first, last), + sprout::make_unique_iterator(last, last) + ); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + unique_copy(InputIterator first, InputIterator last, Result const& result) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::unique_copy_dyn(first, last, result, category()); + } } // namespace detail // // unique_copy @@ -55,10 +92,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type unique_copy(InputIterator first, InputIterator last, Result const& result) { - return first != last - ? sprout::fixed::detail::unique_copy_impl(sprout::next(first), last, result, sprout::size(result), *first) - : sprout::detail::container_complate(result) - ; + return sprout::fixed::detail::unique_copy(first, last, result); } template @@ -103,6 +137,41 @@ namespace sprout { : sprout::detail::container_complate(result, args..., head) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + unique_copy(InputIterator first, InputIterator last, Result const& result, BinaryPredicate pred) { + return first != last + ? sprout::fixed::detail::unique_copy_impl(sprout::next(first), last, result, pred, sprout::size(result), *first) + : sprout::detail::container_complate(result) + ; + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unique_copy_dyn( + InputIterator first, InputIterator last, Result const& result, BinaryPredicate pred, + std::forward_iterator_tag* + ) + { + return sprout::remake( + result, sprout::size(result), + sprout::make_unique_iterator(pred, first, last), + sprout::make_unique_iterator(pred, last, last) + ); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + unique_copy(InputIterator first, InputIterator last, Result const& result, BinaryPredicate pred) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::unique_copy_dyn(first, last, result, pred, category()); + } } // namespace detail // // unique_copy @@ -110,10 +179,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type unique_copy(InputIterator first, InputIterator last, Result const& result, BinaryPredicate pred) { - return first != last - ? sprout::fixed::detail::unique_copy_impl(sprout::next(first), last, result, pred, sprout::size(result), *first) - : sprout::detail::container_complate(result) - ; + return sprout::fixed::detail::unique_copy(first, last, result, pred); } template diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index bd6ddfe3..d1dde63d 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -9,17 +9,19 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/sprout/iterator/adjacent_filter_iterator.hpp b/sprout/iterator/adjacent_filter_iterator.hpp new file mode 100644 index 00000000..58c16106 --- /dev/null +++ b/sprout/iterator/adjacent_filter_iterator.hpp @@ -0,0 +1,177 @@ +#ifndef SPROUT_ITERATOR_ADJACENT_FILTER_ITERATOR_HPP +#define SPROUT_ITERATOR_ADJACENT_FILTER_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // adjacent_filter_iterator + // + template + class adjacent_filter_iterator + : public std::iterator< + typename sprout::min_iterator_category< + typename std::iterator_traits::iterator_category, + std::forward_iterator_tag + >::type, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference + > + { + public: + typedef Predicate predicate_type; + typedef Iterator iterator_type; + typedef typename sprout::min_iterator_category< + typename std::iterator_traits::iterator_category, + std::forward_iterator_tag + >::type 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; + private: + struct private_constructor_tag {}; + private: + static SPROUT_CONSTEXPR iterator_type find_next(iterator_type first, iterator_type last, Predicate pred) { + return sprout::adjacent_find(first, last, pred); + } + static SPROUT_CONSTEXPR iterator_type checked_next(iterator_type found, iterator_type last) { + return found == last ? last + : sprout::next(found) + ; + } + protected: + iterator_type current; + iterator_type last; + Predicate pred; + private: + void satisfy_predicate() { + current = sprout::adjacent_find(current, last, pred); + } + SPROUT_CONSTEXPR adjacent_filter_iterator(Predicate pred, iterator_type it, iterator_type last, private_constructor_tag) + : current(it) + , last(last) + , pred(pred) + {} + public: + adjacent_filter_iterator() = default; + adjacent_filter_iterator(adjacent_filter_iterator const&) = default; + SPROUT_CONSTEXPR adjacent_filter_iterator(Predicate pred, iterator_type it, iterator_type last = iterator_type()) + : current(find_next(it, last, pred)) + , last(last) + , pred(pred) + {} + template + SPROUT_CONSTEXPR adjacent_filter_iterator(adjacent_filter_iterator const& it) + : current(it.current) + , last(it.last) + , pred(it.pred) + {} + template + adjacent_filter_iterator& operator=(adjacent_filter_iterator const& it) { + adjacent_filter_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR iterator_type end() const { + return last; + } + SPROUT_CONSTEXPR Predicate predicate() const { + return pred; + } + SPROUT_CONSTEXPR reference operator*() const { + return *current; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*current; + } + + adjacent_filter_iterator& operator++() { + satisfy_predicate(); + if (current != last) { + ++current; + } + return *this; + } + adjacent_filter_iterator operator++(int) { + adjacent_filter_iterator result(*this); + satisfy_predicate(); + if (current != last) { + ++current; + } + return result; + } + SPROUT_CONSTEXPR adjacent_filter_iterator next() const { + return adjacent_filter_iterator(pred, checked_next(find_next(current, last, pred), last), last, private_constructor_tag()); + } + void swap(adjacent_filter_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(sprout::swap(current, other.current)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(last, other.last)) + && SPROUT_NOEXCEPT_EXPR(sprout::swap(pred, other.pred)) + ) + { + sprout::swap(current, other.current); + sprout::swap(last, other.last); + sprout::swap(pred, other.pred); + } + }; + + template + inline SPROUT_CONSTEXPR bool operator==( + sprout::adjacent_filter_iterator const& lhs, + sprout::adjacent_filter_iterator const& rhs + ) + { + return lhs.base() == rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool operator!=( + sprout::adjacent_filter_iterator const& lhs, + sprout::adjacent_filter_iterator const& rhs + ) + { + return !(lhs == rhs); + } + + // + // make_adjacent_filter_iterator + // + template + inline SPROUT_CONSTEXPR sprout::adjacent_filter_iterator + make_adjacent_filter_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) { + return sprout::adjacent_filter_iterator(pred, it, last); + } + + // + // swap + // + template + inline void + swap(sprout::adjacent_filter_iterator& lhs, sprout::adjacent_filter_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::adjacent_filter_iterator + iterator_next(sprout::adjacent_filter_iterator const& it) { + return it.next(); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_ADJACENT_FILTER_ITERATOR_HPP diff --git a/sprout/iterator/filter_iterator.hpp b/sprout/iterator/filter_iterator.hpp index 969c2bf1..93bfaae1 100644 --- a/sprout/iterator/filter_iterator.hpp +++ b/sprout/iterator/filter_iterator.hpp @@ -2,11 +2,10 @@ #define SPROUT_ITERATOR_FILTER_ITERATOR_HPP #include -#include -#include #include #include #include +#include #include #include @@ -17,10 +16,9 @@ namespace sprout { template class filter_iterator : public std::iterator< - typename std::conditional< - std::is_convertible::iterator_category, std::random_access_iterator_tag>::value, - std::bidirectional_iterator_tag, - typename std::iterator_traits::iterator_category + typename sprout::min_iterator_category< + typename std::iterator_traits::iterator_category, + std::bidirectional_iterator_tag >::type, typename std::iterator_traits::value_type, typename std::iterator_traits::difference_type, @@ -31,10 +29,9 @@ namespace sprout { public: typedef Predicate predicate_type; typedef Iterator iterator_type; - typedef typename std::conditional< - std::is_convertible::iterator_category, std::random_access_iterator_tag>::value, - std::bidirectional_iterator_tag, - typename std::iterator_traits::iterator_category + typedef typename sprout::min_iterator_category< + typename std::iterator_traits::iterator_category, + std::bidirectional_iterator_tag >::type iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; @@ -57,9 +54,7 @@ namespace sprout { Predicate pred; private: void satisfy_predicate() { - while (current != last && !pred(*current)) { - ++current; - } + current = sprout::find_if(current, last, pred); } void satisfy_predicate_backward() { while (!pred(*current)) { diff --git a/sprout/iterator/unique_iterator.hpp b/sprout/iterator/unique_iterator.hpp new file mode 100644 index 00000000..713aecb3 --- /dev/null +++ b/sprout/iterator/unique_iterator.hpp @@ -0,0 +1,50 @@ +#ifndef SPROUT_ITERATOR_UNIQUE_ITERATOR_HPP +#define SPROUT_ITERATOR_UNIQUE_ITERATOR_HPP + +#include +#include +#include + +namespace sprout { + // + // unique_filter + // + template > + class unique_filter { + public: + typedef bool result_type; + private: + Predicate pred_; + public: + SPROUT_CONSTEXPR unique_filter() + : pred_() + {} + explicit SPROUT_CONSTEXPR unique_filter(Predicate pred) + : pred_(pred) + {} + template + SPROUT_CONSTEXPR bool operator()(T const& lhs, U const& rhs) const { + return !pred_(lhs, rhs); + } + }; + + // + // make_unique_iterator + // + template + inline SPROUT_CONSTEXPR sprout::adjacent_filter_iterator, Iterator> + make_unique_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) { + return sprout::adjacent_filter_iterator, Iterator>( + sprout::unique_filter(pred), it, last + ); + } + template + inline SPROUT_CONSTEXPR sprout::adjacent_filter_iterator, Iterator> + make_unique_iterator(Iterator it, Iterator last = Iterator()) { + return sprout::adjacent_filter_iterator, Iterator>( + sprout::unique_filter<>(), it, last + ); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_UNIQUE_ITERATOR_HPP diff --git a/sprout/range/adaptor/adjacent_filtered.hpp b/sprout/range/adaptor/adjacent_filtered.hpp new file mode 100644 index 00000000..d61c92a8 --- /dev/null +++ b/sprout/range/adaptor/adjacent_filtered.hpp @@ -0,0 +1,118 @@ +#ifndef SPROUT_RANGE_ADAPTOR_ADJACENT_FILTERED_HPP +#define SPROUT_RANGE_ADAPTOR_ADJACENT_FILTERED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // adjacent_filtered_range + // + template + class adjacent_filtered_range + : public sprout::adaptors::detail::adapted_range_default< + Range, + sprout::adjacent_filter_iterator< + Predicate, + typename sprout::container_traits::iterator + > + > + { + public: + typedef Predicate predicate_type; + typedef sprout::adaptors::detail::adapted_range_default< + Range, + sprout::adjacent_filter_iterator< + Predicate, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::range_type range_type; + typedef typename base_type::iterator iterator; + public: + adjacent_filtered_range() = default; + adjacent_filtered_range(adjacent_filtered_range const&) = default; + SPROUT_CONSTEXPR adjacent_filtered_range(Predicate pred, range_type& range) + : base_type( + iterator(pred, sprout::begin(range), sprout::end(range)), + iterator(pred, sprout::end(range), sprout::end(range)) + ) + {} + }; + + // + // adjacent_filter_holder + // + template + class adjacent_filter_holder { + public: + typedef Predicate predicate_type; + private: + Predicate pred_; + public: + adjacent_filter_holder() = default; + adjacent_filter_holder(adjacent_filter_holder const&) = default; + SPROUT_CONSTEXPR adjacent_filter_holder(Predicate pred) + : pred_(pred) + {} + SPROUT_CONSTEXPR Predicate predicate() const { + return pred_; + } + }; + + // + // adjacent_filtered_forwarder + // + class adjacent_filtered_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::adjacent_filter_holder + operator()(Predicate pred) { + return sprout::adaptors::adjacent_filter_holder(pred); + } + }; + + // + // adjacent_filtered + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::adjacent_filtered_forwarder adjacent_filtered = {}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::adjacent_filtered_range< + Predicate, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::adjacent_filter_holder const& rhs) { + return sprout::adaptors::adjacent_filtered_range< + Predicate, + typename std::remove_reference::type>::type + >( + rhs.predicate(), + 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_ADJACENT_FILTERED_HPP diff --git a/sprout/range/adaptor/alternated.hpp b/sprout/range/adaptor/alternated.hpp index 5df4039e..58ec33bf 100644 --- a/sprout/range/adaptor/alternated.hpp +++ b/sprout/range/adaptor/alternated.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/amplitude_spectrum.hpp b/sprout/range/adaptor/amplitude_spectrum.hpp index 96f4585b..d3fe7929 100644 --- a/sprout/range/adaptor/amplitude_spectrum.hpp +++ b/sprout/range/adaptor/amplitude_spectrum.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/blanked.hpp b/sprout/range/adaptor/blanked.hpp index ad24a30e..e758df94 100644 --- a/sprout/range/adaptor/blanked.hpp +++ b/sprout/range/adaptor/blanked.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/clamped.hpp b/sprout/range/adaptor/clamped.hpp index bef53a52..0522378e 100644 --- a/sprout/range/adaptor/clamped.hpp +++ b/sprout/range/adaptor/clamped.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/counting.hpp b/sprout/range/adaptor/counting.hpp index 43343dea..1e0a3ed9 100644 --- a/sprout/range/adaptor/counting.hpp +++ b/sprout/range/adaptor/counting.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/dft.hpp b/sprout/range/adaptor/dft.hpp index 326835a0..a66be543 100644 --- a/sprout/range/adaptor/dft.hpp +++ b/sprout/range/adaptor/dft.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/filled.hpp b/sprout/range/adaptor/filled.hpp index 745ee1f4..85129f94 100644 --- a/sprout/range/adaptor/filled.hpp +++ b/sprout/range/adaptor/filled.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/filtered.hpp b/sprout/range/adaptor/filtered.hpp index 369e47e6..59102ca5 100644 --- a/sprout/range/adaptor/filtered.hpp +++ b/sprout/range/adaptor/filtered.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/idft.hpp b/sprout/range/adaptor/idft.hpp index e6afdbaf..b4b6dd40 100644 --- a/sprout/range/adaptor/idft.hpp +++ b/sprout/range/adaptor/idft.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/indexed.hpp b/sprout/range/adaptor/indexed.hpp index 4d436f03..9e954885 100644 --- a/sprout/range/adaptor/indexed.hpp +++ b/sprout/range/adaptor/indexed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/jointed.hpp b/sprout/range/adaptor/jointed.hpp index bb3b3697..b0d1aa98 100644 --- a/sprout/range/adaptor/jointed.hpp +++ b/sprout/range/adaptor/jointed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/merged.hpp b/sprout/range/adaptor/merged.hpp index 28b5586e..0bacdc04 100644 --- a/sprout/range/adaptor/merged.hpp +++ b/sprout/range/adaptor/merged.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/modifying.hpp b/sprout/range/adaptor/modifying.hpp index 9ce6e1df..5ede5dfb 100644 --- a/sprout/range/adaptor/modifying.hpp +++ b/sprout/range/adaptor/modifying.hpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/sprout/range/adaptor/outdirected.hpp b/sprout/range/adaptor/outdirected.hpp index f4f8fa66..80cd02de 100644 --- a/sprout/range/adaptor/outdirected.hpp +++ b/sprout/range/adaptor/outdirected.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/phase_spectrum.hpp b/sprout/range/adaptor/phase_spectrum.hpp index c0a34f52..a1fd79a8 100644 --- a/sprout/range/adaptor/phase_spectrum.hpp +++ b/sprout/range/adaptor/phase_spectrum.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/removed.hpp b/sprout/range/adaptor/removed.hpp index 8d34d645..c29ac171 100644 --- a/sprout/range/adaptor/removed.hpp +++ b/sprout/range/adaptor/removed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/removed_if.hpp b/sprout/range/adaptor/removed_if.hpp index 5900f33e..9826837b 100644 --- a/sprout/range/adaptor/removed_if.hpp +++ b/sprout/range/adaptor/removed_if.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/replaced.hpp b/sprout/range/adaptor/replaced.hpp index b97dbb99..7e288ee3 100644 --- a/sprout/range/adaptor/replaced.hpp +++ b/sprout/range/adaptor/replaced.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/replaced_if.hpp b/sprout/range/adaptor/replaced_if.hpp index 1c50ab0c..73282de2 100644 --- a/sprout/range/adaptor/replaced_if.hpp +++ b/sprout/range/adaptor/replaced_if.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/reversed.hpp b/sprout/range/adaptor/reversed.hpp index a7a02e47..778cc937 100644 --- a/sprout/range/adaptor/reversed.hpp +++ b/sprout/range/adaptor/reversed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/sawtooth_wave.hpp b/sprout/range/adaptor/sawtooth_wave.hpp index 48192175..e5a05edc 100644 --- a/sprout/range/adaptor/sawtooth_wave.hpp +++ b/sprout/range/adaptor/sawtooth_wave.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/set_difference.hpp b/sprout/range/adaptor/set_difference.hpp index 03b566e0..3f309b65 100644 --- a/sprout/range/adaptor/set_difference.hpp +++ b/sprout/range/adaptor/set_difference.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/set_intersection.hpp b/sprout/range/adaptor/set_intersection.hpp index 7b68ef54..43dc186b 100644 --- a/sprout/range/adaptor/set_intersection.hpp +++ b/sprout/range/adaptor/set_intersection.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/set_symmetric_difference.hpp b/sprout/range/adaptor/set_symmetric_difference.hpp index 62699015..f93adf71 100644 --- a/sprout/range/adaptor/set_symmetric_difference.hpp +++ b/sprout/range/adaptor/set_symmetric_difference.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/set_union.hpp b/sprout/range/adaptor/set_union.hpp index 3c17b14e..79703fdc 100644 --- a/sprout/range/adaptor/set_union.hpp +++ b/sprout/range/adaptor/set_union.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/sinusoidal.hpp b/sprout/range/adaptor/sinusoidal.hpp index 2754277c..43b66bc8 100644 --- a/sprout/range/adaptor/sinusoidal.hpp +++ b/sprout/range/adaptor/sinusoidal.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/size_enumed.hpp b/sprout/range/adaptor/size_enumed.hpp index 4a9f488e..29ab1c2d 100644 --- a/sprout/range/adaptor/size_enumed.hpp +++ b/sprout/range/adaptor/size_enumed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/sized.hpp b/sprout/range/adaptor/sized.hpp index 21ccd198..16533b60 100644 --- a/sprout/range/adaptor/sized.hpp +++ b/sprout/range/adaptor/sized.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/square_wave.hpp b/sprout/range/adaptor/square_wave.hpp index ac5f4667..3c32d2f7 100644 --- a/sprout/range/adaptor/square_wave.hpp +++ b/sprout/range/adaptor/square_wave.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/steps.hpp b/sprout/range/adaptor/steps.hpp index 8f2de442..1ba45ec2 100644 --- a/sprout/range/adaptor/steps.hpp +++ b/sprout/range/adaptor/steps.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/transformed.hpp b/sprout/range/adaptor/transformed.hpp index 1cbc57a3..ed8e18f6 100644 --- a/sprout/range/adaptor/transformed.hpp +++ b/sprout/range/adaptor/transformed.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/triangle_wave.hpp b/sprout/range/adaptor/triangle_wave.hpp index fc2c1148..3050fa80 100644 --- a/sprout/range/adaptor/triangle_wave.hpp +++ b/sprout/range/adaptor/triangle_wave.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/sprout/range/adaptor/uniqued.hpp b/sprout/range/adaptor/uniqued.hpp new file mode 100644 index 00000000..dc8023ca --- /dev/null +++ b/sprout/range/adaptor/uniqued.hpp @@ -0,0 +1,135 @@ +#ifndef SPROUT_RANGE_ADAPTOR_UNIQUED_HPP +#define SPROUT_RANGE_ADAPTOR_UNIQUED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // uniqued_range + // + template + class uniqued_range + : public sprout::adaptors::detail::adapted_range_default< + Range, + sprout::adjacent_filter_iterator< + sprout::unique_filter, + typename sprout::container_traits::iterator + > + > + { + public: + typedef Predicate predicate_type; + typedef sprout::adaptors::detail::adapted_range_default< + Range, + sprout::adjacent_filter_iterator< + sprout::unique_filter, + typename sprout::container_traits::iterator + > + > base_type; + typedef typename base_type::range_type range_type; + typedef typename base_type::iterator iterator; + public: + uniqued_range() = default; + uniqued_range(uniqued_range const&) = default; + SPROUT_CONSTEXPR uniqued_range(range_type& range, Predicate pred) + : base_type( + iterator(typename iterator::predicate_type(pred), sprout::begin(range), sprout::end(range)), + iterator(typename iterator::predicate_type(pred), sprout::end(range), sprout::end(range)) + ) + {} + }; + + // + // unique_holder + // + template > + class unique_holder { + public: + typedef Predicate predicate_type; + private: + Predicate pred_; + public: + SPROUT_CONSTEXPR unique_holder() + : pred_() + {} + explicit SPROUT_CONSTEXPR unique_holder(Predicate pred) + : pred_(pred) + {} + SPROUT_CONSTEXPR Predicate const& predicate() const { + return pred_; + } + }; + + // + // uniqued_forwarder + // + class uniqued_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::unique_holder + operator()(Predicate pred) { + return sprout::adaptors::unique_holder(pred); + } + }; + + // + // uniqued + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::uniqued_forwarder uniqued = {}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::uniqued_range< + Predicate, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::unique_holder const& rhs) { + return sprout::adaptors::uniqued_range< + Predicate, + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs), + rhs.predicate() + ); + } + template + inline SPROUT_CONSTEXPR sprout::adaptors::uniqued_range< + sprout::equal_to<>, + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::uniqued_forwarder const& rhs) { + return sprout::adaptors::uniqued_range< + sprout::equal_to<>, + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs), + sprout::equal_to<>() + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > + : public sprout::container_construct_traits::base_type> + {}; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_UNIQUED_HPP diff --git a/sprout/range/adaptor/valued.hpp b/sprout/range/adaptor/valued.hpp index cdda4b89..0a0e7c88 100644 --- a/sprout/range/adaptor/valued.hpp +++ b/sprout/range/adaptor/valued.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include