OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_ |
| 6 #define MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_ |
| 7 |
| 8 #include <stddef.h> |
| 9 #include <utility> |
| 10 |
| 11 #include "base/macros.h" |
| 12 #include "mojo/public/cpp/bindings/lib/template_util.h" |
| 13 #include "mojo/public/cpp/bindings/type_converter.h" |
| 14 #include "third_party/WebKit/Source/wtf/HashMap.h" |
| 15 #include "third_party/WebKit/Source/wtf/text/StringHash.h" |
| 16 |
| 17 namespace mojo { |
| 18 |
| 19 // Represents a map backed by WTF::HashMap. Comparing with WTF::HashMap, |
| 20 // mojo::WTFMap is move-only and can be null. |
| 21 // |
| 22 // It is easy to convert between WTF::HashMap<K, V> and mojo::WTFMap<K, V>: |
| 23 // - constructor WTFMap(WTF::HashMap<K, V>&&) takes the contents of a |
| 24 // WTF::HashMap<K, V>; |
| 25 // - method PassStorage() passes the underlying WTF::HashMap. |
| 26 // |
| 27 // NOTE: WTF::HashMap disallows certain key values. For integer types, those are |
| 28 // 0 and -1 (max value instead of -1 for unsigned). For string, that is null. |
| 29 template <typename Key, typename Value> |
| 30 class WTFMap { |
| 31 public: |
| 32 using Iterator = typename WTF::HashMap<Key, Value>::iterator; |
| 33 using ConstIterator = typename WTF::HashMap<Key, Value>::const_iterator; |
| 34 |
| 35 // Constructs an empty map. |
| 36 WTFMap() : is_null_(false) {} |
| 37 // Constructs a null map. |
| 38 WTFMap(std::nullptr_t null_pointer) : is_null_(true) {} |
| 39 |
| 40 ~WTFMap() {} |
| 41 |
| 42 WTFMap(WTF::HashMap<Key, Value>&& other) |
| 43 : map_(std::move(other)), is_null_(false) {} |
| 44 WTFMap(WTFMap&& other) : is_null_(true) { Take(&other); } |
| 45 |
| 46 WTFMap& operator=(WTF::HashMap<Key, Value>&& other) { |
| 47 is_null_ = false; |
| 48 map_ = std::move(other); |
| 49 return *this; |
| 50 } |
| 51 WTFMap& operator=(WTFMap&& other) { |
| 52 Take(&other); |
| 53 return *this; |
| 54 } |
| 55 |
| 56 WTFMap& operator=(std::nullptr_t null_pointer) { |
| 57 is_null_ = true; |
| 58 map_.clear(); |
| 59 return *this; |
| 60 } |
| 61 |
| 62 static bool IsValidKey(const Key& key) { |
| 63 return WTF::HashMap<Key, Value>::isValidKey(key); |
| 64 } |
| 65 |
| 66 // Copies the contents of some other type of map into a new WTFMap using a |
| 67 // TypeConverter. |
| 68 template <typename U> |
| 69 static WTFMap From(const U& other) { |
| 70 return TypeConverter<WTFMap, U>::Convert(other); |
| 71 } |
| 72 |
| 73 // Copies the contents of the WTFMap into some other type of map. |
| 74 template <typename U> |
| 75 U To() const { |
| 76 return TypeConverter<U, WTFMap>::Convert(*this); |
| 77 } |
| 78 |
| 79 // Indicates whether the map is null (which is distinct from empty). |
| 80 bool is_null() const { return is_null_; } |
| 81 |
| 82 // Indicates whether the map is empty (which is distinct from null). |
| 83 bool empty() const { return map_.isEmpty() && !is_null_; } |
| 84 |
| 85 // Indicates the number of keys in the map, which will be zero if the map is |
| 86 // null. |
| 87 size_t size() const { return map_.size(); } |
| 88 |
| 89 // Inserts a key-value pair into the map. Like WTF::HashMap::add(), this does |
| 90 // not insert |value| if |key| is already a member of the map. |
| 91 void insert(const Key& key, const Value& value) { |
| 92 is_null_ = false; |
| 93 map_.add(key, value); |
| 94 } |
| 95 void insert(const Key& key, Value&& value) { |
| 96 is_null_ = false; |
| 97 map_.add(key, std::move(value)); |
| 98 } |
| 99 |
| 100 // Returns a reference to the value associated with the specified key, |
| 101 // crashing the process if the key is not present in the map. |
| 102 Value& at(const Key& key) { return map_.find(key)->value; } |
| 103 const Value& at(const Key& key) const { return map_.find(key)->value; } |
| 104 |
| 105 // Returns a reference to the value associated with the specified key, |
| 106 // creating a new entry if the key is not already present in the map. A |
| 107 // newly-created value will be value-initialized (meaning that it will be |
| 108 // initialized by the default constructor of the value type, if any, or else |
| 109 // will be zero-initialized). |
| 110 Value& operator[](const Key& key) { |
| 111 is_null_ = false; |
| 112 if (!map_.contains(key)) |
| 113 map_.add(key, Value()); |
| 114 return at(key); |
| 115 } |
| 116 |
| 117 // Sets the map to empty (even if previously it was null). |
| 118 void SetToEmpty() { |
| 119 is_null_ = false; |
| 120 map_.clear(); |
| 121 } |
| 122 |
| 123 // Returns a const reference to the WTF::HashMap managed by this class. If |
| 124 // this object is null, the return value will be an empty map. |
| 125 const WTF::HashMap<Key, Value>& storage() const { return map_; } |
| 126 |
| 127 // Passes the underlying storage and resets this map to null. |
| 128 WTF::HashMap<Key, Value> PassStorage() { |
| 129 is_null_ = true; |
| 130 return std::move(map_); |
| 131 } |
| 132 |
| 133 // Swaps the contents of this WTFMap with another WTFMap of the same type |
| 134 // (including nullness). |
| 135 void Swap(WTFMap<Key, Value>* other) { |
| 136 std::swap(is_null_, other->is_null_); |
| 137 map_.swap(other->map_); |
| 138 } |
| 139 |
| 140 // Swaps the contents of this WTFMap with an WTF::HashMap containing keys and |
| 141 // values of the same type. Since WTF::HashMap cannot represent the null |
| 142 // state, the WTF::HashMap will be empty if WTFMap is null. The WTFMap will |
| 143 // always be left in a non-null state. |
| 144 void Swap(WTF::HashMap<Key, Value>* other) { |
| 145 is_null_ = false; |
| 146 map_.swap(*other); |
| 147 } |
| 148 |
| 149 // Returns a new WTFMap that contains a copy of the contents of this map. If |
| 150 // the key/value type defines a Clone() method, it will be used; otherwise |
| 151 // copy constructor/assignment will be used. |
| 152 // |
| 153 // Please note that calling this method will fail compilation if the key/value |
| 154 // type cannot be cloned (which usually means that it is a Mojo handle type or |
| 155 // a type containing Mojo handles). |
| 156 WTFMap Clone() const { |
| 157 WTFMap result; |
| 158 result.is_null_ = is_null_; |
| 159 auto map_end = map_.end(); |
| 160 for (auto it = map_.begin(); it != map_end; ++it) |
| 161 result.map_.add(internal::Clone(it->key), internal::Clone(it->value)); |
| 162 return result; |
| 163 } |
| 164 |
| 165 // Indicates whether the contents of this map are equal to those of another |
| 166 // WTFMap (including nullness). If the key/value type defines an Equals() |
| 167 // method, it will be used; otherwise == operator will be used. |
| 168 bool Equals(const WTFMap& other) const { |
| 169 if (is_null() != other.is_null()) |
| 170 return false; |
| 171 if (size() != other.size()) |
| 172 return false; |
| 173 |
| 174 auto this_end = map_.end(); |
| 175 auto other_end = other.map_.end(); |
| 176 |
| 177 for (auto iter = map_.begin(); iter != this_end; ++iter) { |
| 178 auto other_iter = other.map_.find(iter->key); |
| 179 if (other_iter == other_end || |
| 180 !internal::Equals(iter->value, other_iter->value)) { |
| 181 return false; |
| 182 } |
| 183 } |
| 184 return true; |
| 185 } |
| 186 |
| 187 ConstIterator begin() const { return map_.begin(); } |
| 188 Iterator begin() { return map_.begin(); } |
| 189 |
| 190 ConstIterator end() const { return map_.end(); } |
| 191 Iterator end() { return map_.end(); } |
| 192 |
| 193 // Returns the iterator pointing to the entry for |key|, if present, or else |
| 194 // returns end(). |
| 195 ConstIterator find(const Key& key) const { return map_.find(key); } |
| 196 Iterator find(const Key& key) { return map_.find(key); } |
| 197 |
| 198 explicit operator bool() const { return !is_null_; } |
| 199 |
| 200 private: |
| 201 void Take(WTFMap* other) { |
| 202 operator=(nullptr); |
| 203 Swap(other); |
| 204 } |
| 205 |
| 206 WTF::HashMap<Key, Value> map_; |
| 207 bool is_null_; |
| 208 |
| 209 DISALLOW_COPY_AND_ASSIGN(WTFMap); |
| 210 }; |
| 211 |
| 212 } // namespace mojo |
| 213 |
| 214 #endif // MOJO_PUBLIC_CPP_BINDINGS_WTF_MAP_H_ |
OLD | NEW |