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 <impl/Kokkos_Error.hpp>
26#include <impl/Kokkos_StringManipulation.hpp>
36#ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
38template <typename Integral, bool Signed = std::is_signed<Integral>::value>
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
82template <
class T =
void,
size_t N = KOKKOS_INVALID_INDEX,
class Proxy =
void>
91 T m_internal_implementation_private_member_data[N];
95 using const_reference = std::add_const_t<T>&;
96 using size_type = size_t;
97 using difference_type = ptrdiff_t;
100 using const_pointer = std::add_const_t<T>*;
102 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return N; }
103 KOKKOS_INLINE_FUNCTION
static constexpr bool empty() {
return false; }
104 KOKKOS_INLINE_FUNCTION
constexpr size_type max_size()
const {
return N; }
106 template <
typename iType>
107 KOKKOS_INLINE_FUNCTION
constexpr reference operator[](
const iType& i) {
109 (std::is_integral<iType>::value || std::is_enum<iType>::value),
110 "Must be integral argument");
111 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
112 return m_internal_implementation_private_member_data[i];
115 template <
typename iType>
116 KOKKOS_INLINE_FUNCTION
constexpr const_reference operator[](
117 const iType& i)
const {
119 (std::is_integral<iType>::value || std::is_enum<iType>::value),
120 "Must be integral argument");
121 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
122 return m_internal_implementation_private_member_data[i];
125 KOKKOS_INLINE_FUNCTION
constexpr pointer data() {
126 return &m_internal_implementation_private_member_data[0];
128 KOKKOS_INLINE_FUNCTION
constexpr const_pointer data()
const {
129 return &m_internal_implementation_private_member_data[0];
133template <
class T,
class Proxy>
134struct Array<T, 0, Proxy> {
136 using reference = T&;
137 using const_reference = std::add_const_t<T>&;
138 using size_type = size_t;
139 using difference_type = ptrdiff_t;
140 using value_type = T;
142 using const_pointer = std::add_const_t<T>*;
144 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return 0; }
145 KOKKOS_INLINE_FUNCTION
static constexpr bool empty() {
return true; }
146 KOKKOS_INLINE_FUNCTION
constexpr size_type max_size()
const {
return 0; }
148 template <
typename iType>
149 KOKKOS_INLINE_FUNCTION reference operator[](
const iType&) {
151 (std::is_integral<iType>::value || std::is_enum<iType>::value),
152 "Must be integer argument");
153 Kokkos::abort(
"Unreachable code");
154 return *
reinterpret_cast<pointer
>(-1);
157 template <
typename iType>
158 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType&)
const {
160 (std::is_integral<iType>::value || std::is_enum<iType>::value),
161 "Must be integer argument");
162 Kokkos::abort(
"Unreachable code");
163 return *
reinterpret_cast<const_pointer
>(-1);
166 KOKKOS_INLINE_FUNCTION pointer data() {
return pointer(0); }
167 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return const_pointer(0); }
169 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
170 KOKKOS_DEFAULTED_FUNCTION Array() =
default;
171 KOKKOS_DEFAULTED_FUNCTION Array(
const Array&) =
default;
172 KOKKOS_DEFAULTED_FUNCTION Array& operator=(
const Array&) =
default;
181struct Array<void, KOKKOS_INVALID_INDEX, void> {
182 struct contiguous {};
187struct Array<T, KOKKOS_INVALID_INDEX, Array<>::contiguous> {
193 using reference = T&;
194 using const_reference = std::add_const_t<T>&;
195 using size_type = size_t;
196 using difference_type = ptrdiff_t;
197 using value_type = T;
199 using const_pointer = std::add_const_t<T>*;
201 KOKKOS_INLINE_FUNCTION
constexpr size_type size()
const {
return m_size; }
202 KOKKOS_INLINE_FUNCTION
constexpr bool empty()
const {
return 0 != m_size; }
203 KOKKOS_INLINE_FUNCTION
constexpr size_type max_size()
const {
return m_size; }
205 template <
typename iType>
206 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
208 (std::is_integral<iType>::value || std::is_enum<iType>::value),
209 "Must be integral argument");
210 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
214 template <
typename iType>
215 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
217 (std::is_integral<iType>::value || std::is_enum<iType>::value),
218 "Must be integral argument");
219 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
223 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
224 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
226 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
227 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
228 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
235 KOKKOS_INLINE_FUNCTION
236 Array& operator=(
const Array& rhs) {
237 const size_t n = std::min(m_size, rhs.size());
238 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
242 template <
size_t N,
class P>
243 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
244 const size_t n = std::min(m_size, rhs.size());
245 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
249 KOKKOS_INLINE_FUNCTION
constexpr Array(pointer arg_ptr, size_type arg_size,
251 : m_elem(arg_ptr), m_size(arg_size) {}
255struct Array<T, KOKKOS_INVALID_INDEX, Array<>::strided> {
262 using reference = T&;
263 using const_reference = std::add_const_t<T>&;
264 using size_type = size_t;
265 using difference_type = ptrdiff_t;
266 using value_type = T;
268 using const_pointer = std::add_const_t<T>*;
270 KOKKOS_INLINE_FUNCTION
constexpr size_type size()
const {
return m_size; }
271 KOKKOS_INLINE_FUNCTION
constexpr bool empty()
const {
return 0 != m_size; }
272 KOKKOS_INLINE_FUNCTION
constexpr size_type max_size()
const {
return m_size; }
274 template <
typename iType>
275 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
277 (std::is_integral<iType>::value || std::is_enum<iType>::value),
278 "Must be integral argument");
279 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
280 return m_elem[i * m_stride];
283 template <
typename iType>
284 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
286 (std::is_integral<iType>::value || std::is_enum<iType>::value),
287 "Must be integral argument");
288 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
289 return m_elem[i * m_stride];
292 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
293 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
295 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
296 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
297 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
304 KOKKOS_INLINE_FUNCTION
305 Array& operator=(
const Array& rhs) {
306 const size_t n = std::min(m_size, rhs.size());
307 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
311 template <
size_t N,
class P>
312 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
313 const size_t n = std::min(m_size, rhs.size());
314 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
318 KOKKOS_INLINE_FUNCTION
constexpr Array(pointer arg_ptr, size_type arg_size,
319 size_type arg_stride)
320 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
326template <
class T, std::
size_t N>
327struct std::tuple_size<Kokkos::Array<T, N>>
328 : std::integral_constant<std::size_t, N> {};
330template <std::
size_t I,
class T, std::
size_t N>
331struct std::tuple_element<I, Kokkos::Array<T, N>> {
337template <std::
size_t I,
class T, std::
size_t N>
338KOKKOS_FUNCTION
constexpr T& get(Array<T, N>& a)
noexcept {
342template <std::
size_t I,
class T, std::
size_t N>
343KOKKOS_FUNCTION
constexpr T
const& get(Array<T, N>
const& a)
noexcept {
347template <std::
size_t I,
class T, std::
size_t N>
348KOKKOS_FUNCTION
constexpr T&& get(Array<T, N>&& a)
noexcept {
349 return std::move(a[I]);
352template <std::
size_t I,
class T, std::
size_t N>
353KOKKOS_FUNCTION
constexpr T
const&& get(Array<T, N>
const&& a)
noexcept {
354 return std::move(a[I]);
360#ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
361#undef KOKKOS_IMPL_PUBLIC_INCLUDE
362#undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
Derived from the C++17 'std::array'. Dropping the iterator interface.