SpECTRE Documentation Coverage Report
Current view: top level - Utilities - Array.hpp Hit Total Coverage
Commit: e88482f6bea8064ca40dbebfd81596847f6f1cd9 Lines: 2 46 4.3 %
Date: 2024-10-21 20:40:03
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <cstddef>
       8             : #include <functional>
       9             : #include <iterator>
      10             : #include <ostream>
      11             : #include <utility>
      12             : 
      13             : #include "Utilities/Kokkos/KokkosCore.hpp"
      14             : #include "Utilities/Requires.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : #include "Utilities/TypeTraits/IsA.hpp"
      17             : 
      18             : namespace cpp20 {
      19             : namespace detail {
      20             : template <typename T, size_t Size, size_t... Is>
      21             : KOKKOS_FUNCTION constexpr std::array<T, Size> convert_to_array(
      22             :     // NOLINTNEXTLINE(modernize-avoid-c-arrays)
      23             :     const T (&t)[Size], std::index_sequence<Is...> /*meta*/) {
      24             :   return {{t[Is]...}};
      25             : }
      26             : }  // namespace detail
      27             : 
      28             : /// \brief A `std::array` implementation with partial C++20 support
      29             : ///
      30             : /// \warning This is not a standard-compliant C++20 `std::array` implementation.
      31             : /// We provide this implementation because we need the `constexpr operator==`
      32             : /// from C++20. Note that other C++20 changes, such as the replacement of the
      33             : /// other comparison operators in favor of `operator<=>`, are not implemented.
      34             : /// This class can be removed when we support C++20.
      35             : template <typename T, size_t Size>
      36           1 : struct array {
      37           0 :   using value_type = T;
      38           0 :   using reference = value_type&;
      39           0 :   using const_reference = const value_type&;
      40           0 :   using iterator = value_type*;
      41           0 :   using const_iterator = const value_type*;
      42           0 :   using pointer = value_type*;
      43           0 :   using const_pointer = const value_type*;
      44           0 :   using size_type = size_t;
      45           0 :   using difference_type = std::ptrdiff_t;
      46           0 :   using reverse_iterator = std::reverse_iterator<iterator>;
      47           0 :   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
      48             : 
      49             :   // clang-tidy: mark explicit. We want implicit conversion
      50             :   KOKKOS_FUNCTION constexpr operator std::array<T, Size>() const {  // NOLINT
      51             :     return detail::convert_to_array(data_, std::make_index_sequence<Size>{});
      52             :   }
      53             : 
      54           0 :   KOKKOS_FUNCTION constexpr iterator begin() {
      55             :     return iterator(data_);  // NOLINT
      56             :   }
      57           0 :   KOKKOS_FUNCTION constexpr const_iterator begin() const {
      58             :     return const_iterator(data_);  // NOLINT
      59             :   }
      60           0 :   KOKKOS_FUNCTION constexpr iterator end() {
      61             :     return iterator(data_ + Size);  // NOLINT
      62             :   }
      63           0 :   KOKKOS_FUNCTION constexpr const_iterator end() const {
      64             :     return const_iterator(data_ + Size);  // NOLINT
      65             :   }
      66             : 
      67           0 :   KOKKOS_FUNCTION constexpr const_iterator cbegin() const { return begin(); }
      68           0 :   KOKKOS_FUNCTION constexpr const_iterator cend() const { return end(); }
      69             : 
      70           0 :   KOKKOS_FUNCTION constexpr size_type size() const { return Size; }
      71           0 :   KOKKOS_FUNCTION constexpr size_type max_size() const { return Size; }
      72           0 :   KOKKOS_FUNCTION constexpr bool empty() const { return Size == 0; }
      73             : 
      74           0 :   KOKKOS_FUNCTION constexpr reference operator[](const size_type i) {
      75             :     return data_[i];  // NOLINT
      76             :   }
      77           0 :   KOKKOS_FUNCTION constexpr const_reference operator[](
      78             :       const size_type i) const {
      79             :     return data_[i];  // NOLINT
      80             :   }
      81             : 
      82           0 :   KOKKOS_FUNCTION constexpr reference at(const size_type i) {
      83             :     return data_[i];  // NOLINT
      84             :   }
      85           0 :   KOKKOS_FUNCTION constexpr const_reference at(const size_type i) const {
      86             :     return data_[i];  // NOLINT
      87             :   }
      88             : 
      89           0 :   KOKKOS_FUNCTION constexpr reference front() { return data_[0]; }
      90           0 :   KOKKOS_FUNCTION constexpr const_reference front() const { return data_[0]; }
      91           0 :   KOKKOS_FUNCTION constexpr reference back() {
      92             :     return data_[Size > 0 ? Size - 1 : 0];
      93             :   }
      94           0 :   KOKKOS_FUNCTION constexpr const_reference back() const {
      95             :     return data_[Size > 0 ? Size - 1 : 0];
      96             :   }
      97             : 
      98           0 :   KOKKOS_FUNCTION constexpr value_type* data() { return data_; }
      99           0 :   KOKKOS_FUNCTION constexpr const value_type* data() const { return data_; }
     100             : 
     101             :   // NOLINTNEXTLINE(modernize-avoid-c-arrays)
     102           0 :   value_type data_[Size > 0 ? Size : 1];
     103             : };
     104             : namespace detail {
     105             : template <typename T = void>
     106             : struct Equal {
     107             :   KOKKOS_FUNCTION constexpr bool inline operator()(const T& lhs,
     108             :                                                    const T& rhs) const {
     109             :     return lhs == rhs;
     110             :   }
     111             : };
     112             : 
     113             : template <>
     114             : struct Equal<void> {
     115             :   template <class T0, class T1>
     116             :   KOKKOS_FUNCTION constexpr bool inline operator()(T0&& lhs, T1&& rhs) const {
     117             :     return std::forward<T0>(lhs) == std::forward<T1>(rhs);
     118             :   }
     119             : };
     120             : }  // namespace detail
     121             : 
     122             : template <typename InputIter1, typename InputIter2,
     123             :           typename BinaryPred = detail::Equal<>>
     124           0 : KOKKOS_FUNCTION constexpr bool equal(InputIter1 first1, InputIter1 last1,
     125             :                                      InputIter2 first2,
     126             :                                      BinaryPred pred = detail::Equal<>{}) {
     127             :   for (; first1 != last1; ++first1, ++first2) {
     128             :     if (not pred(*first1, *first2)) {
     129             :       return false;
     130             :     }
     131             :   }
     132             :   return true;
     133             : }
     134             : 
     135             : template <typename InputIter1, typename InputIter2,
     136             :           typename BinaryPred = std::less_equal<>>
     137           0 : KOKKOS_FUNCTION constexpr bool lexicographical_compare(
     138             :     InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2,
     139             :     BinaryPred pred = std::less_equal<>{}) {
     140             :   for (; first2 != last2; ++first1, ++first2) {
     141             :     if (first1 == last1 or pred(*first1, *first2)) {
     142             :       return true;
     143             :     } else if (pred(*first2, *first1)) {
     144             :       return false;
     145             :     }
     146             :   }
     147             :   return false;
     148             : }
     149             : 
     150             : template <class T, size_t Size>
     151           0 : KOKKOS_FUNCTION inline constexpr bool operator==(const array<T, Size>& x,
     152             :                                                  const array<T, Size>& y) {
     153             :   return equal(x.data_, x.data_ + Size, y.data_);  // NOLINT
     154             : }
     155             : 
     156             : template <class T, size_t Size>
     157           0 : KOKKOS_FUNCTION inline constexpr bool operator!=(const array<T, Size>& lhs,
     158             :                                                  const array<T, Size>& rhs) {
     159             :   return not(lhs == rhs);
     160             : }
     161             : 
     162             : template <class T, size_t Size>
     163           0 : KOKKOS_FUNCTION inline constexpr bool operator<(const array<T, Size>& lhs,
     164             :                                                 const array<T, Size>& rhs) {
     165             :   return lexicographical_compare(lhs.__elems_, lhs.__elems_ + Size,
     166             :                                  rhs.__elems_, rhs.__elems_ + Size);
     167             : }
     168             : 
     169             : template <class T, size_t Size>
     170           0 : KOKKOS_FUNCTION inline constexpr bool operator>(const array<T, Size>& lhs,
     171             :                                                 const array<T, Size>& rhs) {
     172             :   return rhs < lhs;
     173             : }
     174             : 
     175             : template <class T, size_t Size>
     176           0 : KOKKOS_FUNCTION inline constexpr bool operator<=(const array<T, Size>& lhs,
     177             :                                                  const array<T, Size>& rhs) {
     178             :   return not(rhs < lhs);
     179             : }
     180             : 
     181             : template <class T, size_t Size>
     182           0 : KOKKOS_FUNCTION inline constexpr bool operator>=(const array<T, Size>& lhs,
     183             :                                                  const array<T, Size>& rhs) {
     184             :   return not(lhs < rhs);
     185             : }
     186             : 
     187             : template <typename T>
     188           0 : inline std::ostream& operator<<(std::ostream& os, const array<T, 0>& /*a*/) {
     189             :   return os << "()";
     190             : }
     191             : 
     192             : template <typename T, size_t N>
     193           0 : inline std::ostream& operator<<(std::ostream& os, const array<T, N>& a) {
     194             :   os << '(';
     195             :   for (size_t i = 0; i < N - 1; ++i) {
     196             :     os << a[i] << ',';
     197             :   }
     198             :   if (N > 0) {
     199             :     os << a[N - 1];
     200             :   }
     201             :   os << ')';
     202             :   return os;
     203             : }
     204             : }  // namespace cpp20
     205             : 
     206             : namespace detail {
     207             : template <typename List, size_t... indices,
     208             :           Requires<not tt::is_a_v<tmpl::list, tmpl::front<List>>> = nullptr>
     209             : KOKKOS_FUNCTION inline constexpr auto make_cpp20_array_from_list_helper(
     210             :     std::integer_sequence<size_t, indices...> /*meta*/)
     211             :     -> cpp20::array<std::decay_t<decltype(tmpl::front<List>::value)>,
     212             :                     tmpl::size<List>::value> {
     213             :   return cpp20::array<std::decay_t<decltype(tmpl::front<List>::value)>,
     214             :                       tmpl::size<List>::value>{
     215             :       {tmpl::at<List, tmpl::size_t<indices>>::value...}};
     216             : }
     217             : }  // namespace detail
     218             : 
     219             : /// \ingroup ConstantExpressionsGroup
     220             : /// Make an array from a typelist that holds std::integral_constant's all of
     221             : /// which have the same `value_type`
     222             : ///
     223             : /// \tparam List the typelist of std::integral_constant's
     224             : /// \return array of integral values from the typelist
     225             : template <typename List,
     226             :           Requires<not tt::is_a_v<tmpl::list, tmpl::front<List>>> = nullptr>
     227           1 : KOKKOS_FUNCTION inline constexpr auto make_cpp20_array_from_list()
     228             :     -> cpp20::array<std::decay_t<decltype(tmpl::front<List>::value)>,
     229             :                     tmpl::size<List>::value> {
     230             :   return detail::make_cpp20_array_from_list_helper<List>(
     231             :       std::make_integer_sequence<size_t, tmpl::size<List>::value>{});
     232             : }
     233             : 
     234             : template <typename TypeForZero,
     235             :           Requires<not tt::is_a_v<tmpl::list, TypeForZero>> = nullptr>
     236             : KOKKOS_FUNCTION inline constexpr cpp20::array<std::decay_t<TypeForZero>, 0>
     237           0 : make_cpp20_array_from_list() {
     238             :   return cpp20::array<std::decay_t<TypeForZero>, 0>{{}};
     239             : }
     240             : 
     241             : namespace detail {
     242             : template <typename T, size_t Size, size_t... Is>
     243             : inline constexpr cpp20::array<T, Size> convert_to_cpp20_array_impl(
     244             :     const std::array<T, Size>& t,
     245             :     std::index_sequence<
     246             :         Is...> /*meta*/) {
     247             :   return {{t[Is]...}};
     248             : }
     249             : }  // namespace detail
     250             : 
     251             : template <typename T, size_t Size, size_t... Is>
     252             : inline constexpr cpp20::array<T, Size>
     253           0 : convert_to_cpp20_array(const std::array<T, Size>& t) {
     254             :   return detail::convert_to_cpp20_array_impl(t,
     255             :                                              std::make_index_sequence<Size>{});
     256             : }

Generated by: LCOV version 1.14