plooc_class.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*****************************************************************************
  2. * Copyright(C)2009-2019 by GorgonMeducer<embedded_zhuoran@hotmail.com> *
  3. * and SimonQian<simonqian@simonqian.com> * with
  4. *support from HenryLong<henry_long@163.com> *
  5. * *
  6. * Licensed under the Apache License, Version 2.0 (the "License"); * you may
  7. *not use this file except in compliance with the License. * You may
  8. *obtain a copy of the License at *
  9. * *
  10. * http://www.apache.org/licenses/LICENSE-2.0 *
  11. * *
  12. * Unless required by applicable law or agreed to in writing, software *
  13. * distributed under the License is distributed on an "AS IS" BASIS, *
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. ** See the License for the specific language governing permissions and *
  16. * limitations under the License. *
  17. * *
  18. ****************************************************************************/
  19. #if defined(__cplusplus) || defined(__OOC_CPP__)
  20. #undef __PLOOC_CLASS_USE_STRICT_TEMPLATE__
  21. #undef PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___
  22. #define PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. #endif
  27. #if defined(__OOC_RELEASE__) || defined(__OOC_CPP__)
  28. #undef __OOC_DEBUG__
  29. #define __OOC_DEBUG__ 1
  30. #endif
  31. #if !defined(__PLOOC_CLASS_USE_STRICT_TEMPLATE__) && \
  32. !defined(__PLOOC_CLASS_USE_SIMPLE_TEMPLATE__) && \
  33. !defined(__PLOOC_CLASS_USE_BLACK_BOX_TEMPLATE__)
  34. #define __PLOOC_CLASS_USE_SIMPLE_TEMPLATE__ 1
  35. #endif
  36. #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && \
  37. !defined(__cplusplus)
  38. #ifndef __OOC_DEBUG__
  39. #define __OOC_DEBUG__
  40. #warning For C89/90, __OOC_DEBUG__ is enforced.
  41. #endif
  42. #if defined(__PLOOC_CLASS_USE_STRICT_TEMPLATE__)
  43. #undef __PLOOC_CLASS_USE_STRICT_TEMPLATE__
  44. #define __PLOOC_CLASS_USE_SIMPLE_TEMPLATE__
  45. #endif
  46. #if defined(__PLOOC_CLASS_USE_BLACK_BOX_TEMPLATE__)
  47. #undef __PLOOC_CLASS_USE_BLACK_BOX_TEMPLATE__
  48. #define __PLOOC_CLASS_USE_SIMPLE_TEMPLATE__
  49. #endif
  50. #if !defined(__OOC_DEBUG__) || !defined(__PLOOC_CLASS_USE_SIMPLE_TEMPLATE__)
  51. #error You must use __OOC_DEBUG__ (or __OOC_RELEASE__) together with the\
  52. __PLOOC_CLASS_USE_SIMPLE_TEMPLATE__ in ANSI-C89/90.
  53. #endif
  54. #endif
  55. #ifdef __cplusplus
  56. }
  57. #endif
  58. #ifndef __PLOOC_CLASS_H__
  59. #define __PLOOC_CLASS_H__
  60. /******************************************************************************
  61. * HOW TO USE *
  62. ******************************************************************************/
  63. //! TODO: Add How to use
  64. /*============================ INCLUDES ======================================*/
  65. //#include <stdint.h>
  66. /*! \NOTE the uint_fast8_t used in this header file is defined in stdint.h
  67. if you don't have stdint.h supported in your toolchain, you should
  68. define uint_fast8_t all by yourself with following rule:
  69. a. if the target processor is 8 bits, define it as uint8_t
  70. b. if the target processor is 16 bits, define it as uint16_t
  71. c. if the target processor is 32 bits, define it as uint32_t
  72. d. if the target processor is 64 bits, define it as either uint32_t or
  73. uint64_t
  74. */
  75. #include <stdlib.h>
  76. #include "./plooc.h"
  77. #ifdef __cplusplus
  78. extern "C" {
  79. #endif
  80. /*============================ MACROS ========================================*/
  81. /*!\ node if you want your code more "elegent", say you want to use "this" with
  82. * "." rather than a pointer with "->", you can add following macros to
  83. * your code, assuming the variable name of the object pointer is
  84. "ptThis".
  85. * If your object pointer has a different name, please feel free to
  86. change
  87. * the macro by yourself
  88. #undef this
  89. #define this (*ptThis)
  90. */
  91. /*============================ MACROFIED FUNCTIONS ===========================*/
  92. //! @{
  93. #ifndef __PLOOC_CONNECT2
  94. #define __PLOOC_CONNECT2(__A, __B) __A##__B
  95. #endif
  96. #ifndef __PLOOC_CONNECT3
  97. #define __PLOOC_CONNECT3(__A, __B, __C) __A##__B##__C
  98. #endif
  99. #ifndef __PLOOC_CONNECT4
  100. #define __PLOOC_CONNECT4(__A, __B, __C, __D) __A##__B##__C##__D
  101. #endif
  102. //! @}
  103. #ifndef __PLOOC_ALIGN
  104. #define __PLOOC_ALIGN(__N) __attribute__((aligned(__N)))
  105. #endif
  106. #ifndef PLOOC_ALIGN
  107. #define PLOOC_ALIGN(__N) __PLOOC_ALIGN(__N)
  108. #endif
  109. /*
  110. #ifndef PLOOC_DEFAULT_OBJ_ALIGN
  111. # define PLOOC_DEFAULT_OBJ_ALIGN sizeof(uint_fast8_t)
  112. #endif
  113. */
  114. #ifndef PLOOC_PACKED
  115. #define PLOOC_PACKED __attribute__((packed))
  116. #endif
  117. //! @{
  118. #ifndef PLOOC_CONNECT2
  119. #define PLOOC_CONNECT2(__A, __B) __PLOOC_CONNECT2(__A, __B)
  120. #endif
  121. #ifndef PLOOC_CONNECT3
  122. #define PLOOC_CONNECT3(__A, __B, __C) __PLOOC_CONNECT3(__A, __B, __C)
  123. #endif
  124. #ifndef PLOOC_CONNECT4
  125. #define PLOOC_CONNECT4(__A, __B, __C, __D) __PLOOC_CONNECT4(__A, __B, __C, __D)
  126. #endif
  127. //! @}
  128. #ifndef PLOOC_UNUSED_PARAM
  129. #define PLOOC_UNUSED_PARAM(__N) \
  130. do { \
  131. (__N) = (__N); \
  132. } while (0)
  133. #endif
  134. #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && \
  135. !defined(__cplusplus)
  136. #ifndef PLOOC_ALIGNOF
  137. #define PLOOC_ALIGNOF(__TYPE) __alignof__(__TYPE)
  138. #endif
  139. #define PLOOC_ALIGNOF_STRUCT(__TYPE) PLOOC_ALIGNOF(struct {__TYPE})
  140. #define PLOOC_SIZEOF_STRUCT(__TYPE) sizeof(struct {__TYPE})
  141. #else
  142. #ifndef PLOOC_ALIGNOF
  143. #define PLOOC_ALIGNOF(...) __alignof__(__VA_ARGS__)
  144. #endif
  145. #define PLOOC_ALIGNOF_STRUCT(...) PLOOC_ALIGNOF(struct {__VA_ARGS__})
  146. #define PLOOC_SIZEOF_STRUCT(...) sizeof(struct {__VA_ARGS__})
  147. /*! \note When both __OOC_DEBUG__ and
  148. *! PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___ are
  149. *! defined, memory layout boundary, i.e. struct wrapper inside PLOOC
  150. *! VISIBLE will be removed. This enables some platform to use the gaps
  151. *! between members with different memory aligments to add members with
  152. *! correct size and aligment for saving space.
  153. *!
  154. *! You can do this when you have all the source code and compile all
  155. *! the source code with the same presence of "__OOC_DEBUG__".
  156. *! If some of the code is compiled with different presence of
  157. *! "__OOC_DEBUG__", i.e. using Lib + source, removing the memory
  158. *! layout boundaries will cause different view of the structure and hence
  159. *! cause undefined behaviours.
  160. */
  161. #if defined(PLOOC_CFG_REMOVE_MEMORY_LAYOUT_BOUNDARY___USE_WITH_CAUTION___)
  162. #define PLOOC_VISIBLE(...) __VA_ARGS__
  163. #else
  164. #define PLOOC_VISIBLE(...) \
  165. struct { \
  166. __VA_ARGS__ \
  167. } PLOOC_ALIGN(PLOOC_ALIGNOF_STRUCT(__VA_ARGS__));
  168. #endif
  169. #if !defined(__PLOOC_CLASS_USE_NO_STRUCT_MASK__)
  170. #define PLOOC_INVISIBLE(...) \
  171. uint8_t PLOOC_CONNECT3(chMask_, __LINE__, \
  172. __COUNTER__)[PLOOC_SIZEOF_STRUCT( \
  173. __VA_ARGS__)] PLOOC_ALIGN(PLOOC_ALIGNOF_STRUCT(__VA_ARGS__));
  174. #else
  175. #define PLOOC_INVISIBLE(...) \
  176. struct { \
  177. __VA_ARGS__ \
  178. } PLOOC_CONNECT3(zzz_, __LINE__, __COUNTER__) \
  179. PLOOC_ALIGN(PLOOC_ALIGNOF_STRUCT(__VA_ARGS__));
  180. #endif /* __PLOOC_CLASS_USE_NO_STRUCT_MASK__ */
  181. #define __PLOOC_PRO_struct struct
  182. #define __PLOOC_PRI_struct struct
  183. #define __PLOOC_EXT_struct struct
  184. #define __PLOOC_PRO_union union
  185. #define __PLOOC_PRI_union union
  186. #define __PLOOC_EXT_union union
  187. #define __PLOOC_EXT_uint8_t uint8_t
  188. #define __PLOOC_PRI_uint8_t uint8_t
  189. #define __PLOOC_PRO_uint8_t uint8_t
  190. #define __PLOOC_EXT_
  191. #define __PLOOC_PRI_
  192. #define __PLOOC_PRO_
  193. #ifdef __OOC_DEBUG__
  194. //! \brief wrapper for shell type
  195. #define __PLOOC_EXT__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  196. #define __PLOOC_EXT__private_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  197. #define __PLOOC_EXT__protected_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  198. #define __PLOOC_EXT__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  199. //! \brief wrapper for internal private type
  200. #define __PLOOC_PRI__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  201. #define __PLOOC_PRI__private_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  202. #define __PLOOC_PRI__protected_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  203. #define __PLOOC_PRI__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  204. //! \brief wrapper for internal protected type
  205. #define __PLOOC_PRO__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  206. #define __PLOOC_PRO__private_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  207. #define __PLOOC_PRO__protected_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  208. #define __PLOOC_PRO__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  209. #else
  210. //! \brief wrapper for shell type
  211. #define __PLOOC_EXT__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  212. #define __PLOOC_EXT__private_member(...) PLOOC_INVISIBLE(__VA_ARGS__)
  213. #define __PLOOC_EXT__protected_member(...) PLOOC_INVISIBLE(__VA_ARGS__)
  214. #define __PLOOC_EXT__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  215. //! \brief wrapper for internal private type
  216. #define __PLOOC_PRI__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  217. #define __PLOOC_PRI__private_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  218. #define __PLOOC_PRI__protected_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  219. #define __PLOOC_PRI__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  220. //! \brief wrapper for internal protected type
  221. #define __PLOOC_PRO__public_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  222. #define __PLOOC_PRO__private_member(...) PLOOC_INVISIBLE(__VA_ARGS__)
  223. #define __PLOOC_PRO__protected_member(...) PLOOC_VISIBLE(__VA_ARGS__)
  224. #define __PLOOC_PRO__which(...) PLOOC_VISIBLE(__VA_ARGS__)
  225. #endif
  226. #endif
  227. #if defined(__cplusplus)
  228. }
  229. #endif
  230. #endif
  231. #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && \
  232. !defined(__cplusplus)
  233. #undef which
  234. #define which(__declare) , _which(__declare)
  235. #else
  236. #undef which
  237. #define which(...) , _which(__VA_ARGS__)
  238. #endif
  239. #undef private_member
  240. #define private_member , _private_member
  241. #undef protected_member
  242. #define protected_member , _protected_member
  243. #undef public_member
  244. #define public_member , _public_member
  245. /*! \brief helper macros for heap managed objects. They use malloc() and free()
  246. *! internally.
  247. *!
  248. *! \note Make sure your constractor is named as <class_name>_init and it takes
  249. *! an configuration structure with a type named as <class_name>_cfg_t.
  250. *!
  251. *! \note Make sure your destructor is named as <class_name>_depose.
  252. */
  253. #define __new_class(__name, ...) \
  254. ({ \
  255. __name##_cfg_t tCFG = {__VA_ARGS__}; \
  256. __name##_init((__name##_t*)malloc(sizeof(__name##_t)), &tCFG); \
  257. })
  258. #define __free_class(__name, __obj) \
  259. do { \
  260. __name##_depose((__name##_t*)(__obj)); \
  261. free(__obj); \
  262. } while (0)
  263. /*============================ TYPES =========================================*/
  264. /*============================ GLOBAL VARIABLES ==============================*/
  265. /*============================ PROTOTYPES ====================================*/
  266. /*============================ INCLUDES ======================================*/
  267. #if defined(__PLOOC_CLASS_USE_STRICT_TEMPLATE__)
  268. #include "./plooc_class_strict.h"
  269. #elif defined(__PLOOC_CLASS_USE_SIMPLE_TEMPLATE__)
  270. #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && \
  271. !defined(__cplusplus)
  272. #include "./plooc_class_simple_c90.h"
  273. #else
  274. #include "./plooc_class_simple.h"
  275. #endif
  276. #elif defined(__PLOOC_CLASS_USE_BLACK_BOX_TEMPLATE__)
  277. #ifndef __PLOOC_I_KNOW_BLACK_BOX_IS_INCOMPATIBLE_WITH_OTHER_TEMPLATES__
  278. #warning The black box template is incompatible with other templates. When\
  279. header files which contains different templates mixing together, the one contains\
  280. black box template will cause conflicts in other header files. To avoid such\
  281. conflicts, you can either use black box alone in a project or in the source code of\
  282. the target module avoid including header files which directly or indirectly \
  283. including the header file of the very same module. To suppress this warning, please\
  284. find the macro __PLOOC_I_KNOW_BLACK_BOX_IS_INCOMPATIBLE_WITH_OTHER_TEMPLATES__ in your\
  285. project to acknowledge that you understand the facts and consequences.
  286. #endif
  287. #include "./plooc_class_black_box.h"
  288. #else
  289. #include "./plooc_class_simple.h"
  290. #endif
  291. #ifdef __cplusplus
  292. extern "C" {
  293. #endif
  294. #undef __PLOOC_CLASS_USE_STRICT_TEMPLATE__
  295. #undef __PLOOC_CLASS_USE_SIMPLE_TEMPLATE__
  296. #undef __PLOOC_CLASS_USE_BLACK_BOX_TEMPLATE__
  297. #undef __PLOOC_CLASS_IMPLEMENT
  298. #undef __PLOOC_CLASS_IMPLEMENT__
  299. #undef __PLOOC_CLASS_INHERIT__
  300. #undef __PLOOC_CLASS_INHERIT
  301. #if defined(__cplusplus)
  302. #undef class
  303. #undef this
  304. #undef private
  305. #undef public
  306. #endif
  307. #if defined(__cplusplus)
  308. }
  309. #endif