fix reverse_iterator

support STL container: some algorithms
This commit is contained in:
bolero-MURAKAMI 2013-01-20 08:53:20 +09:00
parent a9cd556f8e
commit 9a593cbb81
30 changed files with 634 additions and 78 deletions

View file

@ -8,8 +8,10 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/clamp_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/clamp.hpp> #include <sprout/algorithm/clamp.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
@ -56,6 +58,7 @@ namespace sprout {
sprout::distance(first, last) sprout::distance(first, last)
); );
} }
template<typename InputIterator, typename Result, typename Compare, typename... Args> template<typename InputIterator, typename Result, typename Compare, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::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)); return sprout::fixed::detail::clamp_range_copy_impl(first, last, result, low, high, comp, sprout::size(result));
} }
template<typename InputIterator, typename Result, typename Compare>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
clamp_range_copy(
InputIterator first, InputIterator last, Result const& result,
typename std::iterator_traits<InputIterator>::value_type const& low,
typename std::iterator_traits<InputIterator>::value_type const& high,
Compare comp
)
{
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp, category());
}
template<typename InputIterator, typename Result, typename Compare>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
clamp_range_copy(
InputIterator first, InputIterator last, Result const& result,
typename std::iterator_traits<InputIterator>::value_type const& low,
typename std::iterator_traits<InputIterator>::value_type const& high,
Compare comp
)
{
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_clamp_iterator(first, low, high, comp),
sprout::make_clamp_iterator(last, low, high, comp)
);
}
} // namespace detail } // namespace detail
// //
// clamp_range_copy // clamp_range_copy
@ -120,8 +158,7 @@ namespace sprout {
Compare comp Compare comp
) )
{ {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category; return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp);
return sprout::fixed::detail::clamp_range_copy(first, last, result, low, high, comp, category());
} }
template<typename InputIterator, typename Result> template<typename InputIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
@ -136,6 +173,28 @@ namespace sprout {
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<InputIterator>::value_type>() NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<InputIterator>::value_type>()
); );
} }
template<typename Result, typename InputIterator, typename Compare>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
clamp_range_copy(
InputIterator first, InputIterator last,
typename std::iterator_traits<InputIterator>::value_type const& low,
typename std::iterator_traits<InputIterator>::value_type const& high,
Compare comp
)
{
return sprout::fixed::clamp_range_copy(first, last, sprout::pit<Result>(), low, high, comp);
}
template<typename Result, typename InputIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
clamp_range_copy(
InputIterator first, InputIterator last,
typename std::iterator_traits<InputIterator>::value_type const& low,
typename std::iterator_traits<InputIterator>::value_type const& high
)
{
return sprout::fixed::clamp_range_copy(first, last, sprout::pit<Result>(), low, high);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::clamp_range_copy; using sprout::fixed::clamp_range_copy;

View file

@ -27,8 +27,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes >= offset && sprout::math::less(Indexes, offset + size) && sprout::math::less(Indexes, offset + input_size) (Indexes >= offset && sprout::math::less(Indexes, offset + size) && sprout::math::less(Indexes, offset + input_size)
? first[Indexes - offset] ? first[Indexes - offset]
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -107,8 +106,7 @@ namespace sprout {
>::type >::type
copy(InputIterator first, InputIterator last, Result const& result) { copy(InputIterator first, InputIterator last, Result const& result) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
first, last first, last
); );
} }

View file

@ -27,8 +27,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes < offset && sprout::math::greater_equal(Indexes + size, offset) && sprout::math::greater_equal(Indexes + input_size, offset) (Indexes < offset && sprout::math::greater_equal(Indexes + size, offset) && sprout::math::greater_equal(Indexes + input_size, offset)
? last[Indexes - offset] ? last[Indexes - offset]
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -101,19 +100,6 @@ namespace sprout {
typedef typename std::iterator_traits<BidirectionalIterator>::iterator_category* category; typedef typename std::iterator_traits<BidirectionalIterator>::iterator_category* category;
return sprout::fixed::detail::copy_backward(first, last, result, category()); return sprout::fixed::detail::copy_backward(first, last, result, category());
} }
template<typename BidirectionalIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy_backward(BidirectionalIterator first, BidirectionalIterator last, Result const& result) {
return sprout::remake<Result>(
result,
sprout::size(result),
first, last
);
}
} // namespace detail } // namespace detail
// //
// copy_backward // copy_backward

View file

@ -61,9 +61,9 @@ namespace sprout {
>::type >::type
copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result), sprout::make_filter_iterator(pred, first, last),
sprout::make_filter_iterator(pred, first, last), sprout::make_filter_iterator(pred, last, last) sprout::make_filter_iterator(pred, last, last)
); );
} }
} // namespace detail } // namespace detail

