QxOrm
1.5.0
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** https://www.qxorm.com/ 00004 ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com) 00005 ** 00006 ** This file is part of the QxOrm library 00007 ** 00008 ** This software is provided 'as-is', without any express or implied 00009 ** warranty. In no event will the authors be held liable for any 00010 ** damages arising from the use of this software 00011 ** 00012 ** Commercial Usage 00013 ** Licensees holding valid commercial QxOrm licenses may use this file in 00014 ** accordance with the commercial license agreement provided with the 00015 ** Software or, alternatively, in accordance with the terms contained in 00016 ** a written agreement between you and Lionel Marty 00017 ** 00018 ** GNU General Public License Usage 00019 ** Alternatively, this file may be used under the terms of the GNU 00020 ** General Public License version 3.0 as published by the Free Software 00021 ** Foundation and appearing in the file 'license.gpl3.txt' included in the 00022 ** packaging of this file. Please review the following information to 00023 ** ensure the GNU General Public License version 3.0 requirements will be 00024 ** met : http://www.gnu.org/copyleft/gpl.html 00025 ** 00026 ** If you are unsure which license is appropriate for your use, or 00027 ** if you have questions regarding the use of this file, please contact : 00028 ** contact@qxorm.com 00029 ** 00030 ****************************************************************************/ 00031 00032 #ifndef _QX_GENERIC_CONTAINER_H_ 00033 #define _QX_GENERIC_CONTAINER_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #include <QxTraits/is_smart_ptr.h> 00047 #include <QxTraits/remove_attr.h> 00048 #include <QxTraits/remove_smart_ptr.h> 00049 #include <QxTraits/construct_ptr.h> 00050 00051 namespace qx { 00052 namespace trait { 00053 00054 class no_type 00055 { private: void dummy() const { ; } }; 00056 00061 template <class T> 00062 struct generic_container 00063 { typedef no_type type_item; typedef no_type type_key; typedef no_type type_value; typedef no_type type_value_qx; typedef no_type type_iterator; }; 00064 00065 template <typename Key, typename Value> 00066 struct generic_container_item 00067 { 00068 00069 typedef Key type_key; 00070 typedef Value type_value; 00071 typedef typename qx::trait::remove_attr<Value>::type type_value_qx_tmp; 00072 typedef typename qx::trait::remove_smart_ptr<type_value_qx_tmp>::type type_value_qx; 00073 00074 enum { is_key_pointer = (std::is_pointer<type_key>::value || qx::trait::is_smart_ptr<type_key>::value) }; 00075 enum { is_value_pointer = (std::is_pointer<type_value>::value || qx::trait::is_smart_ptr<type_value>::value) }; 00076 00077 private: 00078 00079 std::pair<type_key, type_value> m_pair; 00080 00081 public: 00082 00083 generic_container_item() { ; } 00084 generic_container_item(const Key & key, const Value & value) { m_pair = std::make_pair(key, value); } 00085 ~generic_container_item() { ; } 00086 00087 inline type_key & key() { return m_pair.first; } 00088 inline type_value & value() { return m_pair.second; } 00089 inline const type_key & key() const { return m_pair.first; } 00090 inline const type_value & value() const { return m_pair.second; } 00091 inline type_value_qx & value_qx() { return value_qx_Helper<is_value_pointer, type_value, type_value_qx, 0>::get(m_pair.second); } 00092 inline const type_value_qx & value_qx() const { return value_qx_Helper<is_value_pointer, type_value, type_value_qx, 0>::get(m_pair.second); } 00093 00094 inline void key(const Key & key) { m_pair.first = key; } 00095 inline void value(const Value & value) { m_pair.second = value; } 00096 00097 static inline type_key newKey() { return new_Helper<is_key_pointer, type_key, 0>::get(); } 00098 static inline type_value newValue() { return new_Helper<is_value_pointer, type_value, 0>::get(); } 00099 00100 private: 00101 00102 template <bool bIsPointer /* = true */, typename T, int dummy> 00103 struct new_Helper 00104 { static inline T get() { T t; qx::trait::construct_ptr<T>::get(t); return t; } }; 00105 00106 template <typename T, int dummy> 00107 struct new_Helper<false, T, dummy> 00108 { static inline T get() { return T(); } }; 00109 00110 template <bool bIsPointer /* = true */, typename T, typename U, int dummy> 00111 struct value_qx_Helper 00112 { static inline U & get(T & t) { return (* t); } }; 00113 00114 template <typename T, typename U, int dummy> 00115 struct value_qx_Helper<false, T, U, dummy> 00116 { static inline U & get(T & t) { return t; } }; 00117 00118 }; 00119 00120 } // namespace trait 00121 } // namespace qx 00122 00123 #define QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(TypeContainer, TypeKey, TypeValue) \ 00124 typedef qx::trait::generic_container_item< TypeKey, TypeValue > type_item; \ 00125 typedef typename type_item::type_key type_key; \ 00126 typedef typename type_item::type_value type_value; \ 00127 typedef typename type_item::type_value_qx type_value_qx; \ 00128 typedef typename TypeContainer::iterator type_iterator; 00129 00130 namespace qx { 00131 namespace trait { 00132 namespace detail { 00133 00134 template <typename Container, typename Item> 00135 struct generic_container_base 00136 { 00137 00138 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00139 00140 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00141 static inline void clear(Container & t) { t.clear(); } 00142 static inline void reserve(Container & t, long l) { t.reserve(l); } 00143 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00144 static inline Item * insertItem(Container & t, type_item & item) { t.push_back(item.value()); return (& t.back()); } 00145 static inline type_iterator end(Container & t) { return t.end(); } 00146 00147 static inline type_iterator begin(Container & t, type_item & item) 00148 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00149 00150 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00151 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00152 00153 }; 00154 00155 template <typename Container, typename Item> 00156 struct generic_container_base_without_reserve 00157 { 00158 00159 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00160 00161 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00162 static inline void clear(Container & t) { t.clear(); } 00163 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00164 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00165 static inline Item * insertItem(Container & t, type_item & item) { t.push_back(item.value()); return (& t.back()); } 00166 static inline type_iterator end(Container & t) { return t.end(); } 00167 00168 static inline type_iterator begin(Container & t, type_item & item) 00169 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00170 00171 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00172 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00173 00174 }; 00175 00176 template <typename Container, typename Item> 00177 struct generic_container_base_set 00178 { 00179 00180 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00181 00182 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00183 static inline void clear(Container & t) { t.clear(); } 00184 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00185 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00186 static inline Item * insertItem(Container & t, type_item & item) { return const_cast<Item *>(& (* (t.insert(item.value()).first))); } 00187 static inline type_iterator end(Container & t) { return t.end(); } 00188 00189 static inline type_iterator begin(Container & t, type_item & item) 00190 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00191 00192 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00193 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00194 00195 }; 00196 00197 template <typename Container, typename Item> 00198 struct generic_container_base_multi_set 00199 { 00200 00201 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00202 00203 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00204 static inline void clear(Container & t) { t.clear(); } 00205 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00206 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00207 static inline Item * insertItem(Container & t, type_item & item) { return const_cast<Item *>(& (* (t.insert(item.value())))); } 00208 static inline type_iterator end(Container & t) { return t.end(); } 00209 00210 static inline type_iterator begin(Container & t, type_item & item) 00211 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00212 00213 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00214 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00215 00216 }; 00217 00218 template <typename Container, typename Key, typename Value> 00219 struct generic_container_base_key_value_std_style 00220 { 00221 00222 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00223 00224 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00225 static inline void clear(Container & t) { t.clear(); } 00226 static inline void reserve(Container & t, long l) { t.reserve(l); } 00227 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00228 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value())).first->second)); } 00229 static inline type_iterator end(Container & t) { return t.end(); } 00230 00231 static inline type_iterator begin(Container & t, type_item & item) 00232 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); } 00233 00234 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00235 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; } 00236 00237 }; 00238 00239 template <typename Container, typename Key, typename Value> 00240 struct generic_container_base_key_value_without_reserve 00241 { 00242 00243 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00244 00245 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00246 static inline void clear(Container & t) { t.clear(); } 00247 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00248 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00249 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value())).first->second)); } 00250 static inline type_iterator end(Container & t) { return t.end(); } 00251 00252 static inline type_iterator begin(Container & t, type_item & item) 00253 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); } 00254 00255 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00256 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; } 00257 00258 }; 00259 00260 template <typename Container, typename Key, typename Value> 00261 struct generic_container_base_key_value_multi_std_style 00262 { 00263 00264 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00265 00266 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00267 static inline void clear(Container & t) { t.clear(); } 00268 static inline void reserve(Container & t, long l) { t.reserve(l); } 00269 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00270 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(std::make_pair(item.key(), item.value()))->second)); } 00271 static inline type_iterator end(Container & t) { return t.end(); } 00272 00273 static inline type_iterator begin(Container & t, type_item & item) 00274 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); } 00275 00276 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00277 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; } 00278 00279 }; 00280 00281 template <typename Container, typename Key, typename Value> 00282 struct generic_container_base_key_value_qt_style 00283 { 00284 00285 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00286 00287 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00288 static inline void clear(Container & t) { t.clear(); } 00289 static inline void reserve(Container & t, long l) { t.reserve(l); } 00290 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00291 static inline Value * insertItem(Container & t, type_item & item) { return (& (t.insert(item.key(), item.value()).value())); } 00292 static inline type_iterator end(Container & t) { return t.end(); } 00293 00294 static inline type_iterator begin(Container & t, type_item & item) 00295 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().value()); item.key(* t.begin().key()); return t.begin(); } 00296 00297 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00298 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.value()); item.key(* itr.key()); return itr; } 00299 00300 }; 00301 00302 } // namespace detail 00303 00304 template <typename T> 00305 struct generic_container< std::vector<T> > : public qx::trait::detail::generic_container_base< std::vector<T>, T > 00306 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::vector, T), qx::trait::no_type, T) }; 00307 00308 template <typename T> 00309 struct generic_container< std::list<T> > : public qx::trait::detail::generic_container_base_without_reserve< std::list<T>, T > 00310 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::list, T), qx::trait::no_type, T) }; 00311 00312 template <typename T> 00313 struct generic_container< std::set<T> > : public qx::trait::detail::generic_container_base_set< std::set<T>, T > 00314 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::set, T), qx::trait::no_type, T) }; 00315 00316 template <typename Key, typename Value> 00317 struct generic_container< std::map<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_without_reserve< std::map<Key, Value>, Key, Value > 00318 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::map, Key, Value), Key, Value) }; 00319 00320 #ifdef _QX_ENABLE_BOOST 00321 00322 template <typename T> 00323 struct generic_container< boost::unordered_set<T> > : public qx::trait::detail::generic_container_base_set< boost::unordered_set<T>, T > 00324 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(boost::unordered_set, T), qx::trait::no_type, T) }; 00325 00326 template <typename T> 00327 struct generic_container< boost::unordered_multiset<T> > : public qx::trait::detail::generic_container_base_multi_set< boost::unordered_multiset<T>, T > 00328 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(boost::unordered_multiset, T), qx::trait::no_type, T) }; 00329 00330 template <typename Key, typename Value> 00331 struct 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 > 00332 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_map, Key, Value), Key, Value) }; 00333 00334 template <typename Key, typename Value> 00335 struct 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 > 00336 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_multimap, Key, Value), Key, Value) }; 00337 00338 #endif // _QX_ENABLE_BOOST 00339 00340 template <typename T> 00341 struct generic_container< std::unordered_set<T> > : public qx::trait::detail::generic_container_base_set< std::unordered_set<T>, T > 00342 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::unordered_set, T), qx::trait::no_type, T) }; 00343 00344 template <typename T> 00345 struct generic_container< std::unordered_multiset<T> > : public qx::trait::detail::generic_container_base_multi_set< std::unordered_multiset<T>, T > 00346 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::unordered_multiset, T), qx::trait::no_type, T) }; 00347 00348 template <typename Key, typename Value> 00349 struct 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 > 00350 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::unordered_map, Key, Value), Key, Value) }; 00351 00352 template <typename Key, typename Value> 00353 struct 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 > 00354 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::unordered_multimap, Key, Value), Key, Value) }; 00355 00356 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 00357 template <typename T> 00358 struct generic_container< QVector<T> > : public qx::trait::detail::generic_container_base< QVector<T>, T > 00359 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QVector, T), qx::trait::no_type, T) }; 00360 #endif // (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 00361 00362 #if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) 00363 00364 template <typename T> 00365 struct generic_container< QList<T> > : public qx::trait::detail::generic_container_base< QList<T>, T > 00366 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QList, T), qx::trait::no_type, T) }; 00367 00368 #else // (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) 00369 00370 template <typename T> 00371 struct generic_container< QList<T> > : public qx::trait::detail::generic_container_base_without_reserve< QList<T>, T > 00372 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QList, T), qx::trait::no_type, T) }; 00373 00374 #endif // (QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) 00375 00376 #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0)) 00377 template <typename T> 00378 struct generic_container< QLinkedList<T> > : public qx::trait::detail::generic_container_base_without_reserve< QLinkedList<T>, T > 00379 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QLinkedList, T), qx::trait::no_type, T) }; 00380 #endif // (QT_VERSION < QT_VERSION_CHECK(5, 15, 0)) 00381 00382 template <typename T> 00383 struct generic_container< QSet<T> > : public qx::trait::detail::generic_container_base_multi_set< QSet<T>, T > 00384 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QSet, T), qx::trait::no_type, T) }; 00385 00386 template <typename Key, typename Value> 00387 struct generic_container< QMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMap<Key, Value>, Key, Value > 00388 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMap, Key, Value), Key, Value) }; 00389 00390 template <typename Key, typename Value> 00391 struct generic_container< QMultiMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiMap<Key, Value>, Key, Value > 00392 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiMap, Key, Value), Key, Value) }; 00393 00394 template <typename Key, typename Value> 00395 struct generic_container< QHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QHash<Key, Value>, Key, Value > 00396 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QHash, Key, Value), Key, Value) }; 00397 00398 template <typename Key, typename Value> 00399 struct generic_container< QMultiHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiHash<Key, Value>, Key, Value > 00400 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiHash, Key, Value), Key, Value) }; 00401 00402 template <typename Key, typename Value> 00403 struct generic_container< qx::QxCollection<Key, Value> > 00404 { 00405 00406 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(qx::QxCollection, Key, Value), Key, Value) 00407 00408 static inline long size(const qx::QxCollection<Key, Value> & t) { return static_cast<long>(t.size()); } 00409 static inline void clear(qx::QxCollection<Key, Value> & t) { t.clear(); } 00410 static inline void reserve(qx::QxCollection<Key, Value> & t, long l) { t.reserve(l); } 00411 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00412 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())); } 00413 static inline type_iterator end(qx::QxCollection<Key, Value> & t) { return t.end(); } 00414 00415 static inline type_iterator begin(qx::QxCollection<Key, Value> & t, type_item & item) 00416 { if (t.size() <= 0) { return t.end(); }; item.value(t.getByIndex(0)); item.key(t.getKeyByIndex(0)); return t.begin(); } 00417 00418 static inline type_iterator next(qx::QxCollection<Key, Value> & t, type_iterator itr, type_item & item) 00419 { 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; } 00420 00421 }; 00422 00423 } // namespace trait 00424 } // namespace qx 00425 00426 #endif // _QX_GENERIC_CONTAINER_H_