1 /*
2  * Copyright (C) 2014 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_LIBARTBASE_BASE_HASH_MAP_H_
18 #define ART_LIBARTBASE_BASE_HASH_MAP_H_
19 
20 #include <utility>
21 
22 #include "hash_set.h"
23 
24 namespace art {
25 
26 template <typename Key, typename Value, typename HashFn>
27 class HashMapHashWrapper {
28  public:
operator()29   size_t operator()(const Key& key) const {
30     return hash_fn_(key);
31   }
32 
operator()33   size_t operator()(const std::pair<Key, Value>& pair) const {
34     return hash_fn_(pair.first);
35   }
36 
37  private:
38   HashFn hash_fn_;
39 };
40 
41 template <typename Key, typename Value, typename PredFn>
42 class HashMapPredWrapper {
43  public:
operator()44   bool operator()(const std::pair<Key, Value>& a, const std::pair<Key, Value>& b) const {
45     return pred_fn_(a.first, b.first);
46   }
47 
48   template <typename Element>
operator()49   bool operator()(const std::pair<Key, Value>& a, const Element& element) const {
50     return pred_fn_(a.first, element);
51   }
52 
53  private:
54   PredFn pred_fn_;
55 };
56 
57 template <typename Key, typename Value>
58 class DefaultMapEmptyFn {
59  public:
MakeEmpty(std::pair<Key,Value> & item)60   void MakeEmpty(std::pair<Key, Value>& item) const {
61     item = std::pair<Key, Value>();
62   }
IsEmpty(const std::pair<Key,Value> & item)63   bool IsEmpty(const std::pair<Key, Value>& item) const {
64     return item.first == Key();
65   }
66 };
67 
68 template <class Key,
69           class Value,
70           class EmptyFn = DefaultMapEmptyFn<Key, Value>,
71           class HashFn = DefaultHashFn<Key>,
72           class Pred = DefaultPred<Key>,
73           class Alloc = std::allocator<std::pair<Key, Value>>>
74 class HashMap : public HashSet<std::pair<Key, Value>,
75                                EmptyFn,
76                                HashMapHashWrapper<Key, Value, HashFn>,
77                                HashMapPredWrapper<Key, Value, Pred>,
78                                Alloc> {
79  private:
80   using Base = HashSet<std::pair<Key, Value>,
81                        EmptyFn,
82                        HashMapHashWrapper<Key, Value, HashFn>,
83                        HashMapPredWrapper<Key, Value, Pred>,
84                        Alloc>;
85 
86  public:
87   // Inherit constructors.
88   using Base::Base;
89 
90   // Used to insert a new mapping.
Overwrite(const Key & k,const Value & v)91   typename Base::iterator Overwrite(const Key& k, const Value& v) {
92     auto res = Base::insert({ k, v }).first;
93     *res = { k, v };
94     return res;
95   }
96 };
97 
98 }  // namespace art
99 
100 #endif  // ART_LIBARTBASE_BASE_HASH_MAP_H_
101