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
49 template <
class T,
size_t Size>
struct array {
53 typedef value_type& reference;
54 typedef const value_type& const_reference;
55 typedef value_type* iterator;
56 typedef const value_type* const_iterator;
57 typedef value_type* pointer;
58 typedef const value_type* const_pointer;
59 typedef size_t size_type;
60 typedef ptrdiff_t difference_type;
61 typedef std::reverse_iterator<iterator> reverse_iterator;
62 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
64 value_type elems_[Size > 0 ? Size : 1];
67 void fill(
const value_type& u_) { std::fill_n(elems_, Size, u_); }
68 void swap(array& a_) noexcept(
std::swap(std::declval<T &>(), std::declval<T &>()))
70 std::swap_ranges(elems_, elems_ + Size, a_.elems_);
74 iterator begin() noexcept {
return iterator(elems_); }
75 const_iterator begin() const noexcept {
return const_iterator(elems_); }
76 iterator end() noexcept {
return iterator(elems_ + Size); }
77 const_iterator end() const noexcept {
return const_iterator(elems_ + Size); }
78 reverse_iterator rbegin() noexcept {
return reverse_iterator(end()); }
79 const_reverse_iterator rbegin() const noexcept
81 return const_reverse_iterator(end());
83 reverse_iterator rend() noexcept {
return reverse_iterator(begin()); }
84 const_reverse_iterator rend() const noexcept
86 return const_reverse_iterator(begin());
89 const_iterator cbegin() const noexcept {
return begin(); }
90 const_iterator cend() const noexcept {
return end(); }
91 const_reverse_iterator crbegin() const noexcept {
return rbegin(); }
92 const_reverse_iterator crend() const noexcept {
return rend(); }
94 constexpr size_type size() const noexcept {
return Size; }
95 constexpr size_type max_size() const noexcept {
return Size; }
96 constexpr
bool empty() const noexcept {
return Size == 0; }
98 reference operator[](size_type n_) {
return elems_[n_]; }
99 constexpr const_reference operator[](size_type n_)
const {
return elems_[n_]; }
104 template <
typename I>
106 Vc_ALWAYS_INLINE
auto operator[](I&& arg_)
107 -> decltype(subscript_operator(*
this, std::forward<I>(arg_)))
109 return subscript_operator(*
this, std::forward<I>(arg_));
112 template <
typename I>
113 Vc_ALWAYS_INLINE
auto operator[](I&& arg_) const
114 -> decltype(subscript_operator(*this,
std::forward<I>(arg_)))
116 return subscript_operator(*
this, std::forward<I>(arg_));
120 reference at(size_type n_);
121 constexpr const_reference at(size_type n_)
const;
123 reference front() {
return elems_[0]; }
124 constexpr const_reference front()
const {
return elems_[0]; }
125 reference back() {
return elems_[Size > 0 ? Size - 1 : 0]; }
126 constexpr const_reference back()
const {
return elems_[Size > 0 ? Size - 1 : 0]; }
127 value_type* data() noexcept {
return elems_; }
128 const value_type* data() const noexcept {
return elems_; }
131 template <
class T,
size_t Size>
132 typename array<T, Size>::reference array<T, Size>::at(size_type n_)
135 throw std::out_of_range(
"array::at");
140 template <
class T,
size_t Size>
141 constexpr
typename array<T, Size>::const_reference array<T, Size>::at(size_type n_)
const 143 return n_ >= Size ? (
throw std::out_of_range(
"array::at"), elems_[0]) : elems_[n_];
146 template <
class T,
size_t Size>
147 inline bool operator==(
const array<T, Size>& x_,
const array<T, Size>& y_)
149 return std::equal(x_.elems_, x_.elems_ + Size, y_.elems_);
152 template <
class T,
size_t Size>
153 inline bool operator!=(
const array<T, Size>& x_,
const array<T, Size>& y_)
158 template <
class T,
size_t Size>
159 inline bool operator<(const array<T, Size>& x_,
const array<T, Size>& y_)
161 return std::lexicographical_compare(x_.elems_, x_.elems_ + Size, y_.elems_,
165 template <
class T,
size_t Size>
166 inline bool operator>(
const array<T, Size>& x_,
const array<T, Size>& y_)
171 template <
class T,
size_t Size>
172 inline bool operator<=(const array<T, Size>& x_,
const array<T, Size>& y_)
177 template <
class T,
size_t Size>
178 inline bool operator>=(
const array<T, Size>& x_,
const array<T, Size>& y_)
187 template <
typename T, std::
size_t N>
189 inline auto begin(array<T, N>& arr) -> decltype(arr.begin())
193 template <
typename T, std::
size_t N>
194 inline auto begin(
const array<T, N>& arr) -> decltype(arr.begin())
198 template <
typename T, std::
size_t N>
199 inline auto end(array<T, N>& arr) -> decltype(arr.end())
203 template <
typename T, std::
size_t N>
204 inline auto end(
const array<T, N>& arr) -> decltype(arr.end())
212 template <
typename T, std::
size_t N>
213 struct has_no_allocated_data_impl<
Vc::array<T, N>> :
public std::true_type
216 template <
typename T, std::
size_t N>
217 struct has_contiguous_storage_impl<Vc::array<T, N>> :
public std::true_type
221 static_assert(has_no_allocated_data<
const volatile Vc::array<int, 256> &>::value,
"");
222 static_assert(has_no_allocated_data<
const volatile Vc::array<int, 256>>::value,
"");
223 static_assert(has_no_allocated_data<
volatile Vc::array<int, 256> &>::value,
"");
224 static_assert(has_no_allocated_data<
volatile Vc::array<int, 256>>::value,
"");
225 static_assert(has_no_allocated_data<
const Vc::array<int, 256> &>::value,
"");
226 static_assert(has_no_allocated_data<
const Vc::array<int, 256>>::value,
"");
227 static_assert(has_no_allocated_data<Vc::array<int, 256>>::value,
"");
228 static_assert(has_no_allocated_data<Vc::array<int, 256> &>::value,
"");
229 static_assert(has_no_allocated_data<Vc::array<int, 256> &&>::value,
"");
236 template <
class T,
size_t Size>
245 typename enable_if<is_same<void, decltype(swap(declval<T&>(), declval<T&>()))>::value,
248 swap(
const Vc::array<T, Size>& x_,
249 const Vc::array<T, Size>& y_) noexcept(
swap(declval<T&>(), declval<T&>()))
254 template <
class T,
size_t Size>
255 class tuple_size<
Vc::array<T, Size>> :
public integral_constant<size_t, Size>
259 template <
size_t I,
class T,
size_t Size>
class tuple_element<I, Vc::array<T, Size>>
265 template <
size_t I,
class T,
size_t Size>
266 inline constexpr
typename std::enable_if<(I < Size), T&>::type
get(
267 Vc::array<T, Size>& a_) noexcept
272 template <
size_t I,
class T,
size_t Size>
273 inline constexpr
typename std::enable_if<(I < Size), const T&>::type
get(
274 const Vc::array<T, Size>& a_) noexcept
279 template <
size_t I,
class T,
size_t Size>
280 inline constexpr
typename std::enable_if<(I < Size), T&&>::type
get(
281 Vc::array<T, Size>&& a_) noexcept
283 return std::move(a_.elems_[I]);
287 #endif // VC_INCLUDE_VC_ARRAY_ void swap(Adapter< S, T, N > &a, std::size_t i, S &x)
Swaps one scalar object x with a SIMD slot at offset i in the simdized object a.
result_vector_type< L, R >::mask_type operator!=(L &&lhs, R &&rhs)
Applies != component-wise and concurrently.
result_vector_type< L, R >::mask_type operator==(L &&lhs, R &&rhs)
Applies == component-wise and concurrently.
result_vector_type< L, R >::mask_type operator>=(L &&lhs, R &&rhs)
Applies >= component-wise and concurrently.
Vector Classes Namespace.
result_vector_type< L, R >::mask_type operator>(L &&lhs, R &&rhs)
Applies > component-wise and concurrently.