View file

@ -7,9 +7,12 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/while_iterator.hpp>
#include <sprout/functional/not1.hpp>
#include <sprout/algorithm/find_if.hpp> #include <sprout/algorithm/find_if.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/copy.hpp> #include <sprout/algorithm/fixed/copy.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -24,6 +27,7 @@ namespace sprout {
{ {
return sprout::fixed::copy(first, sprout::find_if(first, last, pred), result); return sprout::fixed::copy(first, sprout::find_if(first, last, pred), result);
} }
template<typename InputIterator, typename Result, typename Predicate, typename... Args> template<typename InputIterator, typename Result, typename Predicate, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),
@ -62,6 +66,29 @@ namespace sprout {
{ {
return sprout::fixed::detail::copy_until_impl(first, last, result, pred, sprout::size(result)); return sprout::fixed::detail::copy_until_impl(first, last, result, pred, sprout::size(result));
} }
template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::fixed::detail::copy_until(first, last, result, pred, category());
}
template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_while_iterator(sprout::not1(pred), first, last),
sprout::make_while_iterator(sprout::not1(pred), last, last)
);
}
} // namespace detail } // namespace detail
// //
// copy_until // copy_until
@ -69,8 +96,13 @@ namespace sprout {
template<typename InputIterator, typename Result, typename Predicate> template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) { copy_until(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category; return sprout::fixed::detail::copy_until(first, last, result, pred);
return sprout::fixed::detail::copy_until(first, last, result, pred, category()); }
template<typename Result, typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
copy_until(InputIterator first, InputIterator last, Predicate pred) {
return sprout::fixed::copy_until(first, last, sprout::pit<Result>(), pred);
} }
} // namespace fixed } // namespace fixed

View file

@ -7,9 +7,11 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/while_iterator.hpp>
#include <sprout/algorithm/find_if_not.hpp> #include <sprout/algorithm/find_if_not.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/copy.hpp> #include <sprout/algorithm/fixed/copy.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -24,6 +26,7 @@ namespace sprout {
{ {
return sprout::fixed::copy(first, sprout::find_if_not(first, last, pred), result); return sprout::fixed::copy(first, sprout::find_if_not(first, last, pred), result);
} }
template<typename InputIterator, typename Result, typename Predicate, typename... Args> template<typename InputIterator, typename Result, typename Predicate, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),
@ -62,6 +65,29 @@ namespace sprout {
{ {
return sprout::fixed::detail::copy_while_impl(first, last, result, pred, sprout::size(result)); return sprout::fixed::detail::copy_while_impl(first, last, result, pred, sprout::size(result));
} }
template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::fixed::detail::copy_while(first, last, result, pred, category());
}
template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_while_iterator(pred, first, last),
sprout::make_while_iterator(pred, last, last)
);
}
} // namespace detail } // namespace detail
// //
// copy_while // copy_while
@ -69,8 +95,13 @@ namespace sprout {
template<typename InputIterator, typename Result, typename Predicate> template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) { copy_while(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
typedef typename std::iterator_traits<InputIterator>::iterator_category* category; return sprout::fixed::detail::copy_while(first, last, result, pred);
return sprout::fixed::detail::copy_while(first, last, result, pred, category()); }
template< typename Result, typename InputIterator,typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
copy_while(InputIterator first, InputIterator last, Predicate pred) {
return sprout::fixed::copy_while(first, last, sprout::pit<Result>(), pred);
} }
} // namespace fixed } // namespace fixed

View file

