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