SpECTRE Documentation Coverage Report
Current view: top level - Utilities - MakeWithValue.hpp Hit Total Coverage
Commit: c428a3e2e0ca78fe0364ec1b0e0493c627d428d4 Lines: 9 13 69.2 %
Date: 2026-04-26 20:20:36
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 make_with_value
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <array>
      10             : #include <complex>
      11             : #include <functional>
      12             : #include <type_traits>
      13             : #include <vector>
      14             : 
      15             : #include "Utilities/Algorithm.hpp"
      16             : #include "Utilities/ErrorHandling/Assert.hpp"
      17             : #include "Utilities/ForceInline.hpp"
      18             : #include "Utilities/MakeArray.hpp"
      19             : 
      20             : /// \ingroup DataStructuresGroup
      21             : /// Implementations of make_with_value.
      22             : namespace MakeWithValueImpls {
      23             : /// Defines a method for determining the number of points represented
      24             : /// by an object.  This allows the object to appear as the input to
      25             : /// make_with_value.
      26             : ///
      27             : /// The MakeWithValueImpls::number_of_points convenience wrapper is
      28             : /// provided to simplify calling this.
      29             : template <typename T, typename = std::nullptr_t>
      30           1 : struct NumberOfPoints {
      31             :   /// The default implementation will produce a compile-time error.
      32           1 :   [[noreturn]] static SPECTRE_ALWAYS_INLINE size_t apply(const T& /*input*/) {
      33             :     static_assert(typename tmpl::has_type<T, std::false_type>::type{},
      34             :                   "Do not know how to obtain a size from this type.  Either "
      35             :                   "implement NumberOfPoints or specialize MakeWithValueImpl "
      36             :                   "for the type you are trying to create.");
      37             :   }
      38             : };
      39             : 
      40             : /// The number of points represented by an object.
      41             : template <typename T>
      42           1 : size_t number_of_points(const T& input) {
      43             :   return NumberOfPoints<T>::apply(input);
      44             : }
      45             : 
      46             : /// Defines a method for producing an object representing a given
      47             : /// number of points.
      48             : ///
      49             : /// Do not call these functions directly.  Use make_with_value
      50             : /// instead, which can take a size as its first argument.
      51             : template <typename R, typename = std::nullptr_t>
      52           1 : struct MakeWithSize {
      53             :   /// The default implementation will produce a compile-time error.
      54             :   /// In specializations, the \p value parameter need not be a template.
      55             :   template <typename T>
      56           1 :   [[noreturn]] static SPECTRE_ALWAYS_INLINE R apply(const size_t /*size*/,
      57             :                                                     const T& /*value*/) {
      58             :     static_assert(typename tmpl::has_type<R, std::false_type>::type{},
      59             :                   "Do not know how to create a sized object of this type.  "
      60             :                   "Either implement MakeWithSize or specialize "
      61             :                   "MakeWithValueImpl for the type you are trying to create.");
      62             :   }
      63             : };
      64             : 
      65             : template <typename R, typename T, typename = std::nullptr_t>
      66           0 : struct MakeWithValueImpl {
      67             :   /// The default implementation uses \ref number_of_points and MakeWithSize.
      68             :   template <typename ValueType>
      69           1 :   static SPECTRE_ALWAYS_INLINE R apply(const T& input, const ValueType value) {
      70             :     return MakeWithSize<R>::apply(number_of_points(input), value);
      71             :   }
      72             : };
      73             : }  // namespace MakeWithValueImpls
      74             : 
      75             : /// \ingroup DataStructuresGroup
      76             : /// \brief Given an object of type `T`, create an object of type `R` whose
      77             : /// elements are initialized to `value`.
      78             : ///
      79             : /// \details This function is useful in function templates in order to
      80             : /// initialize the return type of a function template with `value` for functions
      81             : /// that can be called either at a single grid-point or to fill a data structure
      82             : /// at the same set of grid-points as the `input`
      83             : 
      84             : /// \tparam ValueType The type of `value`. For most containers, this will be
      85             : /// `double`.
      86             : ///
      87             : /// \see MakeWithValueImpls, set_number_of_grid_points
      88             : template <typename R, typename T, typename ValueType>
      89           1 : SPECTRE_ALWAYS_INLINE std::remove_const_t<R> make_with_value(
      90             :     const T& input, const ValueType& value) {
      91             :   return MakeWithValueImpls::MakeWithValueImpl<std::remove_const_t<R>,
      92             :                                                T>::apply(input, value);
      93             : }
      94             : 
      95             : namespace MakeWithValueImpls {
      96             : template <>
      97           0 : struct NumberOfPoints<size_t> {
      98           0 :   static SPECTRE_ALWAYS_INLINE size_t apply(const size_t& input) {
      99             :     return input;
     100             :   }
     101             : };
     102             : 
     103             : /// \brief Returns a double initialized to `value` (`input` is ignored)
     104             : template <typename T>
     105           1 : struct MakeWithValueImpl<double, T> {
     106           0 :   static SPECTRE_ALWAYS_INLINE double apply(const T& /* input */,
     107             :                                             const double value) {
     108             :     return value;
     109             :   }
     110             : };
     111             : 
     112             : template <typename T>
     113             : struct MakeWithValueImpl<std::complex<double>, T> {
     114             :   static SPECTRE_ALWAYS_INLINE std::complex<double> apply(
     115             :       const T& /* input */, const std::complex<double> value) {
     116             :     return value;
     117             :   }
     118             : };
     119             : 
     120             : /// \brief Makes a `std::array`; each element of the `std::array`
     121             : /// must be `make_with_value`-creatable from a `InputType`.
     122             : template <size_t Size, typename T, typename InputType>
     123             : struct MakeWithValueImpl<std::array<T, Size>, InputType> {
     124             :   template <typename ValueType>
     125             :   static SPECTRE_ALWAYS_INLINE std::array<T, Size> apply(
     126             :       const InputType& input, const ValueType value) {
     127             :     return make_array<Size>(make_with_value<T>(input, value));
     128             :   }
     129             : };
     130             : 
     131             : template <size_t Size, typename T>
     132             : struct NumberOfPoints<std::array<T, Size>> {
     133             :   static SPECTRE_ALWAYS_INLINE size_t apply(const std::array<T, Size>& input) {
     134             :     static_assert(Size > 0);
     135             :     // size_t is interpreted as the number of points in other
     136             :     // contexts, but that doesn't make sense here.
     137             :     static_assert(not std::is_same_v<T, size_t>,
     138             :                   "Cannot get size from non-vector.");
     139             :     const size_t points = number_of_points(input[0]);
     140             :     ASSERT(
     141             :         alg::all_of(input,
     142             :                     [&](const T& t) { return number_of_points(t) == points; }),
     143             :         "Inconsistent number of points in array entries.");
     144             :     return points;
     145             :   }
     146             : };
     147             : 
     148             : template <typename T>
     149             : struct NumberOfPoints<std::vector<T>> {
     150             :   static SPECTRE_ALWAYS_INLINE size_t apply(const std::vector<T>& input) {
     151             :     // size_t is interpreted as the number of points in other
     152             :     // contexts, but that doesn't make sense here.
     153             :     static_assert(not std::is_same_v<T, size_t>,
     154             :                   "Cannot get number_of_points from non-vector.");
     155             :     ASSERT(not input.empty(),
     156             :            "Cannot get number of points from empty std::vector.");
     157             :     const size_t points = number_of_points(input[0]);
     158             :     ASSERT(
     159             :         alg::all_of(input,
     160             :                     [&](const T& t) { return number_of_points(t) == points; }),
     161             :         "Inconsistent number of points in vector entries.");
     162             :     return points;
     163             :   }
     164             : };
     165             : 
     166             : template <typename T>
     167             : struct NumberOfPoints<std::reference_wrapper<T>> {
     168             :   static SPECTRE_ALWAYS_INLINE size_t apply(
     169             :       const std::reference_wrapper<T>& input) {
     170             :     return number_of_points(input.get());
     171             :   }
     172             : };
     173             : 
     174             : }  // namespace MakeWithValueImpls

Generated by: LCOV version 1.14