Add OS_IOS defines for the mobile promo.
[chromium-blink-merge.git] / base / property_bag.h
blob16c20fac005362a765694e84e9bdf458afd3a1e4
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 BASE_PROPERTY_BAG_H_
6 #define BASE_PROPERTY_BAG_H_
8 #include <map>
10 #include "base/basictypes.h"
11 #include "base/base_export.h"
13 template <typename T> class linked_ptr;
15 namespace base {
17 class PropertyAccessorBase;
19 // A property bag holds a generalized list of arbitrary metadata called
20 // properties. Each property is a class type derived from PropertyBag::Prop
21 // that can be set and retrieved.
23 // The property bag is not read or written directly. Instead, callers go
24 // through a PropertyAccessor. The Accessor generates the unique IDs that
25 // identify different properties. The Accessor is templatized to also provide
26 // typesafety to the callers.
28 // Example:
29 // // Note: you don't want to use Singleton for your Accessor if you're using
30 // // a simple type like int or string as the data, since it will enforce that
31 // // there is only one singleton for that type, which will conflict. If
32 // // you're putting in some struct that's unique to you, go ahead.
33 // PropertyAccessor<int>* my_accessor() const {
34 // static PropertyAccessor<int>* accessor = NULL;
35 // if (!accessor) accessor = new PropertyAccessor<int>;
36 // return accessor;
37 // }
39 // void doit(SomeObjectThatImplementsPropertyBag* object) {
40 // PropertyAccessor<int>* accessor = my_accessor();
41 // int* property = accessor->GetProperty(object);
42 // if (property)
43 // ... use property ...
45 // accessor->SetProperty(object, 22);
46 // }
47 class BASE_EXPORT PropertyBag {
48 public:
49 // The type that uniquely identifies a property type.
50 typedef int PropID;
51 enum { NULL_PROP_ID = -1 }; // Invalid property ID.
53 // Properties are all derived from this class. They must be deletable and
54 // copyable
55 class Prop {
56 public:
57 virtual ~Prop() {}
59 // Copies the property and returns a pointer to the new one. The caller is
60 // responsible for managing the lifetime.
61 virtual Prop* copy() = 0;
64 PropertyBag();
65 PropertyBag(const PropertyBag& other);
66 virtual ~PropertyBag();
68 PropertyBag& operator=(const PropertyBag& other);
70 private:
71 friend class PropertyAccessorBase;
73 typedef std::map<PropID, linked_ptr<Prop> > PropertyMap;
75 // Used by the PropertyAccessor to set the property with the given ID.
76 // Ownership of the given pointer will be transferred to us. Any existing
77 // property matching the given ID will be deleted.
78 void SetProperty(PropID id, Prop* prop);
80 // Used by the PropertyAccessor to retrieve the property with the given ID.
81 // The returned pointer will be NULL if there is no match. Ownership of the
82 // pointer will stay with the property bag.
83 Prop* GetProperty(PropID id);
84 const Prop* GetProperty(PropID id) const;
86 // Deletes the property with the given ID from the bag if it exists.
87 void DeleteProperty(PropID id);
89 PropertyMap props_;
91 // Copy and assign is explicitly allowed for this class.
94 // PropertyAccessorBase -------------------------------------------------------
96 // Manages getting the unique IDs to identify a property. Callers should use
97 // PropertyAccessor below instead.
98 class BASE_EXPORT PropertyAccessorBase {
99 public:
100 PropertyAccessorBase();
101 virtual ~PropertyAccessorBase() {}
103 // Removes our property, if any, from the given property bag.
104 void DeleteProperty(PropertyBag* bag) {
105 bag->DeleteProperty(prop_id_);
108 protected:
109 void SetPropertyInternal(PropertyBag* bag, PropertyBag::Prop* prop) {
110 bag->SetProperty(prop_id_, prop);
112 PropertyBag::Prop* GetPropertyInternal(PropertyBag* bag) {
113 return bag->GetProperty(prop_id_);
115 const PropertyBag::Prop* GetPropertyInternal(const PropertyBag* bag) const {
116 return bag->GetProperty(prop_id_);
119 private:
120 // Identifier for this property.
121 PropertyBag::PropID prop_id_;
123 DISALLOW_COPY_AND_ASSIGN(PropertyAccessorBase);
126 // PropertyAccessor -----------------------------------------------------------
128 // Provides typesafe accessor functions for a property bag, and manages the
129 // unique identifiers for properties via the PropertyAccessorBase.
130 template<class T>
131 class PropertyAccessor : public PropertyAccessorBase {
132 public:
133 PropertyAccessor() : PropertyAccessorBase() {}
134 virtual ~PropertyAccessor() {}
136 // Makes a copy of the |prop| object for storage.
137 void SetProperty(PropertyBag* bag, const T& prop) {
138 SetPropertyInternal(bag, new Container(prop));
141 // Returns our property in the given bag or NULL if there is no match. The
142 // returned pointer's ownership will stay with the property bag.
143 T* GetProperty(PropertyBag* bag) {
144 PropertyBag::Prop* prop = GetPropertyInternal(bag);
145 if (!prop)
146 return NULL;
147 return static_cast<Container*>(prop)->get();
149 const T* GetProperty(const PropertyBag* bag) const {
150 const PropertyBag::Prop* prop = GetPropertyInternal(bag);
151 if (!prop)
152 return NULL;
153 return static_cast<const Container*>(prop)->get();
156 // See also DeleteProperty on thn PropertyAccessorBase.
158 private:
159 class Container : public PropertyBag::Prop {
160 public:
161 explicit Container(const T& data) : data_(data) {}
163 T* get() { return &data_; }
164 const T* get() const { return &data_; }
166 private:
167 virtual Prop* copy() {
168 return new Container(data_);
171 T data_;
174 DISALLOW_COPY_AND_ASSIGN(PropertyAccessor);
177 } // namespace base
179 #endif // BASE_PROPERTY_BAG_H_