SpECTRE Documentation Coverage Report
Current view: top level - DataStructures - SpinWeighted.hpp Hit Total Coverage
Commit: daeff9d50a2d2e71bdb651f5c29a44f3a1c119f6 Lines: 39 112 34.8 %
Date: 2024-02-26 18:18:56
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 "DataStructures/ComplexDataVector.hpp"
       7             : #include "Utilities/ForceInline.hpp"
       8             : #include "Utilities/Requires.hpp"
       9             : #include "Utilities/SetNumberOfGridPoints.hpp"
      10             : #include "Utilities/TypeTraits.hpp"
      11             : 
      12             : /// @{
      13             : /*!
      14             :  * \ingroup DataStructuresGroup
      15             :  * \brief Make a spin-weighted type `T` with spin-weight `Spin`. Mathematical
      16             :  * operators are restricted to addition, subtraction, multiplication and
      17             :  * division, with spin-weights checked for validity.
      18             :  *
      19             :  * \details For a spin-weighted object, we limit operations to those valid for a
      20             :  * pair of spin-weighted quantities - i.e. addition only makes sense when the
      21             :  * two summands possess the same spin weight, and multiplication (or division)
      22             :  * result in a summed (or subtracted) spin weight.
      23             :  */
      24             : template <typename T, int Spin, bool is_vector = is_derived_of_vector_impl_v<T>>
      25           1 : struct SpinWeighted;
      26             : 
      27             : template <typename T, int Spin>
      28           0 : struct SpinWeighted<T, Spin, false> {
      29           0 :   using value_type = T;
      30           0 :   constexpr static int spin = Spin;
      31             : 
      32           0 :   SpinWeighted() = default;
      33           0 :   SpinWeighted(const SpinWeighted&) = default;
      34           0 :   SpinWeighted(SpinWeighted&&) = default;
      35           0 :   SpinWeighted& operator=(const SpinWeighted&) = default;
      36           0 :   SpinWeighted& operator=(SpinWeighted&&) = default;
      37           0 :   ~SpinWeighted() = default;
      38             : 
      39             :   // clang-tidy asks that these be marked explicit, but we actually do not want
      40             :   // them explicit for use in the math operations below.
      41             :   template <typename Rhs>
      42           0 :   SpinWeighted(const SpinWeighted<Rhs, Spin>& rhs)  // NOLINT
      43             :       : data_{rhs.data()} {}
      44             : 
      45             :   template <typename Rhs>
      46           0 :   SpinWeighted(SpinWeighted<Rhs, Spin>&& rhs)  // NOLINT
      47             :       : data_{std::move(rhs.data())} {}
      48             : 
      49           0 :   SpinWeighted(const T& rhs) : data_{rhs} {}        // NOLINT
      50           0 :   SpinWeighted(T&& rhs) : data_{std::move(rhs)} {}  // NOLINT
      51           0 :   explicit SpinWeighted(const size_t size) : data_{size} {}
      52             :   template <typename U>
      53           0 :   SpinWeighted(const size_t size, const U& val) : data_{size, val} {}
      54             : 
      55             :   template <typename Rhs>
      56           0 :   SpinWeighted& operator=(const SpinWeighted<Rhs, Spin>& rhs) {
      57             :     data_ = rhs.data();
      58             :     return *this;
      59             :   }
      60             : 
      61             :   template <typename Rhs>
      62           0 :   SpinWeighted& operator=(SpinWeighted<Rhs, Spin>&& rhs) {
      63             :     data_ = std::move(rhs.data());
      64             :     return *this;
      65             :   }
      66             : 
      67           0 :   SpinWeighted& operator=(const T& rhs) {
      68             :     data_ = rhs;
      69             :     return *this;
      70             :   }
      71           0 :   SpinWeighted& operator=(T&& rhs) {
      72             :     data_ = std::move(rhs);
      73             :     return *this;
      74             :   }
      75             : 
      76             :   template <typename Rhs>
      77           0 :   auto& operator+=(const SpinWeighted<Rhs, Spin>& rhs) {
      78             :     data_ += rhs.data();
      79             :     return *this;
      80             :   }
      81             : 
      82           0 :   auto& operator+=(const T& rhs) {
      83             :     data_ += rhs;
      84             :     return *this;
      85             :   }
      86             : 
      87             :   template <typename Rhs>
      88           0 :   auto& operator-=(const SpinWeighted<Rhs, Spin>& rhs) {
      89             :     data_ -= rhs.data();
      90             :     return *this;
      91             :   }
      92             : 
      93           0 :   auto& operator-=(const T& rhs) {
      94             :     data_ -= rhs;
      95             :     return *this;
      96             :   }
      97             : 
      98           0 :   T& data() { return data_; }
      99           0 :   const T& data() const { return data_; }
     100             : 
     101           0 :   size_t size() const { return data_.size(); }
     102             : 
     103             :   /// Serialization for Charm++
     104             :   // NOLINTNEXTLINE(google-runtime-references)
     105           1 :   void pup(PUP::er& p);
     106             : 
     107             :  private:
     108           0 :   T data_;
     109             : };
     110             : 
     111             : template <typename T, int Spin>
     112           0 : struct SpinWeighted<T, Spin, true> {
     113           0 :   using value_type = T;
     114           0 :   constexpr static int spin = Spin;
     115             : 
     116           0 :   void set_data_ref(const gsl::not_null<T*> rhs) { data_.set_data_ref(rhs); }
     117             : 
     118             :   // needed for invoking the check in `Variables.hpp` that ensures that
     119             :   // default-constructed `Variables` are never used.
     120           0 :   void set_data_ref(const std::nullptr_t null, const size_t size) {
     121             :     data_.set_data_ref(null, size);
     122             :   }
     123             : 
     124           0 :   void set_data_ref(const gsl::not_null<SpinWeighted<T, spin>*> rhs) {
     125             :     data_.set_data_ref(make_not_null(&(rhs->data_)));
     126             :   }
     127             : 
     128             :   template <typename ValueType>
     129           0 :   void set_data_ref(ValueType* const start, const size_t set_size) {
     130             :     data_.set_data_ref(start, set_size);
     131             :   }
     132             : 
     133           0 :   void destructive_resize(const size_t new_size) {
     134             :     data_.destructive_resize(new_size);
     135             :   }
     136             : 
     137           0 :   SpinWeighted() = default;
     138           0 :   SpinWeighted(const SpinWeighted&) = default;
     139           0 :   SpinWeighted(SpinWeighted&&) = default;
     140           0 :   SpinWeighted& operator=(const SpinWeighted&) = default;
     141           0 :   SpinWeighted& operator=(SpinWeighted&&) = default;
     142           0 :   ~SpinWeighted() = default;
     143             : 
     144             :   // clang-tidy asks that these be marked explicit, but we actually do not want
     145             :   // them explicit for use in the math operations below.
     146             :   template <typename Rhs>
     147           0 :   SpinWeighted(const SpinWeighted<Rhs, Spin>& rhs)  // NOLINT
     148             :       : data_{rhs.data()} {}
     149             : 
     150             :   template <typename Rhs>
     151           0 :   SpinWeighted(SpinWeighted<Rhs, Spin>&& rhs)  // NOLINT
     152             :       : data_{std::move(rhs.data())} {}
     153             : 
     154           0 :   SpinWeighted(const T& rhs) : data_{rhs} {}        // NOLINT
     155           0 :   SpinWeighted(T&& rhs) : data_{std::move(rhs)} {}  // NOLINT
     156           0 :   explicit SpinWeighted(const size_t size) : data_{size} {}
     157             :   template <typename U>
     158           0 :   SpinWeighted(const size_t size, const U& val) : data_{size, val} {}
     159             : 
     160             :   template <typename Rhs>
     161           0 :   SpinWeighted& operator=(const SpinWeighted<Rhs, Spin>& rhs) {
     162             :     data_ = rhs.data();
     163             :     return *this;
     164             :   }
     165             : 
     166             :   template <typename Rhs>
     167           0 :   SpinWeighted& operator=(SpinWeighted<Rhs, Spin>&& rhs) {
     168             :     data_ = std::move(rhs.data());
     169             :     return *this;
     170             :   }
     171             : 
     172           0 :   SpinWeighted& operator=(const T& rhs) {
     173             :     data_ = rhs;
     174             :     return *this;
     175             :   }
     176           0 :   SpinWeighted& operator=(T&& rhs) {
     177             :     data_ = std::move(rhs);
     178             :     return *this;
     179             :   }
     180             : 
     181             :   template <typename Rhs>
     182           0 :   auto& operator+=(const SpinWeighted<Rhs, Spin>& rhs) {
     183             :     data_ += rhs.data();
     184             :     return *this;
     185             :   }
     186             : 
     187           0 :   auto& operator+=(const T& rhs) {
     188             :     data_ += rhs;
     189             :     return *this;
     190             :   }
     191             : 
     192             :   template <typename Rhs>
     193           0 :   auto& operator-=(const SpinWeighted<Rhs, Spin>& rhs) {
     194             :     data_ -= rhs.data();
     195             :     return *this;
     196             :   }
     197             : 
     198           0 :   auto& operator-=(const T& rhs) {
     199             :     data_ -= rhs;
     200             :     return *this;
     201             :   }
     202             : 
     203           0 :   T& data() { return data_; }
     204           0 :   const T& data() const { return data_; }
     205             : 
     206           0 :   size_t size() const { return data_.size(); }
     207             : 
     208             :   /// Serialization for Charm++
     209             :   // NOLINTNEXTLINE(google-runtime-references)
     210           1 :   void pup(PUP::er& p);
     211             : 
     212             :  private:
     213           0 :   T data_;
     214             : };
     215             : /// @}
     216             : 
     217             : template <typename T, int Spin>
     218             : void SpinWeighted<T, Spin, true>::pup(PUP::er& p) {
     219             :   p | data_;
     220             : }
     221             : 
     222             : template <typename T, int Spin>
     223             : void SpinWeighted<T, Spin, false>::pup(PUP::er& p) {
     224             :   p | data_;
     225             : }
     226             : 
     227             : /// @{
     228             : /// \ingroup TypeTraitsGroup
     229             : /// \ingroup DataStructuresGroup
     230             : /// This is a `std::true_type` if the provided type is a `SpinWeighted` of any
     231             : /// type and spin, otherwise is a `std::false_type`.
     232             : template <typename T>
     233           1 : struct is_any_spin_weighted : std::false_type {};
     234             : 
     235             : template <typename T, int S>
     236           0 : struct is_any_spin_weighted<SpinWeighted<T, S>> : std::true_type {};
     237             : /// @}
     238             : 
     239             : template <typename T>
     240           0 : constexpr bool is_any_spin_weighted_v = is_any_spin_weighted<T>::value;
     241             : 
     242             : /// @{
     243             : /// \ingroup TypeTraitsGroup
     244             : /// \ingroup DataStructuresGroup
     245             : /// This is a `std::true_type` if the provided type `T` is a `SpinWeighted` of
     246             : /// `InternalType` and any spin, otherwise is a `std::false_type`.
     247             : template <typename InternalType, typename T>
     248           1 : struct is_spin_weighted_of : std::false_type {};
     249             : 
     250             : template <typename InternalType, int S>
     251           0 : struct is_spin_weighted_of<InternalType, SpinWeighted<InternalType, S>>
     252             :     : std::true_type {};
     253             : /// @}
     254             : 
     255             : template <typename InternalType, typename T>
     256           0 : constexpr bool is_spin_weighted_of_v =
     257             :     is_spin_weighted_of<InternalType, T>::value;
     258             : 
     259             : /// @{
     260             : /// \ingroup TypeTraitsGroup
     261             : /// \ingroup DataStructuresGroup
     262             : /// This is a `std::true_type` if the provided type `T1` is a `SpinWeighted` and
     263             : /// `T2` is a `SpinWeighted`, and both have the same internal type, but any
     264             : /// combination of spin weights.
     265             : template <typename T1, typename T2>
     266           1 : struct is_spin_weighted_of_same_type : std::false_type {};
     267             : 
     268             : template <typename T, int Spin1, int Spin2>
     269           0 : struct is_spin_weighted_of_same_type<SpinWeighted<T, Spin1>,
     270             :                                      SpinWeighted<T, Spin2>> : std::true_type {
     271             : };
     272             : /// @}
     273             : 
     274             : template <typename T1, typename T2>
     275           0 : constexpr bool is_spin_weighted_of_same_type_v =
     276             :     is_spin_weighted_of_same_type<T1, T2>::value;
     277             : 
     278             : /// @{
     279             : /// \brief Add two spin-weighted quantities if the types are compatible and
     280             : /// spins are the same. Un-weighted quantities are assumed to be spin 0.
     281             : // These overloads are designed to allow SpinWeighted to wrap Blaze expression
     282             : // templates to ensure efficient math operations, necessitating the
     283             : // `decltype(declval<T>() ...` syntax
     284             : template <typename T1, typename T2, int Spin>
     285             : SPECTRE_ALWAYS_INLINE
     286             :     SpinWeighted<decltype(std::declval<T1>() + std::declval<T2>()), Spin>
     287           1 :     operator+(const SpinWeighted<T1, Spin>& lhs,
     288             :               const SpinWeighted<T2, Spin>& rhs) {
     289             :   return {lhs.data() + rhs.data()};
     290             : }
     291             : template <typename T>
     292             : SPECTRE_ALWAYS_INLINE
     293             :     SpinWeighted<decltype(std::declval<T>() + std::declval<T>()), 0>
     294           1 :     operator+(const SpinWeighted<T, 0>& lhs, const T& rhs) {
     295             :   return {lhs.data() + rhs};
     296             : }
     297             : template <typename T>
     298             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     299             :     decltype(std::declval<T>() + std::declval<get_vector_element_type_t<T>>()),
     300             :     0>
     301           1 : operator+(const SpinWeighted<T, 0>& lhs,
     302             :           const get_vector_element_type_t<T>& rhs) {
     303             :   return {lhs.data() + rhs};
     304             : }
     305             : template <typename T>
     306             : SPECTRE_ALWAYS_INLINE
     307             :     SpinWeighted<decltype(std::declval<T>() + std::declval<T>()), 0>
     308           1 :     operator+(const T& lhs, const SpinWeighted<T, 0>& rhs) {
     309             :   return {lhs + rhs.data()};
     310             : }
     311             : template <typename T>
     312             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     313             :     decltype(std::declval<get_vector_element_type_t<T>>() + std::declval<T>()),
     314             :     0>
     315           1 : operator+(const get_vector_element_type_t<T>& lhs,
     316             :           const SpinWeighted<T, 0>& rhs) {
     317             :   return {lhs + rhs.data()};
     318             : }
     319             : /// @}
     320             : 
     321             : /// @{
     322             : /// \brief Subtract two spin-weighted quantities if the types are compatible and
     323             : /// spins are the same. Un-weighted quantities are assumed to be spin 0.
     324             : // These overloads are designed to allow SpinWeighted to wrap Blaze expression
     325             : // templates to ensure efficient math operations, necessitating the
     326             : // `decltype(declval<T>() ...` syntax
     327             : template <typename T1, typename T2, int Spin>
     328             : SPECTRE_ALWAYS_INLINE
     329             :     SpinWeighted<decltype(std::declval<T1>() - std::declval<T2>()), Spin>
     330           1 :     operator-(const SpinWeighted<T1, Spin>& lhs,
     331             :               const SpinWeighted<T2, Spin>& rhs) {
     332             :   return {lhs.data() - rhs.data()};
     333             : }
     334             : template <typename T>
     335             : SPECTRE_ALWAYS_INLINE
     336             :     SpinWeighted<decltype(std::declval<T>() - std::declval<T>()), 0>
     337           1 :     operator-(const SpinWeighted<T, 0>& lhs, const T& rhs) {
     338             :   return {lhs.data() - rhs};
     339             : }
     340             : template <typename T>
     341             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     342             :     decltype(std::declval<T>() - std::declval<get_vector_element_type_t<T>>()),
     343             :     0>
     344           1 : operator-(const SpinWeighted<T, 0>& lhs,
     345             :           const get_vector_element_type_t<T>& rhs) {
     346             :   return {lhs.data() - rhs};
     347             : }
     348             : template <typename T>
     349             : SPECTRE_ALWAYS_INLINE
     350             :     SpinWeighted<decltype(std::declval<T>() - std::declval<T>()), 0>
     351           1 :     operator-(const T& lhs, const SpinWeighted<T, 0>& rhs) {
     352             :   return {lhs - rhs.data()};
     353             : }
     354             : template <typename T>
     355             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     356             :     decltype(std::declval<get_vector_element_type_t<T>>() - std::declval<T>()),
     357             :     0>
     358           1 : operator-(const get_vector_element_type_t<T>& lhs,
     359             :           const SpinWeighted<T, 0>& rhs) {
     360             :   return {lhs - rhs.data()};
     361             : }
     362             : /// @}
     363             : 
     364             : /// Negation operator preserves spin
     365             : template <typename T, int Spin>
     366             : SPECTRE_ALWAYS_INLINE SpinWeighted<decltype(-std::declval<T>()), Spin>
     367           1 : operator-(const SpinWeighted<T, Spin>& operand) {
     368             :   return {-operand.data()};
     369             : }
     370             : 
     371             : /// Unary `+` operator preserves spin
     372             : template <typename T, int Spin>
     373             : SPECTRE_ALWAYS_INLINE SpinWeighted<decltype(+std::declval<T>()), Spin>
     374           1 : operator+(const SpinWeighted<T, Spin>& operand) {
     375             :   return {+operand.data()};
     376             : }
     377             : 
     378             : /// @{
     379             : /// \brief Multiply two spin-weighted quantities if the types are compatible and
     380             : /// add the spins. Un-weighted quantities are assumed to be spin 0.
     381             : // These overloads are designed to allow SpinWeighted to wrap Blaze expression
     382             : // templates to ensure efficient math operations, necessitating the
     383             : // `decltype(declval<T>() ...` syntax
     384             : template <typename T1, typename T2, int Spin1, int Spin2>
     385             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     386             :     decltype(std::declval<T1>() * std::declval<T2>()), Spin1 + Spin2>
     387           1 : operator*(const SpinWeighted<T1, Spin1>& lhs,
     388             :           const SpinWeighted<T2, Spin2>& rhs) {
     389             :   return {lhs.data() * rhs.data()};
     390             : }
     391             : template <typename T, int Spin>
     392             : SPECTRE_ALWAYS_INLINE
     393             :     SpinWeighted<decltype(std::declval<T>() * std::declval<T>()), Spin>
     394           1 :     operator*(const SpinWeighted<T, Spin>& lhs, const T& rhs) {
     395             :   return {lhs.data() * rhs};
     396             : }
     397             : template <typename T, int Spin>
     398             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     399             :     decltype(std::declval<T>() * std::declval<get_vector_element_type_t<T>>()),
     400             :     Spin>
     401           1 : operator*(const SpinWeighted<T, Spin>& lhs,
     402             :           const get_vector_element_type_t<T>& rhs) {
     403             :   return {lhs.data() * rhs};
     404             : }
     405             : template <typename T, int Spin>
     406             : SPECTRE_ALWAYS_INLINE
     407             :     SpinWeighted<decltype(std::declval<T>() * std::declval<T>()), Spin>
     408           1 :     operator*(const T& lhs, const SpinWeighted<T, Spin>& rhs) {
     409             :   return {lhs * rhs.data()};
     410             : }
     411             : template <typename T, int Spin>
     412             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     413             :     decltype(std::declval<get_vector_element_type_t<T>>() * std::declval<T>()),
     414             :     Spin>
     415           1 : operator*(const get_vector_element_type_t<T>& lhs,
     416             :           const SpinWeighted<T, Spin>& rhs) {
     417             :   return {lhs * rhs.data()};
     418             : }
     419             : /// @}
     420             : 
     421             : /// @{
     422             : /// \brief Divide two spin-weighted quantities if the types are compatible and
     423             : /// subtract the spins. Un-weighted quantities are assumed to be spin 0.
     424             : // These overloads are designed to allow SpinWeighted to wrap Blaze expression
     425             : // templates to ensure efficient math operations, necessitating the
     426             : // `decltype(declval<T>() ...` syntax
     427             : template <typename T1, typename T2, int Spin1, int Spin2>
     428             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     429             :     decltype(std::declval<T1>() / std::declval<T2>()), Spin1 - Spin2>
     430           1 : operator/(const SpinWeighted<T1, Spin1>& lhs,
     431             :           const SpinWeighted<T2, Spin2>& rhs) {
     432             :   return {lhs.data() / rhs.data()};
     433             : }
     434             : template <typename T, int Spin>
     435             : SPECTRE_ALWAYS_INLINE
     436             :     SpinWeighted<decltype(std::declval<T>() / std::declval<T>()), Spin>
     437           1 :     operator/(const SpinWeighted<T, Spin>& lhs, const T& rhs) {
     438             :   return {lhs.data() / rhs};
     439             : }
     440             : template <typename T, int Spin>
     441             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     442             :     decltype(std::declval<T>() / std::declval<get_vector_element_type_t<T>>()),
     443             :     Spin>
     444           1 : operator/(const SpinWeighted<T, Spin>& lhs,
     445             :           const get_vector_element_type_t<T>& rhs) {
     446             :   return {lhs.data() / rhs};
     447             : }
     448             : template <typename T, int Spin>
     449             : SPECTRE_ALWAYS_INLINE
     450             :     SpinWeighted<decltype(std::declval<T>() / std::declval<T>()), -Spin>
     451           1 :     operator/(const T& lhs, const SpinWeighted<T, Spin>& rhs) {
     452             :   return {lhs / rhs.data()};
     453             : }
     454             : template <typename T, int Spin>
     455             : SPECTRE_ALWAYS_INLINE SpinWeighted<
     456             :     decltype(std::declval<get_vector_element_type_t<T>>() / std::declval<T>()),
     457             :     -Spin>
     458           1 : operator/(const get_vector_element_type_t<T>& lhs,
     459             :           const SpinWeighted<T, Spin>& rhs) {
     460             :   return {lhs / rhs.data()};
     461             : }
     462             : /// @}
     463             : 
     464             : /// conjugate the spin-weighted quantity, inverting the spin
     465             : template <typename T, int Spin>
     466             : SPECTRE_ALWAYS_INLINE SpinWeighted<decltype(conj(std::declval<T>())), -Spin>
     467           1 : conj(const SpinWeighted<T, Spin>& value) {
     468             :   return {conj(value.data())};
     469             : }
     470             : 
     471             : /// Take the exponential of the spin-weighted quantity; only valid for
     472             : /// spin-weight = 0
     473             : template <typename T>
     474           1 : SPECTRE_ALWAYS_INLINE SpinWeighted<decltype(exp(std::declval<T>())), 0> exp(
     475             :     const SpinWeighted<T, 0>& value) {
     476             :   return {exp(value.data())};
     477             : }
     478             : 
     479             : /// Take the square-root of the spin-weighted quantity; only valid for
     480             : /// spin-weight = 0
     481             : template <typename T, int Spin>
     482           1 : SPECTRE_ALWAYS_INLINE SpinWeighted<decltype(sqrt(std::declval<T>())), 0> sqrt(
     483             :     const SpinWeighted<T, Spin>& value) {
     484             :   return {sqrt(value.data())};
     485             : }
     486             : 
     487             : /// @{
     488             : /// \brief Test equivalence of spin-weighted quantities if the types are
     489             : /// compatible and spins are the same. Un-weighted quantities are assumed to
     490             : /// be spin 0.
     491             : template <typename T1, typename T2, int Spin>
     492           1 : SPECTRE_ALWAYS_INLINE bool operator==(const SpinWeighted<T1, Spin>& lhs,
     493             :                                       const SpinWeighted<T2, Spin>& rhs) {
     494             :   return lhs.data() == rhs.data();
     495             : }
     496             : template <typename T>
     497           1 : SPECTRE_ALWAYS_INLINE bool operator==(const SpinWeighted<T, 0>& lhs,
     498             :                                       const T& rhs) {
     499             :   return lhs.data() == rhs;
     500             : }
     501             : template <typename T>
     502           1 : SPECTRE_ALWAYS_INLINE bool operator==(const T& lhs,
     503             :                                       const SpinWeighted<T, 0>& rhs) {
     504             :   return lhs == rhs.data();
     505             : }
     506             : /// @}
     507             : 
     508             : /// @{
     509             : /// \brief Test inequivalence of spin-weighted quantities if the types are
     510             : /// compatible and spins are the same. Un-weighted quantities are assumed to be
     511             : /// spin 0.
     512             : template <typename T1, typename T2, int Spin>
     513           1 : SPECTRE_ALWAYS_INLINE bool operator!=(const SpinWeighted<T1, Spin>& lhs,
     514             :                                       const SpinWeighted<T2, Spin>& rhs) {
     515             :   return not(lhs == rhs);
     516             : }
     517             : template <typename T>
     518           1 : SPECTRE_ALWAYS_INLINE bool operator!=(const SpinWeighted<T, 0>& lhs,
     519             :                                       const T& rhs) {
     520             :   return not(lhs == rhs);
     521             : }
     522             : template <typename T>
     523           1 : SPECTRE_ALWAYS_INLINE bool operator!=(const T& lhs,
     524             :                                       const SpinWeighted<T, 0>& rhs) {
     525             :   return not(lhs == rhs);
     526             : }
     527             : /// @}
     528             : 
     529             : /// \ingroup DataStructuresGroup
     530             : /// Make the input `view` a `const` view of the const data `spin_weighted`, at
     531             : /// offset `offset` and length `extent`.
     532             : ///
     533             : /// \warning This DOES modify the (const) input `view`. The reason `view` is
     534             : /// taken by const pointer is to try to insist that the object to be a `const`
     535             : /// view is actually const. Of course, there are ways of subverting this
     536             : /// intended functionality and editing the data pointed into by `view` after
     537             : /// this function is called; doing so is highly discouraged and results in
     538             : /// undefined behavior.
     539             : template <typename SpinWeightedType,
     540             :           Requires<is_any_spin_weighted_v<SpinWeightedType> and
     541             :                    is_derived_of_vector_impl_v<
     542             :                        typename SpinWeightedType::value_type>> = nullptr>
     543           1 : void make_const_view(const gsl::not_null<const SpinWeightedType*> view,
     544             :                      const SpinWeightedType& spin_weighted, const size_t offset,
     545             :                      const size_t extent) {
     546             :   const_cast<SpinWeightedType*>(view.get())  // NOLINT
     547             :       ->set_data_ref(const_cast<             // NOLINT
     548             :                          typename SpinWeightedType::value_type::value_type*>(
     549             :                          spin_weighted.data().data()) +  // NOLINT
     550             :                          offset,
     551             :                      extent);
     552             : }
     553             : 
     554             : /// Stream operator simply forwards
     555             : template <typename T, int Spin>
     556           1 : std::ostream& operator<<(std::ostream& os, const SpinWeighted<T, Spin>& d) {
     557             :   return os << d.data();
     558             : }
     559             : 
     560             : namespace MakeWithValueImpls {
     561             : template <int Spin, typename SpinWeightedType>
     562           0 : struct NumberOfPoints<SpinWeighted<SpinWeightedType, Spin>> {
     563             :   static SPECTRE_ALWAYS_INLINE size_t
     564           0 :   apply(const SpinWeighted<SpinWeightedType, Spin>& input) {
     565             :     return number_of_points(input.data());
     566             :   }
     567             : };
     568             : 
     569             : template <int Spin, typename SpinWeightedType>
     570           0 : struct MakeWithSize<SpinWeighted<SpinWeightedType, Spin>> {
     571             :   template <typename ValueType>
     572           0 :   static SPECTRE_ALWAYS_INLINE SpinWeighted<SpinWeightedType, Spin> apply(
     573             :       const size_t size, const ValueType value) {
     574             :     return SpinWeighted<SpinWeightedType, Spin>{
     575             :         make_with_value<SpinWeightedType>(size, value)};
     576             :   }
     577             : };
     578             : }  // namespace MakeWithValueImpls
     579             : 
     580             : template <int Spin, typename SpinWeightedType>
     581           0 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<
     582             :     SpinWeighted<SpinWeightedType, Spin>> {
     583           0 :   static constexpr bool is_trivial =
     584             :       SetNumberOfGridPointsImpl<SpinWeightedType>::is_trivial;
     585           0 :   static SPECTRE_ALWAYS_INLINE void apply(
     586             :       const gsl::not_null<SpinWeighted<SpinWeightedType, Spin>*> result,
     587             :       const size_t size) {
     588             :     set_number_of_grid_points(make_not_null(&result->data()), size);
     589             :   }
     590             : };

Generated by: LCOV version 1.14