From b9121b8850b1ed34a44286e3bd8ba54dfec07230 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Wed, 14 Nov 2012 11:22:05 +0900 Subject: [PATCH] workaroud for clang3.2 (inversive_congruential) --- sprout/algorithm/fixed/sort.hpp | 7 -- sprout/random/detail/const_mod.hpp | 87 +++++++++++++++++++++++- sprout/random/inversive_congruential.hpp | 3 +- sprout/random/shuffle_order.hpp | 9 ++- 4 files changed, 94 insertions(+), 12 deletions(-) diff --git a/sprout/algorithm/fixed/sort.hpp b/sprout/algorithm/fixed/sort.hpp index 7d6d8390..04d2aa54 100644 --- a/sprout/algorithm/fixed/sort.hpp +++ b/sprout/algorithm/fixed/sort.hpp @@ -72,13 +72,6 @@ namespace sprout { : r ; } - template - inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type - swap_lr( - Container const& cont, - typename sprout::container_traits::difference_type l, - typename sprout::container_traits::difference_type r - ); template inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm::type sort_part_l( diff --git a/sprout/random/detail/const_mod.hpp b/sprout/random/detail/const_mod.hpp index 5fff6c19..440b0284 100644 --- a/sprout/random/detail/const_mod.hpp +++ b/sprout/random/detail/const_mod.hpp @@ -5,6 +5,9 @@ #include #include #include +#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE +# include +#endif namespace sprout { namespace random { @@ -51,6 +54,84 @@ namespace sprout { static SPROUT_CONSTEXPR unsigned_type unsigned_m() { return m == 0 ? unsigned_type((std::numeric_limits::max)()) + 1 : unsigned_type(m); } +#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE + template + static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return p == 0 ? l2 : invert_euclidian_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) { + return c > 0 + ? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m) + : throw std::domain_error("const_mod<>: domain error (c > 0)") + ; + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return n == 0 ? m - l1 : invert_euclidian0_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return p == 0 ? l2 : invert_euclidian0_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return std::numeric_limits::max() % n != n - 1 + ? invert_euclidian0_2( + c, l1 + (std::numeric_limits::max() / n) * l2, l2, n, + std::numeric_limits::max() - (std::numeric_limits::max() / n) * n + 1 + ) + : throw std::domain_error("const_mod<>: domain error (numeric_limits::max() % n != n - 1)") + ; + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) { + return c > 0 + ? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m) + : throw std::domain_error("const_mod<>: domain error (c > 0)") + ; + } + template + static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) { + return sprout::throw_recursive_function_template_instantiation_exeeded(); + } +#else static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p); } @@ -74,7 +155,10 @@ namespace sprout { } static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { return std::numeric_limits::max() % n != n - 1 - ? invert_euclidian0_2(c, l1 + (std::numeric_limits::max() / n) * l2, l2, n, std::numeric_limits::max() - (std::numeric_limits::max() / n) * n + 1) + ? invert_euclidian0_2( + c, l1 + (std::numeric_limits::max() / n) * l2, l2, n, + std::numeric_limits::max() - (std::numeric_limits::max() / n) * n + 1 + ) : throw std::domain_error("const_mod<>: domain error (numeric_limits::max() % n != n - 1)") ; } @@ -84,6 +168,7 @@ namespace sprout { : throw std::domain_error("const_mod<>: domain error (c > 0)") ; } +#endif public: static SPROUT_CONSTEXPR IntType apply(IntType x) { return ((unsigned_m() - 1) & unsigned_m()) == 0 diff --git a/sprout/random/inversive_congruential.hpp b/sprout/random/inversive_congruential.hpp index 4e771f9c..3ed34490 100644 --- a/sprout/random/inversive_congruential.hpp +++ b/sprout/random/inversive_congruential.hpp @@ -58,7 +58,8 @@ namespace sprout { SPROUT_CONSTEXPR inversive_congruential_engine(IntType const& x, private_constructor_tag) : x_(x) {} - SPROUT_CONSTEXPR sprout::random::random_result generate(result_type result) const { + SPROUT_CONSTEXPR sprout::random::random_result + generate(result_type result) const { return sprout::random::random_result( result, inversive_congruential_engine(result, private_constructor_tag()) diff --git a/sprout/random/shuffle_order.hpp b/sprout/random/shuffle_order.hpp index 436103ad..83cc9766 100644 --- a/sprout/random/shuffle_order.hpp +++ b/sprout/random/shuffle_order.hpp @@ -85,7 +85,8 @@ namespace sprout { : member_type{rng, v, y} {} template - SPROUT_CONSTEXPR sprout::random::random_result generate_1(Random const& rnd, BaseUnsigned j) const { + SPROUT_CONSTEXPR sprout::random::random_result + generate_1(Random const& rnd, BaseUnsigned j) const { return sprout::random::random_result( v_[j], shuffle_order_engine( @@ -97,12 +98,14 @@ namespace sprout { ); } template - SPROUT_CONSTEXPR sprout::random::random_result generate(BaseUnsigned brange, BaseUnsigned off) const { + SPROUT_CONSTEXPR sprout::random::random_result + generate(BaseUnsigned brange, BaseUnsigned off) const { return generate_1( rng_(), k == 1 ? BaseUnsigned(0) : brange < std::numeric_limits::max() / k ? BaseUnsigned(k * off / (brange + 1)) - : brange < std::numeric_limits::max() / k ? static_cast(static_cast(off) * k / (static_cast(brange) + 1)) + : brange < std::numeric_limits::max() / k + ? static_cast(static_cast(off) * k / (static_cast(brange) + 1)) //: static_cast(sprout::random::detail::muldiv(off, k, static_cast(brange) + 1)) // ??? : throw std::domain_error("shuffle_order_engine<>: Sorry, not implemented.") );