From e7b8d74c0f9180b04a5e447367eda155b2596020 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 11 Jan 2014 16:05:18 +0900 Subject: [PATCH] fix shufle_order: support clang 3.3 or later (default template depth 256) --- sprout/random/generate_array.hpp | 62 ++++++++++++++++++++++++++++++++ sprout/random/shuffle_order.hpp | 40 ++++++++++++++++++++- sprout/random/utility.hpp | 1 + tools/testspr/test.sh | 4 +-- 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 sprout/random/generate_array.hpp diff --git a/sprout/random/generate_array.hpp b/sprout/random/generate_array.hpp new file mode 100644 index 00000000..63aa79a1 --- /dev/null +++ b/sprout/random/generate_array.hpp @@ -0,0 +1,62 @@ +/*============================================================================= + Copyright (c) 2011-2014 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_RANDOM_GENERATE_ARRAY_HPP +#define SPROUT_RANDOM_GENERATE_ARRAY_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // generate_array + // + template + inline SPROUT_CXX14_CONSTEXPR sprout::array + generate_array(URNG& rng) { + sprout::array result{{}}; + for (std::size_t i = 0; i != N; ++i) { + result[i] = rng(); + } + return result; + } + + namespace detail { + template + static SPROUT_CONSTEXPR typename std::enable_if< + (sizeof...(Args) + 1 == N), + sprout::pair, URNG> const + >::type generate_array_impl(Random const& rnd, Args const&... args) { + typedef sprout::pair, URNG> const pair_type; + return pair_type{ + sprout::array{{args..., rnd.result()}}, + rnd.engine() + }; + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + (sizeof...(Args) + 1 < N), + sprout::pair, URNG> const + >::type generate_array_impl(Random const& rnd, Args const&... args) { + return sprout::random::detail::generate_array_impl(rnd(), args..., rnd.result()); + } + } // namespace detail + // + // generate_array + // + template + inline SPROUT_CONSTEXPR sprout::pair, URNG> const + generate_array(URNG const& rng) { + return sprout::random::detail::generate_array_impl(rng()); + } + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_GENERATE_ARRAY_HPP diff --git a/sprout/random/shuffle_order.hpp b/sprout/random/shuffle_order.hpp index 4e0a3054..0d521747 100644 --- a/sprout/random/shuffle_order.hpp +++ b/sprout/random/shuffle_order.hpp @@ -23,8 +23,10 @@ #include #include #include +#include #include #include +#include namespace sprout { namespace random { @@ -77,6 +79,36 @@ namespace sprout { return base_type::static_max(); } private: + template + static SPROUT_CONSTEXPR typename std::enable_if< + (M + sizeof...(Args) == k), + member_type + >::type init_member_4(sprout::index_tuple, sprout::array const& a, Random const& rnd, Args const&... args) { + return member_type{ + rnd.engine(), + sprout::array{{a[Indexes]..., args...}}, + rnd.result() + }; + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + (M + sizeof...(Args) == k), + member_type + >::type init_member_3(sprout::array const& a, Random const& rnd, Args const&... args) { + return init_member_4(sprout::make_index_tuple::make(), a, rnd, args...); + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + (M + sizeof...(Args) < k), + member_type + >::type init_member_3(sprout::array const& a, Random const& rnd, Args const&... args) { + return init_member_3(a, rnd(), args..., rnd.result()); + } + template + static SPROUT_CONSTEXPR member_type init_member_2(Pair const& p) { + return init_member_3(p.first, p.second()); + } + template static SPROUT_CONSTEXPR typename std::enable_if< (sizeof...(Args) == k), @@ -95,9 +127,15 @@ namespace sprout { >::type init_member_1(Random const& rnd, Args const&... args) { return init_member_1(rnd(), args..., rnd.result()); } - static SPROUT_CONSTEXPR member_type init_member(base_type const& rng) { + static SPROUT_CONSTEXPR member_type init_member_0(base_type const& rng, std::true_type) { + return init_member_2(sprout::random::generate_array(rng)); + } + static SPROUT_CONSTEXPR member_type init_member_0(base_type const& rng, std::false_type) { return init_member_1(rng()); } + static SPROUT_CONSTEXPR member_type init_member(base_type const& rng) { + return init_member_0(rng, std::integral_constant= SPROUT_RECURSIVE_FUNCTION_TEMPLATE_INSTANTIATION_LIMIT)>()); + } private: using member_type::rng_; using member_type::v_; diff --git a/sprout/random/utility.hpp b/sprout/random/utility.hpp index 6d0e54e0..1261e58d 100644 --- a/sprout/random/utility.hpp +++ b/sprout/random/utility.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/testspr/test.sh b/tools/testspr/test.sh index 71f3d7be..85ec0106 100755 --- a/tools/testspr/test.sh +++ b/tools/testspr/test.sh @@ -23,8 +23,8 @@ std="c++11" declare -a common_options=() declare -a version_options=() declare -A version_specific_options=( - [clang-3.3]='-ftemplate-depth=512' - [clang-3.4]='-ftemplate-depth=512' +# [clang-3.3]='-ftemplate-depth=512' +# [clang-3.4]='-ftemplate-depth=512' ) test_cpp=$(cd $(dirname $0); pwd)/test.cpp test_py=$(cd $(dirname $0); pwd)/test.py