Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <array> 7 : #include <complex> 8 : #include <cstddef> 9 : #include <type_traits> 10 : #include <vector> 11 : 12 : #include "Utilities/Gsl.hpp" 13 : #include "Utilities/MakeWithValue.hpp" 14 : #include "Utilities/TMPL.hpp" 15 : 16 : /// Implementations of \link set_number_of_grid_points \endlink 17 : /// 18 : /// Specializations may be trivial, meaning the object is similar to a 19 : /// `double` and doesn't actually represent grid data. The only 20 : /// requirement for trivial specializations is defining `is_trivial` 21 : /// as `true`. 22 : /// 23 : /// Non-trivial specializations must define `is_trivial` to `false`, 24 : /// and must define a static `apply` function with the signature shown 25 : /// in the below example. Non-trivial specializations must also be 26 : /// accompanied by a specialization of the 27 : /// MakeWithValueImpls::NumberOfPoints struct. The `apply` function 28 : /// will only be called if the current size is incorrect, so 29 : /// implementations should not check the current size. 30 : /// 31 : /// \snippet Test_SetNumberOfGridPoints.cpp SetNumberOfGridPointsImpl 32 1 : namespace SetNumberOfGridPointsImpls { 33 : /// Default implementation is not defined. 34 : template <typename T, typename = std::nullptr_t> 35 1 : struct SetNumberOfGridPointsImpl; 36 : } // namespace SetNumberOfGridPointsImpls 37 : 38 : /// \ingroup DataStructuresGroup 39 : /// Change the number of grid points in an object. 40 : /// 41 : /// Change the number of points stored in \p result to a given value 42 : /// or to match another object. If \p pattern is a `size_t` it will 43 : /// be used as the number of points, otherwise it will be interpreted 44 : /// as data on a collection of grid points. 45 : /// 46 : /// \see SetNumberOfGridPointsImpls, make_with_value 47 : template <typename T, typename U> 48 1 : void set_number_of_grid_points(const gsl::not_null<T*> result, 49 : const U& pattern) { 50 : (void)result; 51 : (void)pattern; 52 : if constexpr (not SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl< 53 : T>::is_trivial) { 54 : const size_t size = MakeWithValueImpls::number_of_points(pattern); 55 : if (UNLIKELY(MakeWithValueImpls::number_of_points(*result) != size)) { 56 : SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<T>::apply(result, 57 : size); 58 : } 59 : } 60 : } 61 : 62 : template <> 63 0 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<double> { 64 0 : static constexpr bool is_trivial = true; 65 : }; 66 : 67 : template <> 68 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl< 69 : std::complex<double>> { 70 : static constexpr bool is_trivial = true; 71 : }; 72 : 73 : template <typename T, size_t N> 74 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<std::array<T, N>> { 75 : static constexpr bool is_trivial = 76 : N == 0 or SetNumberOfGridPointsImpl<T>::is_trivial; 77 : static void apply(const gsl::not_null<std::array<T, N>*> result, 78 : const size_t size) { 79 : for (auto& entry : *result) { 80 : set_number_of_grid_points(make_not_null(&entry), size); 81 : } 82 : } 83 : }; 84 : 85 : template <typename T> 86 : struct SetNumberOfGridPointsImpls::SetNumberOfGridPointsImpl<std::vector<T>> { 87 : static constexpr bool is_trivial = SetNumberOfGridPointsImpl<T>::is_trivial; 88 : static void apply(const gsl::not_null<std::vector<T>*> result, 89 : const size_t size) { 90 : for (auto& entry : *result) { 91 : set_number_of_grid_points(make_not_null(&entry), size); 92 : } 93 : } 94 : }; 95 :