|  | // Copyright 2023 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef BASE_CONTAINERS_MAP_UTIL_H_ | 
|  | #define BASE_CONTAINERS_MAP_UTIL_H_ | 
|  |  | 
|  | #include <memory> | 
|  |  | 
|  | #include "base/types/to_address.h" | 
|  |  | 
|  | namespace base { | 
|  |  | 
|  | namespace internal { | 
|  |  | 
|  | template <typename Map> | 
|  | using MappedType = typename Map::mapped_type; | 
|  |  | 
|  | }  // namespace internal | 
|  |  | 
|  | // Returns a pointer to the const value associated with the given key if it | 
|  | // exists, or null otherwise. | 
|  | template <typename Map, typename Key = Map::key_type> | 
|  | constexpr const internal::MappedType<Map>* FindOrNull(const Map& map, | 
|  | const Key& key) { | 
|  | auto it = map.find(key); | 
|  | return it != map.end() ? &it->second : nullptr; | 
|  | } | 
|  |  | 
|  | // Returns a pointer to the value associated with the given key if it exists, or | 
|  | // null otherwise. | 
|  | template <typename Map, typename Key = Map::key_type> | 
|  | constexpr internal::MappedType<Map>* FindOrNull(Map& map, const Key& key) { | 
|  | auto it = map.find(key); | 
|  | return it != map.end() ? &it->second : nullptr; | 
|  | } | 
|  |  | 
|  | // Returns the const pointer value associated with the given key. If none is | 
|  | // found, null is returned. The function is designed to be used with a map of | 
|  | // keys to pointers or smart pointers. | 
|  | // | 
|  | // This function does not distinguish between a missing key and a key mapped | 
|  | // to a null value. | 
|  | template <typename Map, | 
|  | typename Key = Map::key_type, | 
|  | typename MappedElementType = | 
|  | std::pointer_traits<internal::MappedType<Map>>::element_type> | 
|  | constexpr const MappedElementType* FindPtrOrNull(const Map& map, | 
|  | const Key& key) { | 
|  | auto it = map.find(key); | 
|  | return it != map.end() ? base::to_address(it->second) : nullptr; | 
|  | } | 
|  |  | 
|  | // Returns the pointer value associated with the given key. If none is found, | 
|  | // null is returned. The function is designed to be used with a map of keys to | 
|  | // pointers or smart pointers. | 
|  | // | 
|  | // This function does not distinguish between a missing key and a key mapped | 
|  | // to a null value. | 
|  | template <typename Map, | 
|  | typename Key = Map::key_type, | 
|  | typename MappedElementType = | 
|  | std::pointer_traits<internal::MappedType<Map>>::element_type> | 
|  | constexpr MappedElementType* FindPtrOrNull(Map& map, const Key& key) { | 
|  | auto it = map.find(key); | 
|  | return it != map.end() ? base::to_address(it->second) : nullptr; | 
|  | } | 
|  |  | 
|  | // Insert or assign into a map type. This has semantics very similar to the | 
|  | // following statements: | 
|  | // | 
|  | //    map[key] = Element(params...) | 
|  | //    map[key] = element; | 
|  | //    map[key] = std::move(element); | 
|  | //    map.insert_or_assign(key, element); | 
|  | // | 
|  | // Where key can be any heterogeneous comparable overload of the key_type for | 
|  | // map. In particular, there is no need to construct a temporary `key` of the | 
|  | // type stored in the map as long as `key` is comparable with the | 
|  | // `Map::key_type`. | 
|  | // | 
|  | // The `element` is copied or moved into the map, depending on whether it is | 
|  | // passed by lvalue or rvalue reference. | 
|  | // | 
|  | // TODO(crbug.com/376532871): This can be removed once map::operator[] and | 
|  | // map::insert_or_assign support heterogenous key overloads, in C++26. | 
|  | template <typename Map, | 
|  | typename Key, | 
|  | typename MappedElementType = | 
|  | std::pointer_traits<internal::MappedType<Map>>::element_type> | 
|  | Map::iterator InsertOrAssign(Map& map, | 
|  | const Key& key, | 
|  | MappedElementType&& element) { | 
|  | auto it = map.lower_bound(key); | 
|  | if (it == map.end() || it->first != key) { | 
|  | it = map.emplace_hint(it, key, std::forward<MappedElementType>(element)); | 
|  | } else { | 
|  | it->second = std::forward<MappedElementType>(element); | 
|  | } | 
|  | return it; | 
|  | } | 
|  |  | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_CONTAINERS_MAP_UTIL_H_ |