metadata_macros_internal.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_
  5. #define UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_
  6. #include <string>
  7. #include <utility>
  8. #include "ui/base/metadata/metadata_types.h"
  9. #include "ui/base/metadata/property_metadata.h"
  10. // Internal Metadata Generation Helpers ---------------------------------------
  11. #define METADATA_CLASS_NAME_INTERNAL(class_name) class_name##_MetaData
  12. // Metadata Accessors ---------------------------------------------------------
  13. #define METADATA_ACCESSORS_INTERNAL(class_name) \
  14. static const char kViewClassName[]; \
  15. const char* GetClassName() const override; \
  16. static ui::metadata::ClassMetaData* MetaData(); \
  17. ui::metadata::ClassMetaData* GetClassMetaData() override;
  18. // A version of METADATA_ACCESSORS_INTERNAL for View, the root of the metadata
  19. // hierarchy; here GetClassName() is not declared as an override.
  20. //
  21. // This also introduces the ReinterpretToBaseClass(), which should exist at the
  22. // root of the hierarchy on which the metadata will be attached. This will take
  23. // the given void*, which should be some instance of a subclass of this base
  24. // class, and return a properly typed class_name*. The body of this function
  25. // does a reinterpret_cast<> of the void* to obtain a class_name*. Doing a
  26. // direct static_cast<> from the void* may result in an incorrect
  27. // pointer-to-instance, which may cause a crash. Using this intermediate step of
  28. // reinterpret_cast<> provides more information to the compiler in order to
  29. // obtain the proper result from the static_cast<>. See |AsClass(void* obj)|
  30. // in property_metadata.h for additional info.
  31. #define METADATA_ACCESSORS_INTERNAL_BASE(class_name) \
  32. static const char kViewClassName[]; \
  33. virtual const char* GetClassName() const; \
  34. static ui::metadata::ClassMetaData* MetaData(); \
  35. class_name* ReinterpretToBaseClass(void* obj); \
  36. ui::metadata::ClassMetaData* GetClassMetaData() override;
  37. // Metadata Class -------------------------------------------------------------
  38. #define METADATA_CLASS_INTERNAL(class_name, file, line) \
  39. class METADATA_CLASS_NAME_INTERNAL(class_name) \
  40. : public ui::metadata::ClassMetaData { \
  41. public: \
  42. using TheClass = class_name; \
  43. explicit METADATA_CLASS_NAME_INTERNAL(class_name)() \
  44. : ClassMetaData(file, line) { \
  45. BuildMetaData(); \
  46. } \
  47. METADATA_CLASS_NAME_INTERNAL(class_name) \
  48. (const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \
  49. METADATA_CLASS_NAME_INTERNAL(class_name) & operator=( \
  50. const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \
  51. \
  52. private: \
  53. friend class class_name; \
  54. void BuildMetaData(); \
  55. [[maybe_unused]] static ui::metadata::ClassMetaData* meta_data_; \
  56. }
  57. #define METADATA_PROPERTY_TYPE_INTERNAL(property_type, property_name, ...) \
  58. ui::metadata::ObjectPropertyMetaData< \
  59. TheClass, property_type, decltype(&TheClass::Set##property_name), \
  60. &TheClass::Set##property_name, \
  61. decltype(std::declval<TheClass>().Get##property_name()), \
  62. &TheClass::Get##property_name, ##__VA_ARGS__>
  63. #define METADATA_READONLY_PROPERTY_TYPE_INTERNAL(property_type, property_name, \
  64. ...) \
  65. ui::metadata::ObjectPropertyReadOnlyMetaData< \
  66. TheClass, property_type, \
  67. decltype(std::declval<TheClass>().Get##property_name()), \
  68. &TheClass::Get##property_name, ##__VA_ARGS__>
  69. #define METADATA_CLASS_PROPERTY_TYPE_INTERNAL(property_type, property_key, \
  70. ...) \
  71. ui::metadata::ClassPropertyMetaData<TheClass, decltype(property_key), \
  72. property_type, ##__VA_ARGS__>
  73. #define BEGIN_METADATA_INTERNAL(qualified_class_name, metadata_class_name, \
  74. parent_class_name) \
  75. ui::metadata::ClassMetaData* \
  76. qualified_class_name::metadata_class_name::meta_data_ = nullptr; \
  77. \
  78. ui::metadata::ClassMetaData* qualified_class_name::MetaData() { \
  79. static_assert( \
  80. std::is_base_of<parent_class_name, qualified_class_name>::value, \
  81. "class not child of parent"); \
  82. if (!qualified_class_name::metadata_class_name::meta_data_) { \
  83. qualified_class_name::metadata_class_name::meta_data_ = \
  84. ui::metadata::MakeAndRegisterClassInfo< \
  85. qualified_class_name::metadata_class_name>(); \
  86. } \
  87. return qualified_class_name::metadata_class_name::meta_data_; \
  88. } \
  89. \
  90. ui::metadata::ClassMetaData* qualified_class_name::GetClassMetaData() { \
  91. return MetaData(); \
  92. } \
  93. \
  94. const char* qualified_class_name::GetClassName() const { \
  95. return kViewClassName; \
  96. } \
  97. const char qualified_class_name::kViewClassName[] = #qualified_class_name; \
  98. \
  99. void qualified_class_name::metadata_class_name::BuildMetaData() { \
  100. SetTypeName(std::string(#qualified_class_name));
  101. // See the comment above on the METADATA_ACCESSORS_INTERNAL_BASE macro for more
  102. // information. NOTE: This function should not be modified to access |this|,
  103. // directly or indirectly. It should only do what is necessary to convert |obj|
  104. // to a properly typed pointer.
  105. #define METADATA_REINTERPRET_BASE_CLASS_INTERNAL(qualified_class_name, \
  106. metadata_class_name) \
  107. qualified_class_name* qualified_class_name::ReinterpretToBaseClass( \
  108. void* obj) { \
  109. return reinterpret_cast<qualified_class_name*>(obj); \
  110. }
  111. #define METADATA_PARENT_CLASS_INTERNAL(parent_class_name) \
  112. SetParentClassMetaData(parent_class_name::MetaData());
  113. #endif // UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_