gnss-sim/3rdparty/boost/cobalt/detail/util.hpp

165 lines
3.7 KiB
C++

// 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