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<Integral>::value>
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>
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 pointer data() {
return nullptr; }
199 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return nullptr; }
201 friend KOKKOS_FUNCTION constexpr
bool operator==(Array
const&,
202 Array
const&) noexcept {
205 friend KOKKOS_FUNCTION constexpr
bool operator!=(Array
const&,
206 Array
const&) noexcept {
211 friend KOKKOS_INLINE_FUNCTION constexpr
void kokkos_swap(
212 Array<T, 0>&, Array<T, 0>&) noexcept {}
215 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
217 struct KokkosArrayContiguous {};
218 struct KokkosArrayStrided {};
222 struct KOKKOS_DEPRECATED Array<void, KOKKOS_INVALID_INDEX, void> {
223 using contiguous = Impl::KokkosArrayContiguous;
224 using strided = Impl::KokkosArrayStrided;
228 struct KOKKOS_DEPRECATED
229 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayContiguous> {
235 using reference = T&;
236 using const_reference = std::add_const_t<T>&;
237 using size_type = size_t;
238 using difference_type = ptrdiff_t;
239 using value_type = T;
241 using const_pointer = std::add_const_t<T>*;
243 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
244 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
245 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
247 template <
typename iType>
248 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
250 (std::is_integral<iType>::value || std::is_enum<iType>::value),
251 "Must be integral argument");
252 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
256 template <
typename iType>
257 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
259 (std::is_integral<iType>::value || std::is_enum<iType>::value),
260 "Must be integral argument");
261 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
265 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
266 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
268 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
269 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
270 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
277 KOKKOS_INLINE_FUNCTION
278 Array& operator=(
const Array& rhs) {
279 const size_t n = size() < rhs.size() ? size() : rhs.size();
280 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
284 template <
size_t N,
class P>
285 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
286 const size_t n = size() < rhs.size() ? size() : rhs.size();
287 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
291 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
293 : m_elem(arg_ptr), m_size(arg_size) {}
297 struct KOKKOS_DEPRECATED
298 Array<T, KOKKOS_INVALID_INDEX, Impl::KokkosArrayStrided> {
305 using reference = T&;
306 using const_reference = std::add_const_t<T>&;
307 using size_type = size_t;
308 using difference_type = ptrdiff_t;
309 using value_type = T;
311 using const_pointer = std::add_const_t<T>*;
313 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
314 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
315 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
317 template <
typename iType>
318 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
320 (std::is_integral<iType>::value || std::is_enum<iType>::value),
321 "Must be integral argument");
322 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
323 return m_elem[i * m_stride];
326 template <
typename iType>
327 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
329 (std::is_integral<iType>::value || std::is_enum<iType>::value),
330 "Must be integral argument");
331 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
332 return m_elem[i * m_stride];
335 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
336 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
338 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
339 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
340 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
347 KOKKOS_INLINE_FUNCTION
348 Array& operator=(
const Array& rhs) {
349 const size_t n = size() < rhs.size() ? size() : rhs.size();
350 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
354 template <
size_t N,
class P>
355 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
356 const size_t n = size() < rhs.size() ? size() : rhs.size();
357 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
361 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
362 size_type arg_stride)
363 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
367 template <
typename T,
typename... Us>
368 Array(T, Us...)->Array<T, 1 +
sizeof...(Us)>;
372 template <
typename T,
size_t N,
size_t... I>
373 KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
374 T (&a)[N], std::index_sequence<I...>) {
378 template <
typename T,
size_t N,
size_t... I>
379 KOKKOS_FUNCTION constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
380 T(&&a)[N], std::index_sequence<I...>) {
381 return {{std::move(a[I])...}};
386 template <
typename T,
size_t N>
387 KOKKOS_FUNCTION constexpr
auto to_array(T (&a)[N]) {
388 return Impl::to_array_impl(a, std::make_index_sequence<N>{});
391 template <
typename T,
size_t N>
392 KOKKOS_FUNCTION constexpr
auto to_array(T(&&a)[N]) {
393 return Impl::to_array_impl(std::move(a), std::make_index_sequence<N>{});
399 template <
class T, std::
size_t N>
400 struct std::tuple_size<Kokkos::Array<T, N>>
401 : std::integral_constant<std::size_t, N> {};
403 template <std::
size_t I,
class T, std::
size_t N>
404 struct std::tuple_element<I, Kokkos::Array<T, N>> {
405 static_assert(I < N);
411 template <std::
size_t I,
class T, std::
size_t N>
412 KOKKOS_FUNCTION constexpr T&
get(Array<T, N>& a) noexcept {
413 static_assert(I < N);
417 template <std::
size_t I,
class T, std::
size_t N>
418 KOKKOS_FUNCTION constexpr T
const&
get(Array<T, N>
const& a) noexcept {
419 static_assert(I < N);
423 template <std::
size_t I,
class T, std::
size_t N>
424 KOKKOS_FUNCTION constexpr T&&
get(Array<T, N>&& a) noexcept {
425 static_assert(I < N);
426 return std::move(a[I]);
429 template <std::
size_t I,
class T, std::
size_t N>
430 KOKKOS_FUNCTION constexpr T
const&&
get(Array<T, N>
const&& a) noexcept {
431 static_assert(I < N);
432 return std::move(a[I]);
438 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
439 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
440 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
Derived from the C++17 'std::array'. Dropping the iterator interface.