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