property.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. #pragma once
  2. #include <util/system/compiler.h>
  3. ////////////////////////////////////////////////////////////////////////////////
  4. //! Declares a trivial public read-write property that is passed by reference.
  5. #define DECLARE_BYREF_RW_PROPERTY(type, name) \
  6. public: \
  7. type& name() noexcept; \
  8. const type& name() const noexcept
  9. //! Defines a trivial public read-write property that is passed by reference.
  10. //! All arguments after name are used as default value (via braced-init-list).
  11. #define DEFINE_BYREF_RW_PROPERTY(type, name, ...) \
  12. protected: \
  13. type name##_ { __VA_ARGS__ }; \
  14. \
  15. public: \
  16. Y_FORCE_INLINE type& name() noexcept \
  17. { \
  18. return name##_; \
  19. } \
  20. \
  21. Y_FORCE_INLINE const type& name() const noexcept \
  22. { \
  23. return name##_; \
  24. } \
  25. static_assert(true)
  26. //! Defines a trivial public read-write property that is passed by reference
  27. //! and is not inline-initialized.
  28. #define DEFINE_BYREF_RW_PROPERTY_NO_INIT(type, name) \
  29. protected: \
  30. type name##_; \
  31. \
  32. public: \
  33. Y_FORCE_INLINE type& name() noexcept \
  34. { \
  35. return name##_; \
  36. } \
  37. \
  38. Y_FORCE_INLINE const type& name() const noexcept \
  39. { \
  40. return name##_; \
  41. } \
  42. static_assert(true)
  43. //! Defines a trivial public read-write property override that is passed by reference
  44. //! and is not inline-initialized.
  45. #define DEFINE_BYREF_RW_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  46. protected: \
  47. type name##_; \
  48. \
  49. public: \
  50. Y_FORCE_INLINE type& name() noexcept override \
  51. { \
  52. return name##_; \
  53. } \
  54. \
  55. Y_FORCE_INLINE const type& name() const noexcept override \
  56. { \
  57. return name##_; \
  58. } \
  59. static_assert(true)
  60. //! Forwards a trivial public read-write property that is passed by reference.
  61. #define DELEGATE_BYREF_RW_PROPERTY(declaringType, type, name, delegateTo) \
  62. type& declaringType::name() noexcept \
  63. { \
  64. return (delegateTo).name(); \
  65. } \
  66. \
  67. const type& declaringType::name() const noexcept \
  68. { \
  69. return (delegateTo).name(); \
  70. } \
  71. static_assert(true)
  72. ////////////////////////////////////////////////////////////////////////////////
  73. //! Declares a trivial public read-only property that is passed by reference.
  74. #define DECLARE_BYREF_RO_PROPERTY(type, name) \
  75. public: \
  76. const type& name() const noexcept
  77. //! Defines a trivial public read-only property that is passed by reference.
  78. //! All arguments after name are used as default value (via braced-init-list).
  79. #define DEFINE_BYREF_RO_PROPERTY(type, name, ...) \
  80. protected: \
  81. type name##_ { __VA_ARGS__ }; \
  82. \
  83. public: \
  84. Y_FORCE_INLINE const type& name() const noexcept \
  85. { \
  86. return name##_; \
  87. } \
  88. static_assert(true)
  89. //! Defines a trivial public read-only property that is passed by reference
  90. //! and is not inline-initialized.
  91. #define DEFINE_BYREF_RO_PROPERTY_NO_INIT(type, name) \
  92. protected: \
  93. type name##_; \
  94. \
  95. public: \
  96. Y_FORCE_INLINE const type& name() const noexcept \
  97. { \
  98. return name##_; \
  99. } \
  100. static_assert(true)
  101. //! Defines a trivial public read-only property override that is passed by reference
  102. //! and is not inline-initialized.
  103. #define DEFINE_BYREF_RO_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  104. protected: \
  105. type name##_; \
  106. \
  107. public: \
  108. Y_FORCE_INLINE const type& name() const noexcept override \
  109. { \
  110. return name##_; \
  111. } \
  112. static_assert(true)
  113. //! Forwards a trivial public read-only property that is passed by reference.
  114. #define DELEGATE_BYREF_RO_PROPERTY(declaringType, type, name, delegateTo) \
  115. const type& declaringType::name() const noexcept \
  116. { \
  117. return (delegateTo).name(); \
  118. } \
  119. static_assert(true)
  120. ////////////////////////////////////////////////////////////////////////////////
  121. //! Declares a trivial public read-write property that is passed by value.
  122. #define DECLARE_BYVAL_RW_PROPERTY(type, name) \
  123. public: \
  124. type Get##name() const; \
  125. void Set##name(type value)
  126. //! Defines a trivial public read-write property that is passed by value.
  127. //! All arguments after name are used as default value (via braced-init-list).
  128. #define DEFINE_BYVAL_RW_PROPERTY(type, name, ...) \
  129. protected: \
  130. type name##_ { __VA_ARGS__ }; \
  131. \
  132. public: \
  133. Y_FORCE_INLINE type Get##name() const \
  134. { \
  135. return name##_; \
  136. } \
  137. \
  138. Y_FORCE_INLINE void Set##name(type value) \
  139. { \
  140. name##_ = value; \
  141. } \
  142. static_assert(true)
  143. //! Defines a trivial public read-write boolean property that is passed by value.
  144. //! All arguments after name are used as default value (via braced-init-list).
  145. #define DEFINE_BYVAL_RW_BOOLEAN_PROPERTY(name, ...) \
  146. protected: \
  147. bool name##_ { __VA_ARGS__ }; \
  148. \
  149. public: \
  150. Y_FORCE_INLINE bool Is##name() const \
  151. { \
  152. return name##_; \
  153. } \
  154. \
  155. Y_FORCE_INLINE void Set##name(bool value) \
  156. { \
  157. name##_ = value; \
  158. } \
  159. static_assert(true)
  160. //! Defines a trivial public read-write property that is passed by value.
  161. //! All arguments after name are used as default value (via braced-init-list).
  162. #define DEFINE_BYVAL_RW_PROPERTY_WITH_FLUENT_SETTER(declaringType, type, name, ...) \
  163. protected: \
  164. type name##_ { __VA_ARGS__ }; \
  165. \
  166. public: \
  167. Y_FORCE_INLINE type Get##name() const \
  168. { \
  169. return name##_; \
  170. } \
  171. \
  172. Y_FORCE_INLINE void Set##name(type value) &\
  173. { \
  174. name##_ = value; \
  175. } \
  176. \
  177. Y_FORCE_INLINE declaringType&& Set##name(type value) &&\
  178. { \
  179. name##_ = value; \
  180. return std::move(*this); \
  181. } \
  182. static_assert(true)
  183. //! Defines a trivial public read-write property that is passed by value
  184. //! and is not inline-initialized.
  185. #define DEFINE_BYVAL_RW_PROPERTY_NO_INIT(type, name) \
  186. protected: \
  187. type name##_; \
  188. \
  189. public: \
  190. Y_FORCE_INLINE type Get##name() const \
  191. { \
  192. return name##_; \
  193. } \
  194. \
  195. Y_FORCE_INLINE void Set##name(type value) \
  196. { \
  197. name##_ = value; \
  198. } \
  199. static_assert(true)
  200. //! Defines a trivial public read-write property override that is passed by value
  201. //! and is not inline-initialized.
  202. #define DEFINE_BYVAL_RW_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  203. protected: \
  204. type name##_; \
  205. \
  206. public: \
  207. Y_FORCE_INLINE type Get##name() const override \
  208. { \
  209. return name##_; \
  210. } \
  211. \
  212. Y_FORCE_INLINE void Set##name(type value) override \
  213. { \
  214. name##_ = value; \
  215. } \
  216. static_assert(true)
  217. //! Forwards a trivial public read-write property that is passed by value.
  218. #define DELEGATE_BYVAL_RW_PROPERTY(declaringType, type, name, delegateTo) \
  219. type declaringType::Get##name() const \
  220. { \
  221. return (delegateTo).Get##name(); \
  222. } \
  223. \
  224. void declaringType::Set##name(type value) \
  225. { \
  226. (delegateTo).Set##name(value); \
  227. } \
  228. static_assert(true)
  229. ////////////////////////////////////////////////////////////////////////////////
  230. //! Declares a trivial public read-only property that is passed by value.
  231. #define DECLARE_BYVAL_RO_PROPERTY(type, name) \
  232. public: \
  233. type Get##name() const
  234. //! Defines a trivial public read-only property that is passed by value.
  235. //! All arguments after name are used as default value (via braced-init-list).
  236. #define DEFINE_BYVAL_RO_PROPERTY(type, name, ...) \
  237. protected: \
  238. type name##_ { __VA_ARGS__ }; \
  239. \
  240. public: \
  241. Y_FORCE_INLINE type Get##name() const \
  242. { \
  243. return name##_; \
  244. } \
  245. static_assert(true)
  246. //! Defines a trivial public read-only property that is passed by value
  247. //! and is not inline-initialized.
  248. #define DEFINE_BYVAL_RO_PROPERTY_NO_INIT(type, name) \
  249. protected: \
  250. type name##_; \
  251. \
  252. public: \
  253. Y_FORCE_INLINE type Get##name() const \
  254. { \
  255. return name##_; \
  256. } \
  257. static_assert(true)
  258. //! Defines a trivial public read-only property override that is passed by value
  259. //! and is not inline-initialized.
  260. #define DEFINE_BYVAL_RO_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  261. protected: \
  262. type name##_; \
  263. \
  264. public: \
  265. Y_FORCE_INLINE type Get##name() const override \
  266. { \
  267. return name##_; \
  268. } \
  269. static_assert(true)
  270. //! Forwards a trivial public read-only property that is passed by value.
  271. #define DELEGATE_BYVAL_RO_PROPERTY(declaringType, type, name, delegateTo) \
  272. type declaringType::Get##name() \
  273. { \
  274. return (delegateTo).Get##name(); \
  275. } \
  276. static_assert(true)
  277. ////////////////////////////////////////////////////////////////////////////////
  278. //! Below are macro helpers for extra properties.
  279. //! Extra properties should be used for lazy memory allocation for properties that
  280. //! hold default values for the majority of objects.
  281. //! Initializes extra property holder if it is not initialized.
  282. #define INITIALIZE_EXTRA_PROPERTY_HOLDER(holder) \
  283. if (!holder##_) { \
  284. holder##_.reset(new decltype(holder##_)::element_type()); \
  285. } \
  286. static_assert(true)
  287. //! Declares an extra property holder. Holder contains extra properties values.
  288. //! Holder is not created until some property is set with a non-default value.
  289. //! If there is no holder property getter returns default value.
  290. #define DECLARE_EXTRA_PROPERTY_HOLDER(type, holder) \
  291. public: \
  292. Y_FORCE_INLINE bool HasCustom##holder() const \
  293. { \
  294. return static_cast<bool>(holder##_); \
  295. } \
  296. Y_FORCE_INLINE const type* GetCustom##holder() const \
  297. { \
  298. return holder##_.get(); \
  299. } \
  300. Y_FORCE_INLINE type* GetCustom##holder() \
  301. { \
  302. return holder##_.get(); \
  303. } \
  304. Y_FORCE_INLINE void InitializeCustom##holder() \
  305. { \
  306. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  307. } \
  308. private: \
  309. std::unique_ptr<type> holder##_; \
  310. static const type Default##holder##_
  311. //! Defines a storage for extra properties default values.
  312. #define DEFINE_EXTRA_PROPERTY_HOLDER(class, type, holder) \
  313. const type class::Default##holder##_
  314. //! Defines a public read-write extra property that is passed by value.
  315. #define DEFINE_BYVAL_RW_EXTRA_PROPERTY(holder, name) \
  316. public: \
  317. Y_FORCE_INLINE decltype(holder##_->name) Get##name() const \
  318. { \
  319. if (!holder##_) { \
  320. return Default##holder##_.name; \
  321. } \
  322. return holder##_->name; \
  323. } \
  324. Y_FORCE_INLINE void Set##name(decltype(holder##_->name) val) \
  325. { \
  326. if (!holder##_) { \
  327. if (val == Default##holder##_.name) { \
  328. return; \
  329. } \
  330. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  331. } \
  332. holder##_->name = val; \
  333. } \
  334. static_assert(true)
  335. //! Defines a public read-write extra property that is passed by reference.
  336. #define DEFINE_BYREF_RW_EXTRA_PROPERTY(holder, name) \
  337. public: \
  338. Y_FORCE_INLINE const decltype(holder##_->name)& name() const \
  339. { \
  340. if (!holder##_) { \
  341. return Default##holder##_.name; \
  342. } \
  343. return holder##_->name; \
  344. } \
  345. Y_FORCE_INLINE decltype(holder##_->name)& Mutable##name() \
  346. { \
  347. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  348. return holder##_->name; \
  349. } \
  350. static_assert(true)
  351. ////////////////////////////////////////////////////////////////////////////////