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