Qt 4.8
Classes | Public Types | Public Functions | Public Variables | Static Public Variables | List of all members
QListData Struct Reference

#include <qlist.h>

Classes

struct  Data
 

Public Types

enum  { DataHeaderSize = sizeof(Data) - sizeof(void *) }
 

Public Functions

void ** append (int n)
 
void ** append ()
 
void ** append (const QListData &l)
 
void ** append2 (const QListData &l)
 
void ** at (int i) const
 
void ** begin () const
 
Datadetach (int alloc)
 Detaches the QListData by allocating new memory for a list which possibly has a different size than the copied one. More...
 
Datadetach ()
 
Datadetach2 ()
 Detaches the QListData by reallocating new memory. More...
 
Datadetach3 ()
 Detaches the QListData by reallocating new memory. More...
 
Datadetach_grow (int *i, int n)
 Detaches the QListData by allocating new memory for a list which will be bigger than the copied one and is expected to grow further. More...
 
void ** end () const
 
void ** erase (void **xi)
 
void ** insert (int i)
 
bool isEmpty () const
 
void move (int from, int to)
 
void ** prepend ()
 
void realloc (int alloc)
 
void remove (int i)
 
void remove (int i, int n)
 
int size () const
 

Public Variables

Datad
 

Static Public Variables

static Data shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, true, { 0 } }
 

Detailed Description

Definition at line 71 of file qlist.h.

Enumerations

◆ anonymous enum

anonymous enum
Enumerator
DataHeaderSize 

Definition at line 78 of file qlist.h.

78 { DataHeaderSize = sizeof(Data) - sizeof(void *) };

Functions

◆ append() [1/3]

void ** QListData::append ( int  n)

Definition at line 231 of file qlist.cpp.

232 {
233  Q_ASSERT(d->ref == 1);
234  int e = d->end;
235  if (e + n > d->alloc) {
236  int b = d->begin;
237  if (b - n >= 2 * d->alloc / 3) {
238  // we have enough space. Just not at the end -> move it.
239  e -= b;
240  ::memmove(d->array, d->array + b, e * sizeof(void *));
241  d->begin = 0;
242  } else {
243  realloc(grow(d->alloc + n));
244  }
245  }
246  d->end = e + n;
247  return d->array + e;
248 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void realloc(int alloc)
Definition: qlist.cpp:218
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87
static int grow(int size)
Definition: qlist.cpp:62

◆ append() [2/3]

void ** QListData::append ( )

Definition at line 251 of file qlist.cpp.

Referenced by append2(), and insert().

252 {
253  return append(1);
254 }
void ** append()
Definition: qlist.cpp:251

◆ append() [3/3]

void ** QListData::append ( const QListData l)

Definition at line 260 of file qlist.cpp.

261 {
262  Q_ASSERT(d->ref == 1);
263  int e = d->end;
264  int n = l.d->end - l.d->begin;
265  if (n) {
266  if (e + n > d->alloc)
267  realloc(grow(e + n));
268  ::memcpy(d->array + d->end, l.d->array + l.d->begin, n*sizeof(void*));
269  d->end += n;
270  }
271  return d->array + e;
272 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void realloc(int alloc)
Definition: qlist.cpp:218
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87
static int grow(int size)
Definition: qlist.cpp:62

◆ append2()

void ** QListData::append2 ( const QListData l)

Definition at line 275 of file qlist.cpp.

276 {
277  return append(l.d->end - l.d->begin);
278 }
void ** append()
Definition: qlist.cpp:251
Data * d
Definition: qlist.h:87

◆ at()

void** QListData::at ( int  i) const
inline

Definition at line 100 of file qlist.h.

100 { return d->array + d->begin + i; }
void * array[1]
Definition: qlist.h:76
Data * d
Definition: qlist.h:87

◆ begin()

void** QListData::begin ( ) const
inline

Definition at line 101 of file qlist.h.

Referenced by QList< QPostEvent >::mid(), and QList< QPostEvent >::operator+=().

101 { return d->array + d->begin; }
void * array[1]
Definition: qlist.h:76
Data * d
Definition: qlist.h:87

◆ detach() [1/2]

QListData::Data * QListData::detach ( int  alloc)

Detaches the QListData by allocating new memory for a list which possibly has a different size than the copied one.

Returns the old (shared) data, it is up to the caller to deref() and free() For the new data node_copy needs to be called.

Warning
This function is not part of the public interface.

Definition at line 182 of file qlist.cpp.

183 {
184  Data *x = d;
185  Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *)));
186  Q_CHECK_PTR(t);
187 
188  t->ref = 1;
189  t->sharable = true;
190  t->alloc = alloc;
191  if (!alloc) {
192  t->begin = 0;
193  t->end = 0;
194  } else {
195  t->begin = x->begin;
196  t->end = x->end;
197  }
198  d = t;
199 
200  return x;
201 }
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
Data * d
Definition: qlist.h:87

