Print Preview: Refactoring print/cancel button and print summary.
[chromium-blink-merge.git] / content / common / property_bag.h
blob0e2e2048c61c4ee3bae54412fa9287c1cdb0fb34
1 // Copyright (c) 2011 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.
5 #ifndef CONTENT_COMMON_PROPERTY_BAG_H_
6 #define CONTENT_COMMON_PROPERTY_BAG_H_
7 #pragma once
9 #include <map>
11 #include "base/basictypes.h"
13 template <typename T>
14 class linked_ptr;
15 class PropertyAccessorBase;
17 // A property bag holds a generalized list of arbitrary metadata called
18 // properties. Each property is a class type derived from PropertyBag::Prop
19 // that can be set and retrieved.
21 // The property bag is not read or written directly. Instead, callers go
22 // through a PropertyAccessor. The Accessor generates the unique IDs that
23 // identify different properties. The Accessor is templatized to also provide
24 // typesafety to the callers.
26 // Example:
27 // // Note: you don't want to use Singleton for your Accessor if you're using
28 // // a simple type like int or string as the data, since it will enforce that
29 // // there is only one singleton for that type, which will conflict. If
30 // // you're putting in some struct that's unique to you, go ahead.
31 // PropertyAccessor<int>* my_accessor() const {
32 // static PropertyAccessor<int>* accessor = NULL;
33 // if (!accessor) accessor = new PropertyAccessor<int>;
34 // return accessor;
35 // }
37 // void doit(SomeObjectThatImplementsPropertyBag* object) {
38 // PropertyAccessor<int>* accessor = my_accessor();
39 // int* property = accessor->GetProperty(object);
40 // if (property)
41 // ... use property ...
43 // accessor->SetProperty(object, 22);
44 // }
45 class PropertyBag {
46 public:
47 // The type that uniquely identifies a property type.
48 typedef int PropID;
49 enum { NULL_PROP_ID = -1 }; // Invalid property ID.
51 // Properties are all derived from this class. They must be deletable and
52 // copyable
53 class Prop {
54 public:
55 virtual ~Prop() {}
57 // Copies the property and returns a pointer to the new one. The caller is
58 // responsible for managing the lifetime.
59 virtual Prop* copy() = 0;
62 PropertyBag();
63 PropertyBag(const PropertyBag& other);
64 virtual ~PropertyBag();
66 PropertyBag& operator=(const PropertyBag& other);
68 private:
69 friend class PropertyAccessorBase;
71 typedef std::map<PropID, linked_ptr<Prop> > PropertyMap;
73 // Used by the PropertyAccessor to set the property with the given ID.
74 // Ownership of the given pointer will be transferred to us. Any existing
75 // property matching the given ID will be deleted.
76 void SetProperty(PropID id, Prop* prop);
78 // Used by the PropertyAccessor to retrieve the property with the given ID.
79 // The returned pointer will be NULL if there is no match. Ownership of the
80 // pointer will stay with the property bag.
81 Prop* GetProperty(PropID id);
82 const Prop* GetProperty(PropID id) const;
84 // Deletes the property with the given ID from the bag if it exists.
85 void DeleteProperty(PropID id);
87 PropertyMap props_;
89 // Copy and assign is explicitly allowed for this class.
92 // PropertyAccessorBase -------------------------------------------------------
94 // Manages getting the unique IDs to identify a property. Callers should use
95 // PropertyAccessor below instead.
96 class PropertyAccessorBase {
97 public:
98 PropertyAccessorBase();
99 virtual ~PropertyAccessorBase() {}
101 // Removes our property, if any, from the given property bag.
102 void DeleteProperty(PropertyBag* bag) {
103 bag->DeleteProperty(prop_id_);
106 protected:
107 void SetPropertyInternal(PropertyBag* bag, PropertyBag::Prop* prop) {
108 bag->SetProperty(prop_id_, prop);
110 PropertyBag::Prop* GetPropertyInternal(PropertyBag* bag) {
111 return bag->GetProperty(prop_id_);
113 const PropertyBag::Prop* GetPropertyInternal(const PropertyBag* bag) const {
114 return bag->GetProperty(prop_id_);
117 private:
118 // Identifier for this property.
119 PropertyBag::PropID prop_id_;
121 DISALLOW_COPY_AND_ASSIGN(PropertyAccessorBase);
124 // PropertyAccessor -----------------------------------------------------------
126 // Provides typesafe accessor functions for a property bag, and manages the
127 // unique identifiers for properties via the PropertyAccessorBase.
128 template<class T>
129 class PropertyAccessor : public PropertyAccessorBase {
130 public:
131 PropertyAccessor() : PropertyAccessorBase() {}
132 virtual ~PropertyAccessor() {}
134 // Makes a copy of the |prop| object for storage.
135 void SetProperty(PropertyBag* bag, const T& prop) {
136 SetPropertyInternal(bag, new Container(prop));
139 // Returns our property in the given bag or NULL if there is no match. The
140 // returned pointer's ownership will stay with the property bag.
141 T* GetProperty(PropertyBag* bag) {
142 PropertyBag::Prop* prop = GetPropertyInternal(bag);
143 if (!prop)
144 return NULL;
145 return static_cast<Container*>(prop)->get();
147 const T* GetProperty(const PropertyBag* bag) const {
148 const PropertyBag::Prop* prop = GetPropertyInternal(bag);
149 if (!prop)
150 return NULL;
151 return static_cast<const Container*>(prop)->get();
154 // See also DeleteProperty on thn PropertyAccessorBase.
156 private:
157 class Container : public PropertyBag::Prop {
158 public:
159 explicit Container(const T& data) : data_(data) {}
161 T* get() { return &data_; }
162 const T* get() const { return &data_; }
164 private:
165 virtual Prop* copy() {
166 return new Container(data_);
169 T data_;
172 DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
175 #endif // CONTENT_COMMON_PROPERTY_BAG_H_