#pragma once #include #include #include #include "exopt.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 concept comptime = std::convertible_to and requires{ typename T::comptime_constant_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 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 _I = std::make_index_sequence> constexpr auto array_literal(const T (&a)[N]) noexcept -> Array { constexpr decltype(auto) _array_create = [](auto const& a, std::index_sequence) noexcept { return Array { a[I]... }; }; return _array_create(std::move(a), _I{}); } template, typename _I = std::make_index_sequence> constexpr auto array_literal(T (&&a)[N]) noexcept -> Array { constexpr decltype(auto) _array_create = [](auto&& a, std::index_sequence) noexcept { return Array { std::move(a[I])... }; }; return _array_create(std::move(a), _I{}); } } }