From 3e97ddd286c37e41e82cff14b317825adfb5839a Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 25 Jul 2013 23:32:42 +0900 Subject: [PATCH] workaround for Clang: uniform_int_ditribution, uniform_real_distribution --- sprout/random/uniform_int_distribution.hpp | 402 +++++++++++++++++++- sprout/random/uniform_real_distribution.hpp | 287 +++++++++++--- 2 files changed, 622 insertions(+), 67 deletions(-) diff --git a/sprout/random/uniform_int_distribution.hpp b/sprout/random/uniform_int_distribution.hpp index 86dcace9..4b6aef0a 100644 --- a/sprout/random/uniform_int_distribution.hpp +++ b/sprout/random/uniform_int_distribution.hpp @@ -21,6 +21,399 @@ namespace sprout { Engine engine; }; +#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int(Engine const& eng, T min_value, T max_value, std::true_type); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int(Engine const& eng, T min_value, T max_value, std::true_type); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1( + sprout::random::random_result const& rnd, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, BaseUnsigned bucket_size + ); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1( + sprout::random::random_result const& rnd, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, BaseUnsigned bucket_size + ); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1_1( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, BaseUnsigned bucket_size, BaseUnsigned result + ) + { + typedef T result_type; + return result <= static_cast(range) + ? sprout::random::detail::generate_uniform_int_result{ + sprout::random::detail::add()(result, min_value), + eng + } + : sprout::random::detail::generate_uniform_int_true_3_1( + eng(), min_value, range, + bmin, brange, bucket_size + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1_1( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned, BaseUnsigned, BaseUnsigned + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1( + sprout::random::random_result const& rnd, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, BaseUnsigned bucket_size + ) + { + return sprout::random::detail::generate_uniform_int_true_3_1_1( + rnd.engine(), min_value, range, + bmin, brange, bucket_size, + sprout::random::detail::subtract()(rnd.result(), bmin) / bucket_size + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3_1( + sprout::random::random_result const&, T, RangeType, + BaseResult, BaseUnsigned, BaseUnsigned + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange + ) + { + return sprout::random::detail::generate_uniform_int_true_3_1( + eng(), min_value, range, + bmin, brange, + brange == std::numeric_limits::max() + ? brange / (static_cast(range) + 1) + ( + brange % (static_cast(range) + 1) == static_cast(range) ? 1 : 0 + ) + : (brange + 1) / (static_cast(range) + 1) + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_3( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange + ); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_4( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType result, RangeType result_increment + ) + { + typedef T result_type; + return result < result_increment || result > range + ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : sprout::random::detail::generate_uniform_int_result{ + random::detail::add()(result, min_value), + eng + } + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_4( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned, RangeType, RangeType + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_3( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType result, RangeType mult, RangeType result_increment + ) + { + return std::numeric_limits::max() / mult < result_increment + ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : sprout::random::detail::generate_uniform_int_true_2_4( + eng, min_value, range, + bmin, brange, result + (result_increment * mult), result_increment * mult + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_3( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned, RangeType, RangeType, RangeType + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_2( + Engine const&, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType result, RangeType mult, Result const& result_increment_base + ) + { + return sprout::random::detail::generate_uniform_int_true_2_3( + result_increment_base.engine, min_value, range, + bmin, brange, result, mult, result_increment_base.result + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_2( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned, RangeType, RangeType, Result const& + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType limit, + RangeType result = RangeType(0), RangeType mult = RangeType(1) + ); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType limit, + RangeType result = RangeType(0), RangeType mult = RangeType(1) + ); + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1_1( + sprout::random::random_result const& rnd, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType limit, RangeType result, RangeType mult + ) + { + return mult * RangeType(brange) == range - mult + 1 + ? sprout::random::detail::generate_uniform_int_result{ + static_cast( + result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult) + ), + rnd.engine() + } + : sprout::random::detail::generate_uniform_int_true_2_1( + rnd.engine(), min_value, range, + bmin, brange, limit, + result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult), + mult * (RangeType(brange) + RangeType(1)) + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1_1( + sprout::random::random_result const&, T, RangeType, + BaseResult, BaseUnsigned, RangeType, RangeType, RangeType + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange, RangeType limit, + RangeType result, RangeType mult + ) + { + return mult <= limit + ? sprout::random::detail::generate_uniform_int_true_2_1_1( + eng(), min_value, range, + bmin, brange, limit, + result, mult + ) + : sprout::random::detail::generate_uniform_int_true_2_2( + eng, min_value, range, + bmin, brange, + result, mult, + sprout::random::detail::generate_uniform_int( + eng, + static_cast(0), + static_cast(range / mult), + std::true_type() + ) + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2_1( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned, RangeType, + RangeType, RangeType + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2( + Engine const& eng, T min_value, RangeType range, + BaseResult bmin, BaseUnsigned brange + ) + { + return sprout::random::detail::generate_uniform_int_true_2_1( + eng, min_value, range, + bmin, brange, + range == std::numeric_limits::max() + ? range / (RangeType(brange) + 1) + ( + range % (RangeType(brange) + 1) == RangeType(brange) ? 1 : 0 + ) + : (range + 1) / (RangeType(brange) + 1) + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_2( + Engine const&, T, RangeType, + BaseResult, BaseUnsigned + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_1_1( + sprout::random::random_result const& rnd, T min_value, BaseResult bmin + ) + { + typedef T result_type; + typedef typename std::make_unsigned::type base_unsigned; + return sprout::random::detail::generate_uniform_int_result{ + sprout::random::detail::add()( + base_unsigned(sprout::random::detail::subtract()(rnd.result(), bmin)), + min_value + ), + rnd.engine() + }; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_1_1( + sprout::random::random_result const&, T, BaseResult + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_1( + Engine const& eng, T min_value, T, RangeType range, + BaseResult bmin, BaseUnsigned brange + ) + { + return range == 0 ? sprout::random::detail::generate_uniform_int_result{min_value, eng} + : brange == range ? sprout::random::detail::generate_uniform_int_true_1_1(eng(), min_value, bmin) + : brange < range ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : sprout::random::detail::generate_uniform_int_true_3(eng, min_value, range, bmin, brange) + ; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_true_1( + Engine const&, T, T, RangeType, + BaseResult, BaseUnsigned + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int( + Engine const& eng, T min_value, T max_value, std::true_type + ) + { + typedef T result_type; + typedef typename std::make_unsigned::type range_type; + typedef typename Engine::result_type base_result; + typedef typename std::make_unsigned::type base_unsigned; + return sprout::random::detail::generate_uniform_int_true_1( + eng, min_value, max_value, + range_type(sprout::random::detail::subtract()(max_value, min_value)), + base_result(eng.min()), + base_unsigned(sprout::random::detail::subtract()(eng.max(), eng.min())) + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int( + Engine const&, T, T, std::true_type + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_false_1(Result const& rnd) { + return sprout::random::detail::generate_uniform_int_result{ + rnd.result, rnd.engine.base() + }; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int_false_1(Result const& rnd) { + return sprout::random::detail::generate_uniform_int_result{ + rnd.result, rnd.engine.base() + }; + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int( + Engine const& eng, T min_value, T max_value, std::false_type + ) + { + return sprout::random::detail::generate_uniform_int_false_1( + sprout::random::detail::generate_uniform_int( + sprout::random::detail::uniform_int_float(eng), + min_value, max_value, + std::true_type() + ) + ); + } + template + inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result + generate_uniform_int( + Engine const&, T, T, std::false_type + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } +#else template SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int(Engine const& eng, T min_value, T max_value, std::true_type); @@ -43,7 +436,7 @@ namespace sprout { sprout::random::detail::add()(result, min_value), eng } - : generate_uniform_int_true_3_1( + : sprout::random::detail::generate_uniform_int_true_3_1( eng(), min_value, range, bmin, brange, bucket_size ) @@ -110,7 +503,7 @@ namespace sprout { { return std::numeric_limits::max() / mult < result_increment ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) - : generate_uniform_int_true_2_4( + : sprout::random::detail::generate_uniform_int_true_2_4( eng, min_value, range, bmin, brange, result + (result_increment * mult), result_increment * mult ) @@ -166,7 +559,7 @@ namespace sprout { ) { return mult <= limit - ? generate_uniform_int_true_2_1_1( + ? sprout::random::detail::generate_uniform_int_true_2_1_1( eng(), min_value, range, bmin, brange, limit, result, mult @@ -260,7 +653,7 @@ namespace sprout { Engine const& eng, T min_value, T max_value, std::false_type ) { - return generate_uniform_int_false_1( + return sprout::random::detail::generate_uniform_int_false_1( sprout::random::detail::generate_uniform_int( sprout::random::detail::uniform_int_float(eng), min_value, max_value, @@ -268,6 +661,7 @@ namespace sprout { ) ); } +#endif template inline SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( diff --git a/sprout/random/uniform_real_distribution.hpp b/sprout/random/uniform_real_distribution.hpp index f2506fcf..40355f29 100644 --- a/sprout/random/uniform_real_distribution.hpp +++ b/sprout/random/uniform_real_distribution.hpp @@ -19,17 +19,187 @@ namespace sprout { Engine engine; }; - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( +#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( sprout::random::random_result const& rnd, - T min_value, - T max_value + T min_value, T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( + sprout::random::random_result const& rnd, + T min_value, T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_3( + Engine const& eng, + T min_value, T max_value, + T result + ) + { + return result < max_value + ? sprout::random::detail::generate_uniform_real_result{result, eng} + : sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_3( + Engine const&, + T, T, + T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_2( + Engine const& eng, + T min_value, T max_value, + T numerator, T divisor + ) + { + return SPROUT_ASSERT(divisor > 0), SPROUT_ASSERT(numerator >= 0 && numerator <= divisor), + sprout::random::detail::generate_uniform_real_false_3( + eng, + min_value, max_value, + numerator / divisor * (max_value - min_value) + min_value + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_2( + Engine const&, + T, T, + T, T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( + sprout::random::random_result const& rnd, + T min_value, T max_value + ) + { + return sprout::random::detail::generate_uniform_real_false_2( + rnd.engine(), + min_value, max_value, + static_cast(rnd.result() - rnd.engine().min()), static_cast(rnd.engine().max() - rnd.engine().min()) + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( + sprout::random::random_result const&, + T, T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( + sprout::random::random_result const& rnd, + T min_value, T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( + sprout::random::random_result const& rnd, + T min_value, T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_3( + Engine const& eng, + T min_value, T max_value, + T result + ) + { + return result < max_value + ? sprout::random::detail::generate_uniform_real_result{result, eng} + : sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_3( + Engine const&, + T, T, + T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_2( + Engine const& eng, + T min_value, T max_value, + T numerator, T divisor + ) + { + return SPROUT_ASSERT(divisor > 0), SPROUT_ASSERT(numerator >= 0 && numerator <= divisor), + sprout::random::detail::generate_uniform_real_true_3( + eng, + min_value, max_value, + numerator / divisor * (max_value - min_value) + min_value + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_2( + Engine const&, + T, T, + T, T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( + sprout::random::random_result const& rnd, + T min_value, T max_value + ) + { + typedef typename Engine::result_type base_result; + return sprout::random::detail::generate_uniform_real_true_2( + rnd.engine(), + min_value, max_value, + static_cast(sprout::random::detail::subtract()(rnd.result(), rnd.engine().min())), + static_cast(sprout::random::detail::subtract()(rnd.engine().max(), rnd.engine().min())) + 1 + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( + sprout::random::random_result const&, + T, T + ) + { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } +#else + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( + sprout::random::random_result const& rnd, + T min_value, T max_value ); template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_3( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_3( Engine const& eng, - T min_value, - T max_value, + T min_value, T max_value, T result ) { @@ -39,63 +209,45 @@ namespace sprout { ; } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_2( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_2( Engine const& eng, - T min_value, - T max_value, - T numerator, - T divisor + T min_value, T max_value, + T numerator, T divisor ) { return SPROUT_ASSERT(divisor > 0), SPROUT_ASSERT(numerator >= 0 && numerator <= divisor), sprout::random::detail::generate_uniform_real_false_3( eng, - min_value, - max_value, + min_value, max_value, numerator / divisor * (max_value - min_value) + min_value ) ; } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_false_1( sprout::random::random_result const& rnd, - T min_value, - T max_value + T min_value, T max_value ) { return sprout::random::detail::generate_uniform_real_false_2( rnd.engine(), - min_value, - max_value, - static_cast(rnd.result() - rnd.engine().min()), - static_cast(rnd.engine().max() - rnd.engine().min()) + min_value, max_value, + static_cast(rnd.result() - rnd.engine().min()), static_cast(rnd.engine().max() - rnd.engine().min()) ); } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( - Engine const& eng, - T min_value, - T max_value, - std::false_type - ) - { - return sprout::random::detail::generate_uniform_real_false_1( - eng(), - min_value, - max_value - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( sprout::random::random_result const& rnd, - T min_value, - T max_value + T min_value, T max_value ); template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_3( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_3( Engine const& eng, - T min_value, - T max_value, + T min_value, T max_value, T result ) { @@ -105,64 +257,73 @@ namespace sprout { ; } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_2( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_2( Engine const& eng, - T min_value, - T max_value, - T numerator, - T divisor + T min_value, T max_value, + T numerator, T divisor ) { return SPROUT_ASSERT(divisor > 0), SPROUT_ASSERT(numerator >= 0 && numerator <= divisor), sprout::random::detail::generate_uniform_real_true_3( eng, - min_value, - max_value, + min_value, max_value, numerator / divisor * (max_value - min_value) + min_value ) ; } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real_true_1( sprout::random::random_result const& rnd, - T min_value, - T max_value + T min_value, T max_value ) { typedef typename Engine::result_type base_result; return sprout::random::detail::generate_uniform_real_true_2( rnd.engine(), - min_value, - max_value, + min_value, max_value, static_cast(sprout::random::detail::subtract()(rnd.result(), rnd.engine().min())), static_cast(sprout::random::detail::subtract()(rnd.engine().max(), rnd.engine().min())) + 1 ); } +#endif template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real( Engine const& eng, - T min_value, - T max_value, + T min_value, T max_value, + std::false_type + ) + { + return sprout::random::detail::generate_uniform_real_false_1( + eng(), + min_value, max_value + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real( + Engine const& eng, + T min_value, T max_value, std::true_type ) { return sprout::random::detail::generate_uniform_real_true_1( eng(), - min_value, - max_value + min_value, max_value ); } template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result + generate_uniform_real( Engine const& eng, - T min_value, - T max_value + T min_value, T max_value ) { return sprout::random::detail::generate_uniform_real( eng, - min_value, - max_value, + min_value, max_value, std::is_integral() ); }