summaryrefslogtreecommitdiff
path: root/zen/ring_buffer.h
diff options
context:
space:
mode:
authorB Stack <bgstack15@gmail.com>2018-11-15 11:22:00 +0000
committerB Stack <bgstack15@gmail.com>2018-11-15 11:22:00 +0000
commit77c5c2503d459288720a8894349ac74e5eeec7c6 (patch)
tree30bf08d782d58174a0ca212b2e4b172fabd9c42c /zen/ring_buffer.h
parentMerge branch '10.5' into 'master' (diff)
parent10.6 (diff)
downloadFreeFileSync-77c5c2503d459288720a8894349ac74e5eeec7c6.tar.gz
FreeFileSync-77c5c2503d459288720a8894349ac74e5eeec7c6.tar.bz2
FreeFileSync-77c5c2503d459288720a8894349ac74e5eeec7c6.zip
Merge branch '10.6' into 'master'10.6
10.6 See merge request opensource-tracking/FreeFileSync!3
Diffstat (limited to 'zen/ring_buffer.h')
-rwxr-xr-xzen/ring_buffer.h55
1 files changed, 33 insertions, 22 deletions
diff --git a/zen/ring_buffer.h b/zen/ring_buffer.h
index 232e17da..e3dbd55f 100755
--- a/zen/ring_buffer.h
+++ b/zen/ring_buffer.h
@@ -8,10 +8,7 @@
#define RING_BUFFER_H_01238467085684139453534
#include <cassert>
-#include <vector>
-#include <stdexcept>
#include "scope_guard.h"
-#include "string_tools.h"
namespace zen
@@ -40,13 +37,24 @@ public:
~RingBuffer() { clear(); }
- reference front() { return getBufPtr()[bufStart_]; }
- const_reference front() const { return getBufPtr()[bufStart_]; }
+ reference front() { checkInvariants(); assert(!empty()); return getBufPtr()[bufStart_]; }
+ const_reference front() const { checkInvariants(); assert(!empty()); return getBufPtr()[bufStart_]; }
+
+ reference back() { checkInvariants(); assert(!empty()); return getBufPtr()[getBufPos(size_ - 1)]; }
+ const_reference back() const { checkInvariants(); assert(!empty()); return getBufPtr()[getBufPos(size_ - 1)]; }
+
+ template <class U>
+ void push_front(U&& value)
+ {
+ reserve(size_ + 1); //throw ?
+ ::new (getBufPtr() + getBufPos(capacity_ - 1)) T(std::forward<U>(value)); //throw ?
+ ++size_;
+ bufStart_ = getBufPos(capacity_ - 1);
+ }
template <class U>
void push_back(U&& value)
{
- checkInvariants();
reserve(size_ + 1); //throw ?
::new (getBufPtr() + getBufPos(size_)) T(std::forward<U>(value)); //throw ?
++size_;
@@ -54,15 +62,21 @@ public:
void pop_front()
{
- checkInvariants();
- if (empty())
- throw std::logic_error("Contract violation! " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
-
front().~T();
- ++bufStart_;
--size_;
- if (size_ == 0 || bufStart_ == capacity_)
+ if (size_ == 0)
+ bufStart_ = 0;
+ else
+ bufStart_ = getBufPos(1);
+ }
+
+ void pop_back()
+ {
+ back().~T();
+ --size_;
+
+ if (size_ == 0)
bufStart_ = 0;
}
@@ -80,8 +94,6 @@ public:
template <class Iterator>
void insert_back(Iterator first, Iterator last) //throw ? (strong exception-safety!)
{
- checkInvariants();
-
const size_t len = last - first;
reserve(size_ + len); //throw ?
@@ -100,10 +112,8 @@ public:
void extract_front(Iterator first, Iterator last) //throw ? strongly exception-safe! (but only basic exception safety for [first, last) range)
{
checkInvariants();
-
const size_t len = last - first;
- if (size_ < len)
- throw std::logic_error("Contract violation! " + std::string(__FILE__) + ":" + numberTo<std::string>(__LINE__));
+ assert(size_ >= len);
const size_t frontSize = std::min(len, capacity_ - bufStart_);
@@ -113,13 +123,12 @@ public:
std::destroy(getBufPtr() + bufStart_, getBufPtr() + bufStart_ + frontSize);
std::destroy(getBufPtr(), getBufPtr() + len - frontSize);
- bufStart_ += len;
- size_ -= len;
+ size_ -= len;
if (size_ == 0)
bufStart_ = 0;
- else if (bufStart_ >= capacity_)
- bufStart_ -= capacity_;
+ else
+ bufStart_ = getBufPos(len);
}
void swap(RingBuffer& other)
@@ -132,6 +141,8 @@ public:
void reserve(size_t minSize) //throw ? (strong exception-safety!)
{
+ checkInvariants();
+
if (minSize > capacity_)
{
const size_t newCapacity = std::max(minSize + minSize / 2, minSize); //no minimum capacity: just like std::vector<> implementation
@@ -205,7 +216,7 @@ private:
struct FreeStoreDelete { void operator()(std::byte* p) const { ::operator delete (p); } };
- T* getBufPtr() { return reinterpret_cast<T*>(rawMem_.get()); }
+ /**/ T* getBufPtr() { return reinterpret_cast<T*>(rawMem_.get()); }
const T* getBufPtr() const { return reinterpret_cast<T*>(rawMem_.get()); }
//unlike pure std::uninitialized_move, this one allows for strong exception-safety!
bgstack15