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