Skip to content

Instantly share code, notes, and snippets.

@jakobrs
Last active December 12, 2023 16:37
Show Gist options
  • Save jakobrs/f569effd5b54889b45719480c9450113 to your computer and use it in GitHub Desktop.
Save jakobrs/f569effd5b54889b45719480c9450113 to your computer and use it in GitHub Desktop.
template <typename T, size_t N>
struct mdspan {
T *data;
std::array<size_t, N> extents;
template <typename... OtherIndexTypes>
requires(std::is_convertible_v<OtherIndexTypes, size_t> && ...) &&
(sizeof...(OtherIndexTypes) == N)
constexpr explicit mdspan(T *data, OtherIndexTypes... _extents)
: data(data), extents{} {
auto idx = size_t{0};
(
[&](OtherIndexTypes extent) {
extents[idx++] = static_cast<size_t>(extent);
}(_extents),
...);
}
template <typename... OtherIndexTypes>
requires(std::is_convertible_v<OtherIndexTypes, size_t> && ...) &&
(sizeof...(OtherIndexTypes) == N)
constexpr auto operator()(OtherIndexTypes... indices) -> T & {
auto real_idx = size_t{0};
auto ext_idx = size_t{0};
(
[&](OtherIndexTypes idx) {
real_idx *= extents[ext_idx++];
real_idx += static_cast<size_t>(idx);
}(indices),
...);
return data[real_idx];
}
#if __cpp_multidimensional_subscript >= 202110L
template <typename... OtherIndexTypes>
requires(std::is_convertible_v<OtherIndexTypes, size_t> && ...) &&
(sizeof...(OtherIndexTypes) == N)
constexpr auto operator[](OtherIndexTypes... indices) -> T & {
return operator()(indices...);
}
#endif
};
template <typename T, typename... Integrals>
requires(sizeof...(Integrals) > 0)
explicit mdspan(T *, Integrals...) -> mdspan<T, sizeof...(Integrals)>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment