Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qminimalflatset_p.h
Go to the documentation of this file.
1
// Copyright (C) 2022 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 reason:default
4
5
#
ifndef
QTCORE_QMINIMALFLATSET_P_H
6
#
define
QTCORE_QMINIMALFLATSET_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
/
qcontainerfwd
.
h
>
20
#
include
<
QtCore
/
qfunctionaltools_impl
.
h
>
// CompactStorage
21
#
include
<
QtCore
/
private
/
qglobal_p
.
h
>
22
23
//#define QMINIMAL_FLAT_SET_DEBUG
24
#
ifdef
QMINIMAL_FLAT_SET_DEBUG
25
#
include
<
QtCore
/
qscopeguard
.
h
>
26
#
include
<
QtCore
/
qdebug
.
h
>
27
#
define
QMINIMAL_FLAT_SET_PRINT_AT_END
28
const
auto
sg
=
qScopeGuard
(
[
&
]
{
qDebug
(
)
<<
this
<<
*
this
;
}
)
;
29
#
else
30
#
define
QMINIMAL_FLAT_SET_PRINT_AT_END
31
#
endif
32
33
#
include
<
algorithm
>
// for std::lower_bound, std::sort
34
#
include
<
functional
>
// for std::less, std::ref
35
36
QT_BEGIN_NAMESPACE
37
38
/*
39
This is a minimal version of a QFlatSet, the std::set version of QFlatMap.
40
Like QFlatMap, it has linear insertion and removal, not logarithmic, like
41
real QMap and std::set, so it's only a good container if you either have
42
very few entries or lots, but with separate setup and lookup stages.
43
Because a full QFlatSet would be 10x the work on writing this minimal one,
44
we keep it here for now. When more users pop up and the class has matured a
45
bit, we can consider moving it as QFlatSet alongside QFlatMap.
46
*/
47
48
template
<
typename
T,
typename
Container = QList<T>,
typename
Compare = std::less<T>>
49
class
QMinimalFlatSet : QtPrivate::CompactStorage<Compare>
50
{
51
Container c;
52
using
CompareStorage = QtPrivate::CompactStorage<Compare>;
53
public
:
54
QMinimalFlatSet() =
default
;
55
explicit
QMinimalFlatSet(
const
Compare &cmp) : CompareStorage{cmp} {}
56
explicit
QMinimalFlatSet(std::initializer_list<T> init,
const
Compare &cmp = Compare())
57
: QMinimalFlatSet(init.begin(), init.end(), cmp)
58
{
59
}
60
explicit
QMinimalFlatSet(Container init,
const
Compare &cmp = Compare())
61
: CompareStorage{cmp}, c(std::move(init))
62
{
63
std::sort(c.begin(), c.end(), comparisonObject());
64
c.erase(std::unique(c.begin(), c.end()), c.end());
65
}
66
template
<
typename
InputIt>
67
QMinimalFlatSet(InputIt first, InputIt last,
const
Compare &cmp = Compare())
68
: CompareStorage{cmp}, c(first, last)
69
{
70
std::sort(c.begin(), c.end(), comparisonObject());
71
c.erase(std::unique(c.begin(), c.end()), c.end());
72
}
73
74
// Rule Of Zero applies
75
76
using
const_iterator =
typename
Container::const_iterator;
77
using
iterator = const_iterator;
78
using
const_reverse_iterator =
typename
Container::const_reverse_iterator;
79
using
reverse_iterator = const_reverse_iterator;
80
using
value_type = T;
81
using
key_compare = Compare;
82
using
value_compare = Compare;
83
84
key_compare key_comp()
const
{
return
this
->object(); }
85
value_compare value_comp()
const
{
return
key_comp(); }
86
87
iterator begin()
const
{
return
c.cbegin(); }
88
iterator end()
const
{
return
c.cend(); }
89
iterator cbegin()
const
{
return
begin(); }
90
iterator cend()
const
{
return
end(); }
91
92
reverse_iterator rbegin()
const
{
return
c.crbegin(); }
93
reverse_iterator rend()
const
{
return
c.crend(); }
94
reverse_iterator crbegin()
const
{
return
rbegin(); }
95
reverse_iterator crend()
const
{
return
rend(); }
96
97
void
clear() {
98
QMINIMAL_FLAT_SET_PRINT_AT_END
99
c.clear();
100
}
101
auto
size()
const
{
return
c.size(); }
102
auto
count()
const
{
return
size(); }
103
bool
isEmpty()
const
{
return
size() == 0; }
104
105
std::pair<iterator,
bool
> insert(value_type &&v)
106
{
107
QMINIMAL_FLAT_SET_PRINT_AT_END
108
const
auto
r = lookup(v);
109
if
(r.exists)
110
return
{r.it,
false
};
111
else
112
return
{c.insert(r.it, std::move(v)),
true
};
113
}
114
115
std::pair<iterator,
bool
> insert(
const
value_type &v)
116
{
117
QMINIMAL_FLAT_SET_PRINT_AT_END
118
const
auto
r = lookup(v);
119
if
(r.exists)
120
return
{r.it,
false
};
121
else
122
return
{c.insert(r.it, v),
true
};
123
}
124
125
void
erase(
const
value_type &v)
126
{
127
QMINIMAL_FLAT_SET_PRINT_AT_END
128
const
auto
r = lookup(v);
129
if
(r.exists)
130
c.erase(r.it);
131
}
132
void
remove(
const
value_type &v) { erase(v); }
133
134
bool
contains(
const
value_type &v)
const
135
{
136
return
lookup(v).exists;
137
}
138
139
const
Container &values()
const
& {
return
c; }
140
Container values() && {
return
std::move(c); }
141
142
private
:
143
auto
comparisonObject()
const
{
return
std::cref(
this
->object()); }
144
145
auto
lookup(
const
value_type &v)
const
146
{
147
struct
R {
148
iterator it;
149
bool
exists;
150
};
151
152
const
auto
it = std::lower_bound(c.cbegin(), c.cend(), v, comparisonObject());
153
return
R{it, it != c.cend() && !comparisonObject()(v, *it)};
154
}
155
156
#
ifdef
QMINIMAL_FLAT_SET_DEBUG
157
friend
QDebug operator<<(QDebug dbg,
const
QMinimalFlatSet &set)
158
{
159
const
QDebugStateSaver saver(dbg);
160
dbg.nospace() <<
"QMinimalFlatSet{"
;
161
for
(
auto
&e : set)
162
dbg << e <<
", "
;
163
return
dbg <<
"}"
;
164
}
165
#
endif
166
};
167
168
#
undef
QMINIMAL_FLAT_SET_PRINT_AT_END
169
170
template
<
typename
T, qsizetype N = QVarLengthArrayDefaultPrealloc,
typename
Compare = std::less<T>>
171
using
QMinimalVarLengthFlatSet = QMinimalFlatSet<T, QVarLengthArray<T, N>, Compare>;
172
173
QT_END_NAMESPACE
174
175
#
endif
// QTCORE_QMINIMALFLATSET_P_H
QMINIMAL_FLAT_SET_PRINT_AT_END
#define QMINIMAL_FLAT_SET_PRINT_AT_END
Definition
qminimalflatset_p.h:30
qtbase
src
corelib
tools
qminimalflatset_p.h
Generated on
for Qt by
1.18.0