15template <
typename T, std::
size_t I,
typename U = std::any>
17 { std::get<I>(tuple) } -> std::convertible_to<U>;
21template <
typename T,
typename... Args>
24 typename std::tuple_size<std::remove_cvref_t<T>>::type;
25 requires std::same_as<
27 decltype(std::tuple_size_v<std::remove_cvref_t<T>>)>,
29 } &&
sizeof...(Args) == std::tuple_size_v<std::remove_cvref_t<T>> &&
30 []<std::size_t... I>(std::index_sequence<I...>) {
31 return (TupleElementGettable<T, I, Args> && ...);
32 }(std::make_index_sequence<std::tuple_size_v<std::remove_cvref_t<T>>>());
34template <std::
integral T = std::
size_t>
class index {
39 using second_type = T;
41 constexpr index_type operator[](index_type dim)
const noexcept {
49 template <std::
integral U>
50 requires(std::numeric_limits<U>::max() >= std::numeric_limits<T>::max())
51 constexpr operator index<U>()
const noexcept {
55 template <std::
integral U>
56 requires(std::numeric_limits<U>::max() < std::numeric_limits<T>::max())
57 constexpr explicit operator index<U>()
const noexcept {
61 constexpr index(index_type first, index_type second)
62 : first(first), second(second) {}
64 template <TupleLike<T, T> Tuple>
65 constexpr index(Tuple tuple)
66 : first(std::get<0>(tuple)), second(std::get<1>(tuple)) {}
68 template <std::
integral U>
constexpr index(std::initializer_list<U> tuple) {
69 assert(tuple.size() == 2);
70 first = *tuple.begin();
71 second = *(tuple.begin() + 1);
74 constexpr bool operator==(
const index &)
const noexcept =
default;
75 constexpr bool operator<(
const index &other)
const noexcept
76 requires(std::totally_ordered<T>)
78 if (first < other.first) {
81 if (first == other.first && second < other.second) {
87 template <std::
size_t Index>
88 constexpr T get()
const noexcept
91 if constexpr (Index == 0) {
94 if constexpr (Index == 1) {
114template <std::
size_t Index, std::
integral I>
115struct tuple_element<Index, dr::index<I>>
116 : tuple_element<Index, std::tuple<I, I>> {};
118template <std::
integral I>
119struct tuple_size<dr::index<I>> : integral_constant<std::size_t, 2> {};
121template <std::
size_t Index, std::
integral I>
125 if constexpr (Index == 0) {
128 if constexpr (Index == 1) {