QxOrm 1.4.9
C++ Object Relational Mapping library
Loading...
Searching...
No Matches
generic_container.h
Go to the documentation of this file.
1/****************************************************************************
2**
3** https://www.qxorm.com/
4** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
5**
6** This file is part of the QxOrm library
7**
8** This software is provided 'as-is', without any express or implied
9** warranty. In no event will the authors be held liable for any
10** damages arising from the use of this software
11**
12** Commercial Usage
13** Licensees holding valid commercial QxOrm licenses may use this file in
14** accordance with the commercial license agreement provided with the
15** Software or, alternatively, in accordance with the terms contained in
16** a written agreement between you and Lionel Marty
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3.0 as published by the Free Software
21** Foundation and appearing in the file 'license.gpl3.txt' included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU General Public License version 3.0 requirements will be
24** met : http://www.gnu.org/copyleft/gpl.html
25**
26** If you are unsure which license is appropriate for your use, or
27** if you have questions regarding the use of this file, please contact :
28** contact@qxorm.com
29**
30****************************************************************************/
31
32#ifndef _QX_GENERIC_CONTAINER_H_
33#define _QX_GENERIC_CONTAINER_H_
34
35#ifdef _MSC_VER
36#pragma once
37#endif
38
50
51namespace qx {
52namespace trait {
53
55{ private: void dummy() const { ; } };
56
61template <class T>
64
65template <typename Key, typename Value>
67{
68
69 typedef Key type_key;
70 typedef Value type_value;
73
74 enum { is_key_pointer = (std::is_pointer<type_key>::value || qx::trait::is_smart_ptr<type_key>::value) };
75 enum { is_value_pointer = (std::is_pointer<type_value>::value || qx::trait::is_smart_ptr<type_value>::value) };
76
77private:
78
79 std::pair<type_key, type_value> m_pair;
80
81public:
82
84 generic_container_item(const Key & key, const Value & value) { m_pair = std::make_pair(key, value); }
86
87 inline type_key & key() { return m_pair.first; }
88 inline type_value & value() { return m_pair.second; }
89 inline const type_key & key() const { return m_pair.first; }
90 inline const type_value & value() const { return m_pair.second; }
93
94 inline void key(const Key & key) { m_pair.first = key; }
95 inline void value(const Value & value) { m_pair.second = value; }
96
99
100private:
101
102 template <bool bIsPointer /* = true */, typename T, int dummy>
104 { static inline T get() { T t; qx::trait::construct_ptr<T>::get(t); return t; } };
105
106 template <typename T, int dummy>
107 struct new_Helper<false, T, dummy>
108 { static inline T get() { return T(); } };
109
110 template <bool bIsPointer /* = true */, typename T, typename U, int dummy>
112 { static inline U & get(T & t) { return (* t); } };
113
114 template <typename T, typename U, int dummy>
115 struct value_qx_Helper<false, T, U, dummy>
116 { static inline U & get(T & t) { return t; } };
117
118};
119
120} // namespace trait
121} // namespace qx
122
123#define QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(TypeContainer, TypeKey, TypeValue) \
124typedef qx::trait::generic_container_item< TypeKey, TypeValue > type_item; \
125typedef typename type_item::type_key type_key; \
126typedef typename type_item::type_value type_value; \
127typedef typename type_item::type_value_qx type_value_qx; \
128typedef typename TypeContainer::iterator type_iterator;
129
130namespace qx {
131namespace trait {
132namespace detail {
133
134template <typename Container, typename Item>
136{
137
139
140 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
141 static inline void clear(Container & t) { t.clear(); }
142 static inline void reserve(Container & t, long l) { t.reserve(l); }
143 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
144 static inline Item * insertItem(Container & t, type_item & item) { t.push_back(item.value()); return (& t.back()); }
145 static inline type_iterator end(Container & t) { return t.end(); }
146
147 static inline type_iterator begin(Container & t, type_item & item)
148 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); }
149
150 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
151 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; }
152
153};
154
155template <typename Container, typename Item>
157{
158
160
161 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
162 static inline void clear(Container & t) { t.clear(); }
163 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); }
164 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
165 static inline Item * insertItem(Container & t, type_item & item) { t.push_back(item.value()); return (& t.back()); }
166 static inline type_iterator end(Container & t) { return t.end(); }
167
168 static inline type_iterator begin(Container & t, type_item & item)
169 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); }
170
171 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
172 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; }
173
174};
175
176template <typename Container, typename Item>
178{
179
181
182 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
183 static inline void clear(Container & t) { t.clear(); }
184 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); }
185 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
186 static inline Item * insertItem(Container & t, type_item & item) { return const_cast<Item *>(& (* (t.insert(item.value()).first))); }
187 static inline type_iterator end(Container & t) { return t.end(); }
188
189 static inline type_iterator begin(Container & t, type_item & item)
190 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); }
191
192 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
193 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; }
194
195};
196
197template <typename Container, typename Item>
199{
200
202
203 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
204 static inline void clear(Container & t) { t.clear(); }
205 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); }
206 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
207 static inline Item * insertItem(Container & t, type_item & item) { return const_cast<Item *>(& (* (t.insert(item.value())))); }
208 static inline type_iterator end(Container & t) { return t.end(); }
209
210 static inline type_iterator begin(Container & t, type_item & item)
211 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); }
212
213 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
214 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; }
215
216};
217
218template <typename Container, typename Key, typename Value>
220{
221
222 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value)
223
224 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
225 static inline void clear(Container & t) { t.clear(); }
226 static inline void reserve(Container & t, long l) { t.reserve(l); }
227 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
228 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value())).first->second)); }
229 static inline type_iterator end(Container & t) { return t.end(); }
230
231 static inline type_iterator begin(Container & t, type_item & item)
232 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); }
233
234 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
235 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; }
236
237};
238
239template <typename Container, typename Key, typename Value>
241{
242
243 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value)
244
245 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
246 static inline void clear(Container & t) { t.clear(); }
247 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); }
248 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
249 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value())).first->second)); }
250 static inline type_iterator end(Container & t) { return t.end(); }
251
252 static inline type_iterator begin(Container & t, type_item & item)
253 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); }
254
255 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
256 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; }
257
258};
259
260template <typename Container, typename Key, typename Value>
262{
263
264 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value)
265
266 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
267 static inline void clear(Container & t) { t.clear(); }
268 static inline void reserve(Container & t, long l) { t.reserve(l); }
269 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
270 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value()))->second)); }
271 static inline type_iterator end(Container & t) { return t.end(); }
272
273 static inline type_iterator begin(Container & t, type_item & item)
274 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); }
275
276 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
277 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; }
278
279};
280
281template <typename Container, typename Key, typename Value>
283{
284
285 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value)
286
287 static inline long size(const Container & t) { return static_cast<long>(t.size()); }
288 static inline void clear(Container & t) { t.clear(); }
289 static inline void reserve(Container & t, long l) { t.reserve(l); }
290 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
291 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(item.key(), item.value()).value())); }
292 static inline type_iterator end(Container & t) { return t.end(); }
293
294 static inline type_iterator begin(Container & t, type_item & item)
295 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().value()); item.key(* t.begin().key()); return t.begin(); }
296
297 static inline type_iterator next(Container & t, type_iterator itr, type_item & item)
298 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.value()); item.key(* itr.key()); return itr; }
299
300};
301
302} // namespace detail
303
304template <typename T>
307
308template <typename T>
311
312template <typename T>
315
316template <typename Key, typename Value>
317struct generic_container< std::map<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_without_reserve< std::map<Key, Value>, Key, Value >
318{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::map, Key, Value), Key, Value) };
319
320#ifdef _QX_ENABLE_BOOST
321
322template <typename T>
323struct generic_container< boost::unordered_set<T> > : public qx::trait::detail::generic_container_base_set< boost::unordered_set<T>, T >
325
326template <typename T>
327struct generic_container< boost::unordered_multiset<T> > : public qx::trait::detail::generic_container_base_multi_set< boost::unordered_multiset<T>, T >
328{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(boost::unordered_multiset, T), qx::trait::no_type, T) };
329
330template <typename Key, typename Value>
331struct generic_container< boost::unordered_map<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_std_style< boost::unordered_map<Key, Value>, Key, Value >
332{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_map, Key, Value), Key, Value) };
333
334template <typename Key, typename Value>
335struct generic_container< boost::unordered_multimap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_multi_std_style< boost::unordered_multimap<Key, Value>, Key, Value >
336{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_multimap, Key, Value), Key, Value) };
337
338#endif // _QX_ENABLE_BOOST
339
340template <typename T>
341struct generic_container< std::unordered_set<T> > : public qx::trait::detail::generic_container_base_set< std::unordered_set<T>, T >
343
344template <typename T>
345struct generic_container< std::unordered_multiset<T> > : public qx::trait::detail::generic_container_base_multi_set< std::unordered_multiset<T>, T >
347
348template <typename Key, typename Value>
349struct generic_container< std::unordered_map<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_std_style< std::unordered_map<Key, Value>, Key, Value >
350{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::unordered_map, Key, Value), Key, Value) };
351
352template <typename Key, typename Value>
353struct generic_container< std::unordered_multimap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_multi_std_style< std::unordered_multimap<Key, Value>, Key, Value >
354{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::unordered_multimap, Key, Value), Key, Value) };
355
356#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
357template <typename T>
358struct generic_container< QVector<T> > : public qx::trait::detail::generic_container_base< QVector<T>, T >
360#endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
361
362#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0))
363
364template <typename T>
367
368#else // (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0))
369
370template <typename T>
373
374#endif // (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0))
375
376#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
377template <typename T>
378struct generic_container< QLinkedList<T> > : public qx::trait::detail::generic_container_base_without_reserve< QLinkedList<T>, T >
380#endif // (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
381
382template <typename T>
385
386template <typename Key, typename Value>
387struct generic_container< QMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMap<Key, Value>, Key, Value >
388{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMap, Key, Value), Key, Value) };
389
390template <typename Key, typename Value>
391struct generic_container< QMultiMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiMap<Key, Value>, Key, Value >
392{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiMap, Key, Value), Key, Value) };
393
394template <typename Key, typename Value>
395struct generic_container< QHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QHash<Key, Value>, Key, Value >
396{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QHash, Key, Value), Key, Value) };
397
398template <typename Key, typename Value>
399struct generic_container< QMultiHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiHash<Key, Value>, Key, Value >
400{ QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiHash, Key, Value), Key, Value) };
401
402template <typename Key, typename Value>
403struct generic_container< qx::QxCollection<Key, Value> >
404{
405
407
408 static inline long size(const qx::QxCollection<Key, Value> & t) { return static_cast<long>(t.size()); }
409 static inline void clear(qx::QxCollection<Key, Value> & t) { t.clear(); }
410 static inline void reserve(qx::QxCollection<Key, Value> & t, long l) { t.reserve(l); }
411 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); }
412 static inline Value * insertItem(qx::QxCollection<Key, Value> & t, type_item & item) { t.insert(item.key(), item.value()); return const_cast<Value *>(& t.getByKey(item.key())); }
413 static inline type_iterator end(qx::QxCollection<Key, Value> & t) { return t.end(); }
414
416 { if (t.size() <= 0) { return t.end(); }; item.value(t.getByIndex(0)); item.key(t.getKeyByIndex(0)); return t.begin(); }
417
419 { itr++; if (itr == t.end()) { return t.end(); }; long l = (itr - t.begin()); item.value(t.getByIndex(l)); item.key(t.getKeyByIndex(l)); return itr; }
420
421};
422
423} // namespace trait
424} // namespace qx
425
426#endif // _QX_GENERIC_CONTAINER_H_
#define QX_TEMPLATE_T_P1(T, P1)
Definition QxMacro.h:171
#define QX_TEMPLATE_T_P1_P2(T, P1, P2)
Definition QxMacro.h:172
qx::QxCollection<Key, Value> : QxOrm thread-safe container (keep insertion order + quick access by in...
bool insert(const Key &key, const Value &value)
Add element 'value' at the end of the list indexed by 'key'.
const_reference_key getKeyByIndex(long index) const
Return the key associated with the element at index position 'index'.
long size() const
Return the number of items in the list (same as 'count()')
const_reference_value getByKey(const Key &key) const
Return the item associated with the 'key'.
void reserve(long size)
Request that the capacity of the allocated storage space for the items of the container be at least e...
iterator begin()
Return an STL-style iterator pointing to the first item in the list.
void clear()
Remove all items from the list.
iterator end()
Return an STL-style iterator pointing to the imaginary item after the last item in the list.
const_reference_value getByIndex(long index) const
Return the item at index position 'index'.
qx::trait::construct_ptr<T>::get(T & t, bool bReset = false) : instantiate (or reset) a new pointer,...
#define QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(TypeContainer, TypeKey, TypeValue)
qx::trait::is_smart_ptr<T>::value : return true if T is a smart-pointer of boost, Qt or QxOrm librari...
Root namespace for all QxOrm library features.
qx::trait::remove_attr<T>::type : return a type without pointer, const, reference and/or volatile att...
qx::trait::remove_smart_ptr<T>::type : return a type without smart-pointer attribute from boost,...
static void get(T &t, bool bReset=false)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static Value * insertItem(Container &t, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static Value * insertItem(Container &t, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static Item * insertItem(Container &t, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static void reserve(Container &t, long l)
static type_iterator end(Container &t)
static Item * insertItem(Container &t, type_item &item)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static Item * insertItem(Container &t, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static long size(const Container &t)
static type_iterator end(Container &t)
static void reserve(Container &t, long l)
static type_iterator next(Container &t, type_iterator itr, type_item &item)
static type_iterator begin(Container &t, type_item &item)
static Item * insertItem(Container &t, type_item &item)
static void clear(qx::QxCollection< Key, Value > &t)
static Value * insertItem(qx::QxCollection< Key, Value > &t, type_item &item)
static type_iterator next(qx::QxCollection< Key, Value > &t, type_iterator itr, type_item &item)
static void reserve(qx::QxCollection< Key, Value > &t, long l)
static type_iterator begin(qx::QxCollection< Key, Value > &t, type_item &item)
static type_iterator end(qx::QxCollection< Key, Value > &t)
std::pair< type_key, type_value > m_pair
const type_value_qx & value_qx() const
qx::trait::remove_smart_ptr< type_value_qx_tmp >::type type_value_qx
const type_value & value() const
qx::trait::remove_attr< Value >::type type_value_qx_tmp
generic_container_item(const Key &key, const Value &value)
qx::trait::generic_container<T> : provide some tools to manage all containers without knowing its typ...
qx::trait::is_smart_ptr<T>::value : return true if T is a smart-pointer of boost, Qt or QxOrm librari...