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>
36#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
38template <
typename Integral,
bool Signed = std::is_
signed_v<Integral>>
39struct ArrayBoundsCheck;
41template <
typename Integral>
42struct 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);
55template <
typename Integral>
56struct 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)
75#define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
82#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4
83template <
class T =
void,
size_t N = KOKKOS_INVALID_INDEX,
class Proxy =
void>
85template <
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
161template <
class T,
class Proxy>
162struct 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
219struct KokkosArrayContiguous {};
220struct KokkosArrayStrided {};
224struct KOKKOS_DEPRECATED Array<void, KOKKOS_INVALID_INDEX, void> {
225 using contiguous = Impl::KokkosArrayContiguous;
226 using strided = Impl::KokkosArrayStrided;
230struct 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) {}
299struct 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) {}
369template <
typename T,
typename... Us>
370Array(T, Us...) -> Array<T, 1 +
sizeof...(Us)>;
374template <
typename T,
size_t N,
size_t... I>
375KOKKOS_FUNCTION
constexpr Array<std::remove_cv_t<T>, N> to_array_impl(
376 T (&a)[N], std::index_sequence<I...>) {
380template <
typename T,
size_t N,
size_t... I>
381KOKKOS_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])...}};
388template <
typename T,
size_t N>
389KOKKOS_FUNCTION
constexpr auto to_array(T (&a)[N]) {
390 return Impl::to_array_impl(a, std::make_index_sequence<N>{});
393template <
typename T,
size_t N>
394KOKKOS_FUNCTION
constexpr auto to_array(T (&&a)[N]) {
395 return Impl::to_array_impl(std::move(a), std::make_index_sequence<N>{});
401template <
class T, std::
size_t N>
402struct std::tuple_size<Kokkos::
Array<T, N>>
403 : std::integral_constant<std::size_t, N> {};
405template <std::
size_t I,
class T, std::
size_t N>
406struct std::tuple_element<I, Kokkos::
Array<T, N>> {
407 static_assert(I < N);
413template <std::
size_t I,
class T, std::
size_t N>
414KOKKOS_FUNCTION
constexpr T& get(
Array<T, N>& a)
noexcept {
415 static_assert(I < N);
419template <std::
size_t I,
class T, std::
size_t N>
420KOKKOS_FUNCTION
constexpr T
const& get(
Array<T, N> const& a)
noexcept {
421 static_assert(I < N);
425template <std::
size_t I,
class T, std::
size_t N>
426KOKKOS_FUNCTION
constexpr T&& get(
Array<T, N>&& a)
noexcept {
427 static_assert(I < N);
428 return std::move(a[I]);
431template <std::
size_t I,
class T, std::
size_t N>
432KOKKOS_FUNCTION
constexpr T
const&& get(
Array<T, N> const&& a)
noexcept {
433 static_assert(I < N);
434 return std::move(a[I]);
443template <
class T, std::
size_t N>
444KOKKOS_FUNCTION
constexpr T
const* begin(
Array<T, N> const& a)
noexcept {
448template <
class T, std::
size_t N>
449KOKKOS_FUNCTION
constexpr T* begin(
Array<T, N>& a)
noexcept {
453template <
class T, std::
size_t N>
454KOKKOS_FUNCTION
constexpr T
const* end(
Array<T, N> const& a)
noexcept {
455 return a.data() + a.size();
458template <
class T, std::
size_t N>
459KOKKOS_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
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...
Derived from the C++17 'std::array'. Dropping the iterator interface.