fix recursion depth: detail::count_n, detail::count_n_if, detail::overlap_count

This commit is contained in:
bolero-MURAKAMI 2012-12-17 02:14:07 +09:00
parent 570b834367
commit d5c61e65ca
5 changed files with 80 additions and 45 deletions

View file

@ -8,6 +8,7 @@
#include <sprout/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp>
#include <sprout/detail/algorithm/count_n_if.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT

View file

@ -4,18 +4,45 @@
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/count.hpp>
namespace sprout {
namespace detail {
template<typename InputIterator, typename Size, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n(
InputIterator first, Size n, T const& value,
std::random_access_iterator_tag*
)
{
return sprout::count(first, sprout::next(first, n), value);
}
template<typename InputIterator, typename Size, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n_impl(InputIterator first, Size n, T const& value) {
return n == 0 ? 0
: (*first == value ? 1 : 0) + sprout::detail::count_n_impl(sprout::next(first), n - 1, value)
;
}
template<typename InputIterator, typename Size, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n(
InputIterator first, Size n, T const& value,
void*
)
{
return sprout::detail::count_n_impl(first, n, value);
}
//
// count_n
//
template<typename InputIterator, typename Size, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n(InputIterator first, Size n, T const& value) {
return n == 0 ? 0
: (*first == value ? 1 : 0) + sprout::detail::count_n(sprout::next(first), n - 1, value)
;
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::detail::count_n(first, n, value, category());
}
} // namespace detail
} // namespace sprout

View file

@ -4,18 +4,46 @@
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/count_if.hpp>
namespace sprout {
namespace detail {
template<typename InputIterator, typename Size, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n_if(
InputIterator first, Size n, Predicate pred,
std::random_access_iterator_tag*
)
{
return sprout::count_if(first, sprout::next(first, n), pred);
}
template<typename InputIterator, typename Size, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n_if_impl(InputIterator first, Size n, Predicate pred) {
return n == 0 ? 0
: (pred(*first) ? 1 : 0) + sprout::detail::count_n_if(sprout::next(first), n - 1, pred)
;
}
template<typename InputIterator, typename Size, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n_if(
InputIterator first, Size n, Predicate pred,
void*
)
{
return sprout::detail::count_n_if_impl(first, n, pred);
}
//
// count_n_if
//
template<typename InputIterator, typename Size, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_n_if(InputIterator first, Size n, Predicate pred) {
return n == 0 ? 0
: (pred(*first) ? 1 : 0) + sprout::detail::count_n_if(sprout::next(first), n - 1, pred)
;
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
return sprout::detail::count_n_if(first, n, pred, category());
}
} // namespace detail
} // namespace sprout

View file

@ -4,38 +4,15 @@
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename InputIterator>
template<typename InputIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count_impl(
InputIterator first, InputIterator last,
typename std::iterator_traits<InputIterator>::value_type const& value,
typename std::iterator_traits<InputIterator>::difference_type current = 0
)
{
return first == last ? 0
: *first == value ? 1 + sprout::detail::overlap_count_impl(sprout::next(first), last, value)
: sprout::detail::overlap_count_impl(sprout::next(first), last, *first)
;
}
//
// overlap_count
//
template<typename InputIterator>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count(InputIterator first, InputIterator last) {
return first == last ? 0
: sprout::detail::overlap_count_impl(sprout::next(first), last, *first)
;
}
template<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count_impl(
InputIterator first, InputIterator last,
Predicate pred, typename std::iterator_traits<InputIterator>::value_type const& value
BinaryPredicate pred, typename std::iterator_traits<InputIterator>::value_type const& value
)
{
return first == last ? 0
@ -43,16 +20,26 @@ namespace sprout {
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
;
}
//
// overlap_count
//
template<typename InputIterator, typename Predicate>
template<typename InputIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count(InputIterator first, InputIterator last, Predicate pred) {
overlap_count(InputIterator first, InputIterator last, BinaryPredicate pred) {
return first == last ? 0
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
;
}
template<typename InputIterator>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
overlap_count(InputIterator first, InputIterator last) {
return sprout::detail::overlap_count(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::equal_to<typename std::iterator_traits<InputIterator>::value_type>()
);
}
} // namespace detail
} // namespace sprout

View file

@ -4,6 +4,7 @@
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/functional/less.hpp>
namespace sprout {
namespace detail {
@ -27,9 +28,7 @@ namespace sprout {
: 0
;
}
//
// set_overlap_count
//
template<typename InputIterator1, typename InputIterator2>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator1>::difference_type
set_overlap_count(
@ -37,14 +36,7 @@ namespace sprout {
InputIterator2 first2, InputIterator2 last2
)
{
return first1 != last1 && first2 != last2
? *first1 < *first2
? sprout::detail::set_overlap_count(sprout::next(first1), last1, first2, last2)
: *first2 < *first1
? sprout::detail::set_overlap_count(first1, last1, sprout::next(first2), last2)
: 1 + sprout::detail::set_overlap_count(sprout::next(first1), last1, sprout::next(first2), last2)
: 0
;
return sprout::detail::set_overlap_count(first1, last1, first2, last2, sprout::less<>());
}
} // namespace detail
} // namespace sprout