@ -8,6 +8,7 @@
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/value_iterator.hpp> #include <sprout/iterator/value_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
@ -22,8 +23,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Container>( return sprout::remake<Container>(
cont, cont, sprout::size(cont),
sprout::size(cont),
(Indexes >= offset && Indexes < offset + size (Indexes >= offset && Indexes < offset + size
? value ? value
: *sprout::next(sprout::internal_begin(cont), Indexes) : *sprout::next(sprout::internal_begin(cont), Indexes)
@ -52,9 +52,9 @@ namespace sprout {
>::type >::type
fill(Container const& cont, T const& value) { fill(Container const& cont, T const& value) {
return sprout::remake<Container>( return sprout::remake<Container>(
cont, cont, sprout::size(cont),
sprout::size(cont), sprout::value_iterator<T const&>(value, sprout::size(cont)),
sprout::value_iterator<T const&>(value), sprout::value_iterator<T const&>(value, 0) sprout::value_iterator<T const&>(value, 0)
); );
} }
} // namespace detail } // namespace detail
@ -66,6 +66,12 @@ namespace sprout {
fill(Container const& cont, T const& value) { fill(Container const& cont, T const& value) {
return sprout::fixed::detail::fill(cont, value); return sprout::fixed::detail::fill(cont, value);
} }
template<typename Container, typename T>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
fill(T const& value) {
return sprout::fixed::fill(sprout::pit<Container>(), value);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::fill; using sprout::fixed::fill;

View file

@ -5,8 +5,10 @@
#include <sprout/index_tuple.hpp> #include <sprout/index_tuple.hpp>
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/value_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/fill.hpp> #include <sprout/algorithm/fixed/fill.hpp>
#include <sprout/pit.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
@ -32,9 +34,9 @@ namespace sprout {
>::type >::type
fill_n(Container const& cont, Size n, T const& value) { fill_n(Container const& cont, Size n, T const& value) {
return sprout::remake<Container>( return sprout::remake<Container>(
cont, cont, n,
n, sprout::value_iterator<T const&>(value, n),
sprout::value_iterator<T const&>(value, n), sprout::value_iterator<T const&>(value, 0) sprout::value_iterator<T const&>(value, 0)
); );
} }
} // namespace detail } // namespace detail
@ -46,6 +48,12 @@ namespace sprout {
fill_n(Container const& cont, Size n, T const& value) { fill_n(Container const& cont, Size n, T const& value) {
return sprout::fixed::detail::fill_n(cont, n, value); return sprout::fixed::detail::fill_n(cont, n, value);
} }
template<typename Container, typename Size, typename T>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
fill_n(Size n, T const& value) {
return sprout::fixed::fill_n(sprout::pit<Container>(), n, value);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::fill_n; using sprout::fixed::fill_n;

View file

@ -7,6 +7,7 @@
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/generator/functions.hpp> #include <sprout/generator/functions.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -80,6 +81,12 @@ namespace sprout {
generate(Container const& cont, Generator const& gen) { generate(Container const& cont, Generator const& gen) {
return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont)); return sprout::fixed::detail::generate_impl(cont, gen, sprout::size(cont));
} }
template<typename Container, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
generate(Generator const& gen) {
return sprout::fixed::generate(sprout::pit<Container>());
}
} // namespace fixed } // namespace fixed
using sprout::fixed::generate; using sprout::fixed::generate;

View file

@ -5,6 +5,7 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/generate.hpp> #include <sprout/algorithm/fixed/generate.hpp>
#include <sprout/pit.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
@ -16,6 +17,12 @@ namespace sprout {
generate_n(Container const& cont, Size n, Generator const& gen) { generate_n(Container const& cont, Size n, Generator const& gen) {
return sprout::fixed::detail::generate_impl(cont, gen, n); return sprout::fixed::detail::generate_impl(cont, gen, n);
} }
template<typename Container, typename Size, typename Generator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
generate_n(Size n, Generator const& gen) {
return sprout::fixed::generate_n(sprout::pit<Container>(), n, gen);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::generate_n; using sprout::fixed::generate_n;

View file

@ -8,6 +8,7 @@
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -146,6 +147,12 @@ namespace sprout {
recurrence(Container const& cont, Generator const& gen, Inits const&... inits) { recurrence(Container const& cont, Generator const& gen, Inits const&... inits) {
return sprout::fixed::detail::recurrence_impl(cont, gen, sprout::size(cont), inits...); return sprout::fixed::detail::recurrence_impl(cont, gen, sprout::size(cont), inits...);
} }
template<typename Container, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
recurrence(Generator const& gen, Inits const&... inits) {
return sprout::fixed::recurrence(sprout::pit<Container>(), gen, inits...);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::recurrence; using sprout::fixed::recurrence;

View file

@ -5,6 +5,7 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/recurrence.hpp> #include <sprout/algorithm/fixed/recurrence.hpp>
#include <sprout/pit.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
@ -16,6 +17,12 @@ namespace sprout {
recurrence_n(Container const& cont, Size n, Generator const& gen, Inits const&... inits) { recurrence_n(Container const& cont, Size n, Generator const& gen, Inits const&... inits) {
return sprout::fixed::detail::recurrence_impl(cont, gen, n, inits...); return sprout::fixed::detail::recurrence_impl(cont, gen, n, inits...);
} }
template<typename Container, typename Size, typename Generator, typename... Inits>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
recurrence_n(Size n, Generator const& gen, Inits const&... inits) {
return sprout::fixed::recurrence_n(sprout::pit<Container>(), n, gen, inits...);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::recurrence_n; using sprout::fixed::recurrence_n;

View file

@ -6,7 +6,9 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/remove_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -45,6 +47,28 @@ namespace sprout {
: sprout::detail::container_complate(result, args...) : sprout::detail::container_complate(result, args...)
; ;
} }
template<typename InputIterator, typename Result, typename T>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::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<typename InputIterator, typename Result, typename T>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
remove_copy(InputIterator first, InputIterator last, Result const& result, T const& value) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_remove_iterator(value, first, last),
sprout::make_remove_iterator(value, last, last)
);
}
} // namespace detail } // namespace detail
// //
// remove_copy // remove_copy
@ -52,7 +76,13 @@ namespace sprout {
template<typename InputIterator, typename Result, typename T> template<typename InputIterator, typename Result, typename T>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
remove_copy(InputIterator first, InputIterator last, Result const& result, T const& value) { 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<typename Result, typename InputIterator, typename T>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
remove_copy(InputIterator first, InputIterator last, T const& value) {
return sprout::fixed::remove_copy(first, last, sprout::pit<Result>(), value);
} }
} // namespace fixed } // namespace fixed

View file

@ -6,7 +6,9 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/remove_if_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -45,6 +47,28 @@ namespace sprout {
: sprout::detail::container_complate(result, args...) : sprout::detail::container_complate(result, args...)
; ;
} }
template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::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<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
remove_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_remove_if_iterator(pred, first, last),
sprout::make_remove_if_iterator(pred, last, last)
);
}
} // namespace detail } // namespace detail
// //
// remove_copy_if // remove_copy_if
@ -52,7 +76,13 @@ namespace sprout {
template<typename InputIterator, typename Result, typename Predicate> template<typename InputIterator, typename Result, typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
remove_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred) { 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<typename Result, typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
remove_copy_if(InputIterator first, InputIterator last, Predicate pred) {
return sprout::fixed::remove_copy_if(first, last, sprout::pit<Result>(), pred);
} }
} // namespace fixed } // namespace fixed

View file

@ -29,8 +29,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size
? NS_SSCRISK_CEL_OR_SPROUT::equal_to<T>()(first[Indexes - offset], old_value) ? new_value : first[Indexes - offset] ? NS_SSCRISK_CEL_OR_SPROUT::equal_to<T>()(first[Indexes - offset], old_value) ? new_value : first[Indexes - offset]
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -117,8 +116,7 @@ namespace sprout {
>::type >::type
replace_copy(InputIterator first, InputIterator last, Result const& result, T const& old_value, T const& new_value) { replace_copy(InputIterator first, InputIterator last, Result const& result, T const& old_value, T const& new_value) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
sprout::make_replace_iterator(first, old_value, new_value), sprout::make_replace_iterator(first, old_value, new_value),
sprout::make_replace_iterator(last, old_value, new_value) sprout::make_replace_iterator(last, old_value, new_value)
); );

View file

@ -28,8 +28,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size
? pred(first[Indexes - offset]) ? new_value : first[Indexes - offset] ? pred(first[Indexes - offset]) ? new_value : first[Indexes - offset]
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -116,8 +115,7 @@ namespace sprout {
>::type >::type
replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) { replace_copy_if(InputIterator first, InputIterator last, Result const& result, Predicate pred, T const& new_value) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
sprout::make_replace_if_iterator(first, pred, new_value), sprout::make_replace_if_iterator(first, pred, new_value),
sprout::make_replace_if_iterator(last, pred, new_value) sprout::make_replace_if_iterator(last, pred, new_value)
); );

View file

@ -8,7 +8,9 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/reverse_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -48,6 +50,7 @@ namespace sprout {
sprout::distance(first, last) sprout::distance(first, last)
); );
} }
template<typename BidirectionalIterator, typename Result, typename... Args> template<typename BidirectionalIterator, typename Result, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),
@ -86,6 +89,29 @@ namespace sprout {
{ {
return sprout::fixed::detail::reverse_copy_impl(first, last, result, sprout::size(result)); return sprout::fixed::detail::reverse_copy_impl(first, last, result, sprout::size(result));
} }
template<typename BidirectionalIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) {
typedef typename std::iterator_traits<BidirectionalIterator>::iterator_category* category;
return sprout::fixed::detail::reverse_copy(first, last, result, category());
}
template<typename BidirectionalIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_reverse_iterator(last),
sprout::make_reverse_iterator(first)
);
}
} // namespace detail } // namespace detail
// //
// reverse_copy // reverse_copy
@ -93,8 +119,13 @@ namespace sprout {
template<typename BidirectionalIterator, typename Result> template<typename BidirectionalIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) { reverse_copy(BidirectionalIterator first, BidirectionalIterator last, Result const& result) {
typedef typename std::iterator_traits<BidirectionalIterator>::iterator_category* category; return sprout::fixed::detail::reverse_copy(first, last, result);
return sprout::fixed::detail::reverse_copy(first, last, result, category()); }
template<typename Result, typename BidirectionalIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
reverse_copy(BidirectionalIterator first, BidirectionalIterator last) {
return sprout::fixed::reverse_copy(first, last, sprout::pit<Result>());
} }
} // namespace fixed } // namespace fixed