◆ detach() [2/2]

QListData::Data * QListData::detach ( )

Definition at line 119 of file qlist.cpp.

Referenced by detach3().

120 {
121  Data *x = static_cast<Data *>(qMalloc(DataHeaderSize + d->alloc * sizeof(void *)));
122  Q_CHECK_PTR(x);
123 
124  x->ref = 1;
125  x->sharable = true;
126  x->alloc = d->alloc;
127  if (!x->alloc) {
128  x->begin = 0;
129  x->end = 0;
130  } else {
131  x->begin = d->begin;
132  x->end = d->end;
133  }
134 
135  qSwap(d, x);
136  if (!x->ref.deref())
137  return x;
138  return 0;
139 }
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
Data * d
Definition: qlist.h:87

◆ detach2()

QListData::Data * QListData::detach2 ( )

Detaches the QListData by reallocating new memory.

Returns the old (shared) data, it is up to the caller to deref() and free() For the new data node_copy needs to be called.

Warning
This function is not part of the public interface.

Definition at line 151 of file qlist.cpp.

152 {
153  Data *x = d;
154  Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *)));
155  Q_CHECK_PTR(t);
156 
157  ::memcpy(t, d, DataHeaderSize + d->alloc * sizeof(void *));
158 
159  t->ref = 1;
160  t->sharable = true;
161  t->alloc = x->alloc;
162  if (!t->alloc) {
163  t->begin = 0;
164  t->end = 0;
165  } else {
166  t->begin = x->begin;
167  t->end = x->end;
168  }
169  d = t;
170 
171  return x;
172 }
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
Data * d
Definition: qlist.h:87

◆ detach3()

QListData::Data * QListData::detach3 ( )

Detaches the QListData by reallocating new memory.

Returns the old (shared) data, it is up to the caller to deref() and free() For the new data node_copy needs to be called.

Warning
This function is not part of the public interface.

Definition at line 213 of file qlist.cpp.

214 {
215  return detach(d->alloc);
216 }
Data * detach()
Definition: qlist.cpp:119
Data * d
Definition: qlist.h:87

◆ detach_grow()

QListData::Data * QListData::detach_grow ( int *  idx,
int  num 
)

Detaches the QListData by allocating new memory for a list which will be bigger than the copied one and is expected to grow further.

*idx is the desired insertion point and is clamped to the actual size of the list. num is the number of new elements to insert at the insertion point. Returns the old (shared) data, it is up to the caller to deref() and free(). For the new data node_copy needs to be called.

Warning
This function is not part of the public interface.

Definition at line 79 of file qlist.cpp.

