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 :
|