#pragma once #include #include "type.hpp" namespace util { // // clang-format off template util::enable_if_t, T *> addressof(T &arg) noexcept { return reinterpret_cast(&const_cast(reinterpret_cast(arg))); } template util::enable_if_t, T *> addressof(T &arg) noexcept { return &arg; } // template util::add_rvalue_reference_t declval() noexcept; template inline constexpr util::remove_reference_t &&move(T &&t) noexcept { return static_cast &&>(t); } template inline constexpr T &&forward(util::remove_reference_t &t) noexcept { return static_cast(t); } template inline constexpr T &&forward(util::remove_reference_t &&t) noexcept { static_assert(!util::is_lvalue_reference_v, "Can not forward an rvalue as an lvalue."); return static_cast(t); } template struct integer_sequence { using __type = integer_sequence; using value_type = T; static constexpr size_t size() noexcept { return sizeof...(Ints); } }; template using index_sequence = integer_sequence; namespace detail { template struct concat; template struct concat, integer_sequence> : integer_sequence {}; // uint64_t because this must be able to hold all possible sizes and cannot be T, because then the specialization for 0 // and 1 are not possible template struct gen_integer_sequence : detail::concat::__type, typename gen_integer_sequence::__type> {}; template struct gen_integer_sequence : integer_sequence {}; template struct gen_integer_sequence : integer_sequence {}; } // namespace detail template struct make_integer_sequence : detail::gen_integer_sequence { static_assert(N >= 0, "Integer sequence cannot be negative"); }; template using make_index_sequence = make_integer_sequence; template using index_sequence_for = make_index_sequence; // Not part of , but very useful namespace detail { template inline constexpr integer_sequence add_offset(integer_sequence) { return {}; } } // namespace detail template inline constexpr auto make_offset_integer_sequence() { return detail::add_offset(make_integer_sequence{}); } template inline constexpr auto make_offset_index_sequence() { return make_offset_integer_sequence(); } template auto for_constexpr(Fn &&func, index_sequence) { if constexpr (util::is_void_v>>) { (func(util::integral_constant{}), ...); } else { if ((func(util::integral_constant{}) && ...)) return true; return false; } } // clang-format on } // namespace util