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