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) {
112 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
113 "Must be integral argument");
114 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
115 return m_internal_implementation_private_member_data[i];
118 template <
typename iType>
119 KOKKOS_INLINE_FUNCTION constexpr const_reference operator[](
120 const iType& i)
const {
121 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
122 "Must be integral argument");
123 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
124 return m_internal_implementation_private_member_data[i];
127 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
128 return &m_internal_implementation_private_member_data[0];
130 KOKKOS_INLINE_FUNCTION constexpr const_pointer data()
const {
131 return &m_internal_implementation_private_member_data[0];
134 friend KOKKOS_FUNCTION constexpr
bool operator==(Array
const& lhs,
135 Array
const& rhs) noexcept {
136 for (
size_t i = 0; i != N; ++i)
137 if (lhs[i] != rhs[i])
return false;
141 friend KOKKOS_FUNCTION constexpr
bool operator!=(Array
const& lhs,
142 Array
const& rhs) noexcept {
143 return !(lhs == rhs);
147 template <
class U = T>
148 friend KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<
149 Impl::is_swappable<U>::value>
150 kokkos_swap(Array<T, N>& a,
151 Array<T, N>& b) noexcept(Impl::is_nothrow_swappable_v<U>) {
152 for (std::size_t i = 0; i < N; ++i) {
153 kokkos_swap(a[i], b[i]);
158 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
159 template <
class T,
class Proxy>
160 struct Array<T, 0, Proxy> {
166 using reference = T&;
167 using const_reference = std::add_const_t<T>&;
168 using size_type = size_t;
169 using difference_type = ptrdiff_t;
170 using value_type = T;
172 using const_pointer = std::add_const_t<T>*;
174 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return 0; }
175 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return true; }
176 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return 0; }
178 template <
typename iType>
179 KOKKOS_INLINE_FUNCTION reference operator[](
const iType&) {
180 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
181 "Must be integer argument");
182 Kokkos::abort(
"Unreachable code");
183 return *
reinterpret_cast<pointer
>(-1);
186 template <
typename iType>
187 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType&)
const {
188 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
189 "Must be integer argument");
190 Kokkos::abort(
"Unreachable code");
191 return *
reinterpret_cast<const_pointer
>(-1);
194 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
return nullptr; }
195 KOKKOS_INLINE_FUNCTION constexpr const_pointer data()
const {
199 friend KOKKOS_FUNCTION constexpr
bool operator==(Array
const&,
200 Array
const&) noexcept {
203 friend KOKKOS_FUNCTION constexpr
bool operator!=(Array
const&,
204 Array
const&) noexcept {
209 friend KOKKOS_INLINE_FUNCTION constexpr
void kokkos_swap(
210 Array<T, 0>&, Array<T, 0>&) noexcept {}
213 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
215 struct KokkosArrayContiguous {};
216 struct KokkosArrayStrided {};
220 struct KOKKOS_DEPRECATED Array<void, KOKKOS_INVALID_INDEX, void> {
221 using contiguous = Impl::KokkosArrayContiguous;
222 using strided = Impl::KokkosArrayStrided;
226 struct KOKKOS_DEPRECATED
227 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayContiguous> {
233 using reference = T&;
234 using const_reference = std::add_const_t<T>&;
235 using size_type = size_t;
236 using difference_type = ptrdiff_t;
237 using value_type = T;
239 using const_pointer = std::add_const_t<T>*;
241 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
242 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
243 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
245 template <
typename iType>
246 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
247 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
248 "Must be integral argument");
249 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
253 template <
typename iType>
254 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
255 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
256 "Must be integral argument");
257 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
261 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
262 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
264 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
265 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
266 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
273 KOKKOS_INLINE_FUNCTION
274 Array& operator=(
const Array& rhs) {
275 if (&rhs ==
this)
return *
this;
276 const size_t n = size() < rhs.size() ? size() : rhs.size();
277 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
281 template <
size_t N,
class P>
282 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
283 const size_t n = size() < rhs.size() ? size() : rhs.size();
284 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
288 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
290 : m_elem(arg_ptr), m_size(arg_size) {}
294 struct KOKKOS_DEPRECATED
295 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayStrided> {
302 using reference = T&;
303 using const_reference = std::add_const_t<T>&;
304 using size_type = size_t;
305 using difference_type = ptrdiff_t;
306 using value_type = T;
308 using const_pointer = std::add_const_t<T>*;
310 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
311 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
312 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
314 template <
typename iType>
315 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
316 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
317 "Must be integral argument");
318 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
319 return m_elem[i * m_stride];
322 template <
typename iType>
323 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
324 static_assert((std::is_integral_v<iType> || std::is_enum_v<iType>),
325 "Must be integral argument");
326 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
327 return m_elem[i * m_stride];
330 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
331 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
333 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
334 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
335 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
342 KOKKOS_INLINE_FUNCTION
343 Array& operator=(
const Array& rhs) {
344 if (&rhs ==
this)
return *
this;
345 const size_t n = size() < rhs.size() ? size() : rhs.size();
346 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
350 template <
size_t N,
class P>
351 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
352 const size_t n = size() < rhs.size() ? size() : rhs.size();
353 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
357 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
358 size_type arg_stride)
359 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
363 template <
typename T,
typename... Us>
364 Array(T, Us...) -> Array<T, 1 +
sizeof...(Us)>;
368 template <
typename T,
size_t N,
size_t... I>
369 KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
370 T (&a)[N], std::index_sequence<I...>) {
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...>) {
377 return {{std::move(a[I])...}};
382 template <
typename T,
size_t N>
383 KOKKOS_FUNCTION constexpr
auto to_array(T (&a)[N]) {
384 return Impl::to_array_impl(a, std::make_index_sequence<N>{});
387 template <
typename T,
size_t N>
388 KOKKOS_FUNCTION constexpr
auto to_array(T (&&a)[N]) {
389 return Impl::to_array_impl(std::move(a), std::make_index_sequence<N>{});
395 template <
class T, std::
size_t N>
396 struct std::tuple_size<Kokkos::Array<T, N>>
397 : std::integral_constant<std::size_t, N> {};
399 template <std::
size_t I,
class T, std::
size_t N>
400 struct std::tuple_element<I, Kokkos::Array<T, N>> {
401 static_assert(I < N);
407 template <std::
size_t I,
class T, std::
size_t N>
408 KOKKOS_FUNCTION constexpr T&
get(Array<T, N>& a) noexcept {
409 static_assert(I < N);
413 template <std::
size_t I,
class T, std::
size_t N>
414 KOKKOS_FUNCTION constexpr T
const&
get(Array<T, N>
const& a) noexcept {
415 static_assert(I < N);
419 template <std::
size_t I,
class T, std::
size_t N>
420 KOKKOS_FUNCTION constexpr T&&
get(Array<T, N>&& a) noexcept {
421 static_assert(I < N);
422 return std::move(a[I]);
425 template <std::
size_t I,
class T, std::
size_t N>
426 KOKKOS_FUNCTION constexpr T
const&&
get(Array<T, N>
const&& a) noexcept {
427 static_assert(I < N);
428 return std::move(a[I]);
437 template <
class T, std::
size_t N>
438 KOKKOS_FUNCTION constexpr T
const* begin(Array<T, N>
const& a) noexcept {
442 template <
class T, std::
size_t N>
443 KOKKOS_FUNCTION constexpr T* begin(Array<T, N>& a) noexcept {
447 template <
class T, std::
size_t N>
448 KOKKOS_FUNCTION constexpr T
const* end(Array<T, N>
const& a) noexcept {
449 return a.data() + a.size();
452 template <
class T, std::
size_t N>
453 KOKKOS_FUNCTION constexpr T* end(Array<T, N>& a) noexcept {
454 return a.data() + a.size();
460 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
461 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
462 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY