get_class_name.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /****************************************************************************
  2. **
  3. ** https://www.qxorm.com/
  4. ** Copyright (C) 2013 Lionel Marty (contact@qxorm.com)
  5. **
  6. ** This file is part of the QxOrm library
  7. **
  8. ** This software is provided 'as-is', without any express or implied
  9. ** warranty. In no event will the authors be held liable for any
  10. ** damages arising from the use of this software
  11. **
  12. ** Commercial Usage
  13. ** Licensees holding valid commercial QxOrm licenses may use this file in
  14. ** accordance with the commercial license agreement provided with the
  15. ** Software or, alternatively, in accordance with the terms contained in
  16. ** a written agreement between you and Lionel Marty
  17. **
  18. ** GNU General Public License Usage
  19. ** Alternatively, this file may be used under the terms of the GNU
  20. ** General Public License version 3.0 as published by the Free Software
  21. ** Foundation and appearing in the file 'license.gpl3.txt' included in the
  22. ** packaging of this file. Please review the following information to
  23. ** ensure the GNU General Public License version 3.0 requirements will be
  24. ** met : http://www.gnu.org/copyleft/gpl.html
  25. **
  26. ** If you are unsure which license is appropriate for your use, or
  27. ** if you have questions regarding the use of this file, please contact :
  28. ** contact@qxorm.com
  29. **
  30. ****************************************************************************/
  31. #ifndef _QX_GET_CLASS_NAME_H_
  32. #define _QX_GET_CLASS_NAME_H_
  33. #ifdef _MSC_VER
  34. #pragma once
  35. #endif
  36. /*!
  37. * \file get_class_name.h
  38. * \author Lionel Marty
  39. * \ingroup QxTraits
  40. * \brief qx::trait::get_class_name<T>::get() : return class name of type T under const char * format, T must be registered with QX_REGISTER_CLASS_NAME(T) macro
  41. */
  42. #ifndef _QX_NO_RTTI
  43. #include <typeinfo>
  44. #endif // _QX_NO_RTTI
  45. #include <QxTraits/remove_attr.h>
  46. #define QX_REGISTER_CLASS_NAME_SEP_INF "<"
  47. #define QX_REGISTER_CLASS_NAME_SEP_SUP ">"
  48. #define QX_REGISTER_CLASS_NAME_SEP_NXT ", "
  49. #define QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG "-"
  50. #define QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG "-"
  51. #define QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG "_"
  52. #define QX_GET_CLASS_NAME(TYPE) \
  53. qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get()
  54. #define QX_GET_CLASS_NAME_STD_STR(TYPE) \
  55. std::string(qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get())
  56. #define QX_GET_CLASS_NAME_XML_TAG(TYPE) \
  57. qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get_xml_tag()
  58. #define QX_GET_CLASS_NAME_XML_TAG_STD_STR(TYPE) \
  59. std::string(qx::trait::get_class_name< qx::trait::remove_attr< TYPE >::type >::get_xml_tag())
  60. #define QX_GET_CLASS_NAME_WITH_TYPENAME(TYPE) \
  61. qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get()
  62. #define QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(TYPE) \
  63. std::string(qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get())
  64. #define QX_GET_CLASS_NAME_XML_TAG_WITH_TYPENAME(TYPE) \
  65. qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get_xml_tag()
  66. #define QX_GET_CLASS_NAME_XML_TAG_STD_STR_WITH_TYPENAME(TYPE) \
  67. std::string(qx::trait::get_class_name< typename qx::trait::remove_attr< TYPE >::type >::get_xml_tag())
  68. #define QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG() \
  69. static inline const char * get_xml_tag() \
  70. { \
  71. static std::string result_xml; \
  72. if (! result_xml.empty()) { return result_xml.c_str(); } \
  73. QString tmp = get_class_name::get(); \
  74. tmp.replace(QX_REGISTER_CLASS_NAME_SEP_INF, QX_REGISTER_CLASS_NAME_SEP_INF_XML_TAG); \
  75. tmp.replace(QX_REGISTER_CLASS_NAME_SEP_SUP, QX_REGISTER_CLASS_NAME_SEP_SUP_XML_TAG); \
  76. tmp.replace(QX_REGISTER_CLASS_NAME_SEP_NXT, QX_REGISTER_CLASS_NAME_SEP_NXT_XML_TAG); \
  77. tmp.replace("::", "."); \
  78. tmp.replace(" ", ""); \
  79. result_xml = tmp.toLatin1().constData(); \
  80. return result_xml.c_str(); \
  81. }
  82. #ifdef _QX_NO_RTTI
  83. #define QX_REGISTER_CLASS_NAME_NO_RTTI(className) std::string(#className)
  84. #endif // _QX_NO_RTTI
  85. namespace qx {
  86. namespace trait {
  87. /*!
  88. * \ingroup QxTraits
  89. * \brief qx::trait::get_class_name<T>::get() : return class name of type T under const char * format, T must be registered with QX_REGISTER_CLASS_NAME(T) macro
  90. */
  91. template <typename T>
  92. struct get_class_name
  93. {
  94. static inline const char * get()
  95. {
  96. static std::string result;
  97. if (! result.empty()) { return result.c_str(); }
  98. #ifndef _QX_NO_RTTI
  99. T * dummy = NULL; Q_UNUSED(dummy);
  100. result = std::string(typeid(dummy).name());
  101. #else // _QX_NO_RTTI
  102. result = QX_REGISTER_CLASS_NAME_NO_RTTI(T);
  103. #endif // _QX_NO_RTTI
  104. 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());
  105. return result.c_str();
  106. }
  107. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG();
  108. };
  109. } // namespace trait
  110. } // namespace qx
  111. #define QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className) \
  112. static std::string result; \
  113. if (! result.empty()) { return result.c_str(); } \
  114. result = std::string(#className);
  115. #define QX_REGISTER_CLASS_NAME(className) \
  116. namespace qx { namespace trait { \
  117. template <> \
  118. struct get_class_name< className > \
  119. { \
  120. static inline const char * get() \
  121. { \
  122. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  123. return result.c_str(); \
  124. } \
  125. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  126. }; \
  127. } } // namespace qx::trait
  128. #define QX_REGISTER_CLASS_NAME_TEMPLATE_1(className) \
  129. namespace qx { namespace trait { \
  130. template <typename T> \
  131. struct get_class_name< className<T> > \
  132. { \
  133. static inline const char * get() \
  134. { \
  135. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  136. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  137. return result.c_str(); \
  138. } \
  139. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  140. }; \
  141. } } // namespace qx::trait
  142. #define QX_REGISTER_CLASS_NAME_TEMPLATE_2(className) \
  143. namespace qx { namespace trait { \
  144. template <typename T1, typename T2> \
  145. struct get_class_name< className<T1, T2> > \
  146. { \
  147. static inline const char * get() \
  148. { \
  149. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  150. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  151. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  152. return result.c_str(); \
  153. } \
  154. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  155. }; \
  156. } } // namespace qx::trait
  157. #define QX_REGISTER_CLASS_NAME_TEMPLATE_3(className) \
  158. namespace qx { namespace trait { \
  159. template <typename T1, typename T2, typename T3> \
  160. struct get_class_name< className<T1, T2, T3> > \
  161. { \
  162. static inline const char * get() \
  163. { \
  164. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  165. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  166. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  167. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  168. return result.c_str(); \
  169. } \
  170. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  171. }; \
  172. } } // namespace qx::trait
  173. #define QX_REGISTER_CLASS_NAME_TEMPLATE_4(className) \
  174. namespace qx { namespace trait { \
  175. template <typename T1, typename T2, typename T3, typename T4> \
  176. struct get_class_name< className<T1, T2, T3, T4> > \
  177. { \
  178. static inline const char * get() \
  179. { \
  180. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  181. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  182. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  183. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  184. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  185. return result.c_str(); \
  186. } \
  187. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  188. }; \
  189. } } // namespace qx::trait
  190. #define QX_REGISTER_CLASS_NAME_TEMPLATE_5(className) \
  191. namespace qx { namespace trait { \
  192. template <typename T1, typename T2, typename T3, typename T4, typename T5> \
  193. struct get_class_name< className<T1, T2, T3, T4, T5> > \
  194. { \
  195. static inline const char * get() \
  196. { \
  197. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  198. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  199. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  200. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  201. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  202. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  203. return result.c_str(); \
  204. } \
  205. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  206. }; \
  207. } } // namespace qx::trait
  208. #define QX_REGISTER_CLASS_NAME_TEMPLATE_6(className) \
  209. namespace qx { namespace trait { \
  210. template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> \
  211. struct get_class_name< className<T1, T2, T3, T4, T5, T6> > \
  212. { \
  213. static inline const char * get() \
  214. { \
  215. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  216. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  217. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  218. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  219. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  220. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  221. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  222. return result.c_str(); \
  223. } \
  224. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  225. }; \
  226. } } // namespace qx::trait
  227. #define QX_REGISTER_CLASS_NAME_TEMPLATE_7(className) \
  228. namespace qx { namespace trait { \
  229. template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> \
  230. struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7> > \
  231. { \
  232. static inline const char * get() \
  233. { \
  234. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  235. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  236. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  237. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  238. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  239. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  240. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  241. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  242. return result.c_str(); \
  243. } \
  244. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  245. }; \
  246. } } // namespace qx::trait
  247. #define QX_REGISTER_CLASS_NAME_TEMPLATE_8(className) \
  248. namespace qx { namespace trait { \
  249. template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
  250. struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8> > \
  251. { \
  252. static inline const char * get() \
  253. { \
  254. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  255. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  256. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  257. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  258. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  259. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  260. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  261. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  262. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  263. return result.c_str(); \
  264. } \
  265. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  266. }; \
  267. } } // namespace qx::trait
  268. #define QX_REGISTER_CLASS_NAME_TEMPLATE_9(className) \
  269. namespace qx { namespace trait { \
  270. template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> \
  271. struct get_class_name< className<T1, T2, T3, T4, T5, T6, T7, T8, T9> > \
  272. { \
  273. static inline const char * get() \
  274. { \
  275. QX_REGISTER_CLASS_NAME_TEMPLATE_INIT(className); \
  276. result += QX_REGISTER_CLASS_NAME_SEP_INF + QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T1) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  277. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T2) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  278. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T3) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  279. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T4) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  280. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T5) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  281. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T6) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  282. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T7) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  283. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T8) + QX_REGISTER_CLASS_NAME_SEP_NXT; \
  284. result += QX_GET_CLASS_NAME_STD_STR_WITH_TYPENAME(T9) + QX_REGISTER_CLASS_NAME_SEP_SUP; \
  285. return result.c_str(); \
  286. } \
  287. QX_GET_CLASS_NAME_IMPLEMENT_FCT_GET_XML_TAG(); \
  288. }; \
  289. } } // namespace qx::trait
  290. #endif // _QX_GET_CLASS_NAME_H_