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);