mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
workaroud for clang3.2 (inversive_congruential)
This commit is contained in:
parent
d39f4abe0f
commit
b9121b8850
4 changed files with 94 additions and 12 deletions
|
@ -72,13 +72,6 @@ namespace sprout {
|
||||||
: r
|
: r
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
template<typename Container>
|
|
||||||
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
|
|
||||||
swap_lr(
|
|
||||||
Container const& cont,
|
|
||||||
typename sprout::container_traits<Container>::difference_type l,
|
|
||||||
typename sprout::container_traits<Container>::difference_type r
|
|
||||||
);
|
|
||||||
template<typename Container, typename Compare>
|
template<typename Container, typename Compare>
|
||||||
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
|
inline SPROUT_CONSTEXPR typename sprout::fixed::result_of::algorithm<Container>::type
|
||||||
sort_part_l(
|
sort_part_l(
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||||
|
# include <sprout/workaround/recursive_function_template.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace random {
|
namespace random {
|
||||||
|
@ -51,6 +54,84 @@ namespace sprout {
|
||||||
static SPROUT_CONSTEXPR unsigned_type unsigned_m() {
|
static SPROUT_CONSTEXPR unsigned_type unsigned_m() {
|
||||||
return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m);
|
return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m);
|
||||||
}
|
}
|
||||||
|
#ifdef SPROUT_WORKAROUND_NOT_TERMINATE_RECURSIVE_CONSTEXPR_FUNCTION_TEMPLATE
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
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<D + 1>(c, l1, l2, n, p);
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||||
|
return p == 0 ? l2 : invert_euclidian_3<D + 1>(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||||
|
return invert_euclidian_2<D + 1>(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D = 16, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) {
|
||||||
|
return c > 0
|
||||||
|
? c == 1 ? 1 : invert_euclidian_1<D + 1>(c, 0, 1, c, m)
|
||||||
|
: throw std::domain_error("const_mod<>: domain error (c > 0)")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<int D = 16, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) {
|
||||||
|
return sprout::throw_recursive_function_template_instantiation_exeeded();
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
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<D + 1>(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||||
|
return p == 0 ? l2 : invert_euclidian0_3<D + 1>(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||||
|
return std::numeric_limits<IntType>::max() % n != n - 1
|
||||||
|
? invert_euclidian0_2<D + 1>(
|
||||||
|
c, l1 + (std::numeric_limits<IntType>::max() / n) * l2, l2, n,
|
||||||
|
std::numeric_limits<IntType>::max() - (std::numeric_limits<IntType>::max() / n) * n + 1
|
||||||
|
)
|
||||||
|
: throw std::domain_error("const_mod<>: domain error (numeric_limits<IntType>::max() % n != n - 1)")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<int D, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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<int D = 16, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_CONTINUE(D)>
|
||||||
|
static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) {
|
||||||
|
return c > 0
|
||||||
|
? c == 1 ? 1 : invert_euclidian0_1<D + 1>(c, 0, 1, c, m)
|
||||||
|
: throw std::domain_error("const_mod<>: domain error (c > 0)")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
template<int D = 16, SPROUT_RECURSIVE_FUNCTION_TEMPLATE_BREAK(D)>
|
||||||
|
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) {
|
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);
|
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) {
|
static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||||
return std::numeric_limits<IntType>::max() % n != n - 1
|
return std::numeric_limits<IntType>::max() % n != n - 1
|
||||||
? invert_euclidian0_2(c, l1 + (std::numeric_limits<IntType>::max() / n) * l2, l2, n, std::numeric_limits<IntType>::max() - (std::numeric_limits<IntType>::max() / n) * n + 1)
|
? invert_euclidian0_2(
|
||||||
|
c, l1 + (std::numeric_limits<IntType>::max() / n) * l2, l2, n,
|
||||||
|
std::numeric_limits<IntType>::max() - (std::numeric_limits<IntType>::max() / n) * n + 1
|
||||||
|
)
|
||||||
: throw std::domain_error("const_mod<>: domain error (numeric_limits<IntType>::max() % n != n - 1)")
|
: throw std::domain_error("const_mod<>: domain error (numeric_limits<IntType>::max() % n != n - 1)")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +168,7 @@ namespace sprout {
|
||||||
: throw std::domain_error("const_mod<>: domain error (c > 0)")
|
: throw std::domain_error("const_mod<>: domain error (c > 0)")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
static SPROUT_CONSTEXPR IntType apply(IntType x) {
|
static SPROUT_CONSTEXPR IntType apply(IntType x) {
|
||||||
return ((unsigned_m() - 1) & unsigned_m()) == 0
|
return ((unsigned_m() - 1) & unsigned_m()) == 0
|
||||||
|
|
|
@ -58,7 +58,8 @@ namespace sprout {
|
||||||
SPROUT_CONSTEXPR inversive_congruential_engine(IntType const& x, private_constructor_tag)
|
SPROUT_CONSTEXPR inversive_congruential_engine(IntType const& x, private_constructor_tag)
|
||||||
: x_(x)
|
: x_(x)
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<inversive_congruential_engine> generate(result_type result) const {
|
SPROUT_CONSTEXPR sprout::random::random_result<inversive_congruential_engine>
|
||||||
|
generate(result_type result) const {
|
||||||
return sprout::random::random_result<inversive_congruential_engine>(
|
return sprout::random::random_result<inversive_congruential_engine>(
|
||||||
result,
|
result,
|
||||||
inversive_congruential_engine(result, private_constructor_tag())
|
inversive_congruential_engine(result, private_constructor_tag())
|
||||||
|
|
|
@ -85,7 +85,8 @@ namespace sprout {
|
||||||
: member_type{rng, v, y}
|
: member_type{rng, v, y}
|
||||||
{}
|
{}
|
||||||
template<typename Random, typename BaseUnsigned>
|
template<typename Random, typename BaseUnsigned>
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine> generate_1(Random const& rnd, BaseUnsigned j) const {
|
SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine>
|
||||||
|
generate_1(Random const& rnd, BaseUnsigned j) const {
|
||||||
return sprout::random::random_result<shuffle_order_engine>(
|
return sprout::random::random_result<shuffle_order_engine>(
|
||||||
v_[j],
|
v_[j],
|
||||||
shuffle_order_engine(
|
shuffle_order_engine(
|
||||||
|
@ -97,12 +98,14 @@ namespace sprout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
template<typename BaseUnsigned>
|
template<typename BaseUnsigned>
|
||||||
SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine> generate(BaseUnsigned brange, BaseUnsigned off) const {
|
SPROUT_CONSTEXPR sprout::random::random_result<shuffle_order_engine>
|
||||||
|
generate(BaseUnsigned brange, BaseUnsigned off) const {
|
||||||
return generate_1(
|
return generate_1(
|
||||||
rng_(),
|
rng_(),
|
||||||
k == 1 ? BaseUnsigned(0)
|
k == 1 ? BaseUnsigned(0)
|
||||||
: brange < std::numeric_limits<BaseUnsigned>::max() / k ? BaseUnsigned(k * off / (brange + 1))
|
: brange < std::numeric_limits<BaseUnsigned>::max() / k ? BaseUnsigned(k * off / (brange + 1))
|
||||||
: brange < std::numeric_limits<std::uintmax_t>::max() / k ? static_cast<BaseUnsigned>(static_cast<std::uintmax_t>(off) * k / (static_cast<std::uintmax_t>(brange) + 1))
|
: brange < std::numeric_limits<std::uintmax_t>::max() / k
|
||||||
|
? static_cast<BaseUnsigned>(static_cast<std::uintmax_t>(off) * k / (static_cast<std::uintmax_t>(brange) + 1))
|
||||||
//: static_cast<BaseUnsigned>(sprout::random::detail::muldiv(off, k, static_cast<std::uintmax_t>(brange) + 1)) // ???
|
//: static_cast<BaseUnsigned>(sprout::random::detail::muldiv(off, k, static_cast<std::uintmax_t>(brange) + 1)) // ???
|
||||||
: throw std::domain_error("shuffle_order_engine<>: Sorry, not implemented.")
|
: throw std::domain_error("shuffle_order_engine<>: Sorry, not implemented.")
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue