https://mooseframework.inl.gov
Buffer.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "MooseError.h"
13 
14 #include <vector>
15 
16 namespace MooseUtils
17 {
18 
27 template <typename T>
28 class Buffer
29 {
30 public:
31  typedef typename std::vector<T>::iterator iterator;
32  typedef typename std::vector<T>::const_iterator const_iterator;
33 
37  Buffer();
38 
42  Buffer(const std::size_t capacity);
43 
44  virtual ~Buffer() {}
45 
49  void setCapacity(const std::size_t capacity) { this->_data.resize(capacity); }
53  std::size_t capacity() const { return this->_data.size(); }
54 
58  void setSize(const std::size_t size) { this->_end_pos = this->newEnd(this->_begin_pos + size); }
62  std::size_t size() const { return this->_end_pos - this->_begin_pos; }
63 
67  bool empty() const { return !size(); }
68 
72  void push_back(const T & value);
73 
77  void move(T & value);
78 
84  void append(const_iterator in_begin, const_iterator in_end);
88  void append(const std::vector<T> & vals);
89 
94  void clear();
95 
101  virtual void erase(const std::size_t num) = 0;
102  /*
103  * Similar to erase(), but if the chunk size is larger than the current size,
104  * no error (all elements are erased gracefully).
105  *
106  * Note that erased items are not guaranteed to be freed immediately
107  */
108  virtual void eraseChunk(const std::size_t chunk_size) = 0;
109 
113  iterator begin() { return this->_data.begin() + this->_begin_pos; }
117  const_iterator begin() const { return this->_data.begin() + this->_begin_pos; }
118 
122  iterator end() { return this->_data.begin() + this->_end_pos; }
126  const_iterator end() const { return this->_data.begin() + this->_end_pos; }
127 
132  virtual iterator beginChunk(const std::size_t chunk_size) = 0;
137  virtual const_iterator beginChunk(const std::size_t chunk_size) const = 0;
138 
143  virtual iterator endChunk(const std::size_t chunk_size) = 0;
148  virtual const_iterator endChunk(const std::size_t chunk_size) const = 0;
149 
153  T & operator[](const std::size_t index);
157  const T & operator[](const std::size_t index) const;
158 
162  void swap(std::vector<T> & in_data);
163 
172  const std::vector<T> & data() { return _data; }
173 
182  std::size_t dataBeginPos() const { return _begin_pos; }
183 
192  std::size_t dataEndPos() const { return _end_pos; }
193 
194 protected:
202  virtual std::size_t newEnd(const std::size_t new_end) = 0;
203 
205  std::vector<T> _data;
206 
208  std::size_t _begin_pos;
210  std::size_t _end_pos;
211 };
212 
213 template <typename T>
214 Buffer<T>::Buffer() : _begin_pos(0), _end_pos(0)
215 {
216 }
217 
218 template <typename T>
219 Buffer<T>::Buffer(const std::size_t capacity) : _data(capacity), _begin_pos(0), _end_pos(0)
220 {
221 }
222 
223 template <typename T>
224 void
225 Buffer<T>::push_back(const T & value)
226 {
227  this->_end_pos = newEnd(this->_end_pos + 1);
228  this->_data[this->_end_pos - 1] = value;
229 }
230 
231 template <typename T>
232 void
233 Buffer<T>::move(T & value)
234 {
235  this->_end_pos = newEnd(this->_end_pos + 1);
236  this->_data[this->_end_pos - 1] = std::move(value);
237 }
238 
239 template <typename T>
240 void
242 {
243  const auto additional_size = std::distance(in_begin, in_end);
244  if (additional_size == 0)
245  return;
246 
247  this->_end_pos = this->newEnd(this->_end_pos + additional_size);
248  std::copy(in_begin, in_end, this->end() - additional_size);
249 }
250 
251 template <typename T>
252 void
253 Buffer<T>::append(const std::vector<T> & vals)
254 {
255  this->append(vals.begin(), vals.end());
256 }
257 
258 template <typename T>
259 void
261 {
262  this->_begin_pos = 0;
263  this->_end_pos = 0;
264 }
265 
266 template <typename T>
267 T &
268 Buffer<T>::operator[](const std::size_t index)
269 {
270  mooseAssert(this->_begin_pos + index < this->_end_pos, "Attempt to access off end of Buffer!");
271  return this->_data[this->_begin_pos + index];
272 }
273 
274 template <typename T>
275 const T &
276 Buffer<T>::operator[](const std::size_t index) const
277 {
278  mooseAssert(this->_begin_pos + index < this->_end_pos, "Attempt to access off end of Buffer!");
279  return this->_data[this->_begin_pos + index];
280 }
281 
282 template <typename T>
283 void
284 Buffer<T>::swap(std::vector<T> & in_data)
285 {
286  std::swap(in_data, _data);
287  this->_begin_pos = 0;
288  this->_end_pos = this->_data.size();
289 }
290 
291 }
virtual void eraseChunk(const std::size_t chunk_size)=0
std::size_t size() const
Get the size.
Definition: Buffer.h:62
Buffer()
Create an empty buffer.
Definition: Buffer.h:214
const_iterator end() const
Const iterator for the last entry in the buffer.
Definition: Buffer.h:126
virtual void erase(const std::size_t num)=0
Remove the first num elements.
std::vector< T >::const_iterator const_iterator
Definition: Buffer.h:32
bool empty() const
Whether or not the buffer is empty.
Definition: Buffer.h:67
void swap(std::vector< T > &in_data)
Use in_data as our data vector.
Definition: Buffer.h:284
void swap(std::vector< T > &data, const std::size_t idx0, const std::size_t idx1, const libMesh::Parallel::Communicator &comm)
Swap function for serial or distributed vector of data.
Definition: Shuffle.h:494
virtual ~Buffer()
Definition: Buffer.h:44
std::size_t _end_pos
The ending position.
Definition: Buffer.h:210
void push_back(const T &value)
Add a new entry on the end.
Definition: Buffer.h:225
Base class for a buffer.
Definition: Buffer.h:28
std::size_t dataBeginPos() const
The current beginning position of the buffer in data().
Definition: Buffer.h:182
std::vector< T >::iterator iterator
Definition: Buffer.h:31
std::size_t capacity() const
Get the capacity.
Definition: Buffer.h:53
void append(const_iterator in_begin, const_iterator in_end)
Add new entries to the end.
Definition: Buffer.h:241
std::vector< T > _data
The raw data.
Definition: Buffer.h:205
void setCapacity(const std::size_t capacity)
Resize the capacity.
Definition: Buffer.h:49
T & operator[](const std::size_t index)
Access an entry at index.
Definition: Buffer.h:268
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
iterator end()
Iterator for the last entry in the buffer.
Definition: Buffer.h:122
std::size_t dataEndPos() const
The current end position of the buffer in data().
Definition: Buffer.h:192
void move(T &value)
Moves the object into the buffer (calls std::move())
Definition: Buffer.h:233
std::size_t _begin_pos
The beginning position.
Definition: Buffer.h:208
virtual iterator endChunk(const std::size_t chunk_size)=0
Iterator for the last entry of a chunk size in the buffer If chunk_size is greater than the size of t...
void clear()
Remove all entries (does not change the capacity) Note: this does NOT at all free any entries...
Definition: Buffer.h:260
virtual std::size_t newEnd(const std::size_t new_end)=0
Find out where the new end will be.
virtual iterator beginChunk(const std::size_t chunk_size)=0
Iterator for the first entry with a given chunk size in the buffer If chunk_size is greater than the ...
void setSize(const std::size_t size)
Set the size.
Definition: Buffer.h:58
iterator begin()
Iterator for the first entry in the buffer.
Definition: Buffer.h:113
const std::vector< T > & data()
Access the raw underlying storage.
Definition: Buffer.h:172
const_iterator begin() const
Const iterator for the first entry in the buffer.
Definition: Buffer.h:117