View file

@ -8,7 +8,9 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/joint_iterator.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -56,6 +58,7 @@ namespace sprout {
sprout::distance(first, last) sprout::distance(first, last)
); );
} }
template<typename ForwardIterator, typename Result, typename... Args> template<typename ForwardIterator, typename Result, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),
@ -129,6 +132,29 @@ namespace sprout {
{ {
return sprout::fixed::detail::rotate_copy_impl(first, middle, last, result, sprout::size(result)); return sprout::fixed::detail::rotate_copy_impl(first, middle, last, result, sprout::size(result));
} }
template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) {
typedef typename std::iterator_traits<ForwardIterator>::iterator_category* category;
return sprout::fixed::detail::rotate_copy(first, middle, last, result, category());
}
template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename std::enable_if<
!sprout::is_fixed_container<Result>::value,
typename sprout::fixed::result_of::algorithm<Result>::type
>::type
rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) {
return sprout::remake<Result>(
result, sprout::size(result),
sprout::make_joint_iterator(middle, last, first, first),
sprout::make_joint_iterator(last, last, first, middle)
);
}
} // namespace detail } // namespace detail
// //
// rotate_copy // rotate_copy
@ -136,8 +162,13 @@ namespace sprout {
template<typename ForwardIterator, typename Result> template<typename ForwardIterator, typename Result>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) { rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, Result const& result) {
typedef typename std::iterator_traits<ForwardIterator>::iterator_category* category; return sprout::fixed::detail::rotate_copy(first, middle, last, result);
return sprout::fixed::detail::rotate_copy(first, middle, last, result, category()); }
template<typename Result, typename ForwardIterator>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Result>::type
rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last) {
return sprout::fixed::rotate_copy(first, middle, last, sprout::pit<Result>());
} }
} // namespace fixed } // namespace fixed

