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

Generated by: LCOV version 2.0-1