80 {
81  Data *x = d;
82  int l = x->end - x->begin;
83  int nl = l + num;
84  int alloc = grow(nl);
85  Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *)));
86  Q_CHECK_PTR(t);
87 
88  t->ref = 1;
89  t->sharable = true;
90  t->alloc = alloc;
91  // The space reservation algorithm's optimization is biased towards appending:
92  // Something which looks like an append will put the data at the beginning,
93  // while something which looks like a prepend will put it in the middle
94  // instead of at the end. That's based on the assumption that prepending
95  // is uncommon and even an initial prepend will eventually be followed by
96  // at least some appends.
97  int bg;
98  if (*idx < 0) {
99  *idx = 0;
100  bg = (alloc - nl) >> 1;
101  } else if (*idx > l) {
102  *idx = l;
103  bg = 0;
104  } else if (*idx < (l >> 1)) {
105  bg = (alloc - nl) >> 1;
106  } else {
107  bg = 0;
108  }
109  t->begin = bg;
110  t->end = bg + nl;
111  d = t;
112 
113  return x;
114 }
Q_CORE_EXPORT void * qMalloc(size_t size)
Definition: qmalloc.cpp:53
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
Data * d
Definition: qlist.h:87
QFactoryLoader * l
static int grow(int size)
Definition: qlist.cpp:62

◆ end()

void** QListData::end ( ) const
inline

Definition at line 102 of file qlist.h.

Referenced by QList< QPostEvent >::mid(), and QList< QPostEvent >::operator==().

102 { return d->array + d->end; }
void * array[1]
Definition: qlist.h:76
Data * d
Definition: qlist.h:87

◆ erase()

void ** QListData::erase ( void **  xi)

Definition at line 408 of file qlist.cpp.

