property.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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 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_PROPERTY_WITH_FLUENT_SETTER(declaringType, type, name, ...) \
  146. protected: \
  147. type name##_ { __VA_ARGS__ }; \
  148. \
  149. public: \
  150. Y_FORCE_INLINE type Get##name() const \
  151. { \
  152. return name##_; \
  153. } \
  154. \
  155. Y_FORCE_INLINE void Set##name(type value) &\
  156. { \
  157. name##_ = value; \
  158. } \
  159. \
  160. Y_FORCE_INLINE declaringType&& Set##name(type value) &&\
  161. { \
  162. name##_ = value; \
  163. return std::move(*this); \
  164. } \
  165. static_assert(true)
  166. //! Defines a trivial public read-write property that is passed by value
  167. //! and is not inline-initialized.
  168. #define DEFINE_BYVAL_RW_PROPERTY_NO_INIT(type, name) \
  169. protected: \
  170. type name##_; \
  171. \
  172. public: \
  173. Y_FORCE_INLINE type Get##name() const \
  174. { \
  175. return name##_; \
  176. } \
  177. \
  178. Y_FORCE_INLINE void Set##name(type value) \
  179. { \
  180. name##_ = value; \
  181. } \
  182. static_assert(true)
  183. //! Defines a trivial public read-write property override that is passed by value
  184. //! and is not inline-initialized.
  185. #define DEFINE_BYVAL_RW_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  186. protected: \
  187. type name##_; \
  188. \
  189. public: \
  190. Y_FORCE_INLINE type Get##name() const override \
  191. { \
  192. return name##_; \
  193. } \
  194. \
  195. Y_FORCE_INLINE void Set##name(type value) override \
  196. { \
  197. name##_ = value; \
  198. } \
  199. static_assert(true)
  200. //! Forwards a trivial public read-write property that is passed by value.
  201. #define DELEGATE_BYVAL_RW_PROPERTY(declaringType, type, name, delegateTo) \
  202. type declaringType::Get##name() const \
  203. { \
  204. return (delegateTo).Get##name(); \
  205. } \
  206. \
  207. void declaringType::Set##name(type value) \
  208. { \
  209. (delegateTo).Set##name(value); \
  210. } \
  211. static_assert(true)
  212. ////////////////////////////////////////////////////////////////////////////////
  213. //! Declares a trivial public read-only property that is passed by value.
  214. #define DECLARE_BYVAL_RO_PROPERTY(type, name) \
  215. public: \
  216. type Get##name() const
  217. //! Defines a trivial public read-only property that is passed by value.
  218. //! All arguments after name are used as default value (via braced-init-list).
  219. #define DEFINE_BYVAL_RO_PROPERTY(type, name, ...) \
  220. protected: \
  221. type name##_ { __VA_ARGS__ }; \
  222. \
  223. public: \
  224. Y_FORCE_INLINE type Get##name() const \
  225. { \
  226. return name##_; \
  227. } \
  228. static_assert(true)
  229. //! Defines a trivial public read-only property that is passed by value
  230. //! and is not inline-initialized.
  231. #define DEFINE_BYVAL_RO_PROPERTY_NO_INIT(type, name) \
  232. protected: \
  233. type name##_; \
  234. \
  235. public: \
  236. Y_FORCE_INLINE type Get##name() const \
  237. { \
  238. return name##_; \
  239. } \
  240. static_assert(true)
  241. //! Defines a trivial public read-only property override that is passed by value
  242. //! and is not inline-initialized.
  243. #define DEFINE_BYVAL_RO_PROPERTY_NO_INIT_OVERRIDE(type, name) \
  244. protected: \
  245. type name##_; \
  246. \
  247. public: \
  248. Y_FORCE_INLINE type Get##name() const override \
  249. { \
  250. return name##_; \
  251. } \
  252. static_assert(true)
  253. //! Forwards a trivial public read-only property that is passed by value.
  254. #define DELEGATE_BYVAL_RO_PROPERTY(declaringType, type, name, delegateTo) \
  255. type declaringType::Get##name() \
  256. { \
  257. return (delegateTo).Get##name(); \
  258. } \
  259. static_assert(true)
  260. ////////////////////////////////////////////////////////////////////////////////
  261. //! Below are macro helpers for extra properties.
  262. //! Extra properties should be used for lazy memory allocation for properties that
  263. //! hold default values for the majority of objects.
  264. //! Initializes extra property holder if it is not initialized.
  265. #define INITIALIZE_EXTRA_PROPERTY_HOLDER(holder) \
  266. if (!holder##_) { \
  267. holder##_.reset(new decltype(holder##_)::element_type()); \
  268. } \
  269. static_assert(true)
  270. //! Declares an extra property holder. Holder contains extra properties values.
  271. //! Holder is not created until some property is set with a non-default value.
  272. //! If there is no holder property getter returns default value.
  273. #define DECLARE_EXTRA_PROPERTY_HOLDER(type, holder) \
  274. public: \
  275. Y_FORCE_INLINE bool HasCustom##holder() const \
  276. { \
  277. return static_cast<bool>(holder##_); \
  278. } \
  279. Y_FORCE_INLINE const type* GetCustom##holder() const \
  280. { \
  281. return holder##_.get(); \
  282. } \
  283. Y_FORCE_INLINE type* GetCustom##holder() \
  284. { \
  285. return holder##_.get(); \
  286. } \
  287. Y_FORCE_INLINE void InitializeCustom##holder() \
  288. { \
  289. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  290. } \
  291. private: \
  292. std::unique_ptr<type> holder##_; \
  293. static const type Default##holder##_
  294. //! Defines a storage for extra properties default values.
  295. #define DEFINE_EXTRA_PROPERTY_HOLDER(class, type, holder) \
  296. const type class::Default##holder##_
  297. //! Defines a public read-write extra property that is passed by value.
  298. #define DEFINE_BYVAL_RW_EXTRA_PROPERTY(holder, name) \
  299. public: \
  300. Y_FORCE_INLINE decltype(holder##_->name) Get##name() const \
  301. { \
  302. if (!holder##_) { \
  303. return Default##holder##_.name; \
  304. } \
  305. return holder##_->name; \
  306. } \
  307. Y_FORCE_INLINE void Set##name(decltype(holder##_->name) val) \
  308. { \
  309. if (!holder##_) { \
  310. if (val == Default##holder##_.name) { \
  311. return; \
  312. } \
  313. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  314. } \
  315. holder##_->name = val; \
  316. } \
  317. static_assert(true)
  318. //! Defines a public read-write extra property that is passed by reference.
  319. #define DEFINE_BYREF_RW_EXTRA_PROPERTY(holder, name) \
  320. public: \
  321. Y_FORCE_INLINE const decltype(holder##_->name)& name() const \
  322. { \
  323. if (!holder##_) { \
  324. return Default##holder##_.name; \
  325. } \
  326. return holder##_->name; \
  327. } \
  328. Y_FORCE_INLINE decltype(holder##_->name)& Mutable##name() \
  329. { \
  330. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  331. return holder##_->name; \
  332. } \
  333. static_assert(true)
  334. ////////////////////////////////////////////////////////////////////////////////