From 9a593cbb81e8735f1aff967592d57e85de629182 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sun, 20 Jan 2013 08:53:20 +0900 Subject: [PATCH] fix reverse_iterator support STL container: some algorithms --- sprout/algorithm/fixed/clamp_range_copy.hpp | 63 +++++- sprout/algorithm/fixed/copy.hpp | 6 +- sprout/algorithm/fixed/copy_backward.hpp | 16 +- sprout/algorithm/fixed/copy_if.hpp | 6 +- sprout/algorithm/fixed/copy_until.hpp | 36 +++- sprout/algorithm/fixed/copy_while.hpp | 35 +++- sprout/algorithm/fixed/fill.hpp | 16 +- sprout/algorithm/fixed/fill_n.hpp | 14 +- sprout/algorithm/fixed/generate.hpp | 7 + sprout/algorithm/fixed/generate_n.hpp | 7 + sprout/algorithm/fixed/recurrence.hpp | 7 + sprout/algorithm/fixed/recurrence_n.hpp | 7 + sprout/algorithm/fixed/remove_copy.hpp | 32 ++- sprout/algorithm/fixed/remove_copy_if.hpp | 32 ++- sprout/algorithm/fixed/replace_copy.hpp | 6 +- sprout/algorithm/fixed/replace_copy_if.hpp | 6 +- sprout/algorithm/fixed/reverse_copy.hpp | 35 +++- sprout/algorithm/fixed/rotate_copy.hpp | 35 +++- sprout/algorithm/fixed/swap_element_copy.hpp | 1 + sprout/algorithm/fixed/transform.hpp | 15 +- sprout/algorithm/fixed/unfold.hpp | 7 + sprout/algorithm/fixed/unfold_n.hpp | 7 + sprout/iterator/adaptor.hpp | 3 + sprout/iterator/remake_iterator.hpp | 4 +- sprout/iterator/remove_if_iterator.hpp | 39 ++++ sprout/iterator/remove_iterator.hpp | 39 ++++ sprout/iterator/replace_if_iterator.hpp | 2 +- sprout/iterator/replace_iterator.hpp | 2 +- sprout/iterator/reverse_iterator.hpp | 19 +- sprout/iterator/while_iterator.hpp | 208 +++++++++++++++++++ 30 files changed, 634 insertions(+), 78 deletions(-) create mode 100644 sprout/iterator/remove_if_iterator.hpp create mode 100644 sprout/iterator/remove_iterator.hpp create mode 100644 sprout/iterator/while_iterator.hpp diff --git a/sprout/algorithm/fixed/clamp_range_copy.hpp b/sprout/algorithm/fixed/clamp_range_copy.hpp index 3a9b6032..cdd5e704 100644 --- a/sprout/algorithm/fixed/clamp_range_copy.hpp +++ b/sprout/algorithm/fixed/clamp_range_copy.hpp @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT @@ -56,6 +58,7 @@ namespace sprout { sprout::distance(first, last) ); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -107,6 +110,41 @@ namespace sprout { { return sprout::fixed::detail::clamp_range_copy_impl(first, last, result, low, high, comp, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + clamp_range_copy( + InputIterator first, InputIterator last, Result const& result, + typename std::iterator_traits::value_type const& low, + typename std::iterator_traits::value_type const& high, + Compare comp + ) + { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + clamp_range_copy( + InputIterator first, InputIterator last, Result const& result, + typename std::iterator_traits::value_type const& low, + typename std::iterator_traits::value_type const& high, + Compare comp + ) + { + return sprout::remake( + result, sprout::size(result), + sprout::make_clamp_iterator(first, low, high, comp), + sprout::make_clamp_iterator(last, low, high, comp) + ); + } } // namespace detail // // clamp_range_copy @@ -120,8 +158,7 @@ namespace sprout { Compare comp ) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp, category()); + return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp); } template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type @@ -136,6 +173,28 @@ namespace sprout { NS_SSCRISK_CEL_OR_SPROUT::less::value_type>() ); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + clamp_range_copy( + InputIterator first, InputIterator last, + typename std::iterator_traits::value_type const& low, + typename std::iterator_traits::value_type const& high, + Compare comp + ) + { + return sprout::fixed::clamp_range_copy(first, last, sprout::pit(), low, high, comp); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + clamp_range_copy( + InputIterator first, InputIterator last, + typename std::iterator_traits::value_type const& low, + typename std::iterator_traits::value_type const& high + ) + { + return sprout::fixed::clamp_range_copy(first, last, sprout::pit(), low, high); + } } // namespace fixed using sprout::fixed::clamp_range_copy; diff --git a/sprout/algorithm/fixed/copy.hpp b/sprout/algorithm/fixed/copy.hpp index 9a3c8f91..4cee29e7 100644 --- a/sprout/algorithm/fixed/copy.hpp +++ b/sprout/algorithm/fixed/copy.hpp @@ -27,8 +27,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes >= offset && sprout::math::less(Indexes, offset + size) && sprout::math::less(Indexes, offset + input_size) ? first[Indexes - offset] : *sprout::next(sprout::internal_begin(result), Indexes) @@ -107,8 +106,7 @@ namespace sprout { >::type copy(InputIterator first, InputIterator last, Result const& result) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), first, last ); } diff --git a/sprout/algorithm/fixed/copy_backward.hpp b/sprout/algorithm/fixed/copy_backward.hpp index c302a43d..ad96c64f 100644 --- a/sprout/algorithm/fixed/copy_backward.hpp +++ b/sprout/algorithm/fixed/copy_backward.hpp @@ -27,8 +27,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes < offset && sprout::math::greater_equal(Indexes + size, offset) && sprout::math::greater_equal(Indexes + input_size, offset) ? last[Indexes - offset] : *sprout::next(sprout::internal_begin(result), Indexes) @@ -101,19 +100,6 @@ namespace sprout { typedef typename std::iterator_traits::iterator_category* category; return sprout::fixed::detail::copy_backward(first, last, result, category()); } - - template - inline SPROUT_CONSTEXPR typename std::enable_if< - !sprout::is_fixed_container::value, - typename sprout::fixed::result_of::algorithm::type - >::type - copy_backward(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { - return sprout::remake( - result, - sprout::size(result), - first, last - ); - } } // namespace detail // // copy_backward diff --git a/sprout/algorithm/fixed/copy_if.hpp b/sprout/algorithm/fixed/copy_if.hpp index a173e95e..37fea48d 100644 --- a/sprout/algorithm/fixed/copy_if.hpp +++ b/sprout/algorithm/fixed/copy_if.hpp @@ -61,9 +61,9 @@ namespace sprout { >::type copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { return sprout::remake( - result, - sprout::size(result), - sprout::make_filter_iterator(pred, first, last), sprout::make_filter_iterator(pred, last, last) + result, sprout::size(result), + sprout::make_filter_iterator(pred, first, last), + sprout::make_filter_iterator(pred, last, last) ); } } // namespace detail diff --git a/sprout/algorithm/fixed/copy_until.hpp b/sprout/algorithm/fixed/copy_until.hpp index 03bfb09c..17dcd61c 100644 --- a/sprout/algorithm/fixed/copy_until.hpp +++ b/sprout/algorithm/fixed/copy_until.hpp @@ -7,9 +7,12 @@ #include #include #include +#include +#include #include #include #include +#include #include namespace sprout { @@ -24,6 +27,7 @@ namespace sprout { { return sprout::fixed::copy(first, sprout::find_if(first, last, pred), result); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -62,6 +66,29 @@ namespace sprout { { return sprout::fixed::detail::copy_until_impl(first, last, result, pred, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::copy_until(first, last, result, pred, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + return sprout::remake( + result, sprout::size(result), + sprout::make_while_iterator(sprout::not1(pred), first, last), + sprout::make_while_iterator(sprout::not1(pred), last, last) + ); + } } // namespace detail // // copy_until @@ -69,8 +96,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::copy_until(first, last, result, pred, category()); + return sprout::fixed::detail::copy_until(first, last, result, pred); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_until(InputIterator first, InputIterator last, Predicate pred) { + return sprout::fixed::copy_until(first, last, sprout::pit(), pred); } } // namespace fixed diff --git a/sprout/algorithm/fixed/copy_while.hpp b/sprout/algorithm/fixed/copy_while.hpp index 93d623c8..4c641900 100644 --- a/sprout/algorithm/fixed/copy_while.hpp +++ b/sprout/algorithm/fixed/copy_while.hpp @@ -7,9 +7,11 @@ #include #include #include +#include #include #include #include +#include #include namespace sprout { @@ -24,6 +26,7 @@ namespace sprout { { return sprout::fixed::copy(first, sprout::find_if_not(first, last, pred), result); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -62,6 +65,29 @@ namespace sprout { { return sprout::fixed::detail::copy_while_impl(first, last, result, pred, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::copy_while(first, last, result, pred, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + return sprout::remake( + result, sprout::size(result), + sprout::make_while_iterator(pred, first, last), + sprout::make_while_iterator(pred, last, last) + ); + } } // namespace detail // // copy_while @@ -69,8 +95,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::copy_while(first, last, result, pred, category()); + return sprout::fixed::detail::copy_while(first, last, result, pred); + } + + template< typename Result, typename InputIterator,typename Predicate> + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_while(InputIterator first, InputIterator last, Predicate pred) { + return sprout::fixed::copy_while(first, last, sprout::pit(), pred); } } // namespace fixed diff --git a/sprout/algorithm/fixed/fill.hpp b/sprout/algorithm/fixed/fill.hpp index 5e9a3ba0..dfa03cef 100644 --- a/sprout/algorithm/fixed/fill.hpp +++ b/sprout/algorithm/fixed/fill.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace sprout { namespace fixed { @@ -22,8 +23,7 @@ namespace sprout { ) { return sprout::remake( - cont, - sprout::size(cont), + cont, sprout::size(cont), (Indexes >= offset && Indexes < offset + size ? value : *sprout::next(sprout::internal_begin(cont), Indexes) @@ -52,9 +52,9 @@ namespace sprout { >::type fill(Container const& cont, T const& value) { return sprout::remake( - cont, - sprout::size(cont), - sprout::value_iterator(value), sprout::value_iterator(value, 0) + cont, sprout::size(cont), + sprout::value_iterator(value, sprout::size(cont)), + sprout::value_iterator(value, 0) ); } } // namespace detail @@ -66,6 +66,12 @@ namespace sprout { fill(Container const& cont, T const& value) { return sprout::fixed::detail::fill(cont, value); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + fill(T const& value) { + return sprout::fixed::fill(sprout::pit(), value); + } } // namespace fixed using sprout::fixed::fill; diff --git a/sprout/algorithm/fixed/fill_n.hpp b/sprout/algorithm/fixed/fill_n.hpp index 416f9525..c354511c 100644 --- a/sprout/algorithm/fixed/fill_n.hpp +++ b/sprout/algorithm/fixed/fill_n.hpp @@ -5,8 +5,10 @@ #include #include #include +#include #include #include +#include namespace sprout { namespace fixed { @@ -32,9 +34,9 @@ namespace sprout { >::type fill_n(Container const& cont, Size n, T const& value) { return sprout::remake( - cont, - n, - sprout::value_iterator(value, n), sprout::value_iterator(value, 0) + cont, n, + sprout::value_iterator(value, n), + sprout::value_iterator(value, 0) ); } } // namespace detail @@ -46,6 +48,12 @@ namespace sprout { fill_n(Container const& cont, Size n, T const& value) { return sprout::fixed::detail::fill_n(cont, n, value); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + fill_n(Size n, T const& value) { + return sprout::fixed::fill_n(sprout::pit(), n, value); + } } // namespace fixed using sprout::fixed::fill_n; diff --git a/sprout/algorithm/fixed/generate.hpp b/sprout/algorithm/fixed/generate.hpp index b0f9b0bd..5575118c 100644 --- a/sprout/algorithm/fixed/generate.hpp +++ b/sprout/algorithm/fixed/generate.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -80,6 +81,12 @@ namespace sprout { generate(Container const& cont, Generator const& gen) { return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont)); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + generate(Generator const& gen) { + return sprout::fixed::generate(sprout::pit()); + } } // namespace fixed using sprout::fixed::generate; diff --git a/sprout/algorithm/fixed/generate_n.hpp b/sprout/algorithm/fixed/generate_n.hpp index 8112fc85..8cc1d27c 100644 --- a/sprout/algorithm/fixed/generate_n.hpp +++ b/sprout/algorithm/fixed/generate_n.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace sprout { namespace fixed { @@ -16,6 +17,12 @@ namespace sprout { generate_n(Container const& cont, Size n, Generator const& gen) { return sprout::fixed::detail::generate_impl(cont, gen, n); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + generate_n(Size n, Generator const& gen) { + return sprout::fixed::generate_n(sprout::pit(), n, gen); + } } // namespace fixed using sprout::fixed::generate_n; diff --git a/sprout/algorithm/fixed/recurrence.hpp b/sprout/algorithm/fixed/recurrence.hpp index dd80aec6..66cd4040 100644 --- a/sprout/algorithm/fixed/recurrence.hpp +++ b/sprout/algorithm/fixed/recurrence.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace sprout { @@ -146,6 +147,12 @@ namespace sprout { recurrence(Container const& cont, Generator const& gen, Inits const&... inits) { return sprout::fixed::detail::recurrence_impl(cont, gen, sprout::size(cont), inits...); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + recurrence(Generator const& gen, Inits const&... inits) { + return sprout::fixed::recurrence(sprout::pit(), gen, inits...); + } } // namespace fixed using sprout::fixed::recurrence; diff --git a/sprout/algorithm/fixed/recurrence_n.hpp b/sprout/algorithm/fixed/recurrence_n.hpp index 5059d2c4..a41297b2 100644 --- a/sprout/algorithm/fixed/recurrence_n.hpp +++ b/sprout/algorithm/fixed/recurrence_n.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace sprout { namespace fixed { @@ -16,6 +17,12 @@ namespace sprout { recurrence_n(Container const& cont, Size n, Generator const& gen, Inits const&... inits) { return sprout::fixed::detail::recurrence_impl(cont, gen, n, inits...); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + recurrence_n(Size n, Generator const& gen, Inits const&... inits) { + return sprout::fixed::recurrence_n(sprout::pit(), n, gen, inits...); + } } // namespace fixed using sprout::fixed::recurrence_n; diff --git a/sprout/algorithm/fixed/remove_copy.hpp b/sprout/algorithm/fixed/remove_copy.hpp index 3d308e9e..3c03941b 100644 --- a/sprout/algorithm/fixed/remove_copy.hpp +++ b/sprout/algorithm/fixed/remove_copy.hpp @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -45,6 +47,28 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + remove_copy(InputIterator first, InputIterator last, Result const& result, T const& value) { + return sprout::fixed::detail::remove_copy_impl(first, last, result, value, sprout::size(result)); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + remove_copy(InputIterator first, InputIterator last, Result const& result, T const& value) { + return sprout::remake( + result, sprout::size(result), + sprout::make_remove_iterator(value, first, last), + sprout::make_remove_iterator(value, last, last) + ); + } } // namespace detail // // remove_copy @@ -52,7 +76,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type remove_copy(InputIterator first, InputIterator last, Result const& result, T const& value) { - return sprout::fixed::detail::remove_copy_impl(first, last, result, value, sprout::size(result)); + return sprout::fixed::detail::remove_copy(first, last, result, value); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + remove_copy(InputIterator first, InputIterator last, T const& value) { + return sprout::fixed::remove_copy(first, last, sprout::pit(), value); } } // namespace fixed diff --git a/sprout/algorithm/fixed/remove_copy_if.hpp b/sprout/algorithm/fixed/remove_copy_if.hpp index bc047e16..e1be2a5d 100644 --- a/sprout/algorithm/fixed/remove_copy_if.hpp +++ b/sprout/algorithm/fixed/remove_copy_if.hpp @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -45,6 +47,28 @@ namespace sprout { : sprout::detail::container_complate(result, args...) ; } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + remove_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + return sprout::fixed::detail::remove_copy_if_impl(first, last, result, pred, sprout::size(result)); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + remove_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + return sprout::remake( + result, sprout::size(result), + sprout::make_remove_if_iterator(pred, first, last), + sprout::make_remove_if_iterator(pred, last, last) + ); + } } // namespace detail // // remove_copy_if @@ -52,7 +76,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type remove_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { - return sprout::fixed::detail::remove_copy_if_impl(first, last, result, pred, sprout::size(result)); + return sprout::fixed::detail::remove_copy_if(first, last, result, pred); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + remove_copy_if(InputIterator first, InputIterator last, Predicate pred) { + return sprout::fixed::remove_copy_if(first, last, sprout::pit(), pred); } } // namespace fixed diff --git a/sprout/algorithm/fixed/replace_copy.hpp b/sprout/algorithm/fixed/replace_copy.hpp index 84e3bba3..a765d887 100644 --- a/sprout/algorithm/fixed/replace_copy.hpp +++ b/sprout/algorithm/fixed/replace_copy.hpp @@ -29,8 +29,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size ? NS_SSCRISK_CEL_OR_SPROUT::equal_to()(first[Indexes - offset], old_value) ? new_value : first[Indexes - offset] : *sprout::next(sprout::internal_begin(result), Indexes) @@ -117,8 +116,7 @@ namespace sprout { >::type replace_copy(InputIterator first, InputIterator last, Result const& result, T const& old_value, T const& new_value) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), sprout::make_replace_iterator(first, old_value, new_value), sprout::make_replace_iterator(last, old_value, new_value) ); diff --git a/sprout/algorithm/fixed/replace_copy_if.hpp b/sprout/algorithm/fixed/replace_copy_if.hpp index 00bdf965..b3afce1e 100644 --- a/sprout/algorithm/fixed/replace_copy_if.hpp +++ b/sprout/algorithm/fixed/replace_copy_if.hpp @@ -28,8 +28,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size ? pred(first[Indexes - offset]) ? new_value : first[Indexes - offset] : *sprout::next(sprout::internal_begin(result), Indexes) @@ -116,8 +115,7 @@ namespace sprout { >::type replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), sprout::make_replace_if_iterator(first, pred, new_value), sprout::make_replace_if_iterator(last, pred, new_value) ); diff --git a/sprout/algorithm/fixed/reverse_copy.hpp b/sprout/algorithm/fixed/reverse_copy.hpp index c253aafe..fd93f55a 100644 --- a/sprout/algorithm/fixed/reverse_copy.hpp +++ b/sprout/algorithm/fixed/reverse_copy.hpp @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -48,6 +50,7 @@ namespace sprout { sprout::distance(first, last) ); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -86,6 +89,29 @@ namespace sprout { { return sprout::fixed::detail::reverse_copy_impl(first, last, result, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::reverse_copy(first, last, result, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { + return sprout::remake( + result, sprout::size(result), + sprout::make_reverse_iterator(last), + sprout::make_reverse_iterator(first) + ); + } } // namespace detail // // reverse_copy @@ -93,8 +119,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::reverse_copy(first, last, result, category()); + return sprout::fixed::detail::reverse_copy(first, last, result); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + reverse_copy(BidirectionalIterator first, BidirectionalIterator last) { + return sprout::fixed::reverse_copy(first, last, sprout::pit()); } } // namespace fixed diff --git a/sprout/algorithm/fixed/rotate_copy.hpp b/sprout/algorithm/fixed/rotate_copy.hpp index f3731ffe..af7179e3 100644 --- a/sprout/algorithm/fixed/rotate_copy.hpp +++ b/sprout/algorithm/fixed/rotate_copy.hpp @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -56,6 +58,7 @@ namespace sprout { sprout::distance(first, last) ); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -129,6 +132,29 @@ namespace sprout { { return sprout::fixed::detail::rotate_copy_impl(first, middle, last, result, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::rotate_copy(first, middle, last, result, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) { + return sprout::remake( + result, sprout::size(result), + sprout::make_joint_iterator(middle, last, first, first), + sprout::make_joint_iterator(last, last, first, middle) + ); + } } // namespace detail // // rotate_copy @@ -136,8 +162,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::rotate_copy(first, middle, last, result, category()); + return sprout::fixed::detail::rotate_copy(first, middle, last, result); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last) { + return sprout::fixed::rotate_copy(first, middle, last, sprout::pit()); } } // namespace fixed diff --git a/sprout/algorithm/fixed/swap_element_copy.hpp b/sprout/algorithm/fixed/swap_element_copy.hpp index d15b699c..a94a9a02 100644 --- a/sprout/algorithm/fixed/swap_element_copy.hpp +++ b/sprout/algorithm/fixed/swap_element_copy.hpp @@ -58,6 +58,7 @@ namespace sprout { sprout::distance(first, last) ); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), diff --git a/sprout/algorithm/fixed/transform.hpp b/sprout/algorithm/fixed/transform.hpp index 3f32cac4..464054aa 100644 --- a/sprout/algorithm/fixed/transform.hpp +++ b/sprout/algorithm/fixed/transform.hpp @@ -29,8 +29,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size ? op(first[Indexes - offset]) : *sprout::next(sprout::internal_begin(result), Indexes) @@ -114,9 +113,9 @@ namespace sprout { >::type transform(InputIterator first, InputIterator last, Result const& result, UnaryOperation op) { return sprout::remake( - result, - sprout::size(result), - sprout::make_transform_iterator(first, op), sprout::make_transform_iterator(last, op) + result, sprout::size(result), + sprout::make_transform_iterator(first, op), + sprout::make_transform_iterator(last, op) ); } } // namespace detail @@ -148,8 +147,7 @@ namespace sprout { ) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size ? op(first1[Indexes - offset], first2[Indexes - offset]) : *sprout::next(sprout::internal_begin(result), Indexes) @@ -232,8 +230,7 @@ namespace sprout { >::type transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) { return sprout::remake( - result, - sprout::size(result), + result, sprout::size(result), sprout::make_transform_iterator(first1, first2, op), sprout::make_transform_iterator(last1, first2, op) ); diff --git a/sprout/algorithm/fixed/unfold.hpp b/sprout/algorithm/fixed/unfold.hpp index f267e920..6b24edb4 100644 --- a/sprout/algorithm/fixed/unfold.hpp +++ b/sprout/algorithm/fixed/unfold.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include namespace sprout { @@ -79,6 +80,12 @@ namespace sprout { unfold(Container const& cont, Generator const& gen, Init const& init) { return sprout::fixed::detail::unfold_impl(cont, gen, init, sprout::size(cont)); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unfold(Generator const& gen, Init const& init) { + return sprout::fixed::unfold(sprout::pit(), gen, init); + } } // namespace fixed using sprout::fixed::unfold; diff --git a/sprout/algorithm/fixed/unfold_n.hpp b/sprout/algorithm/fixed/unfold_n.hpp index 9431eb68..e78fb199 100644 --- a/sprout/algorithm/fixed/unfold_n.hpp +++ b/sprout/algorithm/fixed/unfold_n.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace sprout { namespace fixed { @@ -16,6 +17,12 @@ namespace sprout { unfold_n(Container const& cont, Size n, Generator const& gen, Init const& init) { return sprout::fixed::detail::unfold_impl(cont, gen, init, n); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + unfold_n(Size n, Generator const& gen, Init const& init) { + return sprout::fixed::unfold_n(sprout::pit(), n, gen, init); + } } // namespace fixed using sprout::fixed::unfold_n; diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index e3316b6e..b4f40618 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/sprout/iterator/remake_iterator.hpp b/sprout/iterator/remake_iterator.hpp index 9af4af84..18417c96 100644 --- a/sprout/iterator/remake_iterator.hpp +++ b/sprout/iterator/remake_iterator.hpp @@ -178,14 +178,14 @@ namespace sprout { SPROUT_CONSTEXPR remake_iterator next() const { return remake_iterator( sprout::next(current), (is_in_copying() ? sprout::next(current2) : current2), - fst, last, + fst, lst, begin_off - 1, end_off - 1 ); } SPROUT_CONSTEXPR remake_iterator prev() const { return remake_iterator( sprout::prev(current), (begin_off < 0 && end_off >= 0 ? sprout::prev(current2) : current2), - fst, last, + fst, lst, begin_off + 1, end_off + 1 ); } diff --git a/sprout/iterator/remove_if_iterator.hpp b/sprout/iterator/remove_if_iterator.hpp new file mode 100644 index 00000000..64f94b1d --- /dev/null +++ b/sprout/iterator/remove_if_iterator.hpp @@ -0,0 +1,39 @@ +#ifndef SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP +#define SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP + +#include +#include + +namespace sprout { + // + // remove_if_filter + // + template + class remove_if_filter { + public: + typedef bool result_type; + private: + Predicate pred_; + public: + SPROUT_CONSTEXPR remove_if_filter(Predicate pred) + : pred_(pred) + {} + template + SPROUT_CONSTEXPR bool operator()(U const& value) const { + return !pred_(value); + } + }; + + // + // make_remove_if_iterator + // + template + inline SPROUT_CONSTEXPR sprout::filter_iterator, Iterator> + make_remove_if_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) { + return sprout::filter_iterator, Iterator>( + sprout::remove_if_filter(pred), it, last + ); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP diff --git a/sprout/iterator/remove_iterator.hpp b/sprout/iterator/remove_iterator.hpp new file mode 100644 index 00000000..f0627c9a --- /dev/null +++ b/sprout/iterator/remove_iterator.hpp @@ -0,0 +1,39 @@ +#ifndef SPROUT_ITERATOR_REMOVE_ITERATOR_HPP +#define SPROUT_ITERATOR_REMOVE_ITERATOR_HPP + +#include +#include + +namespace sprout { + // + // remove_filter + // + template + class remove_filter { + public: + typedef bool result_type; + private: + T value_; + public: + SPROUT_CONSTEXPR remove_filter(T const& value) + : value_(value) + {} + template + SPROUT_CONSTEXPR bool operator()(U const& value) const { + return value != value_; + } + }; + + // + // make_remove_iterator + // + template + inline SPROUT_CONSTEXPR sprout::filter_iterator, Iterator> + make_remove_iterator(T const& value, Iterator it, Iterator last = Iterator()) { + return sprout::filter_iterator, Iterator>( + sprout::remove_filter(value), it, last + ); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_REMOVE_ITERATOR_HPP diff --git a/sprout/iterator/replace_if_iterator.hpp b/sprout/iterator/replace_if_iterator.hpp index a68bd143..50fb658b 100644 --- a/sprout/iterator/replace_if_iterator.hpp +++ b/sprout/iterator/replace_if_iterator.hpp @@ -12,7 +12,7 @@ namespace sprout { class replace_value_if { public: typedef Predicate predicate_type; - typedef T const& result_type; + typedef T result_type; typedef T const& argument_type; private: Predicate pred_; diff --git a/sprout/iterator/replace_iterator.hpp b/sprout/iterator/replace_iterator.hpp index c14ecaa3..01c46bad 100644 --- a/sprout/iterator/replace_iterator.hpp +++ b/sprout/iterator/replace_iterator.hpp @@ -11,7 +11,7 @@ namespace sprout { template class replace_value { public: - typedef T const& result_type; + typedef T result_type; typedef T const& argument_type; private: T old_; diff --git a/sprout/iterator/reverse_iterator.hpp b/sprout/iterator/reverse_iterator.hpp index 34690c22..fa808e89 100644 --- a/sprout/iterator/reverse_iterator.hpp +++ b/sprout/iterator/reverse_iterator.hpp @@ -32,22 +32,17 @@ namespace sprout { typedef typename std::iterator_traits::reference reference; protected: iterator_type current; - private: - iterator_type deref_tmp; public: reverse_iterator() = default; SPROUT_CONSTEXPR reverse_iterator(reverse_iterator const& other) : current(other.current) - , deref_tmp(other.deref_tmp) {} explicit SPROUT_CONSTEXPR reverse_iterator(iterator_type it) : current(it) - , deref_tmp(sprout::prev(it)) {} template SPROUT_CONSTEXPR reverse_iterator(reverse_iterator const& it) : current(it.base()) - , deref_tmp(sprout::prev(it.base())) {} template reverse_iterator& operator=(reverse_iterator const& it) { @@ -59,31 +54,27 @@ namespace sprout { return current; } SPROUT_CONSTEXPR reference operator*() const { - return *deref_tmp; + return *sprout::prev(current); } SPROUT_CONSTEXPR pointer operator->() const { - return &*deref_tmp; + return &*(*this); } reverse_iterator& operator++() { --current; - --deref_tmp; return *this; } reverse_iterator operator++(int) { reverse_iterator result(*this); --current; - --deref_tmp; return result; } reverse_iterator& operator--() { ++current; - ++deref_tmp; return *this; } reverse_iterator operator--(int) { reverse_iterator temp(*this); ++current; - ++deref_tmp; return temp; } SPROUT_CONSTEXPR reverse_iterator operator+(difference_type n) const { @@ -103,7 +94,7 @@ namespace sprout { return *this; } SPROUT_CONSTEXPR reference operator[](difference_type n) const { - return *(deref_tmp - n); + return *(current - (n + 1)); } SPROUT_CONSTEXPR reverse_iterator next() const { return reverse_iterator(sprout::prev(current)); @@ -114,11 +105,9 @@ namespace sprout { void swap(reverse_iterator& other) SPROUT_NOEXCEPT_EXPR( SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) - && SPROUT_NOEXCEPT_EXPR(swap(deref_tmp, other.deref_tmp)) ) { swap(current, other.current); - swap(deref_tmp, other.deref_tmp); } }; @@ -155,7 +144,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) operator-(sprout::reverse_iterator const& lhs, sprout::reverse_iterator const& rhs) { - return lhs.base() - rhs.base(); + return rhs.base() - lhs.base(); } template inline SPROUT_CONSTEXPR sprout::reverse_iterator diff --git a/sprout/iterator/while_iterator.hpp b/sprout/iterator/while_iterator.hpp new file mode 100644 index 00000000..9fc5efd0 --- /dev/null +++ b/sprout/iterator/while_iterator.hpp @@ -0,0 +1,208 @@ +#ifndef SPROUT_ITERATOR_WHILE_ITERATOR_HPP +#define SPROUT_ITERATOR_WHILE_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // while_iterator + // + template + class while_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 + >::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 std::conditional< + std::is_convertible::iterator_category, std::random_access_iterator_tag>::value, + std::bidirectional_iterator_tag, + typename std::iterator_traits::iterator_category + >::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 first == last || pred(*first) ? first + : last + ; + } + static SPROUT_CONSTEXPR iterator_type find_prev(iterator_type first, Predicate pred) { + return pred(*first) ? first + : find_prev(sprout::prev(first), pred) + ; + } + protected: + iterator_type current; + iterator_type last; + Predicate pred; + private: + void satisfy_predicate() { + if (!pred(*current)) { + current = last; + } + } + void satisfy_predicate_backward() { + while (!pred(*current)) { + --current; + } + } + SPROUT_CONSTEXPR while_iterator(Predicate pred, iterator_type it, iterator_type last, private_constructor_tag) + : current(it) + , last(last) + , pred(pred) + {} + public: + while_iterator() = default; + while_iterator(while_iterator const&) = default; + SPROUT_CONSTEXPR while_iterator(Predicate pred, iterator_type it, iterator_type last = iterator_type()) + : current(find_next(it, last, pred)) + , last(last) + , pred(pred) + {} + template + SPROUT_CONSTEXPR while_iterator(while_iterator const& it) + : current(it.current) + , last(it.last) + , pred(it.pred) + {} + template + while_iterator& operator=(while_iterator const& it) { + while_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; + } + + while_iterator& operator++() { + ++current; + satisfy_predicate(); + return *this; + } + while_iterator operator++(int) { + while_iterator result(*this); + ++current; + satisfy_predicate(); + return result; + } + while_iterator& operator--() { + --current; + satisfy_predicate_backward(); + return *this; + } + while_iterator operator--(int) { + while_iterator temp(*this); + --current; + satisfy_predicate_backward(); + return temp; + } + SPROUT_CONSTEXPR while_iterator next() const { + return while_iterator(pred, find_next(sprout::next(current), last, pred), last, private_constructor_tag()); + } + SPROUT_CONSTEXPR while_iterator prev() const { + return while_iterator(pred, find_prev(sprout::prev(current), pred), last, private_constructor_tag()); + } + void swap(while_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::while_iterator const& lhs, + sprout::while_iterator const& rhs + ) + { + return lhs.base() == rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool operator!=( + sprout::while_iterator const& lhs, + sprout::while_iterator const& rhs + ) + { + return !(lhs == rhs); + } + + // + // make_while_iterator + // + template + inline SPROUT_CONSTEXPR sprout::while_iterator + make_while_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) { + return sprout::while_iterator(pred, it, last); + } + + // + // swap + // + template + inline void + swap(sprout::while_iterator& lhs, sprout::while_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::while_iterator + iterator_next(sprout::while_iterator const& it) { + return it.next(); + } + + // + // iterator_prev + // + template + inline SPROUT_CONSTEXPR sprout::while_iterator + iterator_prev(sprout::while_iterator const& it) { + return it.prev(); + } +} // namespace sprout + +#endif // SPROUT_ITERATOR_WHILE_ITERATOR_HPP