409 {
410  Q_ASSERT(d->ref == 1);
411  int i = xi - (d->array + d->begin);
412  remove(i);
413  return d->array + d->begin + i;
414 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87

◆ insert()

void ** QListData::insert ( int  i)

Definition at line 298 of file qlist.cpp.

299 {
300  Q_ASSERT(d->ref == 1);
301  if (i <= 0)
302  return prepend();
303  int size = d->end - d->begin;
304  if (i >= size)
305  return append();
306 
307  bool leftward = false;
308 
309  if (d->begin == 0) {
310  if (d->end == d->alloc) {
311  // If the array is full, we expand it and move some items rightward
312  realloc(grow(d->alloc + 1));
313  } else {
314  // If there is free space at the end of the array, we move some items rightward
315  }
316  } else {
317  if (d->end == d->alloc) {
318  // If there is free space at the beginning of the array, we move some items leftward
319  leftward = true;
320  } else {
321  // If there is free space at both ends, we move as few items as possible
322  leftward = (i < size - i);
323  }
324  }
325 
326  if (leftward) {
327  --d->begin;
328  ::memmove(d->array + d->begin, d->array + d->begin + 1, i * sizeof(void *));
329  } else {
330  ::memmove(d->array + d->begin + i + 1, d->array + d->begin + i,
331  (size - i) * sizeof(void *));
332  ++d->end;
333  }
334  return d->array + d->begin + i;
335 }
void ** append()
Definition: qlist.cpp:251
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void ** prepend()
Definition: qlist.cpp:280
int size() const
Definition: qlist.h:98
void realloc(int alloc)
Definition: qlist.cpp:218
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87
static int grow(int size)
Definition: qlist.cpp:62

◆ isEmpty()

bool QListData::isEmpty ( ) const
inline

Definition at line 99 of file qlist.h.

99 { return d->end == d->begin; }
Data * d
Definition: qlist.h:87

◆ move()

void QListData::move ( int  from,
int  to 
)

Definition at line 368 of file qlist.cpp.

369 {
370  Q_ASSERT(d->ref == 1);
371  if (from == to)
372  return;
373 
374  from += d->begin;
375  to += d->begin;
376  void *t = d->array[from];
377 
378  if (from < to) {
379  if (d->end == d->alloc || 3 * (to - from) < 2 * (d->end - d->begin)) {
380  ::memmove(d->array + from, d->array + from + 1, (to - from) * sizeof(void *));
381  } else {
382  // optimization
383  if (int offset = from - d->begin)
384  ::memmove(d->array + d->begin + 1, d->array + d->begin, offset * sizeof(void *));
385  if (int offset = d->end - (to + 1))
386  ::memmove(d->array + to + 2, d->array + to + 1, offset * sizeof(void *));
387  ++d->begin;
388  ++d->end;
389  ++to;
390  }
391  } else {
392  if (d->begin == 0 || 3 * (from - to) < 2 * (d->end - d->begin)) {
393  ::memmove(d->array + to + 1, d->array + to, (from - to) * sizeof(void *));
394  } else {
395  // optimization
396  if (int offset = to - d->begin)
397  ::memmove(d->array + d->begin - 1, d->array + d->begin, offset * sizeof(void *));
398  if (int offset = d->end - (from + 1))
399  ::memmove(d->array + from, d->array + from + 1, offset * sizeof(void *));
400  --d->begin;
401  --d->end;
402  --to;
403  }
404  }
405  d->array[to] = t;
406 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87

◆ prepend()

void ** QListData::prepend ( )

Definition at line 280 of file qlist.cpp.

Referenced by insert().

281 {
282  Q_ASSERT(d->ref == 1);
283  if (d->begin == 0) {
284  if (d->end >= d->alloc / 3)
285  realloc(grow(d->alloc + 1));
286 
287  if (d->end < d->alloc / 3)
288  d->begin = d->alloc - 2 * d->end;
289  else
290  d->begin = d->alloc - d->end;
291 
292  ::memmove(d->array + d->begin, d->array, d->end * sizeof(void *));
293  d->end += d->begin;
294  }
295  return d->array + --d->begin;
296 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
void realloc(int alloc)
Definition: qlist.cpp:218
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87
static int grow(int size)
Definition: qlist.cpp:62

◆ realloc()

void QListData::realloc ( int  alloc)

Definition at line 218 of file qlist.cpp.

Referenced by append(), insert(), and prepend().

219 {
220  Q_ASSERT(d->ref == 1);
221  Data *x = static_cast<Data *>(qRealloc(d, DataHeaderSize + alloc * sizeof(void *)));
222  Q_CHECK_PTR(x);
223 
224  d = x;
225  d->alloc = alloc;
226  if (!alloc)
227  d->begin = d->end = 0;
228 }
Q_CORE_EXPORT void * qRealloc(void *ptr, size_t size)
Definition: qmalloc.cpp:63
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87

◆ remove() [1/2]

void QListData::remove ( int  i)

Definition at line 337 of file qlist.cpp.

338 {
339  Q_ASSERT(d->ref == 1);
340  i += d->begin;
341  if (i - d->begin < d->end - i) {
342  if (int offset = i - d->begin)
343  ::memmove(d->array + d->begin + 1, d->array + d->begin, offset * sizeof(void *));
344  d->begin++;
345  } else {
346  if (int offset = d->end - i - 1)
347  ::memmove(d->array + i, d->array + i + 1, offset * sizeof(void *));
348  d->end--;
349  }
350 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87

◆ remove() [2/2]

void QListData::remove ( int  i,
int  n 
)

Definition at line 352 of file qlist.cpp.

353 {
354  Q_ASSERT(d->ref == 1);
355  i += d->begin;
356  int middle = i + n/2;
357  if (middle - d->begin < d->end - middle) {
358  ::memmove(d->array + d->begin + n, d->array + d->begin,
359  (i - d->begin) * sizeof(void*));
360  d->begin += n;
361  } else {
362  ::memmove(d->array + i, d->array + i + n,
363  (d->end - i - n) * sizeof(void*));
364  d->end -= n;
365  }
366 }
void * array[1]
Definition: qlist.h:76
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QBasicAtomicInt ref
Definition: qlist.h:73
Data * d
Definition: qlist.h:87

◆ size()

int QListData::size ( ) const
inline

Definition at line 98 of file qlist.h.

Referenced by insert(), and QList< QPostEvent >::operator==().

98 { return d->end - d->begin; }
Data * d
Definition: qlist.h:87

Properties

◆ d

Data* QListData::d

◆ shared_null

QListData::Data QListData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, 0, true, { 0 } }
static

Definition at line 86 of file qlist.h.

Referenced by QList< QPostEvent >::detachShared(), and QList< QPostEvent >::swap().


The documentation for this struct was generated from the following files: