1 | // Copyright (C) 2020 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 QCONTAINERINFO_H |
5 | #define QCONTAINERINFO_H |
6 | |
7 | #include <QtCore/qglobal.h> |
8 | #include <type_traits> |
9 | |
10 | QT_BEGIN_NAMESPACE |
11 | |
12 | namespace QContainerInfo { |
13 | |
14 | template<typename C> |
15 | using value_type = typename C::value_type; |
16 | |
17 | template<typename C> |
18 | using key_type = typename C::key_type; |
19 | |
20 | template<typename C> |
21 | using mapped_type = typename C::mapped_type; |
22 | |
23 | template<typename C> |
24 | using iterator = typename C::iterator; |
25 | |
26 | template<typename C> |
27 | using const_iterator = typename C::const_iterator; |
28 | |
29 | // Some versions of Apple clang warn about the constexpr variables below being unused. |
30 | QT_WARNING_PUSH |
31 | QT_WARNING_DISABLE_CLANG("-Wunused-const-variable" ) |
32 | |
33 | template<typename C, typename = void> |
34 | inline constexpr bool has_value_type_v = false; |
35 | template<typename C> |
36 | inline constexpr bool has_value_type_v<C, std::void_t<value_type<C>>> = true; |
37 | |
38 | template<typename C, typename = void> |
39 | inline constexpr bool has_key_type_v = false; |
40 | template<typename C> |
41 | inline constexpr bool has_key_type_v<C, std::void_t<key_type<C>>> = true; |
42 | |
43 | template<typename C, typename = void> |
44 | inline constexpr bool has_mapped_type_v = false; |
45 | template<typename C> |
46 | inline constexpr bool has_mapped_type_v<C, std::void_t<mapped_type<C>>> = true; |
47 | |
48 | template<typename C, typename = void> |
49 | inline constexpr bool has_size_v = false; |
50 | template<typename C> |
51 | inline constexpr bool has_size_v<C, std::void_t<decltype(C().size())>> = true; |
52 | |
53 | template<typename C, typename = void> |
54 | inline constexpr bool has_reserve_v = false; |
55 | template<typename C> |
56 | inline constexpr bool has_reserve_v<C, std::void_t<decltype(C().reserve(0))>> = true; |
57 | |
58 | template<typename C, typename = void> |
59 | inline constexpr bool has_clear_v = false; |
60 | template<typename C> |
61 | inline constexpr bool has_clear_v<C, std::void_t<decltype(C().clear())>> = true; |
62 | |
63 | template<typename, typename = void> |
64 | inline constexpr bool has_at_index_v = false; |
65 | template<typename C> |
66 | inline constexpr bool has_at_index_v<C, std::void_t<decltype(C().at(0))>> = true; |
67 | |
68 | template<typename, typename = void> |
69 | inline constexpr bool has_at_key_v = false; |
70 | template<typename C> |
71 | inline constexpr bool has_at_key_v<C, std::void_t<decltype(C().at(key_type<C>()))>> = true; |
72 | |
73 | template<typename, typename = void> |
74 | inline constexpr bool can_get_at_index_v = false; |
75 | template<typename C> |
76 | inline constexpr bool can_get_at_index_v<C, std::void_t<value_type<C>(decltype(C()[0]))>> = true; |
77 | |
78 | template<typename, typename = void> |
79 | inline constexpr bool can_set_at_index_v = false; |
80 | template<typename C> |
81 | inline constexpr bool can_set_at_index_v<C, std::void_t<decltype(C()[0] = value_type<C>())>> = true; |
82 | |
83 | template<typename, typename = void> |
84 | inline constexpr bool has_push_front_v = false; |
85 | template<typename C> |
86 | inline constexpr bool has_push_front_v<C, std::void_t<decltype(C().push_front(value_type<C>()))>> = true; |
87 | |
88 | template<typename, typename = void> |
89 | inline constexpr bool has_push_back_v = false; |
90 | template<typename C> |
91 | inline constexpr bool has_push_back_v<C, std::void_t<decltype(C().push_back(value_type<C>()))>> = true; |
92 | |
93 | template<typename, typename = void> |
94 | inline constexpr bool has_insert_v = false; |
95 | template<typename C> |
96 | inline constexpr bool has_insert_v<C, std::void_t<decltype(C().insert(value_type<C>()))>> = true; |
97 | |
98 | template<typename, typename = void> |
99 | inline constexpr bool has_pop_front_v = false; |
100 | template<typename C> |
101 | inline constexpr bool has_pop_front_v<C, std::void_t<decltype(C().pop_front())>> = true; |
102 | |
103 | template<typename, typename = void> |
104 | inline constexpr bool has_pop_back_v = false; |
105 | template<typename C> |
106 | inline constexpr bool has_pop_back_v<C, std::void_t<decltype(C().pop_back())>> = true; |
107 | |
108 | template<typename, typename = void> |
109 | inline constexpr bool has_iterator_v = false; |
110 | template<typename C> |
111 | inline constexpr bool has_iterator_v<C, std::void_t<iterator<C>>> = true; |
112 | |
113 | template<typename, typename = void> |
114 | inline constexpr bool has_const_iterator_v = false; |
115 | template<typename C> |
116 | inline constexpr bool has_const_iterator_v<C, std::void_t<const_iterator<C>>> = true; |
117 | |
118 | template<typename, typename = void> |
119 | inline constexpr bool can_set_value_at_iterator_v = false; |
120 | template<typename C> |
121 | inline constexpr bool can_set_value_at_iterator_v<C, std::void_t<decltype(*C().begin() = value_type<C>())>> = true; |
122 | |
123 | template<typename, typename = void> |
124 | inline constexpr bool can_set_mapped_at_iterator_v = false; |
125 | template<typename C> |
126 | inline constexpr bool can_set_mapped_at_iterator_v<C, std::void_t<decltype(*C().begin() = mapped_type<C>())>> = true; |
127 | |
128 | template<typename, typename = void> |
129 | inline constexpr bool can_insert_value_at_iterator_v = false; |
130 | template<typename C> |
131 | inline constexpr bool can_insert_value_at_iterator_v<C, std::void_t<decltype(C().insert(C().begin(), value_type<C>()))>> = true; |
132 | |
133 | template<typename, typename = void> |
134 | inline constexpr bool can_erase_at_iterator_v = false; |
135 | template<typename C> |
136 | inline constexpr bool can_erase_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin()))>> = true; |
137 | |
138 | template<typename, typename = void> |
139 | inline constexpr bool can_erase_range_at_iterator_v = false; |
140 | template<typename C> |
141 | inline constexpr bool can_erase_range_at_iterator_v<C, std::void_t<decltype(C().erase(C().begin(), C().end()))>> = true; |
142 | |
143 | template<typename, typename = void> |
144 | inline constexpr bool can_get_at_key_v = false; |
145 | template<typename C> |
146 | inline constexpr bool can_get_at_key_v<C, std::void_t<mapped_type<C>(decltype(C()[key_type<C>()]))>> = true; |
147 | |
148 | template<typename, typename = void> |
149 | inline constexpr bool can_set_at_key_v = false; |
150 | template<typename C> |
151 | inline constexpr bool can_set_at_key_v<C, std::void_t<decltype(C()[key_type<C>()] = mapped_type<C>())>> = true; |
152 | |
153 | template<typename, typename = void> |
154 | inline constexpr bool can_erase_at_key_v = false; |
155 | template<typename C> |
156 | inline constexpr bool can_erase_at_key_v<C, std::void_t<decltype(C().erase(key_type<C>()))>> = true; |
157 | |
158 | template<typename, typename = void> |
159 | inline constexpr bool can_remove_at_key_v = false; |
160 | template<typename C> |
161 | inline constexpr bool can_remove_at_key_v<C, std::void_t<decltype(C().remove(key_type<C>()))>> = true; |
162 | |
163 | template<typename, typename = void> |
164 | inline constexpr bool can_insert_key_v = false; |
165 | template<typename C> |
166 | inline constexpr bool can_insert_key_v<C, std::void_t<decltype(C().insert(key_type<C>()))>> = true; |
167 | |
168 | template<typename, typename = void> |
169 | inline constexpr bool can_insert_pair_v = false; |
170 | template<typename C> |
171 | inline constexpr bool can_insert_pair_v<C, std::void_t<decltype(C().insert({key_type<C>(), mapped_type<C>()}))>> = true; |
172 | |
173 | template<typename, typename = void> |
174 | inline constexpr bool can_insert_key_mapped_v = false; |
175 | template<typename C> |
176 | inline constexpr bool can_insert_key_mapped_v<C, std::void_t<decltype(C().insert(key_type<C>(), mapped_type<C>()))>> = true; |
177 | |
178 | template<typename, typename = void> |
179 | inline constexpr bool has_contains_v = false; |
180 | template<typename C> |
181 | inline constexpr bool has_contains_v<C, std::void_t<decltype(bool(C().contains(key_type<C>())))>> = true; |
182 | |
183 | template<typename, typename = void> |
184 | inline constexpr bool has_find_v = false; |
185 | template<typename C> |
186 | inline constexpr bool has_find_v<C, std::void_t<decltype(C().find(key_type<C>()))>> = true; |
187 | |
188 | template<typename, typename = void> |
189 | inline constexpr bool iterator_dereferences_to_value_v = false; |
190 | template<typename C> |
191 | inline constexpr bool iterator_dereferences_to_value_v<C, std::void_t<decltype(value_type<C>(*C().begin()))>> = true; |
192 | |
193 | template<typename, typename = void> |
194 | inline constexpr bool iterator_has_key_v = false; |
195 | template<typename C> |
196 | inline constexpr bool iterator_has_key_v<C, std::void_t<decltype(key_type<C>(C().begin().key()))>> = true; |
197 | |
198 | template<typename, typename = void> |
199 | inline constexpr bool value_type_has_first_v = false; |
200 | template<typename C> |
201 | inline constexpr bool value_type_has_first_v<C, std::void_t<decltype(key_type<C>(value_type<C>().first))>> = true; |
202 | |
203 | template<typename, typename = void> |
204 | inline constexpr bool iterator_dereferences_to_key_v = false; |
205 | template<typename C> |
206 | inline constexpr bool iterator_dereferences_to_key_v<C, std::void_t<decltype(key_type<C>(*C().begin()))>> = true; |
207 | |
208 | template<typename, typename = void> |
209 | inline constexpr bool iterator_has_value_v = false; |
210 | template<typename C> |
211 | inline constexpr bool iterator_has_value_v<C, std::void_t<decltype(mapped_type<C>(C().begin().value()))>> = true; |
212 | |
213 | template<typename, typename = void> |
214 | inline constexpr bool value_type_has_second_v = false; |
215 | template<typename C> |
216 | inline constexpr bool value_type_has_second_v<C, std::void_t<decltype(mapped_type<C>(value_type<C>().second))>> = true; |
217 | |
218 | template<typename, typename = void> |
219 | inline constexpr bool iterator_dereferences_to_mapped_v = false; |
220 | template<typename C> |
221 | inline constexpr bool iterator_dereferences_to_mapped_v<C, std::void_t<decltype(mapped_type<C>(*C().begin()))>> = true; |
222 | |
223 | QT_WARNING_POP |
224 | |
225 | } |
226 | |
227 | QT_END_NAMESPACE |
228 | |
229 | #endif // QCONTAINERINFO_H |
230 | |