You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
1.9 KiB
81 lines
1.9 KiB
#pragma once
|
|
|
|
#include <utility>
|
|
#include <pointer_traits>
|
|
#include <array>
|
|
|
|
#include <cstddef>
|
|
|
|
namespace util {
|
|
[[gnu::const, gnu::always_inline]]
|
|
constexpr ptrdiff_t ptr_diff(const auto *p1, const auto *p2) noexcept
|
|
{
|
|
auto a1 = std::to_address(p1);
|
|
auto a2 = std::to_address(p2);
|
|
return ptrdiff_t(a1 < a2 ? a2 - a1 : a1 - a2);
|
|
}
|
|
[[gnu::const, gnu::always_inline]]
|
|
constexpr ptrdiff_t ptr_diff(intptr_t p1, intptr_t p2) noexcept
|
|
{
|
|
return ptrdiff_t(p1 < p2 ? p2 - p1 : p1 - p2);
|
|
}
|
|
|
|
|
|
template<size_t... Idx>
|
|
constexpr auto substring_literal(const auto& str, std::index_sequence<Idx...>) noexcept
|
|
requires(requires(size_t n) {
|
|
{ str[n] } noexcept -> std::convertible_to<char>;
|
|
})
|
|
{
|
|
return std::array{ str[Idx]..., '\n' };
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr auto type_name_literal() noexcept
|
|
{
|
|
constexpr std::string_view prefix {
|
|
#if defined(__clang__)
|
|
"[T = "
|
|
#elif defined(__GNUC__)
|
|
"with T = "
|
|
#else
|
|
// Fuck MSVC, don't care.
|
|
#error Unsupported compiler
|
|
#endif
|
|
};
|
|
constexpr std::string_view suffix {"]"};
|
|
constexpr std::string_view function {__PRETTY_FUNCTION__};
|
|
|
|
constexpr auto start = function.find(prefix) + prefix.size();
|
|
constexpr auto end = function.rfind(suffix);
|
|
|
|
static_assert(start < end);
|
|
|
|
constexpr std::string_view name = function.substr(start, (end - start));
|
|
return substring_literal(name, std::make_index_sequence<name.size()>{});
|
|
}
|
|
|
|
template<typename T>
|
|
struct [[gnu::visibility("internal")]] type_name_of {
|
|
constexpr static inline auto value = type_name_literal<T>();
|
|
|
|
[[gnu::const]]
|
|
consteval operator std::string_view() const noexcept {
|
|
constexpr auto& v = value;
|
|
return std::string_view { v.data(), v.size() };
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
constexpr auto type_name() noexcept -> std::string_view
|
|
{
|
|
constexpr auto& value = type_name_of<T>::value;
|
|
return std::string_view { value.data(), value.size() };
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr inline auto type_name_v = type_name<T>();
|
|
|
|
|
|
}
|