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.
libexopt/include/util.hh

104 lines
3.4 KiB

#pragma once
#include <memory>
#include <string_view>
#include <utility>
#include <array>
#include "exopt.h"
#include "optional.h"
#define _EO_CONSTANT_VALUE(X) ([]() { \
struct { \
typedef decltype(X) comptime_constant_t; \
consteval operator comptime_constant_t() const noexcept { return (X); } \
} inner; \
return inner; \
})()
namespace exopt { namespace util [[gnu::visibility("internal")]] {
template<typename T, typename U>
concept comptime = std::convertible_to<T, U> and requires{
typename T::comptime_constant_t;
};
template<typename T>
concept is_complete = requires{ { sizeof(T) == sizeof(T) }; };
constexpr auto comptime_value(auto value) noexcept {
using U = decltype(value);
struct inner {
typedef U comptime_constant_t;
consteval operator comptime_constant_t() const noexcept { return std::move(value); }
U value;
constexpr inner(std::add_rvalue_reference_t<U> m) noexcept : value(std::move(m)) {}
constexpr ~inner() = default;
};
return inner{ std::move(value) };
}
static_assert(comptime_value(std::string_view{"hello"}.size()) == 5, "Bad comptime_value()");
static_assert(_EO_CONSTANT_VALUE(std::string_view{"hello world"}) == std::string_view{"hello world"}, "Bad CONSTANT_VALUE()");
template<typename T, size_t N, typename Array= std::array<T, N>, typename _I = std::make_index_sequence<N>>
constexpr auto array_literal(const T (&a)[N]) noexcept
-> Array
{
constexpr decltype(auto) _array_create = []<size_t... I>(auto const& a, std::index_sequence<I...>) noexcept
{
return Array { a[I]... };
};
return _array_create(std::move(a), _I{});
}
template<typename T, size_t N, typename Array= std::array<T, N>, typename _I = std::make_index_sequence<N>>
constexpr auto array_literal(T (&&a)[N]) noexcept
-> Array
{
constexpr decltype(auto) _array_create = []<size_t... I>(auto&& a, std::index_sequence<I...>) noexcept
{
return Array { std::move(a[I])... };
};
return _array_create(std::move(a), _I{});
}
struct [[gnu::visibility("internal")]] CTInternalFatalError {
constexpr CTInternalFatalError() noexcept = default;
constexpr CTInternalFatalError(CTInternalFatalError const&) noexcept = default;
constexpr CTInternalFatalError(CTInternalFatalError &&) noexcept = default;
constexpr CTInternalFatalError& operator=(CTInternalFatalError const&) noexcept = default;
constexpr CTInternalFatalError& operator=(CTInternalFatalError&&) noexcept = default;
constexpr virtual ~CTInternalFatalError() noexcept = default;
constexpr operator std::string_view() const noexcept { return message(); }
consteval virtual std::string_view message() const noexcept =0;
};
[[noreturn, gnu::noinline, gnu::cold]]
void throw_runtime(std::string_view&&);
[[noreturn]]//, gnu::noinline, gnu::cold]]
constexpr void throw_runtime(std::convertible_to<std::string_view> auto&& msg) {
std::string_view view{msg};
if consteval {
using CTE = CTInternalFatalError;
struct CTIFRuntimeError : public CTE {
using CTE::CTE;
consteval CTIFRuntimeError(std::string_view&& view) noexcept
: CTE(), m_message(std::move(view)) {}
consteval std::string_view message() const noexcept override { return m_message; }
constexpr virtual ~CTIFRuntimeError() noexcept {}
private:
std::string_view m_message;
};
throw CTIFRuntimeError(std::move(view));
} else {
throw_runtime(std::move(view));
}
__builtin_unreachable();
}
} }