diff --git a/docs/source/API/core/STL-Compatibility.rst b/docs/source/API/core/STL-Compatibility.rst index 436a0d307..25665915f 100644 --- a/docs/source/API/core/STL-Compatibility.rst +++ b/docs/source/API/core/STL-Compatibility.rst @@ -10,4 +10,5 @@ Select the links below to see the details. .. toctree:: :maxdepth: 1 + ./stl-compat/Array ./stl-compat/pair diff --git a/docs/source/API/core/stl-compat/Array.rst b/docs/source/API/core/stl-compat/Array.rst new file mode 100644 index 000000000..114a10078 --- /dev/null +++ b/docs/source/API/core/stl-compat/Array.rst @@ -0,0 +1,251 @@ +``Array`` +============== + +.. role:: cppkokkos(code) + :language: cppkokkos + +.. + The (pulic header) file the user will include in their code + +Defined in header ```` which is included from ```` + +.. + High-level, human-language summary of what the thing does, and if possible, brief statement about why it exists (2 - 3 sentences, max); + +Description +----------- + +``Array`` is a contiguous aggregate owning container storing a fixed size sequence of objects (models holding exactly N elements). + +* This is intended as a replacement for ``std::array``. +* This container is an owning container (the data is embeddded in the container itself). +* This container is an aggregate type with the same semantics as a struct holding a C-style array ``T[N]`` as its only non-static data member when ``N > 0``; otherwise, it is an empty container. +* Unlike a C-style array, it doesn't decay to ``T*`` automatically. +* As an aggregate type, it can be initialized with aggregate-initialization given at most ``N`` initializers that are convertible to ``T``: ``Kokkos::Array a = { 1, 2, 3 };``. + +.. + The API of the entity. + +Interface +--------- + +.. versionchanged:: 4.4.0 + +.. cppkokkos:struct:: template Array + + .. + Template parameters (if applicable) + Omit template parameters that are just used for specialization/are deduced/ and/or should not be exposed to the user. + + .. rubric:: Template Parameters + + :tparam T: The type of the element being stored. + :tparam N: The number of elements being stored. + + .. rubric:: Public Types + + .. cppkokkos:type:: value_type = T + .. cppkokkos:type:: pointer = T* + .. cppkokkos:type:: const_pointer = const T* + .. cppkokkos:type:: reference = T& + .. cppkokkos:type:: const_reference = const T& + .. cppkokkos:type:: size_type = size_t + .. cppkokkos:type:: difference_type = ptrdiff_t + + .. rubric:: Public Member Functions + + .. cppkokkos:function:: static constexpr bool empty() + + :return: ``N == 0`` + + .. cppkokkos:function:: static constexpr size_type size() + .. cppkokkos:function:: constexpr size_type max_size() const + + :return: ``N`` + + .. cppkokkos:function:: template constexpr reference operator[](const iType& i) + .. cppkokkos:function:: template constexpr const_reference operator[](const iType& i) const + + :tparam iType: An integral type or an unscoped enum type. + + :return: A reference to the ``i``-th element of the array. + + .. cppkokkos:function:: constexpr pointer data() + .. cppkokkos:function:: constexpr const_pointer data() const + + :return: A pointer to the first element of the array. If ``N == 0``, the return value is unspecified and not dereferenceable. + + +Deduction Guides +---------------- + +.. cppkokkos:function:: template Array(T, U...) -> Array + +Non-Member Functions +-------------------- + +.. + These should only be listed here if they are closely related. E.g. friend operators. However, + something like view_alloc shouldn't be here for view + +.. cppkokkos:function:: template constexpr bool operator==(const Array& l, const Array& r) noexcept + + :return: ``true`` if and only if ∀ the elements in ``l`` and ``r`` compare equal. + +.. cppkokkos:function:: template constexpr bool operator!=(const Array& l, const Array& r) noexcept + + :return: ``!(l == r)`` + +.. cppkokkos:function:: template constexpr kokkos_swap(Array& l, Array& r) noexcept(N == 0 || is_nothrow_swappable_V) + + :return: If ``T`` is swappable or ``N == 0``, each of the elements in `l` and `r` are swapped via ``kokkos_swap``. + +.. cppkokkos:function:: template constexpr Array, N> to_array(T (&a)[N]) +.. cppkokkos:function:: template constexpr Array, N> to_array(T (&&a)[N]) + + :return: An ``Array`` containing the elements copied/moved from ``a``. + +.. cppkokkos:function:: template constexpr T& get(Array& a) noexcept +.. cppkokkos:function:: template constexpr const T& get(const Array& a) noexcept + + :return: ``a[I]`` for (tuple protocol / structured binding support) + +.. cppkokkos:function:: template constexpr T&& get(Array&& a) noexcept +.. cppkokkos:function:: template constexpr const T&& get(const Array&& a) noexcept + + :return: ``std::move(a[I])`` (for tuple protocol / structured binding support) + +.. cppkokkos:function:: template constexpr T* begin(Array& a) noexcept +.. cppkokkos:function:: template constexpr const T* begin(const Array& a) noexcept + + :return: ``a.data()`` + +.. cppkokkos:function:: template constexpr T* end(Array& a) noexcept +.. cppkokkos:function:: template constexpr const T* end(const Array& a) noexcept + + :return: ``a.data() + a.size()`` + +Deprecated Interface +-------------------- +.. deprecated:: 4.4.00 + +.. cppkokkos:struct:: template Array + +* The primary template was an contiguous aggregate owning container of exactly ``N`` elements of type ``T``. +* This container did not support move semantics. + +.. cppkokkos:struct:: template Array + +* This container was an empty container. + +.. cppkokkos:struct:: template Array::contiguous> + +* This container was a non-owning container. +* This container had its size determined at construction time. +* This container could be assigned from any ``Array``. +* Assignment did not change the size of this container. +* This container did not support move semantics. + +.. cppkokkos:struct:: template Array::strided> + +* This container was a non-owning container. +* This container had its size and stride determined at construction time. +* This container could be assigned from any ``Array``. +* Assignment did not change the size or stride of this container. +* This container did not support move semantics. + +.. cppkokkos:struct:: template<> Array + + .. rubric:: Public Types + + .. cppkokkos:type:: contiguous + .. cppkokkos:type:: stided + +* This specialization defined the embedded tag types: ``contiguous`` and ``strided``. + +Examples +________ + +.. code-block:: cpp + + #include "Kokkos_Core.hpp" + #include + #include + #include + #include + #include + #include + #include + #include + + // creates a constexpr array of string_view's + constexpr auto w1n = Kokkos::to_array( + {"Mary", "Patricia", "Linda", "Barbara", "Elizabeth", "Jennifer"}); + static_assert( + std::is_same_v>); + static_assert(w1n.size() == 6 and w1n[5] == "Jennifer"); + + extern int Main(int /* argc */, char const *const /* argv */[]); + int Main(int /* argc */, char const *const /* argv */[]) { + Kokkos::ScopeGuard _; + + // Construction uses aggregate initialization + [[maybe_unused]] Kokkos::Array a1{ + {1, 2, 3}}; // Double-braces required in C++11 + // and still allowed in C++14 and beyond + + Kokkos::Array a2 = {1, 2, 3}; // Double braces never required after = + + // Output is 3 2 1 + std::reverse_copy(std::data(a2), end(a2), + std::ostream_iterator(std::cout, " ")); + std::cout << '\n'; + + // Ranged for loop is supported + // Output is E Ǝ + Kokkos::Array a3{"E", "\u018E"}; + for (const auto &s : a3) + std::cout << s << ' '; + std::cout << '\n'; + + // Deduction guide for array creation + [[maybe_unused]] Kokkos::Array a4{3.0, 1.0, 4.0}; // Kokkos::Array + + // Behavior of unspecified elements is the same as with built-in arrays + [[maybe_unused]] Kokkos::Array a5; // No list init, a5[0] and a5[1] + // are default initialized + [[maybe_unused]] Kokkos::Array + a6{}; // List init, both elements are value + // initialized, a6[0] = a6[1] = 0 + [[maybe_unused]] Kokkos::Array a7{ + 1}; // List init, unspecified element is value + // initialized, a7[0] = 1, a7[1] = 0 + + // copies a string literal + auto t1 = Kokkos::to_array("foo"); + static_assert(t1.size() == 4); + + // deduces both element type and length + auto t2 = Kokkos::to_array({0, 2, 1, 3}); + static_assert(std::is_same_v>); + + // deduces length with element type specified + // implicit conversion happens + auto t3 = Kokkos::to_array({0, 1, 3}); + static_assert(std::is_same_v>); + + auto t4 = Kokkos::to_array>( + {{3, 0.0f}, {4, 0.1f}, {4, 0.1e23f}}); + static_assert(t4.size() == 3); + + // creates a non-copyable Kokkos::Array + auto t5 = Kokkos::to_array({std::make_unique(3)}); + static_assert(t5.size() == 1); + + // error: copying multidimensional arrays is not supported + // char s[2][6] = {"nice", "thing"}; + // auto t6 = Kokkos::to_array(s); + + return 0; + } +