Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:25

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_COBALT_UTIL_HPP
0006 #define BOOST_COBALT_UTIL_HPP
0007 
0008 #include <boost/cobalt/config.hpp>
0009 #include <boost/cobalt/this_thread.hpp>
0010 
0011 #include <boost/core/no_exceptions_support.hpp>
0012 #include <boost/system/result.hpp>
0013 #include <boost/variant2/variant.hpp>
0014 
0015 #include <limits>
0016 #include <type_traits>
0017 #include <coroutine>
0018 
0019 namespace boost::variant2
0020 {
0021 struct monostate;
0022 }
0023 
0024 namespace boost::cobalt::detail
0025 {
0026 
0027 template<typename T>
0028 constexpr std::size_t variadic_first(std::size_t = 0u)
0029 {
0030     return std::numeric_limits<std::size_t>::max();
0031 }
0032 
0033 
0034 template<typename T, typename First, typename ... Args>
0035 constexpr std::size_t variadic_first(std::size_t pos = 0u)
0036 {
0037     if constexpr (std::is_same_v<std::decay_t<First>, T>)
0038         return pos;
0039     else
0040         return variadic_first<T, Args...>(pos+1);
0041 }
0042 
0043 
0044 template<typename T, typename ... Args>
0045 constexpr bool variadic_has = variadic_first<T, Args...>() < sizeof...(Args);
0046 
0047 template<std::size_t Idx, typename First, typename ... Args>
0048     requires (Idx <= sizeof...(Args))
0049 constexpr decltype(auto) get_variadic(First && first, Args  && ... args)
0050 {
0051     if constexpr (Idx == 0u)
0052         return static_cast<First>(first);
0053     else
0054         return get_variadic<Idx-1u>(static_cast<Args>(args)...);
0055 }
0056 
0057 template<std::size_t Idx, typename ... Args>
0058 struct variadic_element;
0059 
0060 template<std::size_t Idx, typename First, typename ...Tail>
0061 struct variadic_element<Idx, First, Tail...>
0062 {
0063     using type = typename variadic_element<Idx-1, Tail...>::type;
0064 };
0065 
0066 template<typename First, typename ...Tail>
0067 struct variadic_element<0u, First, Tail...>
0068 {
0069     using type = First;
0070 };
0071 
0072 template<std::size_t Idx, typename ... Args>
0073 using variadic_element_t = typename variadic_element<Idx, Args...>::type;
0074 
0075 
0076 template<typename ... Args>
0077 struct variadic_last
0078 {
0079     using type = variadic_element_t<sizeof...(Args) - 1, Args...>;
0080 };
0081 
0082 template<>
0083 struct variadic_last<>
0084 {
0085     using type = void;
0086 };
0087 
0088 template<typename ... Args>
0089 using variadic_last_t = typename variadic_last<Args...>::type;
0090 
0091 
0092 template<typename First>
0093 constexpr decltype(auto) get_last_variadic(First && first)
0094 {
0095     return first;
0096 }
0097 
0098 template<typename First, typename ... Args>
0099 constexpr decltype(auto) get_last_variadic(First &&, Args  && ... args)
0100 {
0101     return get_last_variadic(static_cast<Args>(args)...);
0102 }
0103 
0104 template<typename Awaitable>
0105 auto get_resume_result(Awaitable & aw) -> system::result<decltype(aw.await_resume()), std::exception_ptr>
0106 {
0107   using type = decltype(aw.await_resume());
0108   BOOST_TRY
0109   {
0110     if constexpr (std::is_void_v<type>)
0111     {
0112       aw.await_resume();
0113       return {};
0114     }
0115     else
0116       return aw.await_resume();
0117   }
0118   BOOST_CATCH(...)
0119   {
0120     return std::current_exception();
0121   }
0122   BOOST_CATCH_END
0123 }
0124 
0125 #if BOOST_COBALT_NO_SELF_DELETE
0126 
0127 BOOST_COBALT_DECL
0128 void self_destroy(std::coroutine_handle<void> h, const cobalt::executor & exec) noexcept;
0129 
0130 template<typename T>
0131 inline void self_destroy(std::coroutine_handle<T> h) noexcept
0132 {
0133   if constexpr (requires {h.promise().get_executor();})
0134     self_destroy(h, h.promise().get_executor());
0135   else
0136     self_destroy(h, this_thread::get_executor());
0137 }
0138 
0139 #else
0140 
0141 template<typename T>
0142 inline void self_destroy(std::coroutine_handle<T> h) noexcept
0143 {
0144   h.destroy();
0145 }
0146 
0147 template<typename T, typename Executor>
0148 inline void self_destroy(std::coroutine_handle<T> h, const Executor &) noexcept
0149 {
0150   h.destroy();
0151 }
0152 
0153 #endif
0154 
0155 template<typename T>
0156 using void_as_monostate = std::conditional_t<std::is_void_v<T>, variant2::monostate, T>;
0157 
0158 template<typename T>
0159 using monostate_as_void = std::conditional_t<std::is_same_v<T, variant2::monostate>, void, T>;
0160 
0161 
0162 }
0163 
0164 #endif //BOOST_COBALT_UTIL_HPP