chromium/ui/base/class_property.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_CLASS_PROPERTY_H_
#define UI_BASE_CLASS_PROPERTY_H_

#include <stdint.h>

#include <cstring>
#include <map>
#include <memory>
#include <set>
#include <type_traits>

#include "base/component_export.h"
#include "base/time/time.h"
#include "ui/base/ui_base_types.h"

// This header should be included by code that defines ClassProperties.
//
// To define a new ClassProperty:
//
//  #include "foo/foo_export.h"
//  #include "ui/base/class_property.h"
//
//  DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType)
//  namespace foo {
//    // Use this to define an exported property that is primitive,
//    // or a pointer you don't want automatically deleted.
//    DEFINE_UI_CLASS_PROPERTY_KEY(MyType, kMyKey, MyDefault)
//
//    // Use this to define an exported property whose value is a heap
//    // allocated object, and has to be owned and freed by the class.
//    DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::Rect, kRestoreBoundsKey, nullptr)
//
//  }  // foo namespace
//
// To define a new type used for ClassProperty.
//
//  // outside all namespaces:
//  DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType)
//
// If a property type is not exported, use
// DEFINE_UI_CLASS_PROPERTY_TYPE(MyType) which is a shorthand for
// DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(, MyType).
//
// If the properties are used outside the file where they are defined
// their accessor methods should also be declared in a suitable header
// using DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(FOO_EXPORT, MyType)
//
// Cascading properties:
//
// Use the DEFINE_CASCADING_XXX macros to create a class property type that
// will automatically search up an instance hierarchy for the first defined
// property. This only affects the GetProperty() call. SetProperty() will
// still explicitly set the value on the given instance. This is useful for
// hierarchies of instances which a single set property can effect a whole sub-
// tree of instances.
//
// In order to use this feature, you must override GetParentHandler() on the
// class that inherits PropertyHandler.

namespace ui {

// Type of a function to delete a property that this window owns.
PropertyDeallocator;

template<typename T>
struct ClassProperty {};

namespace subtle {

class PropertyHelper;

}

class COMPONENT_EXPORT(UI_BASE) PropertyHandler {};

// No single new-style cast works for every conversion to/from int64_t, so we
// need this helper class.
template<typename T>
class ClassPropertyCaster {};
ClassPropertyCaster<T *>;
template <>
class ClassPropertyCaster<base::TimeDelta> {};
template <>
class ClassPropertyCaster<float> {};

namespace subtle {

class COMPONENT_EXPORT(UI_BASE) PropertyHelper {};

}  // namespace subtle

// Template implementation is necessary in the .h file unless we want to break
// [DECLARE|DEFINE]_EXPORTED_UI_CLASS_PROPERTY_TYPE() below into different
// macros for owned and unowned properties; implementing them as pure templates
// makes them nearly impossible to implement or use incorrectly at the cost of a
// small amount of code duplication across libraries.

template <typename T>
void PropertyHandler::SetProperty(const ClassProperty<T*>* property,
                                  const T& value) {}

template <typename T>
void PropertyHandler::SetProperty(const ClassProperty<T*>* property,
                                  T&& value) {}

template <typename T>
T* PropertyHandler::SetProperty(const ClassProperty<T*>* property,
                                std::unique_ptr<T> value) {}

}  // namespace ui

// Macros to declare the property getter/setter template functions.
#define DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(EXPORT, T)

// Macros to instantiate the property getter/setter template functions.
#define DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(EXPORT, T)

#define DEFINE_UI_CLASS_PROPERTY_TYPE(T)

#define DEFINE_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT)

#define DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT)

#define DEFINE_CASCADING_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT)

#define DEFINE_CASCADING_OWNED_UI_CLASS_PROPERTY_KEY(TYPE, NAME, DEFAULT)

#endif  // UI_BASE_CLASS_PROPERTY_H_