SpECTRE Documentation Coverage Report
Current view: top level - Utilities - DereferenceWrapper.hpp Hit Total Coverage
Commit: a8efe75339f4781ca06d43fed14c40144d5e8a08 Lines: 2 2 100.0 %
Date: 2024-10-17 21:19:21
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 1.14