1 : // Copyright (c) 2006-2008 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 :
5 : #ifndef BASE_ID_MAP_H__
6 : #define BASE_ID_MAP_H__
7 :
8 : #include "base/basictypes.h"
9 : #include "base/hash_tables.h"
10 : #include "base/logging.h"
11 :
12 : // This object maintains a list of IDs that can be quickly converted to
13 : // pointers to objects. It is implemented as a hash table, optimized for
14 : // relatively small data sets (in the common case, there will be exactly one
15 : // item in the list).
16 : //
17 : // Items can be inserted into the container with arbitrary ID, but the caller
18 : // must ensure they are unique. Inserting IDs and relying on automatically
19 : // generated ones is not allowed because they can collide.
20 : template<class T>
21 0 : class IDMap {
22 : private:
23 : typedef base::hash_map<int32, T*> HashTable;
24 : typedef typename HashTable::iterator iterator;
25 :
26 : public:
27 : // support const iterators over the items
28 : // Note, use iterator->first to get the ID, iterator->second to get the T*
29 : typedef typename HashTable::const_iterator const_iterator;
30 :
31 3 : IDMap() : next_id_(1) {
32 3 : }
33 : IDMap(const IDMap& other) : next_id_(other.next_id_),
34 : data_(other.data_) {
35 : }
36 :
37 0 : const_iterator begin() const {
38 0 : return data_.begin();
39 : }
40 0 : const_iterator end() const {
41 0 : return data_.end();
42 : }
43 :
44 : // Adds a view with an automatically generated unique ID. See AddWithID.
45 : int32 Add(T* data) {
46 : int32 this_id = next_id_;
47 : DCHECK(data_.find(this_id) == data_.end()) << "Inserting duplicate item";
48 : data_[this_id] = data;
49 : next_id_++;
50 : return this_id;
51 : }
52 :
53 : // Adds a new data member with the specified ID. The ID must not be in
54 : // the list. The caller either must generate all unique IDs itself and use
55 : // this function, or allow this object to generate IDs and call Add. These
56 : // two methods may not be mixed, or duplicate IDs may be generated
57 0 : void AddWithID(T* data, int32 id) {
58 0 : DCHECK(data_.find(id) == data_.end()) << "Inserting duplicate item";
59 0 : data_[id] = data;
60 0 : }
61 :
62 0 : void Remove(int32 id) {
63 0 : iterator i = data_.find(id);
64 0 : if (i == data_.end()) {
65 0 : NOTREACHED() << "Attempting to remove an item not in the list";
66 0 : return;
67 : }
68 0 : data_.erase(i);
69 : }
70 :
71 : bool IsEmpty() const {
72 : return data_.empty();
73 : }
74 :
75 0 : void Clear() {
76 0 : data_.clear();
77 0 : }
78 :
79 0 : bool HasData(const T* data) const {
80 : // XXX would like to use <algorithm> here ...
81 0 : for (const_iterator it = begin(); it != end(); ++it)
82 0 : if (data == it->second)
83 0 : return true;
84 0 : return false;
85 : }
86 :
87 0 : T* Lookup(int32 id) const {
88 0 : const_iterator i = data_.find(id);
89 0 : if (i == data_.end())
90 0 : return NULL;
91 0 : return i->second;
92 : }
93 :
94 : size_t size() const {
95 : return data_.size();
96 : }
97 :
98 : protected:
99 : // The next ID that we will return from Add()
100 : int32 next_id_;
101 :
102 : HashTable data_;
103 : };
104 :
105 : #endif // BASE_ID_MAP_H__
|