Created
August 18, 2020 13:35
-
-
Save willwray/fb7e6c5d4316a84be361a1d34238e96e to your computer and use it in GitHub Desktop.
simple c++20 array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://godbolt.org/z/cdjrj4 | |
#include <compare> | |
#include <concepts> | |
// same_ish<T> utility concept to match a forwarding reference argument <T>(T&& a) | |
template <typename T, typename U> concept same_ish = std::same_as<std::remove_cvref_t<T>,U>; | |
template <typename A> concept zero_size_array = sizeof(A) == 0 && ! std::is_class_v<A>; | |
// carray concept designed to match zero-size arrays as well as bounded C-arrays | |
// (zero-size arrays are a non-standard extension in gcc and clang, so fail -pedantic) | |
template <typename A> concept carray = zero_size_array<A> || std::is_bounded_array_v<A>; | |
template <carray A> | |
struct array | |
{ | |
A data; | |
using element_type = std::remove_cvref_t<decltype(*data)>; | |
static constexpr auto extent_v = sizeof data / sizeof *data; | |
friend constexpr auto&& data(same_ish<array> auto&& a) noexcept { | |
return ((decltype(a)&&)a).data; | |
} | |
constexpr auto size() const noexcept { return extent_v; } | |
//friend consteval std::integral_constant<std::size_t,extent_v> size(array const&) noexcept { return {}; } | |
friend consteval std::size_t size(array const&) noexcept { return extent_v; } | |
constexpr auto& operator[](int i)& noexcept { return data[i]; } | |
constexpr auto&& operator[](int i)&& noexcept { return ((A&&)data)[i]; } | |
constexpr auto& operator[](int i) const& noexcept { return data[i]; } | |
constexpr auto&& operator[](int i) const&& noexcept { return ((A const&&)data)[i]; } | |
constexpr auto begin() noexcept { return data; } | |
constexpr auto end() noexcept { return &data[size()]; } | |
constexpr auto begin() const noexcept { return data; } | |
constexpr auto end() const noexcept { return &data[size()]; } | |
friend constexpr void swap(array& l, array& r) noexcept(std::is_nothrow_swappable_v<A>) { | |
std::swap(l.data,r.data); | |
} | |
friend auto operator<=>(array const&, array const&) noexcept = default; | |
}; | |
template <carray A> array(A const&) -> array<A>; | |
template <typename T, int N> array(T const(&)[N]) -> array<T[N]>; | |
template <typename T, int M, int N> array(T const(&)[M][N]) -> array<T[M][N]>; | |
// to_array() copy-converts a c-array to array class (redundant with P1997) | |
constexpr auto to_array(carray auto&& a) -> decltype(array{a}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment