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

Generated by: LCOV version 2.0-1