![]() |
QxOrm
1.2.3
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://www.qxorm.com/ 00004 ** http://sourceforge.net/projects/qxorm/ 00005 ** Original file by Lionel Marty 00006 ** 00007 ** This file is part of the QxOrm library 00008 ** 00009 ** This software is provided 'as-is', without any express or implied 00010 ** warranty. In no event will the authors be held liable for any 00011 ** damages arising from the use of this software. 00012 ** 00013 ** GNU Lesser General Public License Usage 00014 ** This file must be used under the terms of the GNU Lesser 00015 ** General Public License version 2.1 as published by the Free Software 00016 ** Foundation and appearing in the file 'license.lgpl.txt' included in the 00017 ** packaging of this file. Please review the following information to 00018 ** ensure the GNU Lesser General Public License version 2.1 requirements 00019 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 00020 ** 00021 ** If you have questions regarding the use of this file, please contact : 00022 ** contact@qxorm.com 00023 ** 00024 ****************************************************************************/ 00025 00026 #ifndef _QX_GENERIC_CONTAINER_H_ 00027 #define _QX_GENERIC_CONTAINER_H_ 00028 00029 #ifdef _MSC_VER 00030 #pragma once 00031 #endif 00032 00040 #include <boost/type_traits/is_pointer.hpp> 00041 00042 #include <QxTraits/is_smart_ptr.h> 00043 #include <QxTraits/remove_attr.h> 00044 #include <QxTraits/remove_smart_ptr.h> 00045 #include <QxTraits/construct_ptr.h> 00046 00047 namespace qx { 00048 namespace trait { 00049 00050 class no_type 00051 { private: void dummy() const { ; } }; 00052 00057 template <class T> 00058 struct generic_container 00059 { 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; }; 00060 00061 template <typename Key, typename Value> 00062 struct generic_container_item 00063 { 00064 00065 typedef Key type_key; 00066 typedef Value type_value; 00067 typedef typename qx::trait::remove_attr<Value>::type type_value_qx_tmp; 00068 typedef typename qx::trait::remove_smart_ptr<type_value_qx_tmp>::type type_value_qx; 00069 00070 enum { is_key_pointer = (boost::is_pointer<type_key>::value || qx::trait::is_smart_ptr<type_key>::value) }; 00071 enum { is_value_pointer = (boost::is_pointer<type_value>::value || qx::trait::is_smart_ptr<type_value>::value) }; 00072 00073 private: 00074 00075 std::pair<type_key, type_value> m_pair; 00076 00077 public: 00078 00079 generic_container_item() { ; } 00080 generic_container_item(const Key & key, const Value & value) { m_pair = std::make_pair(key, value); } 00081 ~generic_container_item() { ; } 00082 00083 inline type_key & key() { return m_pair.first; } 00084 inline type_value & value() { return m_pair.second; } 00085 inline const type_key & key() const { return m_pair.first; } 00086 inline const type_value & value() const { return m_pair.second; } 00087 inline type_value_qx & value_qx() { return value_qx_Helper<is_value_pointer, type_value, type_value_qx, 0>::get(m_pair.second); } 00088 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); } 00089 00090 inline void key(const Key & key) { m_pair.first = key; } 00091 inline void value(const Value & value) { m_pair.second = value; } 00092 00093 static inline type_key newKey() { return new_Helper<is_key_pointer, type_key, 0>::get(); } 00094 static inline type_value newValue() { return new_Helper<is_value_pointer, type_value, 0>::get(); } 00095 00096 private: 00097 00098 template <bool bIsPointer /* = true */, typename T, int dummy> 00099 struct new_Helper 00100 { static inline T get() { T t; qx::trait::construct_ptr<T>::get(t); return t; } }; 00101 00102 template <typename T, int dummy> 00103 struct new_Helper<false, T, dummy> 00104 { static inline T get() { return T(); } }; 00105 00106 template <bool bIsPointer /* = true */, typename T, typename U, int dummy> 00107 struct value_qx_Helper 00108 { static inline U & get(T & t) { return (* t); } }; 00109 00110 template <typename T, typename U, int dummy> 00111 struct value_qx_Helper<false, T, U, dummy> 00112 { static inline U & get(T & t) { return t; } }; 00113 00114 }; 00115 00116 } // namespace trait 00117 } // namespace qx 00118 00119 #define QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(TypeContainer, TypeKey, TypeValue) \ 00120 typedef qx::trait::generic_container_item< TypeKey, TypeValue > type_item; \ 00121 typedef typename type_item::type_key type_key; \ 00122 typedef typename type_item::type_value type_value; \ 00123 typedef typename type_item::type_value_qx type_value_qx; \ 00124 typedef typename TypeContainer::iterator type_iterator; 00125 00126 namespace qx { 00127 namespace trait { 00128 namespace detail { 00129 00130 template <typename Container, typename Item> 00131 struct generic_container_base 00132 { 00133 00134 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00135 00136 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00137 static inline void clear(Container & t) { t.clear(); } 00138 static inline void reserve(Container & t, long l) { t.reserve(l); } 00139 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00140 static inline void insertItem(Container & t, type_item & item) { t.push_back(item.value()); } 00141 static inline type_iterator end(Container & t) { return t.end(); } 00142 00143 static inline type_iterator begin(Container & t, type_item & item) 00144 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00145 00146 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00147 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00148 00149 }; 00150 00151 template <typename Container, typename Item> 00152 struct generic_container_base_without_reserve 00153 { 00154 00155 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00156 00157 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00158 static inline void clear(Container & t) { t.clear(); } 00159 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00160 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00161 static inline void insertItem(Container & t, type_item & item) { t.push_back(item.value()); } 00162 static inline type_iterator end(Container & t) { return t.end(); } 00163 00164 static inline type_iterator begin(Container & t, type_item & item) 00165 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00166 00167 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00168 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00169 00170 }; 00171 00172 template <typename Container, typename Item> 00173 struct generic_container_base_set 00174 { 00175 00176 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, qx::trait::no_type, Item) 00177 00178 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00179 static inline void clear(Container & t) { t.clear(); } 00180 static inline void reserve(Container & t, long l) { Q_UNUSED(t); Q_UNUSED(l); } 00181 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00182 static inline void insertItem(Container & t, type_item & item) { t.insert(item.value()); } 00183 static inline type_iterator end(Container & t) { return t.end(); } 00184 00185 static inline type_iterator begin(Container & t, type_item & item) 00186 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin()); return t.begin(); } 00187 00188 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00189 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr); return itr; } 00190 00191 }; 00192 00193 template <typename Container, typename Key, typename Value> 00194 struct generic_container_base_key_value_std_style 00195 { 00196 00197 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00198 00199 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00200 static inline void clear(Container & t) { t.clear(); } 00201 static inline void reserve(Container & t, long l) { t.reserve(l); } 00202 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00203 static inline void insertItem(Container & t, type_item & item) { t.insert(std::make_pair(item.key(), item.value())); } 00204 static inline type_iterator end(Container & t) { return t.end(); } 00205 00206 static inline type_iterator begin(Container & t, type_item & item) 00207 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().second); item.key(* t.begin().first); return t.begin(); } 00208 00209 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00210 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.second); item.key(* itr.first); return itr; } 00211 00212 }; 00213 00214 template <typename Container, typename Key, typename Value> 00215 struct generic_container_base_key_value_qt_style 00216 { 00217 00218 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(Container, Key, Value) 00219 00220 static inline long size(const Container & t) { return static_cast<long>(t.size()); } 00221 static inline void clear(Container & t) { t.clear(); } 00222 static inline void reserve(Container & t, long l) { t.reserve(l); } 00223 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00224 static inline void insertItem(Container & t, type_item & item) { t.insert(item.key(), item.value()); } 00225 static inline type_iterator end(Container & t) { return t.end(); } 00226 00227 static inline type_iterator begin(Container & t, type_item & item) 00228 { if (t.size() <= 0) { return t.end(); }; item.value(* t.begin().value()); item.key(* t.begin().key()); return t.begin(); } 00229 00230 static inline type_iterator next(Container & t, type_iterator itr, type_item & item) 00231 { itr++; if (itr == t.end()) { return t.end(); }; item.value(* itr.value()); item.key(* itr.key()); return itr; } 00232 00233 }; 00234 00235 } // namespace detail 00236 00237 template <typename T> 00238 struct generic_container< std::vector<T> > : public qx::trait::detail::generic_container_base< std::vector<T>, T > 00239 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::vector, T), qx::trait::no_type, T) }; 00240 00241 template <typename T> 00242 struct generic_container< std::list<T> > : public qx::trait::detail::generic_container_base_without_reserve< std::list<T>, T > 00243 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::list, T), qx::trait::no_type, T) }; 00244 00245 template <typename T> 00246 struct generic_container< std::set<T> > : public qx::trait::detail::generic_container_base_set< std::set<T>, T > 00247 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(std::set, T), qx::trait::no_type, T) }; 00248 00249 template <typename Key, typename Value> 00250 struct generic_container< std::map<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_std_style< std::map<Key, Value>, Key, Value > 00251 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(std::map, Key, Value), Key, Value) }; 00252 00253 template <typename T> 00254 struct generic_container< boost::unordered_set<T> > : public qx::trait::detail::generic_container_base_set< boost::unordered_set<T>, T > 00255 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(boost::unordered_set, T), qx::trait::no_type, T) }; 00256 00257 template <typename T> 00258 struct generic_container< boost::unordered_multiset<T> > : public qx::trait::detail::generic_container_base_set< boost::unordered_multiset<T>, T > 00259 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(boost::unordered_multiset, T), qx::trait::no_type, T) }; 00260 00261 template <typename Key, typename Value> 00262 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 > 00263 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_map, Key, Value), Key, Value) }; 00264 00265 template <typename Key, typename Value> 00266 struct generic_container< boost::unordered_multimap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_std_style< boost::unordered_multimap<Key, Value>, Key, Value > 00267 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(boost::unordered_multimap, Key, Value), Key, Value) }; 00268 00269 template <typename T> 00270 struct generic_container< QVector<T> > : public qx::trait::detail::generic_container_base< QVector<T>, T > 00271 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QVector, T), qx::trait::no_type, T) }; 00272 00273 template <typename T> 00274 struct generic_container< QList<T> > : public qx::trait::detail::generic_container_base_without_reserve< QList<T>, T > 00275 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QList, T), qx::trait::no_type, T) }; 00276 00277 template <typename T> 00278 struct generic_container< QLinkedList<T> > : public qx::trait::detail::generic_container_base_without_reserve< QLinkedList<T>, T > 00279 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QLinkedList, T), qx::trait::no_type, T) }; 00280 00281 template <typename T> 00282 struct generic_container< QSet<T> > : public qx::trait::detail::generic_container_base_set< QSet<T>, T > 00283 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1(QSet, T), qx::trait::no_type, T) }; 00284 00285 template <typename Key, typename Value> 00286 struct generic_container< QMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMap<Key, Value>, Key, Value > 00287 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMap, Key, Value), Key, Value) }; 00288 00289 template <typename Key, typename Value> 00290 struct generic_container< QMultiMap<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiMap<Key, Value>, Key, Value > 00291 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiMap, Key, Value), Key, Value) }; 00292 00293 template <typename Key, typename Value> 00294 struct generic_container< QHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QHash<Key, Value>, Key, Value > 00295 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QHash, Key, Value), Key, Value) }; 00296 00297 template <typename Key, typename Value> 00298 struct generic_container< QMultiHash<Key, Value> > : public qx::trait::detail::generic_container_base_key_value_qt_style< QMultiHash<Key, Value>, Key, Value > 00299 { QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(QMultiHash, Key, Value), Key, Value) }; 00300 00301 template <typename Key, typename Value> 00302 struct generic_container< qx::QxCollection<Key, Value> > 00303 { 00304 00305 QX_TRAIT_GENERIC_CONTAINER_TYPEDEF(QX_TEMPLATE_T_P1_P2(qx::QxCollection, Key, Value), Key, Value) 00306 00307 static inline long size(const qx::QxCollection<Key, Value> & t) { return static_cast<long>(t.size()); } 00308 static inline void clear(qx::QxCollection<Key, Value> & t) { t.clear(); } 00309 static inline void reserve(qx::QxCollection<Key, Value> & t, long l) { t.reserve(l); } 00310 static inline type_item createItem() { return type_item(type_item::newKey(), type_item::newValue()); } 00311 static inline void insertItem(qx::QxCollection<Key, Value> & t, type_item & item) { t.insert(item.key(), item.value()); } 00312 static inline type_iterator end(qx::QxCollection<Key, Value> & t) { return t.end(); } 00313 00314 static inline type_iterator begin(qx::QxCollection<Key, Value> & t, type_item & item) 00315 { if (t.size() <= 0) { return t.end(); }; item.value(t.getByIndex(0)); item.key(t.getKeyByIndex(0)); return t.begin(); } 00316 00317 static inline type_iterator next(qx::QxCollection<Key, Value> & t, type_iterator itr, type_item & item) 00318 { 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; } 00319 00320 }; 00321 00322 } // namespace trait 00323 } // namespace qx 00324 00325 #endif // _QX_GENERIC_CONTAINER_H_