![]() |
QxOrm
1.4.3
C++ Object Relational Mapping library
|
00001 /**************************************************************************** 00002 ** 00003 ** http://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_GET_CLASS_NAME_H_ 00033 #define _QX_GET_CLASS_NAME_H_ 00034 00035 #ifdef _MSC_VER 00036 #pragma once 00037 #endif 00038 00046 #ifndef _QX_NO_RTTI 00047 #include <typeinfo> 00048 #endif // _QX_NO_RTTI 00049 00050 #include <boost/algorithm/string.hpp> 00051 00052 #include <QxTraits/remove_attr.h> 00053 00054 #define QX_REGISTER_CLASS_NAME_SEP_INF std::string("<") 00055 #define QX_REGISTER_CLASS_NAME_SEP_SUP std::string(">") 00056 #define QX_REGISTER_CLASS_NAME_SEP_NXT std::string(", ") 00057 00058 #define QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG std::string("-") 00059 #define QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG std::string("-") 00060 #define QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG std::string("_") 00061 00062 #define QX_GET_CLASS_NAME(TYPE) \ 00063 qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get() 00064 00065 #define QX_GET_CLASS_NAME_STD_STR(TYPE) \ 00066 std::string(qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get()) 00067 00068 #define QX_GET_CLASS_NAME_XML_TAG(TYPE) \ 00069 qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get_xml_tag() 00070 00071 #define QX_GET_CLASS_NAME_XML_TAG_STD_STR(TYPE) \ 00072 std::string(qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get_xml_tag()) 00073 00074 #define QX_GET_CLASS_NAME_WITH_TYPENAME(TYPE) \ 00075 qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get() 00076 00077 #define QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(TYPE) \ 00078 std::string(qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get()) 00079 00080 #define QX_GET_CLASS_NAME_XML_TAG_WITH_TYPENAME(TYPE) \ 00081 qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get_xml_tag() 00082 00083 #define QX_GET_CLASS_NAME_XML_TAG_STD_STR_WITH_TYPENAME(TYPE) \ 00084 std::string(qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get_xml_tag()) 00085 00086 #define QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG() \ 00087 static inline const char * get_xml_tag() \ 00088 { \ 00089 static std::string result_xml; \ 00090 if (! result_xml.empty()) { return result_xml.c_str(); } \ 00091 result_xml = std::string(get_class_name::get()); \ 00092 boost::replace_all(result_xml, QX_REGISTER_CLASS_NAME_SEP_INF, QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG); \ 00093 boost::replace_all(result_xml, QX_REGISTER_CLASS_NAME_SEP_SUP, QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG); \ 00094 boost::replace_all(result_xml, QX_REGISTER_CLASS_NAME_SEP_NXT, QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG); \ 00095 boost::replace_all(result_xml, "::", "."); \ 00096 boost::replace_all(result_xml, " ", ""); \ 00097 return result_xml.c_str(); \ 00098 } 00099 00100 #ifdef _QX_NO_RTTI 00101 #define QX_REGISTER_CLASS_NAME_NO_RTTI(className) std::string(#className) 00102 #endif // _QX_NO_RTTI 00103 00104 namespace qx { 00105 namespace trait { 00106 00111 template <typename T> 00112 struct get_class_name 00113 { 00114 00115 static inline const char * get() 00116 { 00117 static std::string result; 00118 if (! result.empty()) { return result.c_str(); } 00119 00120 #ifndef _QX_NO_RTTI 00121 T * dummy = NULL; Q_UNUSED(dummy); 00122 result = std::string(typeid(dummy).name()); 00123 #else // _QX_NO_RTTI 00124 result = QX_REGISTER_CLASS_NAME_NO_RTTI(T); 00125 #endif // _QX_NO_RTTI 00126 00127 qDebug("[QxOrm] Unable to define correct class name : '%s' => use macro 'QX_REGISTER_CLASS_NAME()' or 'QX_REGISTER_CLASS_NAME_TEMPLATE_X()'", result.c_str()); 00128 qAssert(false); 00129 return result.c_str(); 00130 } 00131 00132 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); 00133 00134 }; 00135 00136 } // namespace trait 00137 } // namespace qx 00138 00139 #define QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className) \ 00140 static std::string result; \ 00141 if (! result.empty()) { return result.c_str(); } \ 00142 result = std::string(#className); 00143 00144 #define QX_REGISTER_CLASS_NAME(className) \ 00145 namespace qx { namespace trait { \ 00146 template <> \ 00147 struct get_class_name< className > \ 00148 { \ 00149 static inline const char * get() \ 00150 { \ 00151 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00152 return result.c_str(); \ 00153 } \ 00154 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00155 }; \ 00156 } } // namespace qx::trait 00157 00158 #define QX_REGISTER_CLASS_NAME_TEMPLATE_1(className) \ 00159 namespace qx { namespace trait { \ 00160 template <typename T> \ 00161 struct get_class_name< className<T> > \ 00162 { \ 00163 static inline const char * get() \ 00164 { \ 00165 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00166 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00167 return result.c_str(); \ 00168 } \ 00169 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00170 }; \ 00171 } } // namespace qx::trait 00172 00173 #define QX_REGISTER_CLASS_NAME_TEMPLATE_2(className) \ 00174 namespace qx { namespace trait { \ 00175 template <typename T1, typename T2> \ 00176 struct get_class_name< className<T1, T2> > \ 00177 { \ 00178 static inline const char * get() \ 00179 { \ 00180 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00181 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00182 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00183 return result.c_str(); \ 00184 } \ 00185 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00186 }; \ 00187 } } // namespace qx::trait 00188 00189 #define QX_REGISTER_CLASS_NAME_TEMPLATE_3(className) \ 00190 namespace qx { namespace trait { \ 00191 template <typename T1, typename T2, typename T3> \ 00192 struct get_class_name< className<T1, T2, T3> > \ 00193 { \ 00194 static inline const char * get() \ 00195 { \ 00196 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00197 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00198 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00199 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00200 return result.c_str(); \ 00201 } \ 00202 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00203 }; \ 00204 } } // namespace qx::trait 00205 00206 #define QX_REGISTER_CLASS_NAME_TEMPLATE_4(className) \ 00207 namespace qx { namespace trait { \ 00208 template <typename T1, typename T2, typename T3, typename T4> \ 00209 struct get_class_name< className<T1, T2, T3, T4> > \ 00210 { \ 00211 static inline const char * get() \ 00212 { \ 00213 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00214 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00215 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00216 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00217 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00218 return result.c_str(); \ 00219 } \ 00220 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00221 }; \ 00222 } } // namespace qx::trait 00223 00224 #define QX_REGISTER_CLASS_NAME_TEMPLATE_5(className) \ 00225 namespace qx { namespace trait { \ 00226 template <typename T1, typename T2, typename T3, typename T4, typename T5> \ 00227 struct get_class_name< className<T1, T2, T3, T4, T5> > \ 00228 { \ 00229 static inline const char * get() \ 00230 { \ 00231 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00232 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00233 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00234 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00235 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00236 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00237 return result.c_str(); \ 00238 } \ 00239 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00240 }; \ 00241 } } // namespace qx::trait 00242 00243 #define QX_REGISTER_CLASS_NAME_TEMPLATE_6(className) \ 00244 namespace qx { namespace trait { \ 00245 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> \ 00246 struct get_class_name< className<T1, T2, T3, T4, T5, T6> > \ 00247 { \ 00248 static inline const char * get() \ 00249 { \ 00250 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00251 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00252 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00253 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00254 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00255 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00256 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00257 return result.c_str(); \ 00258 } \ 00259 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00260 }; \ 00261 } } // namespace qx::trait 00262 00263 #define QX_REGISTER_CLASS_NAME_TEMPLATE_7(className) \ 00264 namespace qx { namespace trait { \ 00265 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> \ 00266 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7> > \ 00267 { \ 00268 static inline const char * get() \ 00269 { \ 00270 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00271 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00272 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00273 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00274 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00275 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00276 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00277 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00278 return result.c_str(); \ 00279 } \ 00280 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00281 }; \ 00282 } } // namespace qx::trait 00283 00284 #define QX_REGISTER_CLASS_NAME_TEMPLATE_8(className) \ 00285 namespace qx { namespace trait { \ 00286 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \ 00287 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8> > \ 00288 { \ 00289 static inline const char * get() \ 00290 { \ 00291 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00292 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00293 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00294 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00295 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00296 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00297 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00298 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00299 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00300 return result.c_str(); \ 00301 } \ 00302 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00303 }; \ 00304 } } // namespace qx::trait 00305 00306 #define QX_REGISTER_CLASS_NAME_TEMPLATE_9(className) \ 00307 namespace qx { namespace trait { \ 00308 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> \ 00309 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8, T9> > \ 00310 { \ 00311 static inline const char * get() \ 00312 { \ 00313 QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \ 00314 result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00315 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00316 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00317 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00318 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00319 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00320 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00321 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_NXT; \ 00322 result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T9) + QX_REGISTER_CLASS_NAME_SEP_SUP; \ 00323 return result.c_str(); \ 00324 } \ 00325 QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \ 00326 }; \ 00327 } } // namespace qx::trait 00328 00329 #endif // _QX_GET_CLASS_NAME_H_