diff --git a/util.hpp b/util.hpp index 12818a1..e074bba 100644 --- a/util.hpp +++ b/util.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "../type/type.hpp" namespace util { @@ -23,4 +25,80 @@ inline constexpr T &&forward(type::remove_reference_t &&t) noexcept 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(); +} + } // namespace util