4#ifndef QCONTIGUOUSCACHE_H
5#define QCONTIGUOUSCACHE_H
7#include <QtCore/qatomic.h>
8#include <QtCore/qassert.h>
9#include <QtCore/qtclasshelpermacros.h>
10#include <QtCore/qtcoreexports.h>
11#include <QtCore/qtypeinfo.h>
19#undef QT_QCONTIGUOUSCACHE_DEBUG
33#ifdef QT_QCONTIGUOUSCACHE_DEBUG
46 static_assert(std::is_nothrow_destructible_v<T>,
"Types with throwing destructors are not supported in Qt containers.");
65 inline void detach() {
if (
d->ref.loadRelaxed() != 1) detach_helper(); }
66 inline bool isDetached()
const {
return d->ref.loadRelaxed() == 1; }
73 template <
typename U = T>
78 if (
other.d->start !=
d->start
79 ||
other.d->count !=
d->count
80 ||
other.d->offset !=
d->offset
81 ||
other.d->alloc !=
d->alloc)
88 template <
typename U = T>
90 {
return !(*
this ==
other); }
100 inline bool isEmpty()
const {
return d->count == 0; }
101 inline bool isFull()
const {
return d->count ==
d->alloc; }
135 {
return d->offset >= 0 &&
d->offset < (std::numeric_limits<qsizetype>::max)() -
d->count && (
d->offset %
d->alloc) ==
d->start; }
139#ifdef QT_QCONTIGUOUSCACHE_DEBUG
140 void dump()
const {
d->dump(); }
143 void detach_helper();
146 void freeData(Data *
x);
153 x->ref.storeRelaxed(1);
156 x->offset =
d->offset;
159 T *dest =
x->array +
x->start;
160 T *
src =
d->array +
d->start;
165 if (dest ==
x->array +
x->alloc)
168 if (
src ==
d->array +
d->alloc)
181 if (asize ==
d->alloc)
185 x->ref.storeRelaxed(1);
187 x->count =
qMin(
d->count, asize);
188 x->offset =
d->offset +
d->count -
x->count;
190 x->start =
x->offset %
x->alloc;
197 T *dest =
x->array + (
x->start +
x->count-1) %
x->alloc;
198 T *
src =
d->array + (
d->start +
d->count-1) %
d->alloc;
201 if (dest ==
x->array)
202 dest =
x->array +
x->alloc;
205 src =
d->array +
d->alloc;
217 if (
d->ref.loadRelaxed() == 1) {
220 T *
i =
d->array +
d->start;
221 T *
e =
d->array +
d->alloc;
229 d->count =
d->start =
d->offset = 0;
232 x->ref.storeRelaxed(1);
234 x->count =
x->start =
x->offset = 0;
252 d->ref.storeRelaxed(1);
254 d->count =
d->start =
d->offset = 0;
272 T *
i =
d->array +
d->start;
273 T *
e =
d->array +
d->alloc;
289 if (
d->count ==
d->alloc)
290 (
d->array + (
d->start+
d->count) %
d->alloc)->~T();
291 new (
d->array + (
d->start+
d->count) %
d->alloc) T(std::move(
value));
293 if (
d->count ==
d->alloc) {
295 d->start %=
d->alloc;
308 if (
d->count ==
d->alloc)
309 (
d->array + (
d->start+
d->count) %
d->alloc)->~T();
310 new (
d->array + (
d->start+
d->count) %
d->alloc) T(
value);
312 if (
d->count ==
d->alloc) {
314 d->start %=
d->alloc;
330 d->start =
d->alloc-1;
333 if (
d->count !=
d->alloc)
336 (
d->array +
d->start)->~T();
338 new (
d->array +
d->start) T(std::move(
value));
350 d->start =
d->alloc-1;
353 if (
d->count !=
d->alloc)
356 (
d->array +
d->start)->~T();
358 new (
d->array +
d->start) T(
value);
364 Q_ASSERT_X(
pos >= 0,
"QContiguousCache<T>::insert",
"index out of range");
368 if (containsIndex(
pos)) {
370 }
else if (
pos ==
d->offset-1)
372 else if (
pos ==
d->offset+
d->count)
378 d->start =
pos %
d->alloc;
380 new (
d->array +
d->start) T(std::move(
value));
391{
Q_ASSERT_X(
pos >=
d->offset &&
pos -
d->offset <
d->count,
"QContiguousCache<T>::at",
"index out of range");
return d->array[
pos %
d->alloc]; }
400 if (!containsIndex(
pos))
402 return d->array[
pos %
d->alloc];
412 (
d->array +
d->start)->~T();
413 d->start = (
d->start + 1) %
d->alloc;
424 (
d->array + (
d->start +
d->count) %
d->alloc)->~T();
429{ T
t = std::move(
first()); removeFirst();
return t; }
433{ T
t = std::move(last()); removeLast();
return t; }
const value_type * const_pointer
qsizetype firstIndex() const
Returns the first valid index in the cache.
T takeFirst()
Removes the first item in the cache and returns it.
qsizetype available() const
Returns the number of items that can be added to the cache before it becomes full.
void setCapacity(qsizetype size)
Sets the capacity of the cache to the given size.
qsizetype lastIndex() const
Returns the last valid index in the cache.
const T & at(qsizetype pos) const
Returns the item at index position i in the cache.
void removeFirst()
Removes the first item from the cache.
void insert(qsizetype pos, T &&value)
QTypeTraits::compare_eq_result< U > operator!=(const QContiguousCache< T > &other) const
Returns true if other is not equal to this cache; otherwise returns false.
bool containsIndex(qsizetype pos) const
Returns true if the cache's index range includes the given index i.
qsizetype capacity() const
Returns the number of items the cache can store before it is full.
qsizetype count() const
Same as size().
bool isEmpty() const
Returns true if no items are stored within the cache.
QContiguousCache(qsizetype capacity=0)
Constructs a cache with the given capacity.
qsizetype size() const
Returns the number of items contained within the cache.
QContiguousCache< T > & operator=(const QContiguousCache< T > &other)
Assigns other to this cache and returns a reference to this cache.
T & last()
Returns a reference to the last item in the cache.
~QContiguousCache()
Destroys the cache.
void normalizeIndexes()
Moves the first index and last index of the cache such that they point to valid indexes.
bool isFull() const
Returns true if the number of items stored within the cache is equal to the capacity of the cache.
bool areIndexesValid() const
Returns whether the indexes for items stored in the cache are valid.
T & first()
Returns a reference to the first item in the cache.
const value_type & const_reference
T & operator[](qsizetype i)
Returns the item at index position i as a modifiable reference.
void clear()
Removes all items from the cache.
const T & last() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void removeLast()
Removes the last item from the cache.
QContiguousCache(const QContiguousCache< T > &v)
Constructs a copy of other.
const T & first() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
QTypeTraits::compare_eq_result< U > operator==(const QContiguousCache< T > &other) const
Returns true if other is equal to this cache; otherwise returns false.
T takeLast()
Removes the last item in the cache and returns it.
list append(new Employee("Blackpool", "Stephen"))
cache insert(employee->id(), employee)
Combined button and popup list for selecting options.
std::enable_if_t< std::conjunction_v< QTypeTraits::has_operator_equal< T >... >, bool > compare_eq_result
static QArrayData * allocateData(qsizetype allocSize)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMin(const T &a, const T &b)
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_ASSERT_X(cond, x, msg)
static QString dump(const QByteArray &)
constexpr void qt_ptr_swap(T *&lhs, T *&rhs) noexcept
static QContiguousCacheData * allocateData(qsizetype size, qsizetype alignment)