1 /* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */
2
3 #ifndef MPT_BASE_ARRAY_HPP
4 #define MPT_BASE_ARRAY_HPP
5
6
7
8 #include "mpt/base/detect.hpp"
9 #include "mpt/base/namespace.hpp"
10
11 #include <array>
12 #include <type_traits>
13
14 #include <cstddef>
15
16
17
18 namespace mpt {
19 inline namespace MPT_INLINE_NS {
20
21
22 template <typename T>
23 struct stdarray_extent : std::integral_constant<std::size_t, 0> { };
24
25 template <typename T, std::size_t N>
26 struct stdarray_extent<std::array<T, N>> : std::integral_constant<std::size_t, N> { };
27
28 template <typename T>
29 struct is_stdarray : std::false_type { };
30
31 template <typename T, std::size_t N>
32 struct is_stdarray<std::array<T, N>> : std::true_type { };
33
34 // mpt::extent is the same as std::extent,
35 // but also works for std::array,
36 // and asserts that the given type is actually an array type instead of returning 0.
37 // use as:
38 // mpt::extent<decltype(expr)>()
39 // mpt::extent<decltype(variable)>()
40 // mpt::extent<decltype(type)>()
41 // mpt::extent<type>()
42 template <typename T>
extent()43 constexpr std::size_t extent() noexcept {
44 using Tarray = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
45 static_assert(std::is_array<Tarray>::value || mpt::is_stdarray<Tarray>::value);
46 if constexpr (mpt::is_stdarray<Tarray>::value) {
47 return mpt::stdarray_extent<Tarray>();
48 } else {
49 return std::extent<Tarray>();
50 }
51 }
52
53 template <typename>
54 struct array_size;
55
56 template <typename T, std::size_t N>
57 struct array_size<std::array<T, N>> {
58 static constexpr std::size_t size = N;
59 };
60
61 template <typename T, std::size_t N>
62 struct array_size<T[N]> {
63 static constexpr std::size_t size = N;
64 };
65
66
67 template <typename T, std::size_t N, typename Tx>
init_array(const Tx & x)68 constexpr std::array<T, N> init_array(const Tx & x) {
69 std::array<T, N> result{};
70 for (std::size_t i = 0; i < N; ++i) {
71 result[i] = x;
72 }
73 return result;
74 }
75
76
77 } // namespace MPT_INLINE_NS
78 } // namespace mpt
79
80
81
82 #endif // MPT_BASE_ARRAY_HPP
83