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 <type_traits>
8 : #include <vector>
9 :
10 : #include "DataStructures/DataVector.hpp"
11 :
12 : /// \cond
13 : namespace PUP {
14 : class er;
15 : } // namespace PUP
16 : /// \endcond
17 :
18 : /**
19 : * \ingroup DataStructuresGroup
20 : *
21 : * \brief A dynamically sized vector of `DataVector`s. For convenience it can
22 : * also be instantiated for fundamental types.
23 : *
24 : * \details This class is useful when one wants to create a `std::vector<T>`
25 : * with a size that is unknown at compile time. It allocates all `DataVector`s
26 : * in a single memory chunk rather than allocating each individually. If the
27 : * size of the vector is known at compile time, a `TempBuffer` object should be
28 : * used instead.
29 : *
30 : * Currently this can only be used for `DataVector`s, but if needed, it should
31 : * be fairly straightforward to generalize to `ComplexDataVector`.
32 : */
33 : template <typename T>
34 1 : class DynamicBuffer {
35 : public:
36 : // Only vector type supported is DataVector
37 0 : static constexpr bool is_data_vector_type = std::is_same_v<DataVector, T>;
38 :
39 0 : DynamicBuffer() = default;
40 :
41 : /*!
42 : * Constructs a `DynamicBuffer`. The `number_of_vectors` corresponds to the
43 : * number of `DataVector`s which are saved inside, each of which has size
44 : * `number_of_grid_points`. `number_of_grid_points` has to be 1 if T is a
45 : * fundamental type.
46 : */
47 1 : DynamicBuffer(size_t number_of_vectors, size_t number_of_grid_points);
48 0 : ~DynamicBuffer() = default;
49 0 : DynamicBuffer(DynamicBuffer&& other) = default;
50 0 : DynamicBuffer& operator=(DynamicBuffer&& other) = default;
51 :
52 0 : DynamicBuffer(const DynamicBuffer& other);
53 :
54 0 : DynamicBuffer& operator=(const DynamicBuffer& other);
55 :
56 0 : T& operator[](size_t index) { return data_[index]; }
57 0 : T& at(size_t index) { return data_.at(index); }
58 0 : const T& operator[](size_t index) const { return data_[index]; }
59 0 : const T& at(size_t index) const { return data_.at(index); }
60 :
61 0 : auto begin() { return data_.begin(); }
62 0 : auto end() { return data_.end(); }
63 0 : auto begin() const { return data_.begin(); }
64 0 : auto end() const { return data_.end(); }
65 :
66 0 : size_t size() const { return data_.size(); }
67 :
68 : // NOLINTNEXTLINE(google-runtime-references)
69 0 : void pup(PUP::er& p);
70 :
71 : private:
72 : // sets data references for all `data_` into `buffer_`
73 0 : void set_references();
74 :
75 : template <typename LocalT>
76 : // NOLINTNEXTLINE(readability-redundant-declaration)
77 0 : friend bool operator==(const DynamicBuffer<LocalT>& lhs,
78 : const DynamicBuffer<LocalT>& rhs);
79 :
80 0 : size_t number_of_grid_points_;
81 : // vector of non-owning DataVectors pointing into `buffer_`. In case of
82 : // fundamental type T the data is saved in `data_` directly.
83 0 : std::vector<T> data_;
84 : // memory buffer for all DataVectors. Unused in case of fundamental type T.
85 0 : std::vector<double> buffer_;
86 : };
87 :
88 : template <typename T>
89 0 : bool operator!=(const DynamicBuffer<T>& lhs, const DynamicBuffer<T>& rhs);
|