From 5fcb039ab433e4569755d3dce39043dd759ac9e9 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sun, 23 Dec 2012 17:59:00 +0900 Subject: [PATCH] fix recursion depth: distance add random::make_range --- sprout/iterator/distance.hpp | 43 +++++++++++++++++++++++++++----- sprout/random.hpp | 1 + sprout/random/range.hpp | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 sprout/random/range.hpp diff --git a/sprout/iterator/distance.hpp b/sprout/iterator/distance.hpp index bbb73118..1187be1c 100644 --- a/sprout/iterator/distance.hpp +++ b/sprout/iterator/distance.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace sprout_adl { @@ -22,18 +23,48 @@ namespace sprout { return last - first; } - // Copyright (C) 2011 RiSK (sscrisk) template - inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type - iterator_distance_impl(InputIterator first, InputIterator last) { - return first == last ? 0 - : 1 + sprout::iterator_detail::iterator_distance_impl(sprout::next(first), last) + inline SPROUT_CONSTEXPR sprout::pair::difference_type> + iterator_distance_impl_1( + sprout::pair::difference_type> const& current, + InputIterator last, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair::difference_type> type; + return current.first == last ? current + : n == 1 ? type(sprout::next(current.first), current.second + 1) + : sprout::iterator_detail::iterator_distance_impl_1( + sprout::iterator_detail::iterator_distance_impl_1( + current, + last, n / 2 + ), + last, n - n / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair::difference_type> + iterator_distance_impl( + sprout::pair::difference_type> const& current, + InputIterator last, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::pair::difference_type> type; + return current.first == last ? current + : sprout::iterator_detail::iterator_distance_impl( + sprout::iterator_detail::iterator_distance_impl_1( + current, + last, n + ), + last, n * 2 + ) ; } template inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type iterator_distance(InputIterator first, InputIterator last, void*) { - return sprout::iterator_detail::iterator_distance_impl(first, last); + typedef sprout::pair::difference_type> type; + return sprout::iterator_detail::iterator_distance_impl(type(first, 0), last, 1).second; } template diff --git a/sprout/random.hpp b/sprout/random.hpp index b7cf38b7..a47897d7 100644 --- a/sprout/random.hpp +++ b/sprout/random.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #endif // #ifndef SPROUT_RANDOM_HPP diff --git a/sprout/random/range.hpp b/sprout/random/range.hpp new file mode 100644 index 00000000..e7a56ec5 --- /dev/null +++ b/sprout/random/range.hpp @@ -0,0 +1,48 @@ +#ifndef SPROUT_RANDOM_RANGE_HPP +#define SPROUT_RANDOM_RANGE_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // make_range + // + template< + typename Engine, typename Distribution, + typename sprout::enabler_if::value>::type = sprout::enabler + > + inline SPROUT_CONSTEXPR auto + make_range( + Engine const& engine, Distribution const& distribution, + typename sprout::generator_iterator::type>::difference_type count = -1 + ) + -> sprout::range::range_container::type> > + { + return sprout::range::range_container::type> >( + sprout::random::begin(engine, distribution, count), + sprout::random::end(engine, distribution) + ); + } + template + inline SPROUT_CONSTEXPR auto + make_range( + Engine const& engine, + typename sprout::generator_iterator::type>::difference_type count = -1 + ) + -> sprout::range::range_container::type> > + { + return sprout::range::range_container::type> >( + sprout::random::begin(engine, count), + sprout::random::end(engine) + ); + } + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_RANGE_HPP