Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <utility>
8 :
9 : #include "DataStructures/TaggedTuple.hpp"
10 : #include "DataStructures/TempBuffer.hpp"
11 : #include "Utilities/Gsl.hpp"
12 : #include "Utilities/TMPL.hpp"
13 :
14 : /*!
15 : * \ingroup DataStructuresGroup
16 : * A temporary buffer with contents computed on demand.
17 : *
18 : * When an entry in the buffer is first requested, it is computed by the
19 : * `computer` that is passed to the `get_var` function. Subsequent requests just
20 : * return the cached value. The computer can itself request data from the cache
21 : * to use in its computations.
22 : *
23 : * For the cache
24 : * \snippet Test_CachedTempBuffer.cpp alias
25 : * the function used to compute `Tags::Scalar2<DataType>` is
26 : * \snippet Test_CachedTempBuffer.cpp compute_func
27 : */
28 : template <typename... Tags>
29 1 : class CachedTempBuffer {
30 : public:
31 0 : using tags_list = tmpl::list<Tags...>;
32 :
33 : /// Construct the buffer with the given computer. `size` is passed
34 : /// to the underlying `TempBuffer` constructor.
35 1 : CachedTempBuffer(const size_t size) : data_(size) {}
36 :
37 : /// Obtain a value from the buffer, computing it if necessary.
38 : template <typename Computer, typename Tag>
39 1 : const typename Tag::type& get_var(const Computer& computer, Tag /*meta*/) {
40 : static_assert(tmpl::list_contains_v<tmpl::list<Tags...>, Tag>,
41 : "The requested tag is not available. See the template "
42 : "parameters of 'CachedTempBuffer' for the computer type and "
43 : "the available tags, and the template parameter of the "
44 : "'get_var' function for the requested tag.");
45 : // This function can't be called "get" because that interferes
46 : // with the ADL needed to access data_.
47 : if (not get<Computed<Tag>>(computed_flags_)) {
48 : computer(make_not_null(&get<Tag>(data_)), make_not_null(this), Tag{});
49 : get<Computed<Tag>>(computed_flags_) = true;
50 : }
51 : return get<Tag>(data_);
52 : }
53 0 : size_t number_of_grid_points() const { return data_.number_of_grid_points(); }
54 :
55 : private:
56 : template <typename Tag>
57 0 : struct Computed {
58 0 : using type = bool;
59 : };
60 :
61 0 : TempBuffer<tmpl::list<Tags...>> data_;
62 0 : tuples::TaggedTuple<Computed<Tags>...> computed_flags_{
63 : ((void)Tags{}, false)...};
64 : };
65 :
66 : /// Instantiate a `CachedTempBuffer` from a typelist instead of a parameter pack
67 : template <typename Tags>
68 1 : using cached_temp_buffer_from_typelist = tmpl::wrap<Tags, CachedTempBuffer>;
|