Add a SafeMap equivalent to std::map but without the error-prone operator[].
Change-Id: Iae5ba2091c55a34dbd1005cf3d25fce2a8d5c1f9
diff --git a/src/safe_map.h b/src/safe_map.h
new file mode 100644
index 0000000..1544181
--- /dev/null
+++ b/src/safe_map.h
@@ -0,0 +1,82 @@
+#ifndef ART_SRC_SAFE_MAP_H_
+#define ART_SRC_SAFE_MAP_H_
+
+#include <map>
+
+#include "logging.h"
+
+namespace art {
+
+// Equivalent to std::map, but without operator[] and its bug-prone semantics (in particular,
+// the implicit insertion of a default-constructed value on failed lookups).
+template <typename K, typename V, typename Comparator = std::less<K> >
+class SafeMap {
+ private:
+ typedef SafeMap<K, V, Comparator> Self;
+
+ public:
+ typedef typename ::std::map<K, V, Comparator>::iterator iterator;
+ typedef typename ::std::map<K, V, Comparator>::const_iterator const_iterator;
+ typedef typename ::std::map<K, V, Comparator>::size_type size_type;
+ typedef typename ::std::map<K, V, Comparator>::value_type value_type;
+
+ Self& operator=(const Self& rhs) { map_ = rhs.map_; return *this; }
+
+ iterator begin() { return map_.begin(); }
+ const_iterator begin() const { return map_.begin(); }
+ iterator end() { return map_.end(); }
+ const_iterator end() const { return map_.end(); }
+
+ bool empty() const { return map_.empty(); }
+ size_type size() const { return map_.size(); }
+
+ void clear() { return map_.clear(); }
+ void erase(iterator it) { map_.erase(it); }
+ size_type erase(const K& k) { return map_.erase(k); }
+
+ iterator find(const K& k) { return map_.find(k); }
+ const_iterator find(const K& k) const { return map_.find(k); }
+
+ size_type count(const K& k) const { return map_.count(k); }
+
+ // Note that unlike std::map's operator[], this doesn't return a reference to the value.
+ V Get(const K& k) {
+ iterator it = map_.find(k);
+ DCHECK(it != map_.end());
+ return it->second;
+ }
+
+ // Used to insert a new mapping.
+ void Put(const K& k, const V& v) {
+ std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
+ DCHECK(result.second); // Check we didn't accidentally overwrite an existing value.
+ }
+
+ // Used to insert a new mapping or overwrite an existing mapping. Note that if the value type
+ // of this container is a pointer, any overwritten pointer will be lost and if this container
+ // was the owner, you have a leak.
+ void Overwrite(const K& k, const V& v) {
+ map_.insert(std::make_pair(k, v));
+ }
+
+ bool Equals(const Self& rhs) const {
+ return map_ == rhs.map_;
+ }
+
+ private:
+ ::std::map<K, V, Comparator> map_;
+};
+
+template <typename K, typename V, typename Comparator>
+bool operator==(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
+ return lhs.Equals(rhs);
+}
+
+template <typename K, typename V, typename Comparator>
+bool operator!=(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace art
+
+#endif // ART_SRC_SAFE_MAP_H_