1 #ifndef XMIPP_QUEUE_BAG_H 2 #define XMIPP_QUEUE_BAG_H 7 #define RFS_QUEUE_BAG_RUN_TESTS 0 22 static_assert(std::is_trivially_copyable<T>::value,
23 "queue_bag is designed only for trivially copyable elements");
27 T *elements =
nullptr;
28 size_t elementsCapacity = 0;
38 size_t internalIndex(
size_t externalIndex)
const {
40 assert(externalIndex < size);
41 size_t index = head + externalIndex;
42 if (index >= elementsCapacity) {
43 index -= elementsCapacity;
50 #if RFS_QUEUE_BAG_RUN_TESTS 59 if (size == elementsCapacity) {
60 resize(elementsCapacity * 2);
63 elements[tail++] = object;
64 if (tail == elementsCapacity) {
74 if (size == elementsCapacity) {
75 resize(elementsCapacity * 2);
79 head = elementsCapacity - 1;
83 elements[head] = object;
90 size_t needed = size + additional;
91 if (elementsCapacity < needed) {
101 assert(newSize > elementsCapacity);
103 T *newArray = (T*)malloc(
sizeof(T) * newSize);
106 memcpy(newArray, elements + head,
sizeof(T) * size);
107 }
else if (size > 0) {
109 size_t rest = elementsCapacity - head;
110 assert(rest + tail == size);
111 memcpy(newArray, elements + head,
sizeof(T) * rest);
112 memcpy(newArray + rest, elements,
sizeof(T) * tail);
117 elementsCapacity = newSize;
130 if (head == elementsCapacity) {
135 return elements[
index];
145 tail = elementsCapacity - 1;
150 return elements[tail];
159 assert(
index < size);
163 }
else if (
index + 1 == size) {
167 size_t elementsIndex = internalIndex(
index);
168 T result = elements[elementsIndex];
186 return elements[internalIndex(0)];
190 return elements[internalIndex(0)];
195 const T &
last() const noexcept {
196 return elements[internalIndex(size - 1)];
200 return elements[internalIndex(size - 1)];
207 return elements[internalIndex(
index)];
211 return elements[internalIndex(
index)];
220 template<
typename T,
typename Consumer>
222 for (
size_t i = 0;
i < queue.
getSize(); ++
i) {
223 if (!consumer(queue[
i])) {
241 template<
typename T,
typename Predicate>
260 #if RFS_QUEUE_BAG_RUN_TESTS 262 static bool tested =
false;
272 for (
int i = 0;
i < stairs; ++
i) {
275 assert(queue.
first() ==
i);
276 assert(queue.
last() ==
i);
277 assert(queue[queue.
getSize() / 2] == 42);
280 for (
int i = 0;
i < stairs; ++
i) {
281 assert(queue[
i] == stairs - 1 -
i);
282 assert(queue[stairs + 1 +
i] ==
i);
285 int stairCheckIndex = 0;
286 forEach(queue, [&stairCheckIndex, stairs](
const int value){
287 if (stairCheckIndex < stairs) {
288 assert(value == stairs - 1 - stairCheckIndex);
289 }
else if (stairCheckIndex == stairs) {
292 assert(stairCheckIndex - stairs - 1 == value);
298 for (
int i = stairs-1;
i >= 0; --
i) {
307 #endif //XMIPP_QUEUE_BAG_H
const T & operator[](int index) const noexcept
const T & last() const noexcept
size_t removeMatching(queue_bag< T > &queue, Predicate predicate)
void forEach(queue_bag< T > &queue, Consumer consumer)
T removeIndex(int index) noexcept
void resize(int newSize) noexcept
void ensureCapacity(size_t additional) noexcept
bool empty() const noexcept
size_t getSize() const noexcept
void addFirst(T object) noexcept
void addLast(T object) noexcept
const T & first() const noexcept
T & operator[](int index) noexcept