eDSP  0.0.1
A cross-platform DSP library written in C++.
ring_buffer.hpp
Go to the documentation of this file.
1 /*
2  * eDSP, A cross-platform Digital Signal Processing library written in modern C++.
3  * Copyright (C) 2018 Mohammed Boujemaoui Boulaghmoudi, All rights reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22  * File: ring_buffer.hpp
23  * Author Mohammed Boujemaoui Boulaghmoudi on 02/10/18.
24  */
25 
26 #ifndef EDSP_RING_BUFFER_HPP
27 #define EDSP_RING_BUFFER_HPP
28 
29 #include <edsp/meta/unused.hpp>
30 #include <edsp/types/ring_span.hpp>
31 #include <vector>
32 
33 namespace edsp { inline namespace types {
34 
48  template <typename T, typename Allocator = std::allocator<T>>
49  class ring_buffer {
50  public:
51  typedef typename ring_span<T>::value_type value_type;
52  typedef typename ring_span<T>::pointer pointer;
53  typedef typename std::add_const_t<pointer> const_pointer;
54  typedef typename ring_span<value_type>::reference reference;
55  typedef typename ring_span<value_type>::const_reference const_reference;
56  typedef typename ring_span<value_type>::iterator iterator;
57  typedef typename ring_span<value_type>::const_iterator const_iterator;
58  typedef typename ring_span<value_type>::reverse_iterator reverse_iterator;
59  typedef typename ring_span<value_type>::const_reverse_iterator const_reverse_iterator;
60  typedef typename ring_span<value_type>::size_type size_type;
61  typedef std::ptrdiff_t difference_type;
62  typedef std::vector<T, Allocator> container_type;
63 
64  constexpr ring_buffer() = default;
65  constexpr ring_buffer(const ring_buffer&) = default;
66  constexpr ring_buffer(ring_buffer&&) noexcept = default;
67  constexpr ring_buffer& operator=(const ring_buffer&) = default;
68  constexpr ring_buffer& operator=(ring_buffer&&) noexcept = default;
69 
77  explicit ring_buffer(size_type N) {
78  buffer_.resize(N);
79  ring_ = edsp::ring_span<T>(std::begin(buffer_), std::end(buffer_));
80  }
81 
88  ring_buffer(size_type N, const value_type& value) {
89  buffer_.resize(N);
90  ring_ = edsp::ring_span<T>(std::begin(buffer_), std::end(buffer_), std::begin(buffer_), N);
91  std::fill(begin(), end(), value);
92  }
93 
101  ~ring_buffer() = default;
102 
108  void resize(size_type size) {
109  buffer_.resize(size);
110  ring_ = edsp::ring_span<T>(std::begin(buffer_), std::end(buffer_));
111  }
112 
119  void clear() {
120  ring_ = edsp::ring_span<T>(std::begin(buffer_), std::end(buffer_), std::begin(buffer_), 0);
121  }
122 
130  iterator begin() noexcept {
131  return ring_.begin();
132  }
133 
141  const_iterator begin() const noexcept {
142  return ring_.begin();
143  }
144 
152  iterator end() noexcept {
153  return ring_.end();
154  }
155 
163  const_iterator end() const noexcept {
164  return ring_.end();
165  }
166 
167  /*
168  * @brief Returns a read/write iterator that points to the first
169  *
170  * Iteration is done in reverse element order.
171  * @returns Iterator pointing to the first element.
172  */
173  reverse_iterator rbegin() noexcept {
174  return ring_.rbegin();
175  }
176 
184  const_reverse_iterator rbegin() const noexcept {
185  return ring_.rbegin();
186  }
187 
195  reverse_iterator rend() noexcept {
196  return ring_.rend();
197  }
198 
199  /*
200  * @brief Returns a read-only iterator that points to the last
201  * element in the %ring_buffer.
202  *
203  * Iteration is done in reverse element order.
204  * @returns Iterator pointing to the last element.
205  */
206  const_reverse_iterator rend() const noexcept {
207  return ring_.rend();
208  }
209 
217  const_iterator cbegin() const noexcept {
218  return ring_.cbegin();
219  }
220 
228  const_iterator cend() const noexcept {
229  return ring_.cend();
230  }
231 
239  const_reverse_iterator crbegin() const noexcept {
240  return ring_.crbegin();
241  }
242 
250  const_reverse_iterator crend() const noexcept {
251  return ring_.crend();
252  }
253 
258  constexpr size_type size() const {
259  return ring_.size();
260  }
261 
266  constexpr size_type max_size() const {
267  return buffer_.max_size();
268  }
269 
274  constexpr bool empty() const {
275  return ring_.empty();
276  }
277 
282  constexpr bool full() const {
283  return ring_.full();
284  }
285 
290  constexpr size_type capacity() const {
291  return ring_.capacity();
292  }
293 
305  reference operator[](std::size_t i) {
306  return ring_[i];
307  }
308 
320  const_reference operator[](std::size_t i) const {
321  return ring_[i];
322  }
323 
335  reference at(std::size_t i) {
336  return ring_.at(i);
337  }
338 
350  const_reference at(std::size_t i) const {
351  return ring_.at(i);
352  }
353 
359  reference front() {
360  return ring_.front();
361  }
362 
368  const_reference front() const {
369  return ring_.front();
370  }
371 
377  reference back() {
378  return ring_.back();
379  }
380 
386  const_reference back() const {
387  return ring_.back();
388  }
389 
398  template <typename... Args>
399  void emplace_front(Args... arg) {
400  ring_.emplace_front(arg...);
401  }
402 
411  template <typename... Args>
412  void emplace_back(Args... arg) {
413  ring_.emplace_back(arg...);
414  }
415 
424  void push_back(const value_type& item) {
425  ring_.push_back(item);
426  }
427 
437  void pop_front() {
438  ring_.pop_front();
439  }
440 
450  void pop_back() {
451  ring_.pop_back();
452  }
453 
458  const container_type& buffer() const {
459  return buffer_;
460  }
461 
466  const_pointer* data() const {
467  return buffer_.data();
468  }
469 
470  private:
471  container_type buffer_{};
472  edsp::ring_span<T> ring_{std::begin(buffer_), std::end(buffer_)};
473  };
474 
475 }} // namespace edsp::types
476 
477 #endif //EDSP_RING_BUFFER_HPP
ring_span< value_type >::size_type size_type
Definition: ring_buffer.hpp:60
std::add_const_t< pointer > const_pointer
Definition: ring_buffer.hpp:53
ring_span< value_type >::const_iterator const_iterator
Definition: ring_buffer.hpp:57
void pop_front()
Removes the first element of the ring.
Definition: ring_buffer.hpp:437
reference at(std::size_t i)
Provides access to the data contained in the ring_buffer.
Definition: ring_buffer.hpp:335
const_reverse_iterator crbegin() const noexcept
Returns a read-only iterator that points to the first element in the ring_buffer. ...
Definition: ring_buffer.hpp:239
iterator begin() noexcept
Returns a read/write iterator that points to the first element in the ring_buffer.
Definition: ring_buffer.hpp:130
void resize(size_type size)
Resizes the ring_buffer to the specified number of elements.
Definition: ring_buffer.hpp:108
void emplace_back(Args... arg)
Inserts an object at the end of the ring_buffer.
Definition: ring_buffer.hpp:412
std::ptrdiff_t difference_type
Definition: ring_buffer.hpp:61
ring_span< value_type >::reference reference
Definition: ring_buffer.hpp:54
ring_span< value_type >::reverse_iterator reverse_iterator
Definition: ring_buffer.hpp:58
const_reverse_iterator rbegin() const noexcept
Returns a read-only iterator that points to the first element in the ring_buffer. ...
Definition: ring_buffer.hpp:184
const_reference at(std::size_t i) const
Provides access to the data contained in the ring_buffer.
Definition: ring_buffer.hpp:350
This class implements a ring buffer, also called circular buffer.
Definition: ring_buffer.hpp:49
const_iterator begin() const noexcept
Returns a read-only iterator that points to the first element in the ring_buffer. ...
Definition: ring_buffer.hpp:141
const container_type & buffer() const
Returns a const reference to the internal buffer.
Definition: ring_buffer.hpp:458
ring_span< value_type >::iterator iterator
Definition: ring_buffer.hpp:56
const_reverse_iterator crend() const noexcept
Returns a read-only iterator that points to the last element in the ring_buffer.
Definition: ring_buffer.hpp:250
ring_span< T >::value_type value_type
Definition: ring_buffer.hpp:51
reference front()
Returns a read/write reference to the data at the first element of the ring_buffer.
Definition: ring_buffer.hpp:359
reverse_iterator rbegin() noexcept
Definition: ring_buffer.hpp:173
~ring_buffer()=default
Default destructor. The dtor only erases the elements, and note that if the elements themselves are p...
constexpr size_type max_size() const
Definition: ring_buffer.hpp:266
constexpr size_type size() const
Returns the number of elements in the ring_buffer.
Definition: ring_buffer.hpp:258
const_reference back() const
Returns a read-only reference to the data at the last element of the ring_buffer. ...
Definition: ring_buffer.hpp:386
void clear()
Definition: ring_buffer.hpp:119
iterator end() noexcept
Returns a read/write iterator that points to the last element in the ring_buffer. ...
Definition: ring_buffer.hpp:152
const_iterator cend() const noexcept
Returns a read-only te iterator that points to the last element in the ring_buffer.
Definition: ring_buffer.hpp:228
const_reference operator[](std::size_t i) const
Subscript access to the data contained in the ring_buffer.
Definition: ring_buffer.hpp:320
reference operator[](std::size_t i)
Subscript access to the data contained in the ring_buffer.
Definition: ring_buffer.hpp:305
reference back()
Returns a read/write reference to the data at the last element of the ring_buffer.
Definition: ring_buffer.hpp:377
ring_span< value_type >::const_reverse_iterator const_reverse_iterator
Definition: ring_buffer.hpp:59
const_iterator cbegin() const noexcept
Returns a read-only iterator that points to the first element in the ring_buffer. ...
Definition: ring_buffer.hpp:217
ring_span< value_type >::const_reference const_reference
Definition: ring_buffer.hpp:55
constexpr bool empty() const
Definition: ring_buffer.hpp:274
void pop_back()
Removes the last element of the ring_buffer.
Definition: ring_buffer.hpp:450
reverse_iterator rend() noexcept
Returns a read/write iterator that points to the last element in the ring_buffer. ...
Definition: ring_buffer.hpp:195
const_reference front() const
Returns a read-only reference to the data at the first element of the ring_buffer.
Definition: ring_buffer.hpp:368
ring_buffer(size_type N, const value_type &value)
Creates a ring_buffer with copies of an exemplar element.
Definition: ring_buffer.hpp:88
void push_back(const value_type &item)
Add data to the end of the ring_buffer.
Definition: ring_buffer.hpp:424
ring_span< T >::pointer pointer
Definition: ring_buffer.hpp:52
const_pointer * data() const
Returns a const pointer to the underlying data of the internal buffer.
Definition: ring_buffer.hpp:466
void emplace_front(Args... arg)
Inserts an object at the front of the ring_buffer.
Definition: ring_buffer.hpp:399
const_reverse_iterator rend() const noexcept
Definition: ring_buffer.hpp:206
const_iterator end() const noexcept
Returns a read-only iterator that points to the last element in the ring_buffer.
Definition: ring_buffer.hpp:163
constexpr ring_buffer()=default
Definition: amplifier.hpp:29
constexpr bool full() const
Definition: ring_buffer.hpp:282
std::vector< T, Allocator > container_type
Definition: ring_buffer.hpp:62
constexpr size_type capacity() const
Definition: ring_buffer.hpp:290