Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_SAFE_MAP_H_
     18 #define ART_RUNTIME_SAFE_MAP_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 
     23 #include "base/logging.h"
     24 
     25 namespace art {
     26 
     27 // Equivalent to std::map, but without operator[] and its bug-prone semantics (in particular,
     28 // the implicit insertion of a default-constructed value on failed lookups).
     29 template <typename K, typename V, typename Comparator = std::less<K>,
     30           typename Allocator = std::allocator<std::pair<const K, V> > >
     31 class SafeMap {
     32  private:
     33   typedef SafeMap<K, V, Comparator, Allocator> Self;
     34 
     35  public:
     36   typedef typename ::std::map<K, V, Comparator>::iterator iterator;
     37   typedef typename ::std::map<K, V, Comparator>::const_iterator const_iterator;
     38   typedef typename ::std::map<K, V, Comparator>::size_type size_type;
     39   typedef typename ::std::map<K, V, Comparator>::value_type value_type;
     40 
     41   Self& operator=(const Self& rhs) {
     42     map_ = rhs.map_;
     43     return *this;
     44   }
     45 
     46   iterator begin() { return map_.begin(); }
     47   const_iterator begin() const { return map_.begin(); }
     48   iterator end() { return map_.end(); }
     49   const_iterator end() const { return map_.end(); }
     50 
     51   bool empty() const { return map_.empty(); }
     52   size_type size() const { return map_.size(); }
     53 
     54   void clear() { map_.clear(); }
     55   void erase(iterator it) { map_.erase(it); }
     56   size_type erase(const K& k) { return map_.erase(k); }
     57 
     58   iterator find(const K& k) { return map_.find(k); }
     59   const_iterator find(const K& k) const { return map_.find(k); }
     60 
     61   size_type count(const K& k) const { return map_.count(k); }
     62 
     63   // Note that unlike std::map's operator[], this doesn't return a reference to the value.
     64   V Get(const K& k) const {
     65     const_iterator it = map_.find(k);
     66     DCHECK(it != map_.end());
     67     return it->second;
     68   }
     69 
     70   // Used to insert a new mapping.
     71   void Put(const K& k, const V& v) {
     72     std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
     73     DCHECK(result.second);  // Check we didn't accidentally overwrite an existing value.
     74   }
     75 
     76   // Used to insert a new mapping or overwrite an existing mapping. Note that if the value type
     77   // of this container is a pointer, any overwritten pointer will be lost and if this container
     78   // was the owner, you have a leak.
     79   void Overwrite(const K& k, const V& v) {
     80     std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
     81     if (!result.second) {
     82       // Already there - update the value for the existing key
     83       result.first->second = v;
     84     }
     85   }
     86 
     87   bool Equals(const Self& rhs) const {
     88     return map_ == rhs.map_;
     89   }
     90 
     91  private:
     92   ::std::map<K, V, Comparator, Allocator> map_;
     93 };
     94 
     95 template <typename K, typename V, typename Comparator>
     96 bool operator==(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
     97   return lhs.Equals(rhs);
     98 }
     99 
    100 template <typename K, typename V, typename Comparator>
    101 bool operator!=(const SafeMap<K, V, Comparator>& lhs, const SafeMap<K, V, Comparator>& rhs) {
    102   return !(lhs == rhs);
    103 }
    104 
    105 }  // namespace art
    106 
    107 #endif  // ART_RUNTIME_SAFE_MAP_H_
    108