safe_map.h revision 2ac01fc279e8397beacf90302b0f215040eb78fa
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>,
30700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers          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:
3683cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::key_compare key_compare;
3783cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::allocator_type allocator_type;
3883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::iterator iterator;
3983cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::const_iterator const_iterator;
4083cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::size_type size_type;
4183cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  typedef typename ::std::map<K, V, Comparator, Allocator>::value_type value_type;
4283cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko
4383cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  SafeMap() = default;
4483cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  explicit SafeMap(const key_compare& cmp, const allocator_type& allocator = allocator_type())
4583cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko    : map_(cmp, allocator) {
4683cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko  }
47a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
48748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  Self& operator=(const Self& rhs) {
49748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes    map_ = rhs.map_;
50748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes    return *this;
51748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  }
52a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
53a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator begin() { return map_.begin(); }
54a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator begin() const { return map_.begin(); }
55a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator end() { return map_.end(); }
56a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator end() const { return map_.end(); }
57a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
58a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  bool empty() const { return map_.empty(); }
59a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type size() const { return map_.size(); }
60a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
6108f753d5859936f8d3524e9e4faa6cee353873eaIan Rogers  void clear() { map_.clear(); }
62a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void erase(iterator it) { map_.erase(it); }
63a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type erase(const K& k) { return map_.erase(k); }
64a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
65a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  iterator find(const K& k) { return map_.find(k); }
66a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  const_iterator find(const K& k) const { return map_.find(k); }
67a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
682ac01fc279e8397beacf90302b0f215040eb78faVladimir Marko  iterator lower_bound(const K& k) { return map_.lower_bound(k); }
692ac01fc279e8397beacf90302b0f215040eb78faVladimir Marko  const_iterator lower_bound(const K& k) const { return map_.lower_bound(k); }
702ac01fc279e8397beacf90302b0f215040eb78faVladimir Marko
71a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  size_type count(const K& k) const { return map_.count(k); }
72a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
73a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Note that unlike std::map's operator[], this doesn't return a reference to the value.
74b2eb5c18d628dc84bdc424b5e5a491382d867e36TDYa  V Get(const K& k) const {
75b2eb5c18d628dc84bdc424b5e5a491382d867e36TDYa    const_iterator it = map_.find(k);
76a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    DCHECK(it != map_.end());
77a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    return it->second;
78a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
79a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
80a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Used to insert a new mapping.
81a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void Put(const K& k, const V& v) {
82a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
837934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    DCHECK(result.second);  // Check we didn't accidentally overwrite an existing value.
84a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
85a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
86a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // Used to insert a new mapping or overwrite an existing mapping. Note that if the value type
87a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // of this container is a pointer, any overwritten pointer will be lost and if this container
88a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  // was the owner, you have a leak.
89a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  void Overwrite(const K& k, const V& v) {
90d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
91d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    if (!result.second) {
92d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee      // Already there - update the value for the existing key
93d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee      result.first->second = v;
94d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    }
95a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
96a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
97a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  bool Equals(const Self& rhs) const {
98a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    return map_ == rhs.map_;
99a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  }
100a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
101a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes private:
1020a9dc05e704bfd033bac2aa38a4fc6f6b8e6cf93Mathieu Chartier  ::std::map<K, V, Comparator, Allocator> map_;
103a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes};
104a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
105a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughestemplate <typename K, typename V, typename Comparator>
106a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesbool operator==(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
107a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return lhs.Equals(rhs);
108a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
109a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
110a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughestemplate <typename K, typename V, typename Comparator>
111a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesbool operator!=(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
112a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  return !(lhs == rhs);
113a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}
114a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
115a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes}  // namespace art
116a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes
117fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_SAFE_MAP_H_
118