mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
34ced75056
The base class contains the common functionality that will also be used by the wallet rpc server.
71 lines
2.4 KiB
C++
71 lines
2.4 KiB
C++
#pragma once
|
|
#include <string>
|
|
#include <variant>
|
|
#include <array>
|
|
#include <typeinfo>
|
|
#ifdef __GNUG__
|
|
#include <cxxabi.h>
|
|
#include <cstdlib>
|
|
#endif
|
|
|
|
namespace tools {
|
|
|
|
namespace detail {
|
|
|
|
template <typename T, typename T1, typename... Ts>
|
|
constexpr size_t template_index_impl_inner() {
|
|
if constexpr (std::is_same_v<T, T1>) return 0;
|
|
else {
|
|
static_assert(sizeof...(Ts) > 0, "Type not found");
|
|
return 1 + template_index_impl_inner<T, Ts...>();
|
|
}
|
|
}
|
|
|
|
template <typename T, typename C> struct template_index_impl {};
|
|
|
|
template <typename T, template<typename...> typename C, typename... Ts>
|
|
struct template_index_impl<T, C<Ts...>> : std::integral_constant<size_t, template_index_impl_inner<T, Ts...>()> {};
|
|
|
|
} // namespace detail
|
|
|
|
/// Type wrapper that contains an arbitrary list of types.
|
|
template <typename...> struct type_list {};
|
|
|
|
/// Accesses the index of the first T within a template type's type list. E.g.
|
|
///
|
|
/// template_index<int, std::variant<double, short, int>>() == 2
|
|
///
|
|
/// Fails at compile time if T is not in any of the type's class list.
|
|
template <typename T, typename C>
|
|
constexpr size_t template_index = detail::template_index_impl<T, C>::value;
|
|
|
|
/// Access the std::type_info& of the hold value of the given variant. This is basically a runtime
|
|
/// version of `typeid(std::variant_alternative_t<N, variant>)`. Throws std::bad_variant_access if
|
|
/// the variant is valueless_by_exception.
|
|
template <typename... T>
|
|
const std::type_info& variant_type(const std::variant<T...>& v) {
|
|
const size_t index = v.index();
|
|
if (index != std::variant_npos)
|
|
return *std::array<const std::type_info*, sizeof...(T)>{{&typeid(T)...}}[index];
|
|
throw std::bad_variant_access{};
|
|
}
|
|
|
|
/// Converts a std::type_info (typically from a typeid(T) call) into a human-readable name. For GCC
|
|
/// and clang this means demangling it. For anything else we just return .name().
|
|
inline std::string type_name(const std::type_info& ti) {
|
|
#ifdef __GNUG__
|
|
int status = 0;
|
|
char* realname = abi::__cxa_demangle(ti.name(), nullptr, nullptr, &status);
|
|
std::string name = status == 0 ? realname : ti.name();
|
|
std::free(realname);
|
|
#else
|
|
std::string name = ti.name();
|
|
#endif
|
|
return name;
|
|
}
|
|
|
|
/// Same as above, but uses a templated type instead of a type_info argument.
|
|
template <typename T>
|
|
inline std::string type_name() { return type_name(typeid(T)); }
|
|
|
|
} // namespace tools
|