36 #ifndef CUDA_KAT_CONTAINERS_ARRAY_HPP_ 37 #define CUDA_KAT_CONTAINERS_ARRAY_HPP_ 40 #include <kat/detail/range_access.hpp> 49 #include <type_traits> 54 template<
typename T,
size_t NumElements>
57 typedef T type[NumElements];
59 KAT_FHD
static constexpr T& reference(
const type& t,
size_t n) noexcept {
return const_cast<T&
>(t[n]); }
60 KAT_FHD
static constexpr T* pointer(
const type& t) noexcept {
return const_cast<T*
>(t); }
64 struct array_traits<T, 0>
68 KAT_FHD
static constexpr T& reference(
const type&,
size_t) noexcept {
return *
static_cast<T*
>(
nullptr); }
69 KAT_FHD
static constexpr T* pointer(
const type&) noexcept {
return nullptr; }
80 template<
typename T,
size_t NumElements>
84 typedef value_type* pointer;
85 typedef const value_type* const_pointer;
86 typedef value_type& reference;
87 typedef const value_type& const_reference;
88 typedef value_type* iterator;
89 typedef const value_type* const_iterator;
90 typedef size_t size_type;
91 typedef std::ptrdiff_t difference_type;
92 typedef std::reverse_iterator<iterator> reverse_iterator;
93 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
96 typedef array_traits<T, NumElements> array_traits_type;
98 typename array_traits_type::type elements;
103 KAT_FHD CONSTEXPR_SINCE_CPP_14
void fill(
const value_type& u)
106 for(size_type i = 0; i < NumElements; i++) { elements[i] = u; }
110 KAT_FHD CONSTEXPR_SINCE_CPP_14
void swap(
array& other) noexcept(noexcept(std::swap(std::declval<T&>(), std::declval<T&>())))
113 for(size_type i = 0; i < NumElements; i++)
115 auto x = elements[i];
116 auto y = other.elements[i];
118 other.elements[i] = x;
124 KAT_FHD CONSTEXPR_SINCE_CPP_14 iterator begin() noexcept {
return iterator(data()); }
125 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_iterator begin()
const noexcept {
return const_iterator(data()); }
126 KAT_FHD CONSTEXPR_SINCE_CPP_14 iterator end() noexcept {
return iterator(data() + NumElements); }
127 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_iterator end()
const noexcept {
return const_iterator(data() + NumElements); }
128 KAT_FHD CONSTEXPR_SINCE_CPP_14 reverse_iterator rbegin() noexcept {
return reverse_iterator(end()); }
129 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_reverse_iterator rbegin()
const noexcept {
return const_reverse_iterator(end()); }
130 KAT_FHD CONSTEXPR_SINCE_CPP_14 reverse_iterator rend() noexcept {
return reverse_iterator(begin()); }
131 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_reverse_iterator rend()
const noexcept {
return const_reverse_iterator(begin()); }
132 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_iterator cbegin()
const noexcept {
return const_iterator(data()); }
133 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_iterator cend()
const noexcept {
return const_iterator(data() + NumElements); }
134 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_reverse_iterator crbegin()
const noexcept {
return const_reverse_iterator(end()); }
135 KAT_FHD CONSTEXPR_SINCE_CPP_14 const_reverse_iterator crend()
const noexcept {
return const_reverse_iterator(begin()); }
139 KAT_FHD constexpr size_type size()
const noexcept {
return NumElements; }
140 KAT_FHD constexpr size_type max_size()
const noexcept {
return NumElements; }
141 KAT_FHD constexpr
bool empty()
const noexcept {
return size() == 0; }
145 KAT_FHD CONSTEXPR_SINCE_CPP_14 reference operator[](size_type n) noexcept {
return array_traits_type::reference(elements, n); }
147 KAT_FHD constexpr const_reference operator[](size_type n)
const noexcept {
return array_traits_type::reference(elements, n); }
151 KAT_FHD CONSTEXPR_SINCE_CPP_17 reference at(size_type n) noexcept {
152 if (n > NumElements) {
156 throw std::out_of_range(
"kat::array::at: index n exceeds number of elements");
159 return array_traits_type::reference(elements, n);
164 KAT_FHD CONSTEXPR_SINCE_CPP_17 const_reference at(size_type n)
const 166 if (n > NumElements) {
170 throw std::out_of_range(
"kat::array::at: index n exceeds number of elements");
173 return array_traits_type::reference(elements, n);
176 KAT_FHD CONSTEXPR_SINCE_CPP_14 reference front() noexcept
179 KAT_FHD constexpr const_reference front()
const noexcept
180 {
return array_traits_type::reference(elements, 0); }
182 KAT_FHD reference back() noexcept
183 {
return NumElements ? *(end() - 1) : *end(); }
185 KAT_FHD constexpr const_reference back()
const noexcept
188 array_traits_type::reference(elements, NumElements - 1) :
189 array_traits_type::reference(elements, 0);
192 KAT_FHD CONSTEXPR_SINCE_CPP_14 pointer data() noexcept {
return array_traits_type::pointer(elements); }
194 KAT_FHD constexpr const_pointer data()
const noexcept {
return array_traits_type::pointer(elements); }
198 template<
typename T,
size_t NumElements>
199 KAT_FHD CONSTEXPR_SINCE_CPP_17
202 #if __cplusplus >= 202001L 204 return std::equal(one.begin(), one.end(), two.begin());
206 auto first1 = one.cbegin();
207 const auto last1 = one.cend();
208 auto first2 = two.cbegin();
209 for (; first1 != last1; ++first1, ++first2) {
210 if (!(*first1 == *first2)) {
218 template<
typename T,
size_t NumElements>
219 KAT_FHD CONSTEXPR_SINCE_CPP_17
bool 221 {
return !(one == two); }
223 template<
typename T,
size_t NumElements>
224 KAT_FHD
bool CONSTEXPR_SINCE_CPP_17
227 #if __cplusplus >= 202001L 229 return std::lexicographical_compare(a.cbegin(), a.cend(), b.cbegin(), b.cend());
231 auto first1 = a.cbegin();
232 const auto last1 = a.cend();
233 auto first2 = b.cbegin();
234 const auto last2 = b.cend();
235 for ( ; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2 ) {
236 if (*first1 < *first2)
return true;
237 if (*first2 < *first1)
return false;
239 return (first1 == last1) && (first2 != last2);
243 template<
typename T,
size_t NumElements>
244 KAT_FHD
bool CONSTEXPR_SINCE_CPP_17
250 template<
typename T,
size_t NumElements>
251 KAT_FHD
bool CONSTEXPR_SINCE_CPP_17
257 template<
typename T,
size_t NumElements>
258 KAT_FHD
bool CONSTEXPR_SINCE_CPP_17
265 template<
typename T,
size_t NumElements>
267 noexcept(noexcept(one.swap(two)))
272 template<
size_t Integer,
typename T,
size_t NumElements>
275 static_assert(Integer < NumElements,
"index is out of bounds");
276 return array_traits<T, NumElements>::reference(arr.elements, Integer);
279 template<
size_t Integer,
typename T,
size_t NumElements>
282 static_assert(Integer < NumElements,
"index is out of bounds");
283 return std::move(get<Integer>(arr));
286 template<
size_t Integer,
typename T,
size_t NumElements>
289 static_assert(Integer < NumElements,
"index is out of bounds");
290 return array_traits<T, NumElements>::reference(arr.elements, Integer);
303 template<
typename T,
size_t NumElements>
304 struct tuple_size<array<T, NumElements>> :
public std::integral_constant<size_t, NumElements> { };
308 template<
size_t Integer,
typename T,
size_t NumElements>
311 static_assert(Integer < NumElements,
"index is out of bounds");
315 template<
size_t Integer,
typename T,
size_t NumElements>
318 static_assert(Integer < NumElements,
"index is out of bounds");
319 using type =
const T;
322 template<
size_t Integer,
typename T,
size_t NumElements>
323 struct tuple_element<Integer, volatile array<T, NumElements>>
325 static_assert(Integer < NumElements,
"index is out of bounds");
326 using type =
volatile T;
329 template<
size_t Integer,
typename T,
size_t NumElements>
330 struct tuple_element<Integer, const volatile array<T, NumElements>>
332 static_assert(Integer < NumElements,
"index is out of bounds");
333 using type =
const volatile T;
336 #if __cplusplus >= 201402L 337 #ifndef _KAT_TUPLE_ELEMENT_T 338 template <
size_t I,
class T>
340 #define _KAT_TUPLE_ELEMENT_T 355 template<
typename T,
size_t NumElements>
356 struct tuple_size<
kat::array<T, NumElements>> :
public integral_constant<size_t, NumElements> { };
360 template<
size_t Integer,
typename T,
size_t NumElements>
363 static_assert(Integer < NumElements,
"index is out of bounds");
367 template<
size_t Integer,
typename T,
size_t NumElements>
370 static_assert(Integer < NumElements,
"index is out of bounds");
371 using type =
const T;
374 template<
size_t Integer,
typename T,
size_t NumElements>
377 static_assert(Integer < NumElements,
"index is out of bounds");
378 using type =
volatile T;
381 template<
size_t Integer,
typename T,
size_t NumElements>
384 static_assert(Integer < NumElements,
"index is out of bounds");
385 using type =
const volatile T;
392 #endif // CUDA_KAT_CONTAINERS_ARRAY_HPP_
Definition: array.hpp:353
Definition: common.hpp:16
Basic type and macro definitions used throughout the KAT library.
Definition: array.hpp:358
A standard container for storing a fixed size sequence of elements, based on std::array - but fully G...
Definition: array.hpp:81