diff --git a/sprout/stateful.hpp b/sprout/stateful.hpp index fa034f6b..2974168e 100644 --- a/sprout/stateful.hpp +++ b/sprout/stateful.hpp @@ -11,9 +11,9 @@ #include #include #include -#include #include -#include #include +#include +#include #endif // #ifndef SPROUT_STATEFUL_HPP diff --git a/sprout/stateful/slot.hpp b/sprout/stateful/slot.hpp deleted file mode 100644 index d5024518..00000000 --- a/sprout/stateful/slot.hpp +++ /dev/null @@ -1,181 +0,0 @@ -/*============================================================================= - Copyright (c) 2011-2015 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_STATEFUL_SLOT_HPP -#define SPROUT_STATEFUL_SLOT_HPP - -#include -#include -#include -#include - -namespace sprout { -#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR - - namespace slot_detail { -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wnon-template-friend" -#endif -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wundefined-inline" -#endif - template - struct tag { - friend SPROUT_CONSTEXPR int adl_counter(sprout::slot_detail::tag); - friend SPROUT_CONSTEXPR int adl_key(sprout::slot_detail::tag); - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::slot_detail::tag); - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::slot_detail::tag, sprout::integral_constant); - }; -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif - - template - struct state - : public sprout::integral_constant - { - friend SPROUT_CONSTEXPR int adl_counter(sprout::slot_detail::tag) { - return N; - } - friend SPROUT_CONSTEXPR int adl_key(sprout::slot_detail::tag) { - return Key; - } - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::slot_detail::tag) { - return Value; - } - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::slot_detail::tag, sprout::integral_constant) { - return get(); - } - template - static SPROUT_CONSTEXPR std::intmax_t get() { - return K == Key ? Value - : state< - N - 1, - adl_key(sprout::slot_detail::tag()), - adl_value(sprout::slot_detail::tag()) - >::template get() - ; - } - }; - template - struct state<0, Key, Value> - : public sprout::integral_constant - { - friend SPROUT_CONSTEXPR int adl_counter(sprout::slot_detail::tag<0>) { - return 0; - } - friend SPROUT_CONSTEXPR int adl_key(sprout::slot_detail::tag<0>) { - return Key; - } - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::slot_detail::tag<0>) { - return Value; - } - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::slot_detail::tag<0>, sprout::integral_constant) { - return get(); - } - template - static SPROUT_CONSTEXPR std::intmax_t get() { - return SPROUT_ASSERT(K == Key), Value; - } - }; - - template())> - SPROUT_CONSTEXPR bool check(int, sprout::slot_detail::tag) { - return true; - } - template - SPROUT_CONSTEXPR bool check(long, sprout::slot_detail::tag) { - return false; - } - template - SPROUT_CONSTEXPR bool check(bool R = sprout::slot_detail::check(0, sprout::slot_detail::tag())) { - return R; - } - - template - SPROUT_CONSTEXPR int counter(sprout::false_type, sprout::slot_detail::tag) { - return 0; - } - template - SPROUT_CONSTEXPR int counter( - sprout::true_type, sprout::slot_detail::tag, - int R = !sprout::slot_detail::check(0, sprout::slot_detail::tag()) ? N - : counter(sprout::bool_constant())>(), sprout::slot_detail::tag()) - ) - { - return R; - } - template - SPROUT_CONSTEXPR int counter(int R = sprout::slot_detail::counter(sprout::true_type(), sprout::slot_detail::tag())) { - return R; - } - - template - SPROUT_CONSTEXPR std::intmax_t get_impl(sprout::false_type, sprout::slot_detail::tag) { - return 0; - } - template - SPROUT_CONSTEXPR std::intmax_t get_impl( - sprout::true_type, sprout::slot_detail::tag, - std::intmax_t R = !sprout::slot_detail::check() ? adl_get(sprout::slot_detail::tag(), sprout::integral_constant()) - : get_impl(sprout::bool_constant()>(), sprout::slot_detail::tag()) - ) - { - return R; - } - template - SPROUT_CONSTEXPR std::intmax_t get(int R = sprout::slot_detail::get_impl(sprout::true_type(), sprout::slot_detail::tag())) { - return R; - } - } // namespace slot_detail - // - // slot - // - template< - int K, - std::intmax_t R = sprout::slot_detail::get() - > - SPROUT_CONSTEXPR std::intmax_t slot() { - return R; - } - // - // assign_slot - // assign_slot_return - // - template< - int K, std::intmax_t Value, - int N = 0, - std::intmax_t = sprout::slot_detail::state< - sprout::slot_detail::counter(sprout::true_type(), sprout::slot_detail::tag()), - K, Value - >::value - > - SPROUT_CXX14_CONSTEXPR void assign_slot() {} - template< - int K, std::intmax_t Value, - int N = 0, - std::intmax_t R = sprout::slot_detail::state< - sprout::slot_detail::counter(sprout::true_type(), sprout::slot_detail::tag()), - K, Value - >::value - > - SPROUT_CONSTEXPR std::intmax_t assign_slot_return() { - return R; - } - -#endif -} // namespace sprout - -#endif // #ifndef SPROUT_STATEFUL_SLOT_HPP diff --git a/sprout/stateful/typed_rand.hpp b/sprout/stateful/typed_rand.hpp new file mode 100644 index 00000000..084ea77d --- /dev/null +++ b/sprout/stateful/typed_rand.hpp @@ -0,0 +1,213 @@ +/*============================================================================= + Copyright (c) 2011-2015 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_STATEFUL_TYPED_RAND_HPP +#define SPROUT_STATEFUL_TYPED_RAND_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { +#ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR + + namespace typed_rand_detail { + template + struct typed { +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnon-template-friend" +#endif +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wundefined-inline" +#endif + template + struct tag { + friend SPROUT_CONSTEXPR int adl_counter(tag); + friend SPROUT_CONSTEXPR bool adl_is_srand(tag); + friend SPROUT_CONSTEXPR unsigned adl_seed(tag); + }; +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif + + template + struct state { + friend SPROUT_CONSTEXPR int adl_counter(tag) { + return N; + } + friend SPROUT_CONSTEXPR bool adl_is_srand(tag) { + return IsSrand; + } + friend SPROUT_CONSTEXPR unsigned adl_seed(tag) { + return Seed; + } + // generate a next random number + SPROUT_STATIC_CONSTEXPR sprout::detail::rand_result_type result + SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(( + !IsSrand + ? state< + N - 1, + adl_is_srand(tag()), + adl_seed(tag()) + >::result() + : sprout::detail::rand_result_type( + Seed, + sprout::detail::rand_generator_type(Seed), + sprout::detail::rand_distribution_type(0, RAND_MAX) + ) + )) + ; + SPROUT_STATIC_CONSTEXPR int value = result; + }; + template + struct state<0, IsSrand, Seed> { + friend SPROUT_CONSTEXPR int adl_counter(tag<0>) { + return 0; + } + friend SPROUT_CONSTEXPR bool adl_is_srand(tag<0>) { + return IsSrand; + } + friend SPROUT_CONSTEXPR unsigned adl_seed(tag<0>) { + return Seed; + } + // generate a first random number between [0, RAND_MAX] + SPROUT_STATIC_CONSTEXPR sprout::detail::rand_result_type result + SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_INNER(( + !IsSrand + ? sprout::detail::rand_distribution_type(0, RAND_MAX) + (sprout::as_const(sprout::detail::rand_generator_type(!IsSrand ? sprout::detail::rand_default_seed : Seed))) + : sprout::detail::rand_result_type( + Seed, + sprout::detail::rand_generator_type(Seed), + sprout::detail::rand_distribution_type(0, RAND_MAX) + ) + )) + ; + static SPROUT_CONSTEXPR int value = result; + }; + + template())> + static SPROUT_CONSTEXPR bool check(int, tag) { + return true; + } + template + static SPROUT_CONSTEXPR bool check(long, tag) { + return false; + } + template + static SPROUT_CONSTEXPR bool check(bool R = check(0, tag())) { + return R; + } + + template + static SPROUT_CONSTEXPR int counter(sprout::false_type, tag) { + return 0; + } + template + static SPROUT_CONSTEXPR int counter( + sprout::true_type, tag, + int R = !check() ? N + : counter(sprout::bool_constant()>(), tag()) + ) + { + return R; + } + template + static SPROUT_CONSTEXPR int counter(int R = counter(sprout::true_type(), tag())) { + return R; + } + }; + template + template + SPROUT_CONSTEXPR_OR_CONST sprout::detail::rand_result_type sprout::typed_rand_detail::typed::state::result + SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER(( + !IsSrand + ? state< + N - 1, + adl_is_srand(tag()), + adl_seed(tag()) + >::result() + : sprout::detail::rand_result_type( + 0, + sprout::detail::rand_generator_type(Seed), + sprout::detail::rand_distribution_type(0, RAND_MAX) + ) + )) + ; + template + template + SPROUT_CONSTEXPR_OR_CONST int sprout::typed_rand_detail::typed::state::value; + + template + template + SPROUT_CONSTEXPR_OR_CONST sprout::detail::rand_result_type sprout::typed_rand_detail::typed::state<0, IsSrand, Seed>::result + SPROUT_STATIC_CONSTEXPR_DATA_MEMBER_OUTER( + !IsSrand + ? sprout::detail::rand_distribution_type(0, RAND_MAX) + (sprout::as_const(sprout::detail::rand_generator_type(!IsSrand ? sprout::detail::rand_default_seed : Seed))) + : sprout::detail::rand_result_type( + Seed, + sprout::detail::rand_generator_type(Seed), + sprout::detail::rand_distribution_type(0, RAND_MAX) + ) + ) + ; + template + template + SPROUT_CONSTEXPR_OR_CONST int sprout::typed_rand_detail::typed::state<0, IsSrand, Seed>::value; + } // namespace typed_rand_detail + // + // rand + // + template< + typename T, + int N = 1, + int R = sprout::typed_rand_detail::typed::template state< + sprout::typed_rand_detail::typed::template counter(sprout::true_type(), typename sprout::typed_rand_detail::typed::template tag()) + N - 1 + >::value + > + SPROUT_CONSTEXPR int rand() { + return R; + } + + // + // srand + // srand_return + // + template< + typename T, unsigned Seed, + int N = 1, + int = sprout::typed_rand_detail::typed::template state< + sprout::typed_rand_detail::typed::template counter(sprout::true_type(), typename sprout::typed_rand_detail::typed::template tag()) + N - 1, + true, Seed + >::value + > + SPROUT_CXX14_CONSTEXPR void srand() {} + template< + typename T, unsigned Seed, + int N = 1, + int R = sprout::typed_rand_detail::typed::template state< + sprout::typed_rand_detail::typed::template counter(sprout::true_type(), typename sprout::typed_rand_detail::typed::template tag()) + N - 1, + true, Seed + >::value + > + SPROUT_CONSTEXPR unsigned srand_return() { + return R; + } + +#endif +} // namespace sprout + +#endif // #ifndef SPROUT_STATEFUL_TYPED_RAND_HPP diff --git a/sprout/stateful/typed_slot.hpp b/sprout/stateful/typed_slot.hpp index a6746427..77c8f85b 100644 --- a/sprout/stateful/typed_slot.hpp +++ b/sprout/stateful/typed_slot.hpp @@ -11,13 +11,13 @@ #include #include #include -#include -#include namespace sprout { #ifndef SPROUT_CONFIG_DISABLE_CONSTEXPR namespace typed_slot_detail { + template + struct typed { #if defined(__GNUC__) && !defined(__clang__) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wnon-template-friend" @@ -26,14 +26,11 @@ namespace sprout { # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wundefined-inline" #endif - template - struct tag { - friend SPROUT_CONSTEXPR int adl_counter(sprout::typed_slot_detail::tag); - friend SPROUT_CONSTEXPR int adl_key(sprout::typed_slot_detail::tag); - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::typed_slot_detail::tag); - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::typed_slot_detail::tag, sprout::integral_constant); - }; + template + struct tag { + friend SPROUT_CONSTEXPR int adl_counter(tag); + friend SPROUT_CONSTEXPR std::intmax_t adl_value(tag); + }; #if defined(__clang__) # pragma clang diagnostic pop #endif @@ -41,135 +38,99 @@ namespace sprout { # pragma GCC diagnostic pop #endif - template - struct state - : public sprout::integral_constant - { - friend SPROUT_CONSTEXPR int adl_counter(sprout::typed_slot_detail::tag) { - return N; + template + struct state + : public sprout::integral_constant + { + friend SPROUT_CONSTEXPR int adl_counter(tag) { + return N; + } + friend SPROUT_CONSTEXPR std::intmax_t adl_value(tag) { + return Value; + } + }; + + template())> + static SPROUT_CONSTEXPR bool check(int, tag) { + return true; } - friend SPROUT_CONSTEXPR int adl_key(sprout::typed_slot_detail::tag) { - return Key; + template + static SPROUT_CONSTEXPR bool check(long, tag) { + return false; } - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::typed_slot_detail::tag) { - return Value; + template + static SPROUT_CONSTEXPR bool check(bool R = check(0, tag())) { + return R; } - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::typed_slot_detail::tag, sprout::integral_constant) { - return get(); - } - template - static SPROUT_CONSTEXPR std::intmax_t get() { - return K == Key ? Value - : state< - N - 1, - adl_key(sprout::typed_slot_detail::tag()), - adl_value(sprout::typed_slot_detail::tag()) - >::template get() - ; - } - }; - template - struct state<0, Key, Value> - : public sprout::integral_constant - { - friend SPROUT_CONSTEXPR int adl_counter(sprout::typed_slot_detail::tag<0>) { + + template + static SPROUT_CONSTEXPR int counter(sprout::false_type, tag) { return 0; } - friend SPROUT_CONSTEXPR int adl_key(sprout::typed_slot_detail::tag<0>) { - return Key; + template + static SPROUT_CONSTEXPR int counter( + sprout::true_type, tag, + int R = !check() ? N + : counter(sprout::bool_constant()>(), tag()) + ) + { + return R; } - friend SPROUT_CONSTEXPR std::intmax_t adl_value(sprout::typed_slot_detail::tag<0>) { - return Value; + template + static SPROUT_CONSTEXPR int counter(int R = counter(sprout::true_type(), tag())) { + return R; } - template - friend SPROUT_CONSTEXPR std::intmax_t adl_get(sprout::typed_slot_detail::tag<0>, sprout::integral_constant) { - return get(); + + template + static SPROUT_CONSTEXPR std::intmax_t val(sprout::false_type, tag) { + return 0; } - template - static SPROUT_CONSTEXPR std::intmax_t get() { - return SPROUT_ASSERT(K == Key), Value; + template + static SPROUT_CONSTEXPR std::intmax_t val( + sprout::true_type, tag, + std::intmax_t R = !check() ? adl_value(tag()) + : val(sprout::bool_constant()>(), tag()) + ) + { + return R; + } + template + static SPROUT_CONSTEXPR std::intmax_t val(std::intmax_t R = val(sprout::true_type(), tag())) { + return R; } }; - - template())> - SPROUT_CONSTEXPR bool check(int, sprout::typed_slot_detail::tag) { - return true; - } - template - SPROUT_CONSTEXPR bool check(long, sprout::typed_slot_detail::tag) { - return false; - } - template - SPROUT_CONSTEXPR bool check(bool R = sprout::typed_slot_detail::check(0, sprout::typed_slot_detail::tag())) { - return R; - } - - template - SPROUT_CONSTEXPR int counter(sprout::false_type, sprout::typed_slot_detail::tag) { - return 0; - } - template - SPROUT_CONSTEXPR int counter( - sprout::true_type, sprout::typed_slot_detail::tag, - int R = !sprout::typed_slot_detail::check(0, sprout::typed_slot_detail::tag()) ? N - : counter(sprout::bool_constant())>(), sprout::typed_slot_detail::tag()) - ) - { - return R; - } - template - SPROUT_CONSTEXPR int counter(int R = sprout::typed_slot_detail::counter(sprout::true_type(), sprout::typed_slot_detail::tag())) { - return R; - } - - template - SPROUT_CONSTEXPR std::intmax_t get_impl(sprout::false_type, sprout::typed_slot_detail::tag) { - return 0; - } - template - SPROUT_CONSTEXPR std::intmax_t get_impl( - sprout::true_type, sprout::typed_slot_detail::tag, - std::intmax_t R = !sprout::typed_slot_detail::check(0, sprout::typed_slot_detail::tag()) ? adl_get(sprout::typed_slot_detail::tag(), sprout::integral_constant()) - : get_impl(sprout::bool_constant())>(), sprout::typed_slot_detail::tag()) - ) - { - return R; - } - template - SPROUT_CONSTEXPR std::intmax_t get(int R = sprout::typed_slot_detail::get_impl(sprout::true_type(), sprout::typed_slot_detail::tag())) { - return R; - } } // namespace typed_slot_detail // // slot // template< typename T, - std::intmax_t R = sprout::typed_slot_detail::get::value>() + int N = 1, + std::intmax_t R = sprout::typed_slot_detail::typed::template val(sprout::true_type(), typename sprout::typed_slot_detail::typed::template tag()) > SPROUT_CONSTEXPR std::intmax_t slot() { return R; } + // // assign_slot // assign_slot_return // template< typename T, std::intmax_t Value, - int N = 0, - std::intmax_t = sprout::typed_slot_detail::state< - sprout::typed_slot_detail::counter(sprout::true_type(), sprout::typed_slot_detail::tag()), - sprout::typed_id::value, Value + int N = 1, + std::intmax_t = sprout::typed_slot_detail::typed::template state< + sprout::typed_slot_detail::typed::template counter(sprout::true_type(), typename sprout::typed_slot_detail::typed::template tag()) + N - 1, + Value >::value > SPROUT_CXX14_CONSTEXPR void assign_slot() {} template< typename T, std::intmax_t Value, - int N = 0, - std::intmax_t R = sprout::typed_slot_detail::state< - sprout::typed_slot_detail::counter(sprout::true_type(), sprout::typed_slot_detail::tag()), - sprout::typed_id::value, Value + int N = 1, + std::intmax_t R = sprout::typed_slot_detail::typed::template state< + sprout::typed_slot_detail::typed::template counter(sprout::true_type(), typename sprout::typed_slot_detail::typed::template tag()) + N - 1, + Value >::value > SPROUT_CONSTEXPR std::intmax_t assign_slot_return() {