2c2
< * Copyright (c) 2015 ARM Limited
---
> * Copyright (c) 2015,2017-2018 ARM Limited
46a47
> #include "base/circular_queue.hh"
51c52
< * Circular buffer backed by a vector
---
> * Circular buffer backed by a vector though a CircularQueue.
54,58c55
< * vector. _start designates the first element in the buffer and _stop
< * points to the last element + 1 (i.e., the position of the next
< * insertion). The _stop index may be outside the range of the backing
< * store, which means that the actual index must be calculated as
< * _stop % capacity.
---
> * vector.
60,65d56
< * Invariants:
< * <ul>
< * <li>_start <= _stop
< * <li>_start < capacity
< * <li>_stop < 2 * capacity
< * </ul>
68c59
< class CircleBuf
---
> class CircleBuf : public CircularQueue<T>
71,73d61
< typedef T value_type;
<
< public:
75c63,70
< : buf(size), _start(0), _stop(0) {}
---
> : CircularQueue<T>(size) {}
> using CircularQueue<T>::empty;
> using CircularQueue<T>::size;
> using CircularQueue<T>::capacity;
> using CircularQueue<T>::begin;
> using CircularQueue<T>::end;
> using CircularQueue<T>::pop_front;
> using CircularQueue<T>::advance_tail;
77,78d71
< /** Is the buffer empty? */
< bool empty() const { return _stop == _start; }
80,98d72
< * Return the maximum number of elements that can be stored in
< * the buffer at any one time.
< */
< size_t capacity() const { return buf.size(); }
< /** Return the number of elements stored in the buffer. */
< size_t size() const { return _stop - _start; }
<
< /**
< * Remove all the elements in the buffer.
< *
< * Note: This does not actually remove elements from the backing
< * store.
< */
< void flush() {
< _start = 0;
< _stop = 0;
< }
<
< /**
121,133c95
< const off_t real_start((offset + _start) % buf.size());
< if (real_start + len <= buf.size()) {
< std::copy(buf.begin() + real_start,
< buf.begin() + real_start + len,
< out);
< } else {
< const size_t head_size(buf.size() - real_start);
< const size_t tail_size(len - head_size);
< std::copy(buf.begin() + real_start, buf.end(),
< out);
< std::copy(buf.begin(), buf.begin() + tail_size,
< out + head_size);
< }
---
> std::copy(begin() + offset, begin() + offset + len, out);
145,147c107
<
< _start += len;
< normalize();
---
> pop_front(len);
160,162c120,122
< if (len > buf.size()) {
< in += len - buf.size();
< len = buf.size();
---
> if (len > capacity()) {
> in += len - capacity();
> len = capacity();
165,178c125,126
< const size_t next(_stop % buf.size());
< const size_t head_len(std::min(buf.size() - next, len));
<
< std::copy(in, in + head_len, buf.begin() + next);
< std::copy(in + head_len, in + len, buf.begin());
<
< _stop += len;
< // We may have written past the old _start pointer. Readjust
< // the _start pointer to remove the oldest entries in that
< // case.
< if (size() > buf.size())
< _start = _stop - buf.size();
<
< normalize();
---
> std::copy(in, in + len, end());
> advance_tail(len);
180,201d127
<
< protected:
< /**
< * Normalize the start and stop pointers to ensure that pointer
< * invariants hold after updates.
< */
< void normalize() {
< if (_start >= buf.size()) {
< _stop -= buf.size();
< _start -= buf.size();
< }
<
< assert(_start < buf.size());
< assert(_stop < 2 * buf.size());
< assert(_start <= _stop);
< }
<
< protected:
< std::vector<value_type> buf;
< size_t _start;
< size_t _stop;
<
204d129
<