property.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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. //! Forwards a trivial public read-write property that is passed by reference.
  44. #define DELEGATE_BYREF_RW_PROPERTY(declaringType, type, name, delegateTo) \
  45. type& declaringType::name() noexcept \
  46. { \
  47. return (delegateTo).name(); \
  48. } \
  49. \
  50. const type& declaringType::name() const noexcept \
  51. { \
  52. return (delegateTo).name(); \
  53. } \
  54. static_assert(true)
  55. ////////////////////////////////////////////////////////////////////////////////
  56. //! Declares a trivial public read-only property that is passed by reference.
  57. #define DECLARE_BYREF_RO_PROPERTY(type, name) \
  58. public: \
  59. const type& name() const noexcept
  60. //! Defines a trivial public read-only property that is passed by reference.
  61. //! All arguments after name are used as default value (via braced-init-list).
  62. #define DEFINE_BYREF_RO_PROPERTY(type, name, ...) \
  63. protected: \
  64. type name##_ { __VA_ARGS__ }; \
  65. \
  66. public: \
  67. Y_FORCE_INLINE const type& name() const noexcept \
  68. { \
  69. return name##_; \
  70. } \
  71. static_assert(true)
  72. //! Defines a trivial public read-only property that is passed by reference
  73. //! and is not inline-initialized.
  74. #define DEFINE_BYREF_RO_PROPERTY_NO_INIT(type, name) \
  75. protected: \
  76. type name##_; \
  77. \
  78. public: \
  79. Y_FORCE_INLINE const type& name() const noexcept \
  80. { \
  81. return name##_; \
  82. } \
  83. static_assert(true)
  84. //! Forwards a trivial public read-only property that is passed by reference.
  85. #define DELEGATE_BYREF_RO_PROPERTY(declaringType, type, name, delegateTo) \
  86. const type& declaringType::name() const noexcept \
  87. { \
  88. return (delegateTo).name(); \
  89. } \
  90. static_assert(true)
  91. ////////////////////////////////////////////////////////////////////////////////
  92. //! Declares a trivial public read-write property that is passed by value.
  93. #define DECLARE_BYVAL_RW_PROPERTY(type, name) \
  94. public: \
  95. type Get##name() const; \
  96. void Set##name(type value)
  97. //! Defines a trivial public read-write property that is passed by value.
  98. //! All arguments after name are used as default value (via braced-init-list).
  99. #define DEFINE_BYVAL_RW_PROPERTY(type, name, ...) \
  100. protected: \
  101. type name##_ { __VA_ARGS__ }; \
  102. \
  103. public: \
  104. Y_FORCE_INLINE type Get##name() const \
  105. { \
  106. return name##_; \
  107. } \
  108. \
  109. Y_FORCE_INLINE void Set##name(type value) \
  110. { \
  111. name##_ = value; \
  112. } \
  113. static_assert(true)
  114. //! Defines a trivial public read-write property that is passed by value.
  115. //! All arguments after name are used as default value (via braced-init-list).
  116. #define DEFINE_BYVAL_RW_PROPERTY_WITH_FLUENT_SETTER(declaringType, type, name, ...) \
  117. protected: \
  118. type name##_ { __VA_ARGS__ }; \
  119. \
  120. public: \
  121. Y_FORCE_INLINE type Get##name() const \
  122. { \
  123. return name##_; \
  124. } \
  125. \
  126. Y_FORCE_INLINE void Set##name(type value) &\
  127. { \
  128. name##_ = value; \
  129. } \
  130. \
  131. Y_FORCE_INLINE declaringType&& Set##name(type value) &&\
  132. { \
  133. name##_ = value; \
  134. return std::move(*this); \
  135. } \
  136. static_assert(true)
  137. //! Defines a trivial public read-write property that is passed by value
  138. //! and is not inline-initialized.
  139. #define DEFINE_BYVAL_RW_PROPERTY_NO_INIT(type, name, ...) \
  140. protected: \
  141. type name##_; \
  142. \
  143. public: \
  144. Y_FORCE_INLINE type Get##name() const \
  145. { \
  146. return name##_; \
  147. } \
  148. \
  149. Y_FORCE_INLINE void Set##name(type value) \
  150. { \
  151. name##_ = value; \
  152. } \
  153. static_assert(true)
  154. //! Forwards a trivial public read-write property that is passed by value.
  155. #define DELEGATE_BYVAL_RW_PROPERTY(declaringType, type, name, delegateTo) \
  156. type declaringType::Get##name() const \
  157. { \
  158. return (delegateTo).Get##name(); \
  159. } \
  160. \
  161. void declaringType::Set##name(type value) \
  162. { \
  163. (delegateTo).Set##name(value); \
  164. } \
  165. static_assert(true)
  166. ////////////////////////////////////////////////////////////////////////////////
  167. //! Declares a trivial public read-only property that is passed by value.
  168. #define DECLARE_BYVAL_RO_PROPERTY(type, name) \
  169. public: \
  170. type Get##name() const
  171. //! Defines a trivial public read-only property that is passed by value.
  172. //! All arguments after name are used as default value (via braced-init-list).
  173. #define DEFINE_BYVAL_RO_PROPERTY(type, name, ...) \
  174. protected: \
  175. type name##_ { __VA_ARGS__ }; \
  176. \
  177. public: \
  178. Y_FORCE_INLINE type Get##name() const \
  179. { \
  180. return name##_; \
  181. } \
  182. static_assert(true)
  183. //! Defines a trivial public read-only property that is passed by value
  184. //! and is not inline-initialized.
  185. #define DEFINE_BYVAL_RO_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. static_assert(true)
  195. //! Forwards a trivial public read-only property that is passed by value.
  196. #define DELEGATE_BYVAL_RO_PROPERTY(declaringType, type, name, delegateTo) \
  197. type declaringType::Get##name() \
  198. { \
  199. return (delegateTo).Get##name(); \
  200. } \
  201. static_assert(true)
  202. ////////////////////////////////////////////////////////////////////////////////
  203. //! Below are macro helpers for extra properties.
  204. //! Extra properties should be used for lazy memory allocation for properties that
  205. //! hold default values for the majority of objects.
  206. //! Initializes extra property holder if it is not initialized.
  207. #define INITIALIZE_EXTRA_PROPERTY_HOLDER(holder) \
  208. if (!holder##_) { \
  209. holder##_.reset(new decltype(holder##_)::element_type()); \
  210. } \
  211. static_assert(true)
  212. //! Declares an extra property holder. Holder contains extra properties values.
  213. //! Holder is not created until some property is set with a non-default value.
  214. //! If there is no holder property getter returns default value.
  215. #define DECLARE_EXTRA_PROPERTY_HOLDER(type, holder) \
  216. public: \
  217. Y_FORCE_INLINE bool HasCustom##holder() const \
  218. { \
  219. return static_cast<bool>(holder##_); \
  220. } \
  221. Y_FORCE_INLINE const type* GetCustom##holder() const \
  222. { \
  223. return holder##_.get(); \
  224. } \
  225. Y_FORCE_INLINE type* GetCustom##holder() \
  226. { \
  227. return holder##_.get(); \
  228. } \
  229. Y_FORCE_INLINE void InitializeCustom##holder() \
  230. { \
  231. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  232. } \
  233. private: \
  234. std::unique_ptr<type> holder##_; \
  235. static const type Default##holder##_
  236. //! Defines a storage for extra properties default values.
  237. #define DEFINE_EXTRA_PROPERTY_HOLDER(class, type, holder) \
  238. const type class::Default##holder##_
  239. //! Defines a public read-write extra property that is passed by value.
  240. #define DEFINE_BYVAL_RW_EXTRA_PROPERTY(holder, name) \
  241. public: \
  242. Y_FORCE_INLINE decltype(holder##_->name) Get##name() const \
  243. { \
  244. if (!holder##_) { \
  245. return Default##holder##_.name; \
  246. } \
  247. return holder##_->name; \
  248. } \
  249. Y_FORCE_INLINE void Set##name(decltype(holder##_->name) val) \
  250. { \
  251. if (!holder##_) { \
  252. if (val == Default##holder##_.name) { \
  253. return; \
  254. } \
  255. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  256. } \
  257. holder##_->name = val; \
  258. } \
  259. static_assert(true)
  260. //! Defines a public read-write extra property that is passed by reference.
  261. #define DEFINE_BYREF_RW_EXTRA_PROPERTY(holder, name) \
  262. public: \
  263. Y_FORCE_INLINE const decltype(holder##_->name)& name() const \
  264. { \
  265. if (!holder##_) { \
  266. return Default##holder##_.name; \
  267. } \
  268. return holder##_->name; \
  269. } \
  270. Y_FORCE_INLINE decltype(holder##_->name)& Mutable##name() \
  271. { \
  272. INITIALIZE_EXTRA_PROPERTY_HOLDER(holder); \
  273. return holder##_->name; \
  274. } \
  275. static_assert(true)
  276. ////////////////////////////////////////////////////////////////////////////////