diff --git a/sprout/algorithm/fit/copy.hpp b/sprout/algorithm/fit/copy.hpp index 9b91bc14..8df8b190 100644 --- a/sprout/algorithm/fit/copy.hpp +++ b/sprout/algorithm/fit/copy.hpp @@ -7,8 +7,8 @@ #include #include #include -#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT #include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace fit { diff --git a/sprout/algorithm/fixed/copy.hpp b/sprout/algorithm/fixed/copy.hpp index eb94722f..9a3c8f91 100644 --- a/sprout/algorithm/fixed/copy.hpp +++ b/sprout/algorithm/fixed/copy.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -94,18 +95,17 @@ namespace sprout { sprout::is_fixed_container::value, typename sprout::fixed::result_of::algorithm::type >::type - copy(InputIterator first, InputIterator last, Result const& result) - { + copy(InputIterator first, InputIterator last, Result const& result) { typedef typename std::iterator_traits::iterator_category* category; return sprout::fixed::detail::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 - copy(InputIterator first, InputIterator last, Result const& result) - { + copy(InputIterator first, InputIterator last, Result const& result) { return sprout::remake( result, sprout::size(result), @@ -121,6 +121,12 @@ namespace sprout { copy(InputIterator first, InputIterator last, Result const& result) { return sprout::fixed::detail::copy(first, last, result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy(InputIterator first, InputIterator last) { + return sprout::fixed::copy(first, last, sprout::pit()); + } } // namespace fixed using sprout::fixed::copy; diff --git a/sprout/algorithm/fixed/copy_backward.hpp b/sprout/algorithm/fixed/copy_backward.hpp index 4c6de95d..c302a43d 100644 --- a/sprout/algorithm/fixed/copy_backward.hpp +++ b/sprout/algorithm/fixed/copy_backward.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -86,12 +87,33 @@ namespace sprout { ) { return sprout::fixed::detail::copy_backward_impl( - first, - last, - result, + 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 + copy_backward(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { + 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 @@ -99,13 +121,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type copy_backward(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::copy_backward( - first, - last, - result, - category() - ); + return sprout::fixed::detail::copy_backward(first, last, result); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_backward(BidirectionalIterator first, BidirectionalIterator last) { + return sprout::fixed::copy_backward(first, last, sprout::pit()); } } // namespace fixed diff --git a/sprout/algorithm/fixed/copy_if.hpp b/sprout/algorithm/fixed/copy_if.hpp index 6f5e47fa..a173e95e 100644 --- a/sprout/algorithm/fixed/copy_if.hpp +++ b/sprout/algorithm/fixed/copy_if.hpp @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -42,6 +44,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 + copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { + return sprout::fixed::detail::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 + 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) + ); + } } // namespace detail // // copy_if @@ -49,7 +73,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { - return sprout::fixed::detail::copy_if_impl(first, last, result, pred, sprout::size(result)); + return sprout::fixed::detail::copy_if(first, last, result, pred); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_if(InputIterator first, InputIterator last, Predicate pred) { + return sprout::fixed::copy_if(first, last, sprout::pit(), pred); } } // namespace fixed diff --git a/sprout/algorithm/fixed/copy_n.hpp b/sprout/algorithm/fixed/copy_n.hpp index 06800019..41ab10c2 100644 --- a/sprout/algorithm/fixed/copy_n.hpp +++ b/sprout/algorithm/fixed/copy_n.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ namespace sprout { { return sprout::fixed::copy(first, sprout::next(first, n), result); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -61,6 +63,35 @@ namespace sprout { { return sprout::fixed::detail::copy_n_impl(first, n, 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 + copy_n(InputIterator first, Size n, Result const& result) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::copy_n(first, n, result, category()); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_n_dyn( + ForwardIterator first, Size n, Result const& result, + std::forward_iterator_tag* + ) + { + return sprout::fixed::copy(first, sprout::next(first, n), result); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + copy_n(InputIterator first, Size n, Result const& result) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::copy_n_dyn(first, n, result, category()); + } } // namespace detail // // copy_n @@ -68,8 +99,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type copy_n(InputIterator first, Size n, Result const& result) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::copy_n(first, n, result, category()); + return sprout::fixed::detail::copy_n(first, n, result); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_n(InputIterator first, Size n) { + return sprout::fixed::copy_n(first, n, sprout::pit()); } } // namespace fixed diff --git a/sprout/algorithm/fixed/fill.hpp b/sprout/algorithm/fixed/fill.hpp index c33491b4..5e9a3ba0 100644 --- a/sprout/algorithm/fixed/fill.hpp +++ b/sprout/algorithm/fixed/fill.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace sprout { @@ -29,6 +30,33 @@ namespace sprout { )... ); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + fill(Container const& cont, T const& value) { + return sprout::fixed::detail::fill_impl( + cont, value, + sprout::index_range<0, sprout::container_traits::static_size>::make(), + sprout::internal_begin_offset(cont), + sprout::size(cont) + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + fill(Container const& cont, T const& value) { + return sprout::remake( + cont, + sprout::size(cont), + sprout::value_iterator(value), sprout::value_iterator(value, 0) + ); + } } // namespace detail // // fill @@ -36,12 +64,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type fill(Container const& cont, T const& value) { - return sprout::fixed::detail::fill_impl( - cont, value, - sprout::index_range<0, sprout::container_traits::static_size>::make(), - sprout::internal_begin_offset(cont), - sprout::size(cont) - ); + return sprout::fixed::detail::fill(cont, value); } } // namespace fixed diff --git a/sprout/algorithm/fixed/fill_n.hpp b/sprout/algorithm/fixed/fill_n.hpp index 4d92202e..416f9525 100644 --- a/sprout/algorithm/fixed/fill_n.hpp +++ b/sprout/algorithm/fixed/fill_n.hpp @@ -10,18 +10,41 @@ namespace sprout { namespace fixed { + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + fill_n(Container const& cont, Size n, T const& value) { + return sprout::fixed::detail::fill_impl( + cont, value, + sprout::index_range<0, sprout::container_traits::static_size>::make(), + sprout::internal_begin_offset(cont), + n + ); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::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) + ); + } + } // namespace detail // // fill_n // template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type fill_n(Container const& cont, Size n, T const& value) { - return sprout::fixed::detail::fill_impl( - cont, value, - sprout::index_range<0, sprout::container_traits::static_size>::make(), - sprout::internal_begin_offset(cont), - n - ); + return sprout::fixed::detail::fill_n(cont, n, value); } } // namespace fixed diff --git a/sprout/algorithm/fixed/replace_copy.hpp b/sprout/algorithm/fixed/replace_copy.hpp index 3bc122c0..84e3bba3 100644 --- a/sprout/algorithm/fixed/replace_copy.hpp +++ b/sprout/algorithm/fixed/replace_copy.hpp @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT @@ -97,6 +99,30 @@ namespace sprout { { return sprout::fixed::detail::replace_copy_impl(first, last, result, old_value, new_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 + replace_copy(InputIterator first, InputIterator last, Result const& result, T const& old_value, T const& new_value) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::replace_copy(first, last, result, old_value, new_value, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::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), + sprout::make_replace_iterator(first, old_value, new_value), + sprout::make_replace_iterator(last, old_value, new_value) + ); + } } // namespace detail // // replace_copy @@ -104,8 +130,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type replace_copy(InputIterator first, InputIterator last, Result const& result, T const& old_value, T const& new_value) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::replace_copy(first, last, result, old_value, new_value, category()); + return sprout::fixed::detail::replace_copy(first, last, result, old_value, new_value); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + replace_copy(InputIterator first, InputIterator last, T const& old_value, T const& new_value) { + return sprout::fixed::replace_copy(first, last, sprout::pit(), old_value, new_value); } } // namespace fixed diff --git a/sprout/algorithm/fixed/replace_copy_if.hpp b/sprout/algorithm/fixed/replace_copy_if.hpp index e500f3af..00bdf965 100644 --- a/sprout/algorithm/fixed/replace_copy_if.hpp +++ b/sprout/algorithm/fixed/replace_copy_if.hpp @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include namespace sprout { @@ -96,6 +98,30 @@ namespace sprout { { return sprout::fixed::detail::replace_copy_if_impl(first, last, result, pred, new_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 + replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::replace_copy_if(first, last, result, pred, new_value, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) { + return sprout::remake( + result, + sprout::size(result), + sprout::make_replace_if_iterator(first, pred, new_value), + sprout::make_replace_if_iterator(last, pred, new_value) + ); + } } // namespace detail // // replace_copy_if @@ -103,8 +129,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::replace_copy_if(first, last, result, pred, new_value, category()); + return sprout::fixed::detail::replace_copy_if(first, last, result, pred, new_value); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + replace_copy_if(InputIterator first, InputIterator last, Predicate pred, T const& new_value) { + return sprout::fixed::replace_copy_if(first, last, sprout::pit(), pred, new_value); } } // namespace fixed diff --git a/sprout/algorithm/fixed/transform.hpp b/sprout/algorithm/fixed/transform.hpp index bb9bb98f..3f32cac4 100644 --- a/sprout/algorithm/fixed/transform.hpp +++ b/sprout/algorithm/fixed/transform.hpp @@ -8,7 +8,10 @@ #include #include #include +#include +#include #include +#include #include namespace sprout { @@ -51,6 +54,7 @@ namespace sprout { sprout::distance(first, last) ); } + template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::container_traits::static_size == sizeof...(Args), @@ -92,6 +96,29 @@ namespace sprout { { return sprout::fixed::detail::transform_impl(first, last, result, op, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + transform(InputIterator first, InputIterator last, Result const& result, UnaryOperation op) { + typedef typename std::iterator_traits::iterator_category* category; + return sprout::fixed::detail::transform(first, last, result, op, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::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) + ); + } } // namespace detail // // transform @@ -99,8 +126,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type transform(InputIterator first, InputIterator last, Result const& result, UnaryOperation op) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::transform(first, last, result, op, category()); + return sprout::fixed::detail::transform(first, last, result, op); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + transform(InputIterator first, InputIterator last, UnaryOperation op) { + return sprout::fixed::transform(first, last, sprout::pit(), op); } namespace detail { @@ -182,6 +214,30 @@ namespace sprout { { return sprout::fixed::detail::transform_impl(first1, last1, first2, result, op, sprout::size(result)); } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) { + typedef typename sprout::common_iterator_category::type* category; + return sprout::fixed::detail::transform(first1, last1, first2, result, op, category()); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::fixed::result_of::algorithm::type + >::type + transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) { + return sprout::remake( + result, + sprout::size(result), + sprout::make_transform_iterator(first1, first2, op), + sprout::make_transform_iterator(last1, first2, op) + ); + } } // namespace detail // // transform @@ -189,8 +245,13 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) { - typedef typename std::iterator_traits::iterator_category* category; - return sprout::fixed::detail::transform(first1, last1, first2, result, op, category()); + return sprout::fixed::detail::transform(first1, last1, first2, result, op); + } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryOperation op) { + return sprout::fixed::transform(first1, last1, first2, sprout::pit(), op); } } // namespace fixed diff --git a/sprout/container/container_construct_traits.hpp b/sprout/container/container_construct_traits.hpp index 350f66dc..9e0517f8 100644 --- a/sprout/container/container_construct_traits.hpp +++ b/sprout/container/container_construct_traits.hpp @@ -4,6 +4,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include namespace sprout { @@ -33,6 +40,43 @@ namespace sprout { return copied_type{sprout::forward(args)...}; } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_fixed_container::value, + typename sprout::container_construct_traits::copied_type + >::type + default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { + return sprout::container_construct_traits::make(sprout::forward(args)...); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::container_construct_traits::copied_type + >::type + default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { + return sprout::container_construct_traits::make(sprout::forward(args)...); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::is_fixed_container::value, + typename sprout::container_construct_traits::copied_type + >::type + default_remake_container(Cont&& cont, typename sprout::container_traits::difference_type size, InputIterator first, InputIterator last) { + typedef typename sprout::container_construct_traits::copied_type copied_type; + return copied_type( + sprout::make_remake_iterator( + sprout::internal_begin(cont), first, + first, last, + sprout::internal_begin_offset(cont), sprout::internal_end_offset(cont) + ), + sprout::make_remake_iterator( + sprout::internal_end(cont), last, + first, last, + sprout::internal_begin_offset_backward(cont), sprout::internal_end_offset_backward(cont) + ) + ); + } + template struct container_construct_traits_impl { public: @@ -51,7 +95,10 @@ namespace sprout { template static SPROUT_CONSTEXPR copied_type remake(Cont&& cont, typename sprout::container_traits::difference_type size, Args&&... args) { - return make(sprout::forward(args)...); + return sprout::detail::default_remake_container( + sprout::forward(cont), size, + sprout::forward(args)... + ); } }; } // namespace detail diff --git a/sprout/container/functions.hpp b/sprout/container/functions.hpp index 0accbb26..9b7ea053 100644 --- a/sprout/container/functions.hpp +++ b/sprout/container/functions.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/sprout/container/internal_size.hpp b/sprout/container/internal_size.hpp new file mode 100644 index 00000000..6a1b93d3 --- /dev/null +++ b/sprout/container/internal_size.hpp @@ -0,0 +1,21 @@ +#ifndef SPROUT_CONTAINER_INTERNAL_SIZE_HPP +#define SPROUT_CONTAINER_INTERNAL_SIZE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // internal_size + // + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::difference_type + internal_size(Container const& cont) { + return sprout::distance(sprout::internal_begin(cont), sprout::internal_end(cont)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_CONTAINER_INTERNAL_SIZE_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index c36574c1..e3316b6e 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -12,5 +14,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_ITERATOR_ADAPTOR_HPP diff --git a/sprout/iterator/remake_iterator.hpp b/sprout/iterator/remake_iterator.hpp new file mode 100644 index 00000000..9af4af84 --- /dev/null +++ b/sprout/iterator/remake_iterator.hpp @@ -0,0 +1,343 @@ +#ifndef SPROUT_ITERATOR_REMAKE_ITERATOR_HPP +#define SPROUT_ITERATOR_REMAKE_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT + +namespace sprout { + // + // remake_iterator + // + template + class remake_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 DstIterator iterator_type; + typedef SrcIterator 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; + private: + SPROUT_CONSTEXPR remake_iterator advance_impl(difference_type n) const { + return n >= 0 + ? remake_iterator( + sprout::next(current, n), + begin_off - n >= 0 ? fst + : (end_off - begin_off >= sprout::distance(fst, lst) && begin_off - n <= -sprout::distance(fst, lst)) ? lst + : begin_off <= 0 + ? sprout::next(current2, NS_SSCRISK_CEL_OR_SPROUT::min(NS_SSCRISK_CEL_OR_SPROUT::min(n, end_off), sprout::distance(current2, lst))) + : sprout::next(current2, NS_SSCRISK_CEL_OR_SPROUT::min(NS_SSCRISK_CEL_OR_SPROUT::min(n - begin_off, end_off), sprout::distance(current2, lst))) + , + fst, lst, + begin_off - n, end_off - n + ) + : remake_iterator( + sprout::next(current, n), + begin_off - n >= 0 ? fst + : (end_off - begin_off >= sprout::distance(fst, lst) && begin_off - n <= -sprout::distance(fst, lst)) ? lst + : begin_off >= -sprout::distance(fst, lst) + ? sprout::next(current2, n) + : sprout::next(current2, n - (begin_off + sprout::distance(fst, lst))) + , + fst, lst, + begin_off - n, end_off - n + ) + ; + } + protected: + iterator_type current; + iterator2_type current2; + iterator2_type fst; + iterator2_type lst; + difference_type begin_off; + difference_type end_off; + public: + remake_iterator() = default; + SPROUT_CONSTEXPR remake_iterator(remake_iterator const& other) + : current(other.current), current2(other.current2) + , fst(other.fst) , lst(other.lst) + , begin_off(other.begin_off) , end_off(other.end_off) + {} + SPROUT_CONSTEXPR remake_iterator(iterator_type it, iterator2_type it2, iterator2_type fst, iterator2_type lst, difference_type begin_off, difference_type end_off) + : current(it), current2(it2) + , fst(fst), lst(lst) + , begin_off(begin_off) , end_off(end_off) + {} + template + SPROUT_CONSTEXPR remake_iterator(remake_iterator const& it) + : current(it.base()), current2(it.base2()) + , fst(it.first()), lst(it.last()) + , begin_off(it.begin_offset()) , end_off(it.end_offset()) + {} + template + remake_iterator& operator=(remake_iterator const& it) { + remake_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR iterator2_type base2() const { + return current2; + } + SPROUT_CONSTEXPR iterator2_type first() const { + return fst; + } + SPROUT_CONSTEXPR iterator2_type last() const { + return lst; + } + SPROUT_CONSTEXPR difference_type begin_offset() const { + return begin_off; + } + SPROUT_CONSTEXPR difference_type end_offset() const { + return end_off; + } + SPROUT_CONSTEXPR bool is_in_copying() const { + return begin_off <= 0 && end_off > 0 && current2 != lst; + } + SPROUT_CONSTEXPR reference operator*() const { + return is_in_copying() ? *current2 : *current; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*(*this); + } + remake_iterator& operator++() { + ++current; + if (is_in_copying()) { + ++current2; + } + --begin_off; + --end_off; + return *this; + } + remake_iterator operator++(int) { + remake_iterator result(*this); + ++current; + if (is_in_copying()) { + ++current2; + } + --begin_off; + --end_off; + return result; + } + remake_iterator& operator--() { + --current; + if (begin_off < 0 && end_off >= 0) { + --current2; + } + ++begin_off; + ++end_off; + return *this; + } + remake_iterator operator--(int) { + remake_iterator temp(*this); + --current; + if (begin_off < 0 && end_off >= 0) { + --current2; + } + ++begin_off; + ++end_off; + return temp; + } + SPROUT_CONSTEXPR remake_iterator operator+(difference_type n) const { + return advance_impl(n); + } + SPROUT_CONSTEXPR remake_iterator operator-(difference_type n) const { + return advance_impl(-n); + } + remake_iterator& operator+=(difference_type n) { + remake_iterator temp(*this + n); + temp.swap(*this); + return *this; + } + remake_iterator& operator-=(difference_type n) { + remake_iterator temp(*this - n); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return *(*this + n); + } + SPROUT_CONSTEXPR remake_iterator next() const { + return remake_iterator( + sprout::next(current), (is_in_copying() ? sprout::next(current2) : current2), + fst, last, + 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, + begin_off + 1, end_off + 1 + ); + } + void swap(remake_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) + && SPROUT_NOEXCEPT_EXPR(swap(current2, other.current2)) + && SPROUT_NOEXCEPT_EXPR(swap(fst, other.fst)) + && SPROUT_NOEXCEPT_EXPR(swap(lst, other.lst)) + && SPROUT_NOEXCEPT_EXPR(swap(begin_off, other.begin_off)) + && SPROUT_NOEXCEPT_EXPR(swap(end_off, other.end_off)) + ) + { + swap(current, other.current); + swap(current2, other.current2); + swap(fst, other.fst); + swap(lst, other.lst); + swap(begin_off, other.begin_off); + swap(end_off, other.end_off); + } + }; + + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator==( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return lhs.base() == rhs.base(); + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator!=( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return !(lhs == rhs); + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator<( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return lhs.base() < rhs.base(); + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator>( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return rhs < lhs; + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator<=( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return !(rhs < lhs); + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR bool operator>=( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return !(lhs < rhs); + } + template< + typename DstIterator1, typename SrcIterator1, + typename DstIterator2, typename SrcIterator2 + > + inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) + operator-( + sprout::remake_iterator const& lhs, + sprout::remake_iterator const& rhs + ) + { + return lhs.base() - rhs.base(); + } + template + inline SPROUT_CONSTEXPR sprout::remake_iterator operator+( + typename sprout::remake_iterator::difference_type n, + sprout::remake_iterator const& it + ) + { + return it + n; + } + + // + // make_remake_iterator + // + template + inline SPROUT_CONSTEXPR sprout::remake_iterator + make_remake_iterator( + DstIterator it, SrcIterator it2, + SrcIterator fst, SrcIterator lst, + typename sprout::remake_iterator::difference_type begin_off, + typename sprout::remake_iterator::difference_type end_off + ) + { + return sprout::remake_iterator(it, it2, fst, lst, begin_off, end_off); + } + + // + // swap + // + template + inline void + swap(sprout::remake_iterator& lhs, sprout::remake_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::remake_iterator + iterator_next(sprout::remake_iterator const& it) { + return it.next(); + } + + // + // iterator_prev + // + template + inline SPROUT_CONSTEXPR sprout::remake_iterator + iterator_prev(sprout::remake_iterator const& it) { + return it.prev(); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_REMAKE_ITERATOR_HPP diff --git a/sprout/iterator/replace_if_iterator.hpp b/sprout/iterator/replace_if_iterator.hpp new file mode 100644 index 00000000..a68bd143 --- /dev/null +++ b/sprout/iterator/replace_if_iterator.hpp @@ -0,0 +1,42 @@ +#ifndef SPROUT_ITERATOR_REPLACE_ITERATOR_HPP +#define SPROUT_ITERATOR_REPLACE_ITERATOR_HPP + +#include +#include + +namespace sprout { + // + // replace_value_if + // + template + class replace_value_if { + public: + typedef Predicate predicate_type; + typedef T const& result_type; + typedef T const& argument_type; + private: + Predicate pred_; + T new_; + public: + SPROUT_CONSTEXPR replace_value_if(Predicate pred, T const& new_value) + : pred_(pred) + , new_(new_value) + {} + SPROUT_CONSTEXPR T operator()(T const& value) const { + return pred_(value) ? new_ : value; + } + }; + + // + // make_replace_if_iterator + // + template + inline SPROUT_CONSTEXPR sprout::transform_iterator, Iterator> + make_replace_if_iterator(Iterator it, Predicate pred, T const& new_value) { + return sprout::transform_iterator, Iterator>( + it, sprout::replace_value_if(pred, new_value) + ); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_REPLACE_ITERATOR_HPP diff --git a/sprout/iterator/replace_iterator.hpp b/sprout/iterator/replace_iterator.hpp new file mode 100644 index 00000000..c14ecaa3 --- /dev/null +++ b/sprout/iterator/replace_iterator.hpp @@ -0,0 +1,41 @@ +#ifndef SPROUT_ITERATOR_REPLACE_IF_ITERATOR_HPP +#define SPROUT_ITERATOR_REPLACE_IF_ITERATOR_HPP + +#include +#include + +namespace sprout { + // + // replace_value + // + template + class replace_value { + public: + typedef T const& result_type; + typedef T const& argument_type; + private: + T old_; + T new_; + public: + SPROUT_CONSTEXPR replace_value(T const& old_value, T const& new_value) + : old_(old_value) + , new_(new_value) + {} + SPROUT_CONSTEXPR T operator()(T const& value) const { + return (value == old_) ? new_ : value; + } + }; + + // + // make_replace_iterator + // + template + inline SPROUT_CONSTEXPR sprout::transform_iterator, Iterator> + make_replace_iterator(Iterator it, T const& old_value, T const& new_value) { + return sprout::transform_iterator, Iterator>( + it, sprout::replace_value(old_value, new_value) + ); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_REPLACE_IF_ITERATOR_HPP diff --git a/sprout/pit/container.hpp b/sprout/pit/container.hpp index 9bd7515b..805907fe 100644 --- a/sprout/pit/container.hpp +++ b/sprout/pit/container.hpp @@ -8,30 +8,72 @@ #include namespace sprout { + namespace detail { + template + struct pit_container_construct_traits; + + template + struct pit_container_construct_traits< + sprout::pit, + typename std::enable_if::value>::type + > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type + deep_copy(Cont&& cont) { + return copied_type(); + } + 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)...); + } + }; + + template + struct pit_container_construct_traits< + sprout::pit, + typename std::enable_if::value>::type + > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type + deep_copy(Cont&& cont) { + return copied_type(); + } + 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)...); + } + template + static SPROUT_CONSTEXPR copied_type + remake(Cont&& cont, typename sprout::container_traits >::difference_type size, InputIterator first, InputIterator last) { + return copied_type(first, last); + } + }; + } // namespace detail // // 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 copied_type(); - } - 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)...); - } - }; + struct container_construct_traits > + : public sprout::detail::pit_container_construct_traits > + {}; // // container_transform_traits diff --git a/sprout/range/adaptor/copied.hpp b/sprout/range/adaptor/copied.hpp index afc2dcb5..76d0c212 100644 --- a/sprout/range/adaptor/copied.hpp +++ b/sprout/range/adaptor/copied.hpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -37,7 +36,7 @@ namespace sprout { {} template SPROUT_CONSTEXPR operator Result() const { - return sprout::range::fixed::copy(*this, sprout::pit()); + return sprout::range::fixed::copy(*this); } }; diff --git a/sprout/range/adaptor/replaced.hpp b/sprout/range/adaptor/replaced.hpp index 690250c6..67ee7cd2 100644 --- a/sprout/range/adaptor/replaced.hpp +++ b/sprout/range/adaptor/replaced.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -15,25 +16,6 @@ namespace sprout { namespace adaptors { - namespace detail { - template - class replace_value { - public: - typedef T const& result_type; - typedef T const& argument_type; - private: - T old_; - T new_; - public: - SPROUT_CONSTEXPR replace_value(T const& old_value, T const& new_value) - : old_(old_value) - , new_(new_value) - {} - SPROUT_CONSTEXPR T operator()(T const& value) const { - return (value == old_) ? new_ : value; - } - }; - } // namespace detail // // replaced_range // @@ -42,7 +24,7 @@ namespace sprout { : public sprout::adaptors::detail::adapted_range_default< Range, sprout::transform_iterator< - sprout::adaptors::detail::replace_value::value_type>, + sprout::replace_value::value_type>, typename sprout::container_traits::iterator > > @@ -51,7 +33,7 @@ namespace sprout { typedef sprout::adaptors::detail::adapted_range_default< Range, sprout::transform_iterator< - sprout::adaptors::detail::replace_value::value_type>, + sprout::replace_value::value_type>, typename sprout::container_traits::iterator > > base_type; diff --git a/sprout/range/adaptor/replaced_if.hpp b/sprout/range/adaptor/replaced_if.hpp index f73a3b0b..842b0d2b 100644 --- a/sprout/range/adaptor/replaced_if.hpp +++ b/sprout/range/adaptor/replaced_if.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -15,26 +16,6 @@ namespace sprout { namespace adaptors { - namespace detail { - template - class replace_value_if { - public: - typedef Predicate predicate_type; - typedef T const& result_type; - typedef T const& argument_type; - private: - Predicate pred_; - T new_; - public: - SPROUT_CONSTEXPR replace_value_if(Predicate pred, T const& new_value) - : pred_(pred) - , new_(new_value) - {} - SPROUT_CONSTEXPR T operator()(T const& value) const { - return pred_(value) ? new_ : value; - } - }; - } // namespace detail // // replaced_if_range // @@ -43,7 +24,7 @@ namespace sprout { : public sprout::adaptors::detail::adapted_range_default< Range, sprout::transform_iterator< - sprout::adaptors::detail::replace_value_if::value_type>, + sprout::replace_value_if::value_type>, typename sprout::container_traits::iterator > > @@ -53,7 +34,7 @@ namespace sprout { typedef sprout::adaptors::detail::adapted_range_default< Range, sprout::transform_iterator< - sprout::adaptors::detail::replace_value_if::value_type>, + sprout::replace_value_if::value_type>, typename sprout::container_traits::iterator > > base_type; diff --git a/sprout/range/algorithm/fixed/copy.hpp b/sprout/range/algorithm/fixed/copy.hpp index dc3d22c7..8e6de8c8 100644 --- a/sprout/range/algorithm/fixed/copy.hpp +++ b/sprout/range/algorithm/fixed/copy.hpp @@ -18,6 +18,12 @@ namespace sprout { copy(Input const& input, Result const& result) { return sprout::fixed::copy(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy(Input const& input) { + return sprout::fixed::copy(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::copy; diff --git a/sprout/range/algorithm/fixed/copy_backward.hpp b/sprout/range/algorithm/fixed/copy_backward.hpp index 2be2605a..22269f53 100644 --- a/sprout/range/algorithm/fixed/copy_backward.hpp +++ b/sprout/range/algorithm/fixed/copy_backward.hpp @@ -18,6 +18,12 @@ namespace sprout { copy_backward(Input const& input, Result const& result) { return sprout::fixed::copy_backward(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_backward(Input const& input) { + return sprout::fixed::copy_backward(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::copy_backward; diff --git a/sprout/range/algorithm/fixed/copy_if.hpp b/sprout/range/algorithm/fixed/copy_if.hpp index 0aaef456..af04e113 100644 --- a/sprout/range/algorithm/fixed/copy_if.hpp +++ b/sprout/range/algorithm/fixed/copy_if.hpp @@ -18,6 +18,12 @@ namespace sprout { copy_if(Input const& input, Result const& result, Predicate pred) { return sprout::fixed::copy_if(sprout::begin(input), sprout::end(input), result); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + copy_if(Input const& input, Predicate pred) { + return sprout::fixed::copy_if(sprout::begin(input), sprout::end(input)); + } } // namespace fixed using sprout::range::fixed::copy_if; diff --git a/sprout/range/algorithm/fixed/replace_copy.hpp b/sprout/range/algorithm/fixed/replace_copy.hpp index 28701e53..7019ae4d 100644 --- a/sprout/range/algorithm/fixed/replace_copy.hpp +++ b/sprout/range/algorithm/fixed/replace_copy.hpp @@ -18,6 +18,12 @@ namespace sprout { replace_copy(Input const& input, Result const& result, T const& old_value, T const& new_value) { return sprout::fixed::replace_copy(sprout::begin(input), sprout::end(input), result, old_value, new_value); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + replace_copy(Input const& input, T const& old_value, T const& new_value) { + return sprout::fixed::replace_copy(sprout::begin(input), sprout::end(input), old_value, new_value); + } } // namespace fixed using sprout::range::fixed::replace_copy; diff --git a/sprout/range/algorithm/fixed/replace_copy_if.hpp b/sprout/range/algorithm/fixed/replace_copy_if.hpp index d6cc7dcc..647d12e8 100644 --- a/sprout/range/algorithm/fixed/replace_copy_if.hpp +++ b/sprout/range/algorithm/fixed/replace_copy_if.hpp @@ -18,6 +18,12 @@ namespace sprout { replace_copy_if(Input const& input, Result const& result, Predicate pred, T const& new_value) { return sprout::fixed::replace_copy_if(sprout::begin(input), sprout::end(input), result, pred, new_value); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + replace_copy_if(Input const& input, Predicate pred, T const& new_value) { + return sprout::fixed::replace_copy_if(sprout::begin(input), sprout::end(input), pred, new_value); + } } // namespace fixed using sprout::range::fixed::replace_copy_if; diff --git a/sprout/range/algorithm/fixed/transform.hpp b/sprout/range/algorithm/fixed/transform.hpp index 83e8af67..10833f0a 100644 --- a/sprout/range/algorithm/fixed/transform.hpp +++ b/sprout/range/algorithm/fixed/transform.hpp @@ -23,6 +23,17 @@ namespace sprout { transform(Input1 const& input1, Input2 const& input2, Result const& result, BinaryOperation op) { return sprout::fixed::transform(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), result, op); } + + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + transform(Input const& input, UnaryOperation op) { + return sprout::fixed::transform(sprout::begin(input), sprout::end(input), op); + } + template + inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type + transform(Input1 const& input1, Input2 const& input2, BinaryOperation op) { + return sprout::fixed::transform(sprout::begin(input1), sprout::end(input1), sprout::begin(input2), op); + } } // namespace fixed using sprout::range::fixed::transform; diff --git a/sprout/sub_array/container.hpp b/sprout/sub_array/container.hpp index 0080450e..aa9e72b1 100644 --- a/sprout/sub_array/container.hpp +++ b/sprout/sub_array/container.hpp @@ -10,7 +10,6 @@ #include namespace sprout { - // // container_construct_traits // @@ -63,7 +62,7 @@ namespace sprout { return remake_impl( sprout::forward(cont), size, - sprout::make(sprout::forward(args)...) + sprout::remake(cont, size, sprout::forward(args)...) ); } };