36 #ifndef VC_INCLUDE_VC_ARRAY_
37 #define VC_INCLUDE_VC_ARRAY_
39 #include <type_traits>
45 #include "common/subscript.h"
47 namespace Vc_VERSIONED_NAMESPACE
86 template <
class T,
size_t Size>
struct array {
90 typedef value_type& reference;
91 typedef const value_type& const_reference;
92 typedef value_type* iterator;
93 typedef const value_type* const_iterator;
94 typedef value_type* pointer;
95 typedef const value_type* const_pointer;
96 typedef size_t size_type;
97 typedef ptrdiff_t difference_type;
98 typedef std::reverse_iterator<iterator> reverse_iterator;
99 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
101 value_type elems_[Size > 0 ? Size : 1];
104 void fill(
const value_type& u_) { std::fill_n(elems_, Size, u_); }
107 std::swap_ranges(elems_, elems_ + Size, a_.elems_);
111 iterator begin() noexcept {
return iterator(elems_); }
112 const_iterator begin()
const noexcept {
return const_iterator(elems_); }
113 iterator end() noexcept {
return iterator(elems_ + Size); }
114 const_iterator end()
const noexcept {
return const_iterator(elems_ + Size); }
115 reverse_iterator rbegin() noexcept {
return reverse_iterator(end()); }
116 const_reverse_iterator rbegin()
const noexcept
118 return const_reverse_iterator(end());
120 reverse_iterator rend() noexcept {
return reverse_iterator(begin()); }
121 const_reverse_iterator rend()
const noexcept
123 return const_reverse_iterator(begin());
126 const_iterator cbegin()
const noexcept {
return begin(); }
127 const_iterator cend()
const noexcept {
return end(); }
128 const_reverse_iterator crbegin()
const noexcept {
return rbegin(); }
129 const_reverse_iterator crend()
const noexcept {
return rend(); }
131 constexpr size_type size()
const noexcept {
return Size; }
132 constexpr size_type max_size()
const noexcept {
return Size; }
133 constexpr
bool empty()
const noexcept {
return Size == 0; }
135 reference operator[](size_type n_) {
return elems_[n_]; }
136 constexpr const_reference operator[](size_type n_)
const {
return elems_[n_]; }
141 template <
typename I>
143 Vc_ALWAYS_INLINE
auto operator[](I&& arg_)
144 -> decltype(subscript_operator(*
this, std::forward<I>(arg_)))
146 return subscript_operator(*
this, std::forward<I>(arg_));
149 template <
typename I>
150 Vc_ALWAYS_INLINE
auto operator[](I&& arg_)
const
151 -> decltype(subscript_operator(*
this, std::forward<I>(arg_)))
153 return subscript_operator(*
this, std::forward<I>(arg_));
157 reference at(size_type n_);
158 constexpr const_reference at(size_type n_)
const;
160 reference front() {
return elems_[0]; }
161 constexpr const_reference front()
const {
return elems_[0]; }
162 reference back() {
return elems_[Size > 0 ? Size - 1 : 0]; }
163 constexpr const_reference back()
const {
return elems_[Size > 0 ? Size - 1 : 0]; }
164 value_type* data() noexcept {
return elems_; }
165 const value_type* data()
const noexcept {
return elems_; }
168 template <
class T,
size_t Size>
172 throw std::out_of_range(
"array::at");
177 template <
class T,
size_t Size>
178 constexpr
typename array<T, Size>::const_reference array<T, Size>::at(size_type n_)
const
180 return n_ >= Size ? (
throw std::out_of_range(
"array::at"), elems_[0]) : elems_[n_];
183 template <
class T,
size_t Size>
184 inline bool operator==(
const array<T, Size>& x_,
const array<T, Size>& y_)
186 return std::equal(x_.elems_, x_.elems_ + Size, y_.elems_);
189 template <
class T,
size_t Size>
190 inline bool operator!=(
const array<T, Size>& x_,
const array<T, Size>& y_)
195 template <
class T,
size_t Size>
196 inline bool operator<(
const array<T, Size>& x_,
const array<T, Size>& y_)
198 return std::lexicographical_compare(x_.elems_, x_.elems_ + Size, y_.elems_,
202 template <
class T,
size_t Size>
203 inline bool operator>(
const array<T, Size>& x_,
const array<T, Size>& y_)
208 template <
class T,
size_t Size>
209 inline bool operator<=(
const array<T, Size>& x_,
const array<T, Size>& y_)
214 template <
class T,
size_t Size>
215 inline bool operator>=(
const array<T, Size>& x_,
const array<T, Size>& y_)
224 template <
typename T, std::
size_t N>
226 inline auto begin(array<T, N>& arr) -> decltype(arr.begin())
230 template <
typename T, std::
size_t N>
231 inline auto begin(
const array<T, N>& arr) -> decltype(arr.begin())
235 template <
typename T, std::
size_t N>
236 inline auto end(array<T, N>& arr) -> decltype(arr.end())
240 template <
typename T, std::
size_t N>
241 inline auto end(
const array<T, N>& arr) -> decltype(arr.end())
249 template <
typename T, std::
size_t N>
250 struct has_no_allocated_data_impl<
Vc::array<T, N>> :
public std::true_type
253 template <
typename T, std::
size_t N>
254 struct has_contiguous_storage_impl<
Vc::array<T, N>> :
public std::true_type
262 template <
class T,
size_t Size>
271 typename enable_if<is_same<void, decltype(swap(declval<T&>(), declval<T&>()))>::value,
280 template <
class T,
size_t Size>
281 class tuple_size<
Vc::array<T, Size>> :
public integral_constant<size_t, Size>
285 template <
size_t I,
class T,
size_t Size>
class tuple_element<I,
Vc::array<T, Size>>
291 template <
size_t I,
class T,
size_t Size>
292 inline constexpr
typename std::enable_if<(I < Size), T&>::type get(
298 template <
size_t I,
class T,
size_t Size>
299 inline constexpr
typename std::enable_if<(I < Size), const T&>::type get(
305 template <
size_t I,
class T,
size_t Size>
306 inline constexpr
typename std::enable_if<(I < Size), T&&>::type get(
309 return std::move(a_.elems_[I]);
313 #endif // VC_INCLUDE_VC_ARRAY_