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