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>
 
  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 
Derived from the C++17 'std::array'. Dropping the iterator interface.