safe_map.h revision 7934ac288acfb2552bb0b06ec1f61e5820d924a4
1748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes/*
2748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * Copyright (C) 2012 The Android Open Source Project
3748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes *
4748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
5748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * you may not use this file except in compliance with the License.
6748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * You may obtain a copy of the License at
7748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes *
8748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
9748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes *
10748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * Unless required by applicable law or agreed to in writing, software
11748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
12748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * See the License for the specific language governing permissions and
14748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes * limitations under the License.
15748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes */
16748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_SAFE_MAP_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_SAFE_MAP_H_
19a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
20a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include <map>
210a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartier#include <memory>
22a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
2307ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
24a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
25a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesnamespace art {
26a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
27a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes// Equivalent to std::map, but without operator[] and its bug-prone semantics (in particular,
28a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes// the implicit insertion of a default-constructed value on failed lookups).
290a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartiertemplate <typename K, typename V, typename Comparator = std::less<K>,
300a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartier          typename Allocator = std::allocator<std::pair<const K, V> > >
31a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesclass SafeMap {
32a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes private:
330a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartier  typedef SafeMap<K, V, Comparator, Allocator> Self;
34a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
35a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes public:
36a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  typedef typename ::std::map<K, V, Comparator>::iterator iterator;
37a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  typedef typename ::std::map<K, V, Comparator>::const_iterator const_iterator;
38a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  typedef typename ::std::map<K, V, Comparator>::size_type size_type;
39a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  typedef typename ::std::map<K, V, Comparator>::value_type value_type;
40a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
41748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  Self& operator=(const Self& rhs) {
42748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes    map_ = rhs.map_;
43748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes    return *this;
44748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  }
45a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
46a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator begin() { return map_.begin(); }
47a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator begin() const { return map_.begin(); }
48a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator end() { return map_.end(); }
49a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator end() const { return map_.end(); }
50a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
51a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  bool empty() const { return map_.empty(); }
52a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type size() const { return map_.size(); }
53a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
5408f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  void clear() { map_.clear(); }
55a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void erase(iterator it) { map_.erase(it); }
56a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type erase(const K& k) { return map_.erase(k); }
57a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
58a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator find(const K& k) { return map_.find(k); }
59a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator find(const K& k) const { return map_.find(k); }
60a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
61a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type count(const K& k) const { return map_.count(k); }
62a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
63a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Note that unlike std::map's operator[], this doesn't return a reference to the value.
64b2eb5c18d628dc84bdc424b5e5a491382d867e36TDYa  V Get(const K& k) const {
65b2eb5c18d628dc84bdc424b5e5a491382d867e36TDYa    const_iterator it = map_.find(k);
66a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    DCHECK(it != map_.end());
67a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    return it->second;
68a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
69a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
70a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Used to insert a new mapping.
71a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void Put(const K& k, const V& v) {
72a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
737934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    DCHECK(result.second);  // Check we didn't accidentally overwrite an existing value.
74a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
75a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
76a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Used to insert a new mapping or overwrite an existing mapping. Note that if the value type
77a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // of this container is a pointer, any overwritten pointer will be lost and if this container
78a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // was the owner, you have a leak.
79a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void Overwrite(const K& k, const V& v) {
80d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
81d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    if (!result.second) {
82d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee      // Already there - update the value for the existing key
83d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee      result.first->second = v;
84d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    }
85a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
86a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
87a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  bool Equals(const Self& rhs) const {
88a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    return map_ == rhs.map_;
89a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
90a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
91a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes private:
920a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartier  ::std::map<K, V, Comparator, Allocator> map_;
93a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes};
94a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
95a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughestemplate <typename K, typename V, typename Comparator>
96a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesbool operator==(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
97a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return lhs.Equals(rhs);
98a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
99a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
100a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughestemplate <typename K, typename V, typename Comparator>
101a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesbool operator!=(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
102a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return !(lhs == rhs);
103a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
104a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
105a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}  // namespace art
106a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
107fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_SAFE_MAP_H_
108