123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- // Copyright (c) 2022 Klemens D. Morgenstern
- //
- // 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 BOOST_COBALT_UTIL_HPP
- #define BOOST_COBALT_UTIL_HPP
- #include <boost/cobalt/config.hpp>
- #include <boost/cobalt/this_thread.hpp>
- #include <boost/core/no_exceptions_support.hpp>
- #include <boost/system/result.hpp>
- #include <boost/variant2/variant.hpp>
- #include <limits>
- #include <type_traits>
- #include <coroutine>
- namespace boost::variant2
- {
- struct monostate;
- }
- namespace boost::cobalt::detail
- {
- template<typename T>
- constexpr std::size_t variadic_first(std::size_t = 0u)
- {
- return std::numeric_limits<std::size_t>::max();
- }
- template<typename T, typename First, typename ... Args>
- constexpr std::size_t variadic_first(std::size_t pos = 0u)
- {
- if constexpr (std::is_same_v<std::decay_t<First>, T>)
- return pos;
- else
- return variadic_first<T, Args...>(pos+1);
- }
- template<typename T, typename ... Args>
- constexpr bool variadic_has = variadic_first<T, Args...>() < sizeof...(Args);
- template<std::size_t Idx, typename First, typename ... Args>
- requires (Idx <= sizeof...(Args))
- constexpr decltype(auto) get_variadic(First && first, Args && ... args)
- {
- if constexpr (Idx == 0u)
- return static_cast<First>(first);
- else
- return get_variadic<Idx-1u>(static_cast<Args>(args)...);
- }
- template<std::size_t Idx, typename ... Args>
- struct variadic_element;
- template<std::size_t Idx, typename First, typename ...Tail>
- struct variadic_element<Idx, First, Tail...>
- {
- using type = typename variadic_element<Idx-1, Tail...>::type;
- };
- template<typename First, typename ...Tail>
- struct variadic_element<0u, First, Tail...>
- {
- using type = First;
- };
- template<std::size_t Idx, typename ... Args>
- using variadic_element_t = typename variadic_element<Idx, Args...>::type;
- template<typename ... Args>
- struct variadic_last
- {
- using type = variadic_element_t<sizeof...(Args) - 1, Args...>;
- };
- template<>
- struct variadic_last<>
- {
- using type = void;
- };
- template<typename ... Args>
- using variadic_last_t = typename variadic_last<Args...>::type;
- template<typename First>
- constexpr decltype(auto) get_last_variadic(First && first)
- {
- return first;
- }
- template<typename First, typename ... Args>
- constexpr decltype(auto) get_last_variadic(First &&, Args && ... args)
- {
- return get_last_variadic(static_cast<Args>(args)...);
- }
- template<typename Awaitable>
- auto get_resume_result(Awaitable & aw) -> system::result<decltype(aw.await_resume()), std::exception_ptr>
- {
- using type = decltype(aw.await_resume());
- BOOST_TRY
- {
- if constexpr (std::is_void_v<type>)
- {
- aw.await_resume();
- return {};
- }
- else
- return aw.await_resume();
- }
- BOOST_CATCH(...)
- {
- return std::current_exception();
- }
- BOOST_CATCH_END
- }
- #if BOOST_COBALT_NO_SELF_DELETE
- BOOST_COBALT_DECL
- void self_destroy(std::coroutine_handle<void> h, const cobalt::executor & exec) noexcept;
- template<typename T>
- inline void self_destroy(std::coroutine_handle<T> h) noexcept
- {
- if constexpr (requires {h.promise().get_executor();})
- self_destroy(h, h.promise().get_executor());
- else
- self_destroy(h, this_thread::get_executor());
- }
- #else
- template<typename T>
- inline void self_destroy(std::coroutine_handle<T> h) noexcept
- {
- h.destroy();
- }
- template<typename T, typename Executor>
- inline void self_destroy(std::coroutine_handle<T> h, const Executor &) noexcept
- {
- h.destroy();
- }
- #endif
- template<typename T>
- using void_as_monostate = std::conditional_t<std::is_void_v<T>, variant2::monostate, T>;
- template<typename T>
- using monostate_as_void = std::conditional_t<std::is_same_v<T, variant2::monostate>, void, T>;
- }
- #endif //BOOST_COBALT_UTIL_HPP
|