View file

@ -58,6 +58,7 @@ namespace sprout {
sprout::distance(first, last) sprout::distance(first, last)
); );
} }
template<typename ForwardIterator, typename Result, typename... Args> template<typename ForwardIterator, typename Result, typename... Args>
inline SPROUT_CONSTEXPR typename std::enable_if< inline SPROUT_CONSTEXPR typename std::enable_if<
sprout::container_traits<Result>::static_size == sizeof...(Args), sprout::container_traits<Result>::static_size == sizeof...(Args),

View file

@ -29,8 +29,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size
? op(first[Indexes - offset]) ? op(first[Indexes - offset])
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -114,9 +113,9 @@ namespace sprout {
>::type >::type
transform(InputIterator first, InputIterator last, Result const& result, UnaryOperation op) { transform(InputIterator first, InputIterator last, Result const& result, UnaryOperation op) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result), sprout::make_transform_iterator(first, op),
sprout::make_transform_iterator(first, op), sprout::make_transform_iterator(last, op) sprout::make_transform_iterator(last, op)
); );
} }
} // namespace detail } // namespace detail
@ -148,8 +147,7 @@ namespace sprout {
) )
{ {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
(Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size
? op(first1[Indexes - offset], first2[Indexes - offset]) ? op(first1[Indexes - offset], first2[Indexes - offset])
: *sprout::next(sprout::internal_begin(result), Indexes) : *sprout::next(sprout::internal_begin(result), Indexes)
@ -232,8 +230,7 @@ namespace sprout {
>::type >::type
transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) { transform(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Result const& result, BinaryOperation op) {
return sprout::remake<Result>( return sprout::remake<Result>(
result, result, sprout::size(result),
sprout::size(result),
sprout::make_transform_iterator(first1, first2, op), sprout::make_transform_iterator(first1, first2, op),
sprout::make_transform_iterator(last1, first2, op) sprout::make_transform_iterator(last1, first2, op)
); );

View file

@ -7,6 +7,7 @@
#include <sprout/container/functions.hpp> #include <sprout/container/functions.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/generator/functions.hpp> #include <sprout/generator/functions.hpp>
#include <sprout/pit.hpp>
#include <sprout/detail/container_complate.hpp> #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
@ -79,6 +80,12 @@ namespace sprout {
unfold(Container const& cont, Generator const& gen, Init const& init) { unfold(Container const& cont, Generator const& gen, Init const& init) {
return sprout::fixed::detail::unfold_impl(cont, gen, init, sprout::size(cont)); return sprout::fixed::detail::unfold_impl(cont, gen, init, sprout::size(cont));
} }
template<typename Container, typename Generator, typename Init>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
unfold(Generator const& gen, Init const& init) {
return sprout::fixed::unfold(sprout::pit<Container>(), gen, init);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::unfold; using sprout::fixed::unfold;

View file

@ -5,6 +5,7 @@
#include <sprout/container/traits.hpp> #include <sprout/container/traits.hpp>
#include <sprout/algorithm/fixed/result_of.hpp> #include <sprout/algorithm/fixed/result_of.hpp>
#include <sprout/algorithm/fixed/unfold.hpp> #include <sprout/algorithm/fixed/unfold.hpp>
#include <sprout/pit.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
@ -16,6 +17,12 @@ namespace sprout {
unfold_n(Container const& cont, Size n, Generator const& gen, Init const& init) { unfold_n(Container const& cont, Size n, Generator const& gen, Init const& init) {
return sprout::fixed::detail::unfold_impl(cont, gen, init, n); return sprout::fixed::detail::unfold_impl(cont, gen, init, n);
} }
template<typename Container, typename Size,typename Generator, typename Init>
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
unfold_n(Size n, Generator const& gen, Init const& init) {
return sprout::fixed::unfold_n(sprout::pit<Container>(), n, gen, init);
}
} // namespace fixed } // namespace fixed
using sprout::fixed::unfold_n; using sprout::fixed::unfold_n;

View file

@ -7,6 +7,9 @@
#include <sprout/iterator/replace_iterator.hpp> #include <sprout/iterator/replace_iterator.hpp>
#include <sprout/iterator/replace_if_iterator.hpp> #include <sprout/iterator/replace_if_iterator.hpp>
#include <sprout/iterator/filter_iterator.hpp> #include <sprout/iterator/filter_iterator.hpp>
#include <sprout/iterator/remove_iterator.hpp>
#include <sprout/iterator/remove_if_iterator.hpp>
#include <sprout/iterator/while_iterator.hpp>
#include <sprout/iterator/step_iterator.hpp> #include <sprout/iterator/step_iterator.hpp>
#include <sprout/iterator/indexed_iterator.hpp> #include <sprout/iterator/indexed_iterator.hpp>
#include <sprout/iterator/valued_iterator.hpp> #include <sprout/iterator/valued_iterator.hpp>

View file

@ -178,14 +178,14 @@ namespace sprout {
SPROUT_CONSTEXPR remake_iterator next() const { SPROUT_CONSTEXPR remake_iterator next() const {
return remake_iterator( return remake_iterator(
sprout::next(current), (is_in_copying() ? sprout::next(current2) : current2), sprout::next(current), (is_in_copying() ? sprout::next(current2) : current2),
fst, last, fst, lst,
begin_off - 1, end_off - 1 begin_off - 1, end_off - 1
); );
} }
SPROUT_CONSTEXPR remake_iterator prev() const { SPROUT_CONSTEXPR remake_iterator prev() const {
return remake_iterator( return remake_iterator(
sprout::prev(current), (begin_off < 0 && end_off >= 0 ? sprout::prev(current2) : current2), sprout::prev(current), (begin_off < 0 && end_off >= 0 ? sprout::prev(current2) : current2),
fst, last, fst, lst,
begin_off + 1, end_off + 1 begin_off + 1, end_off + 1
); );
} }

View file

@ -0,0 +1,39 @@
#ifndef SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP
#define SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/filter_iterator.hpp>
namespace sprout {
//
// remove_if_filter
//
template<typename Predicate>
class remove_if_filter {
public:
typedef bool result_type;
private:
Predicate pred_;
public:
SPROUT_CONSTEXPR remove_if_filter(Predicate pred)
: pred_(pred)
{}
template<typename U>
SPROUT_CONSTEXPR bool operator()(U const& value) const {
return !pred_(value);
}
};
//
// make_remove_if_iterator
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::filter_iterator<sprout::remove_if_filter<Predicate>, Iterator>
make_remove_if_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) {
return sprout::filter_iterator<sprout::remove_if_filter<Predicate>, Iterator>(
sprout::remove_if_filter<Predicate>(pred), it, last
);
}
} // namespace sprout
#endif // SPROUT_ITERATOR_REMOVE_IF_ITERATOR_HPP

View file

@ -0,0 +1,39 @@
#ifndef SPROUT_ITERATOR_REMOVE_ITERATOR_HPP
#define SPROUT_ITERATOR_REMOVE_ITERATOR_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/filter_iterator.hpp>
namespace sprout {
//
// remove_filter
//
template<typename T>
class remove_filter {
public:
typedef bool result_type;
private:
T value_;
public:
SPROUT_CONSTEXPR remove_filter(T const& value)
: value_(value)
{}
template<typename U>
SPROUT_CONSTEXPR bool operator()(U const& value) const {
return value != value_;
}
};
//
// make_remove_iterator
//
template<typename T, typename Iterator>
inline SPROUT_CONSTEXPR sprout::filter_iterator<sprout::remove_filter<T>, Iterator>
make_remove_iterator(T const& value, Iterator it, Iterator last = Iterator()) {
return sprout::filter_iterator<sprout::remove_filter<T>, Iterator>(
sprout::remove_filter<T>(value), it, last
);
}
} // namespace sprout
#endif // SPROUT_ITERATOR_REMOVE_ITERATOR_HPP

View file

@ -12,7 +12,7 @@ namespace sprout {
class replace_value_if { class replace_value_if {
public: public:
typedef Predicate predicate_type; typedef Predicate predicate_type;
typedef T const& result_type; typedef T result_type;
typedef T const& argument_type; typedef T const& argument_type;
private: private:
Predicate pred_; Predicate pred_;

View file

@ -11,7 +11,7 @@ namespace sprout {
template<typename T> template<typename T>
class replace_value { class replace_value {
public: public:
typedef T const& result_type; typedef T result_type;
typedef T const& argument_type; typedef T const& argument_type;
private: private:
T old_; T old_;

View file

@ -32,22 +32,17 @@ namespace sprout {
typedef typename std::iterator_traits<iterator_type>::reference reference; typedef typename std::iterator_traits<iterator_type>::reference reference;
protected: protected:
iterator_type current; iterator_type current;
private:
iterator_type deref_tmp;
public: public:
reverse_iterator() = default; reverse_iterator() = default;
SPROUT_CONSTEXPR reverse_iterator(reverse_iterator const& other) SPROUT_CONSTEXPR reverse_iterator(reverse_iterator const& other)
: current(other.current) : current(other.current)
, deref_tmp(other.deref_tmp)
{} {}
explicit SPROUT_CONSTEXPR reverse_iterator(iterator_type it) explicit SPROUT_CONSTEXPR reverse_iterator(iterator_type it)
: current(it) : current(it)
, deref_tmp(sprout::prev(it))
{} {}
template<typename U> template<typename U>
SPROUT_CONSTEXPR reverse_iterator(reverse_iterator<U> const& it) SPROUT_CONSTEXPR reverse_iterator(reverse_iterator<U> const& it)
: current(it.base()) : current(it.base())
, deref_tmp(sprout::prev(it.base()))
{} {}
template<typename U> template<typename U>
reverse_iterator& operator=(reverse_iterator<U> const& it) { reverse_iterator& operator=(reverse_iterator<U> const& it) {
@ -59,31 +54,27 @@ namespace sprout {
return current; return current;
} }
SPROUT_CONSTEXPR reference operator*() const { SPROUT_CONSTEXPR reference operator*() const {
return *deref_tmp; return *sprout::prev(current);
} }
SPROUT_CONSTEXPR pointer operator->() const { SPROUT_CONSTEXPR pointer operator->() const {
return &*deref_tmp; return &*(*this);
} }
reverse_iterator& operator++() { reverse_iterator& operator++() {
--current; --current;
--deref_tmp;
return *this; return *this;
} }
reverse_iterator operator++(int) { reverse_iterator operator++(int) {
reverse_iterator result(*this); reverse_iterator result(*this);
--current; --current;
--deref_tmp;
return result; return result;
} }
reverse_iterator& operator--() { reverse_iterator& operator--() {
++current; ++current;
++deref_tmp;
return *this; return *this;
} }
reverse_iterator operator--(int) { reverse_iterator operator--(int) {
reverse_iterator temp(*this); reverse_iterator temp(*this);
++current; ++current;
++deref_tmp;
return temp; return temp;
} }
SPROUT_CONSTEXPR reverse_iterator operator+(difference_type n) const { SPROUT_CONSTEXPR reverse_iterator operator+(difference_type n) const {
@ -103,7 +94,7 @@ namespace sprout {
return *this; return *this;
} }
SPROUT_CONSTEXPR reference operator[](difference_type n) const { SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return *(deref_tmp - n); return *(current - (n + 1));
} }
SPROUT_CONSTEXPR reverse_iterator next() const { SPROUT_CONSTEXPR reverse_iterator next() const {
return reverse_iterator(sprout::prev(current)); return reverse_iterator(sprout::prev(current));
@ -114,11 +105,9 @@ namespace sprout {
void swap(reverse_iterator& other) void swap(reverse_iterator& other)
SPROUT_NOEXCEPT_EXPR( SPROUT_NOEXCEPT_EXPR(
SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) SPROUT_NOEXCEPT_EXPR(swap(current, other.current))
&& SPROUT_NOEXCEPT_EXPR(swap(deref_tmp, other.deref_tmp))
) )
{ {
swap(current, other.current); swap(current, other.current);
swap(deref_tmp, other.deref_tmp);
} }
}; };
@ -155,7 +144,7 @@ namespace sprout {
template<typename Iterator1, typename Iterator2> template<typename Iterator1, typename Iterator2>
inline SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>()) inline SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>())
operator-(sprout::reverse_iterator<Iterator1> const& lhs, sprout::reverse_iterator<Iterator2> const& rhs) { operator-(sprout::reverse_iterator<Iterator1> const& lhs, sprout::reverse_iterator<Iterator2> const& rhs) {
return lhs.base() - rhs.base(); return rhs.base() - lhs.base();
} }
template<typename Iterator> template<typename Iterator>
inline SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator> inline SPROUT_CONSTEXPR sprout::reverse_iterator<Iterator>

View file

@ -0,0 +1,208 @@
#ifndef SPROUT_ITERATOR_WHILE_ITERATOR_HPP
#define SPROUT_ITERATOR_WHILE_ITERATOR_HPP
#include <iterator>
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/iterator/next.hpp>
#include <sprout/iterator/prev.hpp>
#include <sprout/utility/swap.hpp>
namespace sprout {
//
// while_iterator
//
template<typename Predicate, typename Iterator>
class while_iterator
: public std::iterator<
typename std::conditional<
std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value,
std::bidirectional_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category
>::type,
typename std::iterator_traits<Iterator>::value_type,
typename std::iterator_traits<Iterator>::difference_type,
typename std::iterator_traits<Iterator>::pointer,
typename std::iterator_traits<Iterator>::reference
>
{
public:
typedef Predicate predicate_type;
typedef Iterator iterator_type;
typedef typename std::conditional<
std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value,
std::bidirectional_iterator_tag,
typename std::iterator_traits<Iterator>::iterator_category
>::type iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef typename std::iterator_traits<Iterator>::pointer pointer;
typedef typename std::iterator_traits<Iterator>::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<typename U>
SPROUT_CONSTEXPR while_iterator(while_iterator<Predicate, U> const& it)
: current(it.current)
, last(it.last)
, pred(it.pred)
{}
template<typename U>
while_iterator& operator=(while_iterator<Predicate, U> 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<typename Predicate, typename Iterator1, typename Iterator2>
inline SPROUT_CONSTEXPR bool operator==(
sprout::while_iterator<Predicate, Iterator1> const& lhs,
sprout::while_iterator<Predicate, Iterator2> const& rhs
)
{
return lhs.base() == rhs.base();
}
template<typename Predicate, typename Iterator1, typename Iterator2>
inline SPROUT_CONSTEXPR bool operator!=(
sprout::while_iterator<Predicate, Iterator1> const& lhs,
sprout::while_iterator<Predicate, Iterator2> const& rhs
)
{
return !(lhs == rhs);
}
//
// make_while_iterator
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::while_iterator<Predicate, Iterator>
make_while_iterator(Predicate pred, Iterator it, Iterator last = Iterator()) {
return sprout::while_iterator<Predicate, Iterator>(pred, it, last);
}
//
// swap
//
template<typename Predicate, typename Iterator>
inline void
swap(sprout::while_iterator<Predicate, Iterator>& lhs, sprout::while_iterator<Predicate, Iterator>& rhs)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
//
// iterator_next
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::while_iterator<Predicate, Iterator>
iterator_next(sprout::while_iterator<Predicate, Iterator> const& it) {
return it.next();
}
//
// iterator_prev
//
template<typename Predicate, typename Iterator>
inline SPROUT_CONSTEXPR sprout::while_iterator<Predicate, Iterator>
iterator_prev(sprout::while_iterator<Predicate, Iterator> const& it) {
return it.prev();
}
} // namespace sprout
#endif // SPROUT_ITERATOR_WHILE_ITERATOR_HPP