17 #ifndef KOKKOS_ARRAY_HPP
18 #define KOKKOS_ARRAY_HPP
19 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20 #define KOKKOS_IMPL_PUBLIC_INCLUDE
21 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
24 #include <Kokkos_Macros.hpp>
25 #include <Kokkos_Swap.hpp>
26 #include <impl/Kokkos_Error.hpp>
27 #include <impl/Kokkos_StringManipulation.hpp>
29 #include <type_traits>
36 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
38 template <
typename Integral,
bool Signed = std::is_
signed_v<Integral>>
39 struct ArrayBoundsCheck;
41 template <
typename Integral>
42 struct ArrayBoundsCheck<Integral, true> {
43 KOKKOS_INLINE_FUNCTION
44 constexpr ArrayBoundsCheck(Integral i,
size_t N) {
46 char err[128] =
"Kokkos::Array: index ";
47 to_chars_i(err + strlen(err), err + 128, i);
51 ArrayBoundsCheck<Integral, false>(i, N);
55 template <
typename Integral>
56 struct ArrayBoundsCheck<Integral, false> {
57 KOKKOS_INLINE_FUNCTION
58 constexpr ArrayBoundsCheck(Integral i,
size_t N) {
60 char err[128] =
"Kokkos::Array: index ";
61 to_chars_i(err + strlen(err), err + 128, i);
63 to_chars_i(err + strlen(err), err + 128, N);
70 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) \
71 Kokkos::Impl::ArrayBoundsCheck<decltype(i)>(i, N)
73 #else // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
75 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
77 #endif // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
82 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
83 template <
class T =
void,
size_t N = KOKKOS_INVALID_INDEX,
class Proxy =
void>
85 template <
class T,
size_t N>
95 T m_internal_implementation_private_member_data[N];
99 using const_reference = std::add_const_t<T>&;
100 using size_type = size_t;
101 using difference_type = ptrdiff_t;
102 using value_type = T;
104 using const_pointer = std::add_const_t<T>*;
106 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return N; }
107 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return false; }
108 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return N; }
110 template <
typename iType>
111 KOKKOS_INLINE_FUNCTION constexpr reference operator[](
const iType& i) {
113 (std::is_integral<iType>::value || std::is_enum<iType>::value),
114 "Must be integral argument");
115 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
116 return m_internal_implementation_private_member_data[i];
119 template <
typename iType>
120 KOKKOS_INLINE_FUNCTION constexpr const_reference operator[](
121 const iType& i)
const {
123 (std::is_integral<iType>::value || std::is_enum<iType>::value),
124 "Must be integral argument");
125 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
126 return m_internal_implementation_private_member_data[i];
129 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
130 return &m_internal_implementation_private_member_data[0];
132 KOKKOS_INLINE_FUNCTION constexpr const_pointer data()
const {
133 return &m_internal_implementation_private_member_data[0];
136 friend KOKKOS_FUNCTION constexpr
bool operator==(Array
const& lhs,
137 Array
const& rhs) noexcept {
138 for (
size_t i = 0; i != N; ++i)
139 if (lhs[i] != rhs[i])
return false;
143 friend KOKKOS_FUNCTION constexpr
bool operator!=(Array
const& lhs,
144 Array
const& rhs) noexcept {
145 return !(lhs == rhs);
149 template <
class U = T>
150 friend KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
151 Impl::is_swappable<U>::value>
152 kokkos_swap(Array<T, N>& a,
153 Array<T, N>& b) noexcept(Impl::is_nothrow_swappable_v<U>) {
154 for (std::size_t i = 0; i < N; ++i) {
155 kokkos_swap(a[i], b[i]);
160 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
161 template <
class T,
class Proxy>
162 struct Array<T, 0, Proxy> {
168 using reference = T&;
169 using const_reference = std::add_const_t<T>&;
170 using size_type = size_t;
171 using difference_type = ptrdiff_t;
172 using value_type = T;
174 using const_pointer = std::add_const_t<T>*;
176 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return 0; }
177 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return true; }
178 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return 0; }
180 template <
typename iType>
181 KOKKOS_INLINE_FUNCTION reference operator[](
const iType&) {
183 (std::is_integral<iType>::value || std::is_enum<iType>::value),
184 "Must be integer argument");
185 Kokkos::abort(
"Unreachable code");
186 return *
reinterpret_cast<pointer
>(-1);
189 template <
typename iType>
190 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType&)
const {
192 (std::is_integral<iType>::value || std::is_enum<iType>::value),
193 "Must be integer argument");
194 Kokkos::abort(
"Unreachable code");
195 return *
reinterpret_cast<const_pointer
>(-1);
198 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
return nullptr; }
199 KOKKOS_INLINE_FUNCTION constexpr const_pointer data()
const {
203 friend KOKKOS_FUNCTION constexpr
bool operator==(Array
const&,
204 Array
const&) noexcept {
207 friend KOKKOS_FUNCTION constexpr
bool operator!=(Array
const&,
208 Array
const&) noexcept {
213 friend KOKKOS_INLINE_FUNCTION constexpr
void kokkos_swap(
214 Array<T, 0>&, Array<T, 0>&) noexcept {}
217 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
219 struct KokkosArrayContiguous {};
220 struct KokkosArrayStrided {};
224 struct KOKKOS_DEPRECATED Array<void, KOKKOS_INVALID_INDEX, void> {
225 using contiguous = Impl::KokkosArrayContiguous;
226 using strided = Impl::KokkosArrayStrided;
230 struct KOKKOS_DEPRECATED
231 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayContiguous> {
237 using reference = T&;
238 using const_reference = std::add_const_t<T>&;
239 using size_type = size_t;
240 using difference_type = ptrdiff_t;
241 using value_type = T;
243 using const_pointer = std::add_const_t<T>*;
245 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
246 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
247 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
249 template <
typename iType>
250 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
252 (std::is_integral<iType>::value || std::is_enum<iType>::value),
253 "Must be integral argument");
254 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
258 template <
typename iType>
259 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
261 (std::is_integral<iType>::value || std::is_enum<iType>::value),
262 "Must be integral argument");
263 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
267 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
268 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
270 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
271 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
272 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
279 KOKKOS_INLINE_FUNCTION
280 Array& operator=(
const Array& rhs) {
281 const size_t n = size() < rhs.size() ? size() : rhs.size();
282 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
286 template <
size_t N,
class P>
287 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
288 const size_t n = size() < rhs.size() ? size() : rhs.size();
289 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
293 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
295 : m_elem(arg_ptr), m_size(arg_size) {}
299 struct KOKKOS_DEPRECATED
300 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayStrided> {
307 using reference = T&;
308 using const_reference = std::add_const_t<T>&;
309 using size_type = size_t;
310 using difference_type = ptrdiff_t;
311 using value_type = T;
313 using const_pointer = std::add_const_t<T>*;
315 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
316 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
317 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
319 template <
typename iType>
320 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
322 (std::is_integral<iType>::value || std::is_enum<iType>::value),
323 "Must be integral argument");
324 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
325 return m_elem[i * m_stride];
328 template <
typename iType>
329 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
331 (std::is_integral<iType>::value || std::is_enum<iType>::value),
332 "Must be integral argument");
333 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
334 return m_elem[i * m_stride];
337 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
338 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
340 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
341 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
342 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
349 KOKKOS_INLINE_FUNCTION
350 Array& operator=(
const Array& rhs) {
351 const size_t n = size() < rhs.size() ? size() : rhs.size();
352 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
356 template <
size_t N,
class P>
357 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
358 const size_t n = size() < rhs.size() ? size() : rhs.size();
359 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
363 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
364 size_type arg_stride)
365 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
369 template <
typename T,
typename... Us>
370 Array(T, Us...) -> Array<T, 1 +
sizeof...(Us)>;
374 template <
typename T,
size_t N,
size_t... I>
375 KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
376 T (&a)[N], std::index_sequence<I...>) {
380 template <
typename T,
size_t N,
size_t... I>
381 KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
382 T (&&a)[N], std::index_sequence<I...>) {
383 return {{std::move(a[I])...}};
388 template <
typename T,
size_t N>
389 KOKKOS_FUNCTION constexpr
auto to_array(T (&a)[N]) {
390 return Impl::to_array_impl(a, std::make_index_sequence<N>{});
393 template <
typename T,
size_t N>
394 KOKKOS_FUNCTION constexpr
auto to_array(T (&&a)[N]) {
395 return Impl::to_array_impl(std::move(a), std::make_index_sequence<N>{});
401 template <
class T, std::
size_t N>
402 struct std::tuple_size<Kokkos::Array<T, N>>
403 : std::integral_constant<std::size_t, N> {};
405 template <std::
size_t I,
class T, std::
size_t N>
406 struct std::tuple_element<I, Kokkos::Array<T, N>> {
407 static_assert(I < N);
413 template <std::
size_t I,
class T, std::
size_t N>
414 KOKKOS_FUNCTION constexpr T&
get(Array<T, N>& a) noexcept {
415 static_assert(I < N);
419 template <std::
size_t I,
class T, std::
size_t N>
420 KOKKOS_FUNCTION constexpr T
const&
get(Array<T, N>
const& a) noexcept {
421 static_assert(I < N);
425 template <std::
size_t I,
class T, std::
size_t N>
426 KOKKOS_FUNCTION constexpr T&&
get(Array<T, N>&& a) noexcept {
427 static_assert(I < N);
428 return std::move(a[I]);
431 template <std::
size_t I,
class T, std::
size_t N>
432 KOKKOS_FUNCTION constexpr T
const&&
get(Array<T, N>
const&& a) noexcept {
433 static_assert(I < N);
434 return std::move(a[I]);
443 template <
class T, std::
size_t N>
444 KOKKOS_FUNCTION constexpr T
const* begin(Array<T, N>
const& a) noexcept {
448 template <
class T, std::
size_t N>
449 KOKKOS_FUNCTION constexpr T* begin(Array<T, N>& a) noexcept {
453 template <
class T, std::
size_t N>
454 KOKKOS_FUNCTION constexpr T
const* end(Array<T, N>
const& a) noexcept {
455 return a.data() + a.size();
458 template <
class T, std::
size_t N>
459 KOKKOS_FUNCTION constexpr T* end(Array<T, N>& a) noexcept {
460 return a.data() + a.size();
466 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
467 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
468 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY