2 * Copyright 2017 Jacob Lifshay
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #ifndef UTIL_CONSTEXPR_ARRAY_H_
25 #define UTIL_CONSTEXPR_ARRAY_H_
27 #include "is_swappable.h"
28 #include <type_traits>
39 template <typename T
, std::size_t N
>
40 struct Constexpr_array_helper
42 typedef T values_type
[N
];
43 static constexpr T
*get_values_pointer(values_type
&values
) noexcept
47 static constexpr const T
*get_values_pointer(const values_type
&values
) noexcept
54 struct Constexpr_array_helper
<T
, 0>
59 static constexpr T
*get_values_pointer(values_type
&values
) noexcept
63 static constexpr const T
*get_values_pointer(const values_type
&values
) noexcept
70 template <typename T
, std::size_t N
>
71 struct Constexpr_array
74 typedef detail::Constexpr_array_helper
<T
, N
> Helper
;
75 typedef typename
Helper::values_type values_type
;
76 constexpr T
*get_values_pointer() noexcept
78 return Helper::get_values_pointer(values
);
80 constexpr const T
*get_values_pointer() const noexcept
82 return Helper::get_values_pointer(values
);
88 typedef std::size_t size_type
;
89 typedef std::ptrdiff_t difference_type
;
91 typedef const T
&const_reference
;
93 typedef const T
*const_pointer
;
95 typedef const T
*const_iterator
;
96 typedef std::reverse_iterator
<iterator
> reverse_iterator
;
97 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
98 constexpr T
&at(std::size_t index
)
101 throw std::out_of_range("Constexpr_array::at");
102 return get_values_pointer()[index
];
104 constexpr const T
&at(std::size_t index
) const
107 throw std::out_of_range("Constexpr_array::at");
108 return get_values_pointer()[index
];
110 constexpr T
&operator[](std::size_t index
) noexcept
112 return get_values_pointer()[index
];
114 constexpr const T
&operator[](std::size_t index
) const noexcept
116 return get_values_pointer()[index
];
118 constexpr T
&front() noexcept
120 return get_values_pointer()[0];
122 constexpr const T
&front() const noexcept
124 return get_values_pointer()[0];
126 constexpr T
&back() noexcept
128 return get_values_pointer()[N
- 1];
130 constexpr const T
&back() const noexcept
132 return get_values_pointer()[N
- 1];
134 constexpr T
*data() noexcept
136 return get_values_pointer();
138 constexpr const T
*data() const noexcept
140 return get_values_pointer();
142 constexpr iterator
begin() noexcept
144 return get_values_pointer();
146 constexpr const_iterator
begin() const noexcept
148 return get_values_pointer();
150 constexpr const_iterator
cbegin() const noexcept
152 return get_values_pointer();
154 constexpr iterator
end() noexcept
156 return get_values_pointer() + N
;
158 constexpr const_iterator
end() const noexcept
160 return get_values_pointer() + N
;
162 constexpr const_iterator
cend() const noexcept
164 return get_values_pointer() + N
;
166 constexpr reverse_iterator
rbegin() noexcept
168 return reverse_iterator(end());
170 constexpr const_reverse_iterator
rbegin() const noexcept
172 return const_reverse_iterator(end());
174 constexpr const_reverse_iterator
crbegin() const noexcept
176 return const_reverse_iterator(end());
178 constexpr reverse_iterator
rend() noexcept
180 return reverse_iterator(begin());
182 constexpr const_reverse_iterator
rend() const noexcept
184 return const_reverse_iterator(begin());
186 constexpr const_reverse_iterator
crend() const noexcept
188 return const_reverse_iterator(begin());
190 constexpr bool empty() const noexcept
194 constexpr std::size_t size() const noexcept
198 constexpr std::size_t max_size() const noexcept
202 constexpr void fill(const T
&value
) noexcept(std::is_nothrow_copy_assignable
<T
>::value
)
207 constexpr void swap(Constexpr_array
&other
) noexcept(is_nothrow_swappable_v
<T
>)
210 for(std::size_t index
= 0; index
< size(); index
++)
211 swap(get_values_pointer()[index
], other
.get_values_pointer()[index
]);
215 template <typename T
, std::size_t N
>
216 constexpr void swap(Constexpr_array
<T
, N
> &a
,
217 Constexpr_array
<T
, N
> &b
) noexcept(is_nothrow_swappable_v
<T
>)
222 template <std::size_t I
, typename T
, std::size_t N
>
223 constexpr T
&get(Constexpr_array
<T
, N
> &v
) noexcept
225 static_assert(I
< N
, "");
229 template <std::size_t I
, typename T
, std::size_t N
>
230 constexpr const T
&get(const Constexpr_array
<T
, N
> &v
) noexcept
232 static_assert(I
< N
, "");
236 template <std::size_t I
, typename T
, std::size_t N
>
237 constexpr const T
&&get(const Constexpr_array
<T
, N
> &&v
) noexcept
239 static_assert(I
< N
, "");
240 return std::move(v
[I
]);
243 template <std::size_t I
, typename T
, std::size_t N
>
244 constexpr T
&&get(Constexpr_array
<T
, N
> &&v
) noexcept
246 static_assert(I
< N
, "");
247 return std::move(v
[I
]);
252 #endif /* UTIL_CONSTEXPR_ARRAY_H_ */