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>
37 #ifdef KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK
39 template <typename Integral, bool Signed = std::is_signed<Integral>::value>
40 struct ArrayBoundsCheck;
42 template <
typename Integral>
43 struct ArrayBoundsCheck<Integral, true> {
44 KOKKOS_INLINE_FUNCTION
45 constexpr ArrayBoundsCheck(Integral i,
size_t N) {
47 char err[128] =
"Kokkos::Array: index ";
48 to_chars_i(err + strlen(err), err + 128, i);
52 ArrayBoundsCheck<Integral, false>(i, N);
56 template <
typename Integral>
57 struct ArrayBoundsCheck<Integral, false> {
58 KOKKOS_INLINE_FUNCTION
59 constexpr ArrayBoundsCheck(Integral i,
size_t N) {
61 char err[128] =
"Kokkos::Array: index ";
62 to_chars_i(err + strlen(err), err + 128, i);
64 to_chars_i(err + strlen(err), err + 128, N);
71 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) \
72 Kokkos::Impl::ArrayBoundsCheck<decltype(i)>(i, N)
74 #else // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
76 #define KOKKOS_ARRAY_BOUNDS_CHECK(i, N) (void)0
78 #endif // !defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
83 template <
class T =
void,
size_t N = KOKKOS_INVALID_INDEX,
class Proxy =
void>
92 T m_internal_implementation_private_member_data[N];
96 using const_reference = std::add_const_t<T>&;
97 using size_type = size_t;
98 using difference_type = ptrdiff_t;
101 using const_pointer = std::add_const_t<T>*;
103 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return N; }
104 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return false; }
105 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return N; }
107 template <
typename iType>
108 KOKKOS_INLINE_FUNCTION constexpr reference operator[](
const iType& i) {
110 (std::is_integral<iType>::value || std::is_enum<iType>::value),
111 "Must be integral argument");
112 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
113 return m_internal_implementation_private_member_data[i];
116 template <
typename iType>
117 KOKKOS_INLINE_FUNCTION constexpr const_reference operator[](
118 const iType& i)
const {
120 (std::is_integral<iType>::value || std::is_enum<iType>::value),
121 "Must be integral argument");
122 KOKKOS_ARRAY_BOUNDS_CHECK(i, N);
123 return m_internal_implementation_private_member_data[i];
126 KOKKOS_INLINE_FUNCTION constexpr pointer data() {
127 return &m_internal_implementation_private_member_data[0];
129 KOKKOS_INLINE_FUNCTION constexpr const_pointer data()
const {
130 return &m_internal_implementation_private_member_data[0];
134 template <
class T,
class Proxy>
135 struct Array<T, 0, Proxy> {
137 using reference = T&;
138 using const_reference = std::add_const_t<T>&;
139 using size_type = size_t;
140 using difference_type = ptrdiff_t;
141 using value_type = T;
143 using const_pointer = std::add_const_t<T>*;
145 KOKKOS_INLINE_FUNCTION
static constexpr size_type size() {
return 0; }
146 KOKKOS_INLINE_FUNCTION
static constexpr
bool empty() {
return true; }
147 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return 0; }
149 template <
typename iType>
150 KOKKOS_INLINE_FUNCTION reference operator[](
const iType&) {
152 (std::is_integral<iType>::value || std::is_enum<iType>::value),
153 "Must be integer argument");
154 Kokkos::abort(
"Unreachable code");
155 return *
reinterpret_cast<pointer
>(-1);
158 template <
typename iType>
159 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType&)
const {
161 (std::is_integral<iType>::value || std::is_enum<iType>::value),
162 "Must be integer argument");
163 Kokkos::abort(
"Unreachable code");
164 return *
reinterpret_cast<const_pointer
>(-1);
167 KOKKOS_INLINE_FUNCTION pointer data() {
return nullptr; }
168 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return nullptr; }
170 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
171 KOKKOS_DEFAULTED_FUNCTION Array() =
default;
172 KOKKOS_DEFAULTED_FUNCTION Array(
const Array&) =
default;
173 KOKKOS_DEFAULTED_FUNCTION Array& operator=(
const Array&) =
default;
182 struct Array<void, KOKKOS_INVALID_INDEX, void> {
183 struct contiguous {};
188 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::contiguous> {
194 using reference = T&;
195 using const_reference = std::add_const_t<T>&;
196 using size_type = size_t;
197 using difference_type = ptrdiff_t;
198 using value_type = T;
200 using const_pointer = std::add_const_t<T>*;
202 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
203 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
204 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
206 template <
typename iType>
207 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
209 (std::is_integral<iType>::value || std::is_enum<iType>::value),
210 "Must be integral argument");
211 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
215 template <
typename iType>
216 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
218 (std::is_integral<iType>::value || std::is_enum<iType>::value),
219 "Must be integral argument");
220 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
224 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
225 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
227 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
228 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
229 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array& rhs) =
delete;
236 KOKKOS_INLINE_FUNCTION
237 Array& operator=(
const Array& rhs) {
238 const size_t n = size() < rhs.size() ? size() : rhs.size();
239 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
243 template <
size_t N,
class P>
244 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
245 const size_t n = size() < rhs.size() ? size() : rhs.size();
246 for (
size_t i = 0; i < n; ++i) m_elem[i] = rhs[i];
250 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
252 : m_elem(arg_ptr), m_size(arg_size) {}
256 struct Array<T, KOKKOS_INVALID_INDEX, Array<>::strided> {
263 using reference = T&;
264 using const_reference = std::add_const_t<T>&;
265 using size_type = size_t;
266 using difference_type = ptrdiff_t;
267 using value_type = T;
269 using const_pointer = std::add_const_t<T>*;
271 KOKKOS_INLINE_FUNCTION constexpr size_type size()
const {
return m_size; }
272 KOKKOS_INLINE_FUNCTION constexpr
bool empty()
const {
return 0 == m_size; }
273 KOKKOS_INLINE_FUNCTION constexpr size_type max_size()
const {
return m_size; }
275 template <
typename iType>
276 KOKKOS_INLINE_FUNCTION reference operator[](
const iType& i) {
278 (std::is_integral<iType>::value || std::is_enum<iType>::value),
279 "Must be integral argument");
280 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
281 return m_elem[i * m_stride];
284 template <
typename iType>
285 KOKKOS_INLINE_FUNCTION const_reference operator[](
const iType& i)
const {
287 (std::is_integral<iType>::value || std::is_enum<iType>::value),
288 "Must be integral argument");
289 KOKKOS_ARRAY_BOUNDS_CHECK(i, m_size);
290 return m_elem[i * m_stride];
293 KOKKOS_INLINE_FUNCTION pointer data() {
return m_elem; }
294 KOKKOS_INLINE_FUNCTION const_pointer data()
const {
return m_elem; }
296 KOKKOS_DEFAULTED_FUNCTION ~Array() =
default;
297 KOKKOS_INLINE_FUNCTION_DELETED Array() =
delete;
298 KOKKOS_INLINE_FUNCTION_DELETED Array(
const Array&) =
delete;
305 KOKKOS_INLINE_FUNCTION
306 Array& operator=(
const Array& rhs) {
307 const size_t n = size() < rhs.size() ? size() : rhs.size();
308 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
312 template <
size_t N,
class P>
313 KOKKOS_INLINE_FUNCTION Array& operator=(
const Array<T, N, P>& rhs) {
314 const size_t n = size() < rhs.size() ? size() : rhs.size();
315 for (
size_t i = 0; i < n; ++i) m_elem[i * m_stride] = rhs[i];
319 KOKKOS_INLINE_FUNCTION constexpr Array(pointer arg_ptr, size_type arg_size,
320 size_type arg_stride)
321 : m_elem(arg_ptr), m_size(arg_size), m_stride(arg_stride) {}
324 template <
typename T,
typename... Us>
325 Array(T, Us...)->Array<T, 1 +
sizeof...(Us)>;
330 template <
class T, std::
size_t N>
331 struct std::tuple_size<Kokkos::Array<T, N>>
332 : std::integral_constant<std::size_t, N> {};
334 template <std::
size_t I,
class T, std::
size_t N>
335 struct std::tuple_element<I, Kokkos::Array<T, N>> {
341 template <std::
size_t I,
class T, std::
size_t N>
342 KOKKOS_FUNCTION constexpr T&
get(Array<T, N>& a) noexcept {
346 template <std::
size_t I,
class T, std::
size_t N>
347 KOKKOS_FUNCTION constexpr T
const&
get(Array<T, N>
const& a) noexcept {
351 template <std::
size_t I,
class T, std::
size_t N>
352 KOKKOS_FUNCTION constexpr T&&
get(Array<T, N>&& a) noexcept {
353 return std::move(a[I]);
356 template <std::
size_t I,
class T, std::
size_t N>
357 KOKKOS_FUNCTION constexpr T
const&&
get(Array<T, N>
const&& a) noexcept {
358 return std::move(a[I]);
364 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
365 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
366 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ARRAY
Derived from the C++17 'std::array'. Dropping the iterator interface.