QxOrm  1.2.6
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 #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_