ã®ç¶ãã§ããã³ã³ãã¤ã«æã«ãºã³ãã³ãã¨ã·ããã£ã¦ã¿ã¾ããã static_assert
ã§ãã¡ããã¨ã·ã¼ã±ã³ã¹ã®æå¾ã®5ã¤ããºã³ãºã³ãºã³ãºã³ãã³ã«ãªã£ã¦ããããæ¤è¨¼ãã¦ãã¾ããSprout.Randomã¨Boost.MPLã使ç¨ãã¦ãã¾ããåèã«ããè¨äºã¯ä»¥ä¸ã«ãªãã¾ããSprout.Randomã®ä½¿ãæ¹ã¨ãcall_nãåèã«ãã¾ããã
Sprout.Random - コンパイル時の乱数生成 - ボレロ村上 - ENiyGmaA Code
http://d.hatena.ne.jp/osyo-manga/20130413/1365860245
The MPL Reference Manual - 1.60.0
#include <iostream> #include <type_traits> #include <boost/mpl/advance.hpp> #include <boost/mpl/begin_end.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/for_each.hpp> #include <boost/mpl/iterator_range.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/vector.hpp> #include <sprout/random.hpp> namespace mpl = boost::mpl; constexpr std::size_t seed = SPROUT_UNIQUE_SEED; constexpr auto engine = sprout::random::minstd_rand0(seed); constexpr auto dist = sprout::random::uniform_smallint<int>(0, 1); template <typename Gen> constexpr int call_n(Gen&& gen, int index) { return index <= 0 ? *gen : call_n(gen(), index - 1); } struct Zun { static constexpr char const* value = "ãºã³"; }; struct Doko { static constexpr char const* value = "ãã³"; }; template <typename Seq, int N> struct push_back_zundoko; template <typename Seq> struct push_back_zundoko<Seq, 0> { using type = typename mpl::push_back<Seq, Zun>::type; }; template <typename Seq> struct push_back_zundoko<Seq, 1> { using type = typename mpl::push_back<Seq, Doko>::type; }; template <typename Seq, bool EnoughSize> struct is_zundoko_impl { using first = typename mpl::advance_c<typename mpl::end<Seq>::type, -5>::type; using last = typename mpl::end<Seq>::type; using range = mpl::iterator_range<first, last>; using type = typename mpl::equal<range, mpl::vector<Zun, Zun, Zun, Zun, Doko>>::type; }; template <typename Seq> struct is_zundoko_impl<Seq, false> { using type = mpl::false_; }; template <typename Seq> struct is_zundoko { using type = typename is_zundoko_impl<Seq, mpl::size<Seq>::type::value >= 5>::type; }; template <typename Seq, int N, typename Completion> struct zundoko_impl { using next_seq = typename push_back_zundoko<Seq, call_n(dist(engine), N)>::type; using completion = typename is_zundoko<next_seq>::type; using type = typename zundoko_impl<next_seq, N + 1, completion>::type; }; template <typename Seq, int N> struct zundoko_impl<Seq, N, mpl::true_> { using type = Seq; }; struct zundoko { using type = zundoko_impl<mpl::vector<>, 0, mpl::false_>::type; }; int main() { using zundoko_type = zundoko::type; static_assert(is_zundoko<zundoko_type>::type::value, ""); mpl::for_each<zundoko_type>([](auto const& item) { std::cout << std::remove_reference<decltype(item)>::type::value; }); std::cout << "ãã»ã¨ã»ã·ï¼" << std::endl; }
å®è¡çµæä¾(ã³ã³ãã¤ã«æã«ä¹±æ°åçæãçµãã£ã¦ããã®ã§ãã³ã³ãã¤ã«ãç´ããªãéããä½åº¦ãã£ã¦ãåãçµæã«ãªãã¾ã)
clang++3.4以ä¸,g++4.9.0以ä¸ã§åä½ãã¾ããMSVCã¯14.0ã§ãconstexprã®ãµãã¼ããå¼±ãããåãã¾ãã
追è¨
ã³ã¼ããªãã¡ã¯ã¿ãªã³ã°ãã¾ãã
#include <iostream> #include <boost/mpl/advance.hpp> #include <boost/mpl/begin_end.hpp> #include <boost/mpl/equal.hpp> #include <boost/mpl/eval_if.hpp> #include <boost/mpl/for_each.hpp> #include <boost/mpl/iterator_range.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/size.hpp> #include <boost/mpl/vector.hpp> #include <sprout/random.hpp> namespace mpl = boost::mpl; constexpr std::size_t seed = SPROUT_UNIQUE_SEED; constexpr auto engine = sprout::random::minstd_rand0(seed); constexpr auto dist = sprout::random::uniform_smallint<int>(0, 1); template <typename Gen> constexpr int call_n(Gen&& gen, int index) { return index <= 0 ? *gen : call_n(gen(), index - 1); } template <typename Seq> using end_t = typename mpl::end<Seq>::type; template <typename Iter, int N> using advance_c_t = typename mpl::advance_c<Iter, N>::type; template <typename Seq1, typename Seq2> using equal_t = typename mpl::equal<Seq1, Seq2>::type; struct zun { char const* value = "ãºã³"; }; struct doko { char const* value = "ãã³"; }; template <typename Seq, int N> struct push_back_zundoko : public mpl::eval_if_c<N == 0, mpl::push_back<Seq, zun>, mpl::push_back<Seq, doko> >::type {}; template <typename Seq, int N> using push_back_zundoko_t = typename push_back_zundoko<Seq, N>::type; template <typename Seq, bool EnoughSize, typename First> struct is_zundoko_impl : public equal_t< mpl::iterator_range<First, end_t<Seq>>, mpl::vector<zun, zun, zun, zun, doko> > {}; template <typename Seq, typename First> struct is_zundoko_impl<Seq, false, First> : public mpl::false_ {}; template <typename Seq> struct is_zundoko : public is_zundoko_impl<Seq, mpl::size<Seq>::type::value >= 5, advance_c_t<end_t<Seq>, -5> > {}; template <typename Seq> using is_zundoko_t = typename is_zundoko<Seq>::type; template <typename Seq, int N, typename Completion> struct zundoko_impl { private: using next_seq = push_back_zundoko_t<Seq, call_n(dist(engine), N)>; using completion = is_zundoko_t<next_seq>; public: using type = typename zundoko_impl<next_seq, N + 1, completion>::type; }; template <typename Seq, int N> struct zundoko_impl<Seq, N, mpl::true_> { using type = Seq; }; using zundoko = zundoko_impl<mpl::vector<>, 0, mpl::false_>::type; int main() { static_assert(is_zundoko<zundoko>::type::value, ""); mpl::for_each<zundoko>([](auto const& item) { std::cout << item.value; }); std::cout << "ãã»ã¨ã»ã·ï¼" << std::endl; }