QxOrm  1.4.2
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 <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_