6 #ifndef IROHA_COMMON_RING_BUFFER_HPP 7 #define IROHA_COMMON_RING_BUFFER_HPP 10 namespace containers {
17 template <
typename T,
size_t Count>
24 static_assert(Count > 0,
"Unexpected count value. It must be above 0.");
25 static_assert(Count <= (std::numeric_limits<size_t>::max() >> 1),
26 "To prevent overflow");
28 enum { kTypeSize =
sizeof(
Type) };
33 enum { kActualLimit = Count };
41 enum { kVirtualLimit = 2 * kActualLimit };
44 uint8_t data[kTypeSize];
50 inline size_t internalSizeFromPosition(
Handle h)
const {
51 return (((h + kVirtualLimit) - end_) % kVirtualLimit);
54 inline bool handleInBound(
Handle h)
const {
58 auto const sz_handle = internalSizeFromPosition(h);
59 auto const sz_begin = internalSizeFromPosition(begin_);
60 return (sz_handle < sz_begin);
63 inline size_t incrementAndNormalize(
size_t val)
const {
64 return (++val % kVirtualLimit);
67 inline size_t handleToPosition(
Handle h)
const {
68 return (h % kActualLimit);
71 inline size_t internalSize()
const {
72 auto const normalized_size = internalSizeFromPosition(begin_);
73 assert(normalized_size <= kActualLimit);
74 return normalized_size;
77 inline bool internalEmpty()
const {
78 return (begin_ == end_);
81 inline Type &internalGetItem(Node &node) {
82 return *
reinterpret_cast<Type *
>(node.data);
85 inline Type const &internalGetItem(Node
const &node)
const {
86 return *
reinterpret_cast<Type const *
>(node.data);
89 inline void destruct(Node &node) {
90 assert(!internalEmpty());
92 auto &item = internalGetItem(node);
96 template <
typename FuncOnRemove>
97 inline void destructLast(FuncOnRemove &&on_remove) {
98 auto &node = internalToNode(end_);
99 on_remove(end_, internalGetItem(node));
102 end_ = incrementAndNormalize(end_);
105 template <
typename... Args>
106 inline void construct(Node &node, Args &&... args) {
107 assert(internalSize() < kActualLimit);
108 new (node.data)
Type(std::forward<Args>(args)...);
111 template <
typename FuncOnAdd,
typename... Args>
112 inline void constructFirst(FuncOnAdd &&on_add, Args &&... args) {
113 auto &node = internalToNode(begin_);
114 auto const constructed_h = begin_;
116 construct(node, std::forward<Args>(args)...);
117 begin_ = incrementAndNormalize(begin_);
119 on_add(constructed_h, internalGetItem(node));
122 inline Node &internalToNode(
Handle h) {
123 assert(h < kVirtualLimit);
124 return data_[handleToPosition(h)];
127 inline Node
const &internalToNode(
Handle h)
const {
128 assert(h < kVirtualLimit);
129 return data_[handleToPosition(h)];
139 template <
typename FuncOnAdd,
typename FuncOnRemove,
typename... Args>
140 void push(FuncOnAdd &&on_add, FuncOnRemove &&on_remove, Args &&... args) {
141 assert(internalSize() <= kActualLimit);
142 if (internalSize() == kActualLimit) {
143 destructLast(std::move(on_remove));
145 constructFirst(std::move(on_add), std::forward<Args>(args)...);
148 template <
typename FuncOnRemove>
149 void pop(FuncOnRemove &&on_remove) {
150 if (!internalEmpty()) {
151 destructLast(std::move(on_remove));
156 assert(handleInBound(h));
157 return internalGetItem(internalToNode(h));
161 assert(handleInBound(h));
162 return internalGetItem(internalToNode(h));
166 return internalEmpty();
170 return internalSize();
176 #endif // IROHA_COMMON_RING_BUFFER_HPP ~RingBuffer()
Definition: ring_buffer.hpp:135
Type const & getItem(Handle h) const
Definition: ring_buffer.hpp:160
KeyAndValue Type
Definition: ring_buffer.hpp:20
Type & getItem(Handle h)
Definition: ring_buffer.hpp:155
RingBuffer()
Definition: ring_buffer.hpp:133
bool empty() const
Definition: ring_buffer.hpp:165
Definition: block_query.hpp:15
void push(FuncOnAdd &&on_add, FuncOnRemove &&on_remove, Args &&... args)
Definition: ring_buffer.hpp:140
void pop(FuncOnRemove &&on_remove)
Definition: ring_buffer.hpp:149
size_t size() const
Definition: ring_buffer.hpp:169
Definition: ring_buffer.hpp:18
size_t Handle
Definition: ring_buffer.hpp:21