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> // IWYU pragma: keep // for std::move 8 : 9 : #include "DataStructures/TempBuffer.hpp" 10 : #include "Utilities/Gsl.hpp" 11 : #include "Utilities/TMPL.hpp" 12 : #include "Utilities/TaggedTuple.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 : 54 : private: 55 : template <typename Tag> 56 0 : struct Computed { 57 0 : using type = bool; 58 : }; 59 : 60 0 : TempBuffer<tmpl::list<Tags...>> data_; 61 0 : tuples::TaggedTuple<Computed<Tags>...> computed_flags_{ 62 : ((void)Tags{}, false)...}; 63 : }; 64 : 65 : /// Instantiate a `CachedTempBuffer` from a typelist instead of a parameter pack 66 : template <typename Tags> 67 1 : using cached_temp_buffer_from_typelist = tmpl::wrap<Tags, CachedTempBuffer>;