property.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /************************************************************************************
  2. * *
  3. * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
  4. * *
  5. * This file is part of RTTR (Run Time Type Reflection) *
  6. * License: MIT License *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining *
  9. * a copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
  24. * SOFTWARE. *
  25. * *
  26. *************************************************************************************/
  27. #ifndef RTTR_PROPERTY_H_
  28. #define RTTR_PROPERTY_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/class_item_mapper.h"
  31. #include "rttr/parameter_info.h"
  32. #include "rttr/access_levels.h"
  33. #include "rttr/string_view.h"
  34. #include <string>
  35. namespace rttr
  36. {
  37. class variant;
  38. class type;
  39. class enumeration;
  40. class instance;
  41. class argument;
  42. class property;
  43. class visitor;
  44. namespace detail
  45. {
  46. class property_wrapper_base;
  47. }
  48. /*!
  49. * The \ref property class provides several meta information about a property and gives read/write access to its value.
  50. *
  51. * A instance of a property class can only be obtained from the \ref type class.
  52. * See \ref type::get_property() and \ref type::get_properties().
  53. *
  54. * For registration a property, nested inside a class, see \ref registration::class_<T>::property()
  55. * and for global properties see \ref registration::property().
  56. *
  57. * Meta Information
  58. * ----------------
  59. * A \ref property has a \ref get_name() "name", and a \ref get_type() "type" as well as attributes that specify its behavior:
  60. * \ref is_readonly(), \ref is_static(), \ref is_enumeration(), \ref is_array().
  61. * When the \ref property was declared inside a class, then \ref get_declaring_type() can be used to obtain the type of this class.
  62. *
  63. * The property's values are set and retrieved with \ref set_value() and \ref get_value();
  64. * When its not a \ref is_static "static property" you have to provide a class instance to set/get the property value.
  65. * This instance can be the raw type on the stack; the current hierarchy level doesn't matter. It can be also a raw pointer to the object or
  66. * a \ref variant which contains the instance, again as pointer or stack object.
  67. * When the property is declared as \ref is_static "static" you you still have to provide an empty instance object,
  68. * use therefore the default ctor of \ref instance::instance() "instance()", or as shortcut use simply `{}`.
  69. *
  70. * A property will be successfully \ref set_value "set" when the provided instance can be converted to the \ref get_declaring_type() "declared class" type.
  71. * The new forwarded property value must 100% match the type of the registered property. An automatically type conversion is **not** performed.
  72. *
  73. * The return type of \ref get_value() is \ref variant object.
  74. * This object contains not only the value of the property, it also indicates whether the property value could be retrieved or not.
  75. * A \ref variant::is_valid "valid" variant object means, that the property was successfully retrieved, otherwise not.
  76. *
  77. * Another way to get access a property is through \ref type "type's" set and get functions. See \ref type::set_property_value() and type::get_property_value() for details.
  78. *
  79. * Copying and Assignment
  80. * ----------------------
  81. * A \ref property object is lightweight and can be copied by value. However, each copy will refer to the same underlying property.
  82. *
  83. * Typical Usage
  84. * ----------------------
  85. *
  86. \code{.cpp}
  87. using namespace rttr;
  88. struct MyStruct { int value = 23; };
  89. //...
  90. variant obj = type::get_by_name("MyStruct").create({});
  91. property prop = type::get_by_name("MyStruct").get_property("value");
  92. if (prop)
  93. {
  94. variant val = prop.get_value(obj);
  95. std::cout << val.get_value<int>(); // prints 23
  96. MyStruct inst;
  97. val = prop.set_value(inst, 42);
  98. std::cout << inst.value; // prints 42
  99. // or as pointer
  100. MyStruct* ptr = &inst;
  101. val = prop.set_value(ptr, 7);
  102. std::cout << ptr->value; // prints 7
  103. // or do it all in one call
  104. type::get(inst).set_propert_value("value", inst, 1024);
  105. std::cout << inst.value; // prints 1024
  106. }
  107. \endcode
  108. *
  109. * \see method, enumeration, constructor and type
  110. */
  111. class RTTR_API property
  112. {
  113. public:
  114. /*!
  115. * \brief Returns true if this property is valid, otherwise false.
  116. *
  117. * \return True if this property is valid, otherwise false.
  118. */
  119. bool is_valid() const RTTR_NOEXCEPT;
  120. /*!
  121. * \brief Convenience function to check if this property is valid or not.
  122. *
  123. * \return True if this property is valid, otherwise false.
  124. */
  125. explicit operator bool() const RTTR_NOEXCEPT;
  126. /*!
  127. * \brief Returns the access level with which this property was
  128. * \ref registration::class_<T>::property() "registered".
  129. *
  130. * \remark When the property is not valid, this function will return level \ref access_levels::public_access.
  131. *
  132. * \return \ref access_levels of the property.
  133. */
  134. access_levels get_access_level() const RTTR_NOEXCEPT;
  135. /*!
  136. * \brief Returns true if this property is read only, otherwise false.
  137. *
  138. * \remark When the property is not valid, this function will return false.
  139. *
  140. * \return True if this is a read only property, otherwise false.
  141. */
  142. bool is_readonly() const RTTR_NOEXCEPT;
  143. /*!
  144. * \brief Returns true if this property is static property, otherwise false.
  145. * A static property does not need an instance for performing set_value/get_value.
  146. *
  147. * \remark When the property is not valid, this function will return false.
  148. *
  149. * \return True if this is a static property, otherwise false.
  150. */
  151. bool is_static() const RTTR_NOEXCEPT;
  152. /*!
  153. * \brief Returns true if the underlying property is an \ref enumeration.
  154. *
  155. * \remark When the property is not valid, this function will return false.
  156. *
  157. * \return True if this is a \ref enumeration type, otherwise false.
  158. */
  159. bool is_enumeration() const RTTR_NOEXCEPT;
  160. /*!
  161. * \brief Returns the enumerator if this property is an enum type;
  162. * otherwise the returned value is \ref enumeration::is_valid "not valid".
  163. *
  164. * \see is_enumeration()
  165. *
  166. * \return An enumeration object.
  167. */
  168. enumeration get_enumeration() const RTTR_NOEXCEPT;
  169. /*!
  170. * \brief Returns the name of this property.
  171. *
  172. * \remark When the property is not valid, this function will return an empty string_view.
  173. *
  174. * \return Name of the property.
  175. */
  176. string_view get_name() const RTTR_NOEXCEPT;
  177. /*!
  178. * \brief Returns the underlying \ref type object of this property.
  179. *
  180. * \remark When the property is not valid, this function will return an invalid type object.
  181. *
  182. * \return \ref type "Type" of the underlying property.
  183. */
  184. type get_type() const RTTR_NOEXCEPT;
  185. /*!
  186. * \brief Returns the \ref type of the class or struct that declares this property.
  187. *
  188. * \remark When this property does not belong to a class (i.e. is a global property) it will return an invalid type object.
  189. * When this property is not valid, this function will return an invalid type object (see \ref type::is_valid).
  190. *
  191. * \return \ref type "Type" of the declaring class/struct for this property.
  192. */
  193. type get_declaring_type() const RTTR_NOEXCEPT;
  194. /*!
  195. * \brief Set the property of the given instance \p object to the given value \p arg.
  196. *
  197. * \remark When the property is declared as \ref is_readonly "read only" this function will return false.
  198. * When you have a static property just pass an empty instance as object argument.
  199. * When the property is not valid, this function will return false.
  200. *
  201. * \see get_value().
  202. *
  203. * \return The return value indicates whether the operation was successful or not.
  204. */
  205. bool set_value(instance object, argument arg) const;
  206. /*!
  207. * \brief Returns the current property value of the given instance \p object.
  208. *
  209. * \remark When the property is static, you can forward an empty instance.
  210. *
  211. * \see set_value().
  212. *
  213. * \return The property value of the given instance \p object.
  214. */
  215. variant get_value(instance object) const;
  216. /*!
  217. * \brief Returns the meta data for the given key \p key.
  218. *
  219. * \remark When no meta data is registered with the given \p key,
  220. * an invalid \ref variant object is returned (see \ref variant::is_valid).
  221. *
  222. * \return A variant object, containing arbitrary data.
  223. */
  224. variant get_metadata(const variant& key) const;
  225. /*!
  226. * \brief Returns true if this property is the same like the \p other.
  227. *
  228. * \return True if both properties are equal, otherwise false.
  229. */
  230. bool operator==(const property& other) const RTTR_NOEXCEPT;
  231. /*!
  232. * Returns true if this property is the not the same like the \p other.
  233. *
  234. * \return True if both properties are different, otherwise false.
  235. */
  236. bool operator!=(const property& other) const RTTR_NOEXCEPT;
  237. private:
  238. //! Constructs a property from a property_wrapper_base.
  239. property(const detail::property_wrapper_base* wrapper) RTTR_NOEXCEPT;
  240. void visit(visitor& visitor) const RTTR_NOEXCEPT;
  241. template<typename T>
  242. friend T detail::create_item(const detail::class_item_to_wrapper_t<T>* wrapper);
  243. template<typename T>
  244. friend T detail::create_invalid_item();
  245. friend class visitor;
  246. private:
  247. const detail::property_wrapper_base* m_wrapper;
  248. };
  249. } // end namespace rttr
  250. #endif // RTTR_PROPERTY_H_