Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:04:17

0001 //
0002 // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_COBALT_RACE_HPP
0009 #define BOOST_COBALT_RACE_HPP
0010 
0011 #include <boost/cobalt/concepts.hpp>
0012 #include <boost/cobalt/detail/race.hpp>
0013 #include <boost/cobalt/detail/wrapper.hpp>
0014 #include <random>
0015 
0016 namespace boost::cobalt
0017 {
0018 
0019 namespace detail
0020 {
0021 
0022 inline std::default_random_engine &prng()
0023 {
0024   thread_local static std::default_random_engine g(std::random_device{}());
0025   return g;
0026 }
0027 
0028 }
0029 // tag::concept[]
0030 template<typename G>
0031   concept uniform_random_bit_generator =
0032     requires ( G & g)
0033     {
0034       {typename std::decay_t<G>::result_type() } -> std::unsigned_integral; // is an unsigned integer type
0035       // T  Returns the smallest value that G's operator() may return. The value is strictly less than G::max(). The function must be constexpr.
0036       {std::decay_t<G>::min()} -> std::same_as<typename std::decay_t<G>::result_type>;
0037       // T  Returns the largest value that G's operator() may return. The value is strictly greater than G::min(). The function must be constexpr.
0038       {std::decay_t<G>::max()} -> std::same_as<typename std::decay_t<G>::result_type>;
0039       {g()} -> std::same_as<typename std::decay_t<G>::result_type>;
0040     } && (std::decay_t<G>::max() > std::decay_t<G>::min());
0041 
0042 // end::concept[]
0043 
0044 
0045 template<asio::cancellation_type Ct = asio::cancellation_type::all,
0046     uniform_random_bit_generator URBG,
0047     awaitable<detail::fork::promise_type> ... Promise>
0048 auto race(URBG && g, Promise && ... p) -> detail::race_variadic_impl<Ct, URBG, Promise ...>
0049 {
0050   return detail::race_variadic_impl<Ct, URBG, Promise ...>(std::forward<URBG>(g), static_cast<Promise&&>(p)...);
0051 }
0052 
0053 
0054 template<asio::cancellation_type Ct = asio::cancellation_type::all,
0055     uniform_random_bit_generator URBG,
0056     typename PromiseRange>
0057 requires awaitable<std::decay_t<decltype(*std::declval<PromiseRange>().begin())>,
0058     detail::fork::promise_type>
0059 auto race(URBG && g, PromiseRange && p) -> detail::race_ranged_impl<Ct, URBG, PromiseRange>
0060 {
0061   if (std::empty(p))
0062     throw_exception(std::invalid_argument("empty range raceed"));
0063 
0064   return detail::race_ranged_impl<Ct, URBG, PromiseRange>{std::forward<URBG>(g), static_cast<PromiseRange&&>(p)};
0065 }
0066 
0067 template<asio::cancellation_type Ct = asio::cancellation_type::all,
0068          awaitable<detail::fork::promise_type> ... Promise>
0069 auto race(Promise && ... p) -> detail::race_variadic_impl<Ct, std::default_random_engine&, Promise ...>
0070 {
0071   return race<Ct>(detail::prng(), static_cast<Promise&&>(p)...);
0072 }
0073 
0074 
0075 template<asio::cancellation_type Ct = asio::cancellation_type::all, typename PromiseRange>
0076   requires awaitable<std::decay_t<decltype(*std::declval<PromiseRange>().begin())>,
0077       detail::fork::promise_type>
0078 auto race(PromiseRange && p) -> detail::race_ranged_impl<Ct, std::default_random_engine&, PromiseRange>
0079 {
0080   if (std::empty(p))
0081     throw_exception(std::invalid_argument("empty range raceed"));
0082 
0083   return race<Ct>(detail::prng(), static_cast<PromiseRange&&>(p));
0084 }
0085 
0086 template<asio::cancellation_type Ct = asio::cancellation_type::all,
0087     awaitable<detail::fork::promise_type> ... Promise>
0088 auto left_race(Promise && ... p) -> detail::race_variadic_impl<Ct, detail::left_race_tag, Promise ...>
0089 {
0090   return detail::race_variadic_impl<Ct, detail::left_race_tag, Promise ...>(
0091       detail::left_race_tag{}, static_cast<Promise&&>(p)...);
0092 }
0093 
0094 
0095 template<asio::cancellation_type Ct = asio::cancellation_type::all, typename PromiseRange>
0096 requires awaitable<std::decay_t<decltype(*std::declval<PromiseRange>().begin())>,
0097     detail::fork::promise_type>
0098 auto left_race(PromiseRange && p)  -> detail::race_ranged_impl<Ct, detail::left_race_tag, PromiseRange>
0099 {
0100   if (std::empty(p))
0101     throw_exception(std::invalid_argument("empty range left_raceed"));
0102 
0103   return detail::race_ranged_impl<Ct, detail::left_race_tag, PromiseRange>{
0104       detail::left_race_tag{}, static_cast<PromiseRange&&>(p)};
0105 }
0106 
0107 
0108 
0109 
0110 }
0111 
0112 #endif //BOOST_COBALT_RACE_HPP