QxOrm  1.4.4
C++ Object Relational Mapping library
get_class_name.h
Go to the documentation of this file.
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 <QxTraits/remove_attr.h>
00051 
00052 #define QX_REGISTER_CLASS_NAME_SEP_INF "<"
00053 #define QX_REGISTER_CLASS_NAME_SEP_SUP ">"
00054 #define QX_REGISTER_CLASS_NAME_SEP_NXT ", "
00055 
00056 #define QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG "-"
00057 #define QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG "-"
00058 #define QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG "_"
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    QString tmp = get_class_name::get(); \
00090    tmp.replace(QX_REGISTER_CLASS_NAME_SEP_INF, QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG); \
00091    tmp.replace(QX_REGISTER_CLASS_NAME_SEP_SUP, QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG); \
00092    tmp.replace(QX_REGISTER_CLASS_NAME_SEP_NXT, QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG); \
00093    tmp.replace("::", "."); \
00094    tmp.replace(" ", ""); \
00095    result_xml = tmp.toLatin1().constData(); \
00096    return result_xml.c_str(); \
00097 }
00098 
00099 #ifdef _QX_NO_RTTI
00100 #define QX_REGISTER_CLASS_NAME_NO_RTTI(className) std::string(#className)
00101 #endif // _QX_NO_RTTI
00102 
00103 namespace qx {
00104 namespace trait {
00105 
00110 template <typename T>
00111 struct get_class_name
00112 {
00113 
00114    static inline const char * get()
00115    {
00116       static std::string result;
00117       if (! result.empty()) { return result.c_str(); }
00118 
00119 #ifndef _QX_NO_RTTI
00120       T * dummy = NULL; Q_UNUSED(dummy);
00121       result = std::string(typeid(dummy).name());
00122 #else // _QX_NO_RTTI
00123       result = QX_REGISTER_CLASS_NAME_NO_RTTI(T);
00124 #endif // _QX_NO_RTTI
00125 
00126       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());
00127       qAssert(false);
00128       return result.c_str();
00129    }
00130 
00131    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG();
00132 
00133 };
00134 
00135 } // namespace trait
00136 } // namespace qx
00137 
00138 #define QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className) \
00139 static std::string result; \
00140 if (! result.empty()) { return result.c_str(); } \
00141 result = std::string(#className);
00142 
00143 #define QX_REGISTER_CLASS_NAME(className) \
00144 namespace qx { namespace trait { \
00145 template <> \
00146 struct get_class_name< className > \
00147 { \
00148    static inline const char * get() \
00149    { \
00150       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00151       return result.c_str(); \
00152    } \
00153    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00154 }; \
00155 } } // namespace qx::trait
00156 
00157 #define QX_REGISTER_CLASS_NAME_TEMPLATE_1(className) \
00158 namespace qx { namespace trait { \
00159 template <typename T> \
00160 struct get_class_name< className<T> > \
00161 { \
00162    static inline const char * get() \
00163    { \
00164       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00165       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00166       return result.c_str(); \
00167    } \
00168    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00169 }; \
00170 } } // namespace qx::trait
00171 
00172 #define QX_REGISTER_CLASS_NAME_TEMPLATE_2(className) \
00173 namespace qx { namespace trait { \
00174 template <typename T1, typename T2> \
00175 struct get_class_name< className<T1, T2> > \
00176 { \
00177    static inline const char * get() \
00178    { \
00179       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00180       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00181       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00182       return result.c_str(); \
00183    } \
00184    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00185 }; \
00186 } } // namespace qx::trait
00187 
00188 #define QX_REGISTER_CLASS_NAME_TEMPLATE_3(className) \
00189 namespace qx { namespace trait { \
00190 template <typename T1, typename T2, typename T3> \
00191 struct get_class_name< className<T1, T2, T3> > \
00192 { \
00193    static inline const char * get() \
00194    { \
00195       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00196       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00197       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00198       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00199       return result.c_str(); \
00200    } \
00201    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00202 }; \
00203 } } // namespace qx::trait
00204 
00205 #define QX_REGISTER_CLASS_NAME_TEMPLATE_4(className) \
00206 namespace qx { namespace trait { \
00207 template <typename T1, typename T2, typename T3, typename T4> \
00208 struct get_class_name< className<T1, T2, T3, T4> > \
00209 { \
00210    static inline const char * get() \
00211    { \
00212       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00213       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00214       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00215       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00216       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00217       return result.c_str(); \
00218    } \
00219    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00220 }; \
00221 } } // namespace qx::trait
00222 
00223 #define QX_REGISTER_CLASS_NAME_TEMPLATE_5(className) \
00224 namespace qx { namespace trait { \
00225 template <typename T1, typename T2, typename T3, typename T4, typename T5> \
00226 struct get_class_name< className<T1, T2, T3, T4, T5> > \
00227 { \
00228    static inline const char * get() \
00229    { \
00230       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00231       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00232       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00233       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00234       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00235       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00236       return result.c_str(); \
00237    } \
00238    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00239 }; \
00240 } } // namespace qx::trait
00241 
00242 #define QX_REGISTER_CLASS_NAME_TEMPLATE_6(className) \
00243 namespace qx { namespace trait { \
00244 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> \
00245 struct get_class_name< className<T1, T2, T3, T4, T5, T6> > \
00246 { \
00247    static inline const char * get() \
00248    { \
00249       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00250       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00251       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00252       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00253       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00254       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00255       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00256       return result.c_str(); \
00257    } \
00258    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00259 }; \
00260 } } // namespace qx::trait
00261 
00262 #define QX_REGISTER_CLASS_NAME_TEMPLATE_7(className) \
00263 namespace qx { namespace trait { \
00264 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> \
00265 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7> > \
00266 { \
00267    static inline const char * get() \
00268    { \
00269       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00270       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00271       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00272       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00273       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00274       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00275       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00276       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00277       return result.c_str(); \
00278    } \
00279    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00280 }; \
00281 } } // namespace qx::trait
00282 
00283 #define QX_REGISTER_CLASS_NAME_TEMPLATE_8(className) \
00284 namespace qx { namespace trait { \
00285 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
00286 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8> > \
00287 { \
00288    static inline const char * get() \
00289    { \
00290       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00291       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00292       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00293       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00294       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00295       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00296       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00297       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00298       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00299       return result.c_str(); \
00300    } \
00301    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00302 }; \
00303 } } // namespace qx::trait
00304 
00305 #define QX_REGISTER_CLASS_NAME_TEMPLATE_9(className) \
00306 namespace qx { namespace trait { \
00307 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> \
00308 struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8, T9> > \
00309 { \
00310    static inline const char * get() \
00311    { \
00312       QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
00313       result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00314       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00315       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00316       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00317       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00318       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00319       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00320       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
00321       result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T9) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
00322       return result.c_str(); \
00323    } \
00324    QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
00325 }; \
00326 } } // namespace qx::trait
00327 
00328 #endif // _QX_GET_CLASS_NAME_H_