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