blob: f642adb26bc8f3bf10a0684dba31cb5e700ab55e [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_
#define UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_
#include <string>
#include <utility>
#include "base/compiler_specific.h"
#include "ui/base/metadata/metadata_types.h"
#include "ui/base/metadata/property_metadata.h"
// Internal Metadata Generation Helpers ---------------------------------------
#define METADATA_CLASS_NAME_INTERNAL(class_name) class_name##_MetaData
// Metadata Accessors ---------------------------------------------------------
#define METADATA_ACCESSORS_INTERNAL(class_name) \
static const char kViewClassName[]; \
const char* GetClassName() const override; \
static ui::metadata::ClassMetaData* MetaData(); \
ui::metadata::ClassMetaData* GetClassMetaData() override;
// A version of METADATA_ACCESSORS_INTERNAL for View, the root of the metadata
// hierarchy; here GetClassName() is not declared as an override.
//
// This also introduces the ReinterpretToBaseClass(), which should exist at the
// root of the hierarchy on which the metadata will be attached. This will take
// the given void*, which should be some instance of a subclass of this base
// class, and return a properly typed class_name*. The body of this function
// does a reinterpret_cast<> of the void* to obtain a class_name*. Doing a
// direct static_cast<> from the void* may result in an incorrect
// pointer-to-instance, which may cause a crash. Using this intermediate step of
// reinterpret_cast<> provides more information to the compiler in order to
// obtain the proper result from the static_cast<>. See |AsClass(void* obj)|
// in property_metadata.h for additional info.
#define METADATA_ACCESSORS_INTERNAL_BASE(class_name) \
static const char kViewClassName[]; \
virtual const char* GetClassName() const; \
static ui::metadata::ClassMetaData* MetaData(); \
class_name* ReinterpretToBaseClass(void* obj); \
ui::metadata::ClassMetaData* GetClassMetaData() override;
// Metadata Class -------------------------------------------------------------
#define METADATA_CLASS_INTERNAL(class_name, file, line) \
class METADATA_CLASS_NAME_INTERNAL(class_name) \
: public ui::metadata::ClassMetaData { \
public: \
using TheClass = class_name; \
explicit METADATA_CLASS_NAME_INTERNAL(class_name)() \
: ClassMetaData(file, line) { \
BuildMetaData(); \
} \
METADATA_CLASS_NAME_INTERNAL(class_name) \
(const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \
METADATA_CLASS_NAME_INTERNAL(class_name) & operator=( \
const METADATA_CLASS_NAME_INTERNAL(class_name) &) = delete; \
\
private: \
friend class class_name; \
void BuildMetaData(); \
static ui::metadata::ClassMetaData* meta_data_ ALLOW_UNUSED_TYPE; \
}
#define METADATA_PROPERTY_TYPE_INTERNAL(property_type, property_name, ...) \
ui::metadata::ObjectPropertyMetaData< \
TheClass, property_type, decltype(&TheClass::Set##property_name), \
&TheClass::Set##property_name, \
decltype(std::declval<TheClass>().Get##property_name()), \
&TheClass::Get##property_name, ##__VA_ARGS__>
#define METADATA_READONLY_PROPERTY_TYPE_INTERNAL(property_type, property_name, \
...) \
ui::metadata::ObjectPropertyReadOnlyMetaData< \
TheClass, property_type, \
decltype(std::declval<TheClass>().Get##property_name()), \
&TheClass::Get##property_name, ##__VA_ARGS__>
#define METADATA_CLASS_PROPERTY_TYPE_INTERNAL(property_type, property_key, \
...) \
ui::metadata::ClassPropertyMetaData<TheClass, decltype(property_key), \
property_type, ##__VA_ARGS__>
#define BEGIN_METADATA_INTERNAL(qualified_class_name, metadata_class_name, \
parent_class_name) \
ui::metadata::ClassMetaData* \
qualified_class_name::metadata_class_name::meta_data_ = nullptr; \
\
ui::metadata::ClassMetaData* qualified_class_name::MetaData() { \
static_assert( \
std::is_base_of<parent_class_name, qualified_class_name>::value, \
"class not child of parent"); \
if (!qualified_class_name::metadata_class_name::meta_data_) { \
qualified_class_name::metadata_class_name::meta_data_ = \
ui::metadata::MakeAndRegisterClassInfo< \
qualified_class_name::metadata_class_name>(); \
} \
return qualified_class_name::metadata_class_name::meta_data_; \
} \
\
ui::metadata::ClassMetaData* qualified_class_name::GetClassMetaData() { \
return MetaData(); \
} \
\
const char* qualified_class_name::GetClassName() const { \
return kViewClassName; \
} \
const char qualified_class_name::kViewClassName[] = #qualified_class_name; \
\
void qualified_class_name::metadata_class_name::BuildMetaData() { \
SetTypeName(std::string(#qualified_class_name));
// See the comment above on the METADATA_ACCESSORS_INTERNAL_BASE macro for more
// information. NOTE: This function should not be modified to access |this|,
// directly or indirectly. It should only do what is necessary to convert |obj|
// to a properly typed pointer.
#define METADATA_REINTERPRET_BASE_CLASS_INTERNAL(qualified_class_name, \
metadata_class_name) \
qualified_class_name* qualified_class_name::ReinterpretToBaseClass( \
void* obj) { \
return reinterpret_cast<qualified_class_name*>(obj); \
}
#define METADATA_PARENT_CLASS_INTERNAL(parent_class_name) \
SetParentClassMetaData(parent_class_name::MetaData());
#endif // UI_BASE_METADATA_METADATA_MACROS_INTERNAL_H_