Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qpodvector_p.h
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QPODVECTOR_P_H
5#define QPODVECTOR_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qglobal_p.h>
19#include <QtCore/qtclasshelpermacros.h>
20
21#include <type_traits>
22
23QT_BEGIN_NAMESPACE
24
25template<class T, int Increment>
26class QPODVector
27{
28 static_assert(std::is_trivially_constructible_v<T>);
29 static_assert(std::is_trivially_move_constructible_v<T>);
30 static_assert(std::is_trivially_move_assignable_v<T>);
31 static_assert(std::is_trivially_destructible_v<T>);
32
33public:
34 QPODVector()
35 : m_count(0), m_capacity(0), m_data(nullptr) {}
36 ~QPODVector() { if (m_data) ::free(m_data); }
37
38 const T &at(int idx) const {
39 return m_data[idx];
40 }
41
42 T &operator[](int idx) {
43 return m_data[idx];
44 }
45
46 void clear() {
47 m_count = 0;
48 }
49
50 void prepend(const T &v) {
51 insert(0, v);
52 }
53
54 void append(const T &v) {
55 insert(m_count, v);
56 }
57
58 void insert(int idx, const T &v) {
59 if (m_count == m_capacity) {
60 m_capacity += Increment;
61 m_data = (T *)realloc(static_cast<void *>(m_data), m_capacity * sizeof(T));
62 }
63 int moveCount = m_count - idx;
64 if (moveCount)
65 ::memmove(static_cast<void *>(m_data + idx + 1), static_cast<const void *>(m_data + idx), moveCount * sizeof(T));
66 m_count++;
67 m_data[idx] = v;
68 }
69
70 void reserve(int count) {
71 if (count >= m_capacity) {
72 m_capacity = (count + (Increment-1)) & (0xFFFFFFFF - Increment + 1);
73 m_data = (T *)realloc(static_cast<void *>(m_data), m_capacity * sizeof(T));
74 }
75 }
76
77 void insertBlank(int idx, int count) {
78 int newSize = m_count + count;
79 reserve(newSize);
80 int moveCount = m_count - idx;
81 if (moveCount)
82 ::memmove(static_cast<void *>(m_data + idx + count), static_cast<const void *>(m_data + idx),
83 moveCount * sizeof(T));
84 m_count = newSize;
85 }
86
87 void remove(int idx, int count = 1) {
88 int moveCount = m_count - (idx + count);
89 if (moveCount)
90 ::memmove(static_cast<void *>(m_data + idx), static_cast<const void *>(m_data + idx + count),
91 moveCount * sizeof(T));
92 m_count -= count;
93 }
94
95 void removeOne(const T &v) {
96 int idx = 0;
97 while (idx < m_count) {
98 if (m_data[idx] == v) {
99 remove(idx);
100 return;
101 }
102 ++idx;
103 }
104 }
105
106 int find(const T &v) {
107 for (int idx = 0; idx < m_count; ++idx)
108 if (m_data[idx] == v)
109 return idx;
110 return -1;
111 }
112
113 bool contains(const T &v) {
114 return find(v) != -1;
115 }
116
117 int count() const {
118 return m_count;
119 }
120
121 void copyAndClear(QPODVector<T,Increment> &other) {
122 if (other.m_data) ::free(other.m_data);
123 other.m_count = m_count;
124 other.m_capacity = m_capacity;
125 other.m_data = m_data;
126 m_count = 0;
127 m_capacity = 0;
128 m_data = nullptr;
129 }
130
131 QPODVector<T,Increment> &operator<<(const T &v) { append(v); return *this; }
132private:
133 Q_DISABLE_COPY(QPODVector)
134 int m_count;
135 int m_capacity;
136 T *m_data;
137};
138
139QT_END_NAMESPACE
140
141#endif