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/algorithm/fit/result_of.hpp>
#include <sprout/sub_array.hpp> #include <sprout/sub_array.hpp>
#include <sprout/detail/algorithm/count_n_if.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_ALGORITHM_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT

View file

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

View file

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

View file

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

View file

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