SpECTRE Documentation Coverage Report
Current view: top level - Utilities - DereferenceWrapper.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 2 2
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Defines function dereference_wrapper
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <complex>
      10              : #include <functional>
      11              : #include <utility>
      12              : 
      13              : #include "Utilities/ForceInline.hpp"
      14              : #include "Utilities/Math.hpp"
      15              : #include "Utilities/Requires.hpp"
      16              : #include "Utilities/TypeTraits/IsA.hpp"
      17              : 
      18              : /// \ingroup UtilitiesGroup
      19              : /// \brief Returns the reference object held by a reference wrapper, if a
      20              : /// non-reference_wrapper type is passed in then the object is returned
      21              : template <typename T>
      22            1 : decltype(auto) dereference_wrapper(T&& t) {
      23              :   return std::forward<T>(t);
      24              : }
      25              : 
      26              : /// \cond
      27              : template <typename T>
      28              : T& dereference_wrapper(const std::reference_wrapper<T>& t) {
      29              :   return t.get();
      30              : }
      31              : template <typename T>
      32              : T& dereference_wrapper(std::reference_wrapper<T>& t) {
      33              :   return t.get();
      34              : }
      35              : template <typename T>
      36              : T&& dereference_wrapper(const std::reference_wrapper<T>&& t) {
      37              :   return t.get();
      38              : }
      39              : template <typename T>
      40              : T&& dereference_wrapper(std::reference_wrapper<T>&& t) {
      41              :   return t.get();
      42              : }
      43              : /// \endcond
      44              : 
      45              : /// \cond
      46              : // Add overloads of math functions for reference_wrapper.
      47              : // This is necessary because if a class, say DataVector, inherits from
      48              : // blaze vector types and does not specify the math operators specifically for
      49              : // DataVector then the implicit cast from reference_wrapper<DataVector> to
      50              : // DataVector does not result in finding the math operators.
      51              : //
      52              : // We use forwarding references to resolve ambiguity errors with
      53              : // DVecScalarMultExpr and DVecScalarDivExpr, with a std::reference_wrapper
      54              : // The forwarding references match everything perfectly and so the functions
      55              : // here will (almost) always win in overload selection.
      56              : #define UNARY_REF_WRAP_OP(OP)               \
      57              :   template <typename T>                     \
      58              :   SPECTRE_ALWAYS_INLINE decltype(auto) OP(  \
      59              :       const std::reference_wrapper<T>& t) { \
      60              :     return OP(t.get());                     \
      61              :   }
      62              : #define BINARY_REF_WRAP_FUNCTION_OP(OP)                                    \
      63              :   template <                                                               \
      64              :       typename T0, typename T1,                                            \
      65              :       Requires<not tt::is_a_v<std::reference_wrapper, std::decay_t<T1>>> = \
      66              :           nullptr>                                                         \
      67              :   SPECTRE_ALWAYS_INLINE decltype(auto) OP(                                 \
      68              :       const std::reference_wrapper<T0>& t0, T1&& t1) {                     \
      69              :     return OP(t0.get(), t1);                                               \
      70              :   }                                                                        \
      71              :   template <                                                               \
      72              :       typename T0, typename T1,                                            \
      73              :       Requires<not tt::is_a_v<std::reference_wrapper, std::decay_t<T0>>> = \
      74              :           nullptr>                                                         \
      75              :   SPECTRE_ALWAYS_INLINE decltype(auto) OP(                                 \
      76              :       T0&& t0, const std::reference_wrapper<T1>& t1) {                     \
      77              :     return OP(t0, t1.get());                                               \
      78              :   }                                                                        \
      79              :   template <typename T0, typename T1>                                      \
      80              :   SPECTRE_ALWAYS_INLINE decltype(auto) OP(                                 \
      81              :       const std::reference_wrapper<T0>& t0,                                \
      82              :       const std::reference_wrapper<T1>& t1) {                              \
      83              :     return OP(t0.get(), t1.get());                                         \
      84              :   }
      85              : 
      86              : #define BINARY_REF_WRAP_OP(OP)                                             \
      87              :   template <                                                               \
      88              :       typename T0, typename T1,                                            \
      89              :       Requires<not tt::is_a_v<std::reference_wrapper, std::decay_t<T1>>> = \
      90              :           nullptr>                                                         \
      91              :   SPECTRE_ALWAYS_INLINE decltype(auto) operator OP(                        \
      92              :       const std::reference_wrapper<T0>& t0, T1&& t1) {                     \
      93              :     return t0.get() OP t1;                                                 \
      94              :   }                                                                        \
      95              :   template <                                                               \
      96              :       typename T0, typename T1,                                            \
      97              :       Requires<not tt::is_a_v<std::reference_wrapper, std::decay_t<T0>>> = \
      98              :           nullptr>                                                         \
      99              :   SPECTRE_ALWAYS_INLINE decltype(auto) operator OP(                        \
     100              :       T0&& t0, const std::reference_wrapper<T1>& t1) {                     \
     101              :     return t0 OP t1.get();                                                 \
     102              :   }                                                                        \
     103              :   template <typename T0, typename T1>                                      \
     104              :   SPECTRE_ALWAYS_INLINE decltype(auto) operator OP(                        \
     105              :       const std::reference_wrapper<T0>& t0,                                \
     106              :       const std::reference_wrapper<T1>& t1) {                              \
     107              :     return t0.get() OP t1.get();                                           \
     108              :   }
     109              : 
     110              : UNARY_REF_WRAP_OP(abs)
     111              : UNARY_REF_WRAP_OP(acos)
     112              : UNARY_REF_WRAP_OP(acosh)
     113              : UNARY_REF_WRAP_OP(asin)
     114              : UNARY_REF_WRAP_OP(asinh)
     115              : UNARY_REF_WRAP_OP(atan)
     116              : BINARY_REF_WRAP_FUNCTION_OP(atan2)
     117              : UNARY_REF_WRAP_OP(atanh)
     118              : UNARY_REF_WRAP_OP(cbrt)
     119              : UNARY_REF_WRAP_OP(conj)
     120              : UNARY_REF_WRAP_OP(cos)
     121              : UNARY_REF_WRAP_OP(cosh)
     122              : UNARY_REF_WRAP_OP(erf)
     123              : UNARY_REF_WRAP_OP(erfc)
     124              : UNARY_REF_WRAP_OP(exp)
     125              : UNARY_REF_WRAP_OP(exp2)
     126              : UNARY_REF_WRAP_OP(exp10)
     127              : UNARY_REF_WRAP_OP(fabs)
     128              : BINARY_REF_WRAP_FUNCTION_OP(hypot)
     129              : UNARY_REF_WRAP_OP(imag)
     130              : UNARY_REF_WRAP_OP(invcbrt)
     131              : UNARY_REF_WRAP_OP(invsqrt)
     132              : UNARY_REF_WRAP_OP(log)
     133              : UNARY_REF_WRAP_OP(log2)
     134              : UNARY_REF_WRAP_OP(log10)
     135              : UNARY_REF_WRAP_OP(max)
     136              : UNARY_REF_WRAP_OP(min)
     137              : BINARY_REF_WRAP_FUNCTION_OP(pow)
     138              : UNARY_REF_WRAP_OP(real)
     139              : UNARY_REF_WRAP_OP(sin)
     140              : UNARY_REF_WRAP_OP(sinh)
     141              : UNARY_REF_WRAP_OP(sqrt)
     142              : UNARY_REF_WRAP_OP(step_function)
     143              : UNARY_REF_WRAP_OP(tan)
     144              : UNARY_REF_WRAP_OP(tanh)
     145              : 
     146              : BINARY_REF_WRAP_OP(+)
     147              : BINARY_REF_WRAP_OP(-)
     148              : BINARY_REF_WRAP_OP(*)
     149              : BINARY_REF_WRAP_OP(/)
     150              : BINARY_REF_WRAP_OP(==)
     151              : 
     152              : template <typename T>
     153              : SPECTRE_ALWAYS_INLINE decltype(auto) operator-(
     154              :     const std::reference_wrapper<T>& t) {
     155              :   return -t.get();
     156              : }
     157              : 
     158              : #undef UNARY_REF_WRAP_OP
     159              : #undef BINARY_REF_WRAP_OP
     160              : #undef BINARY_REF_WRAP_FUNCTION_OP
     161              : /// \endcond
        

Generated by: LCOV version 2.0-1