xref: /aosp_15_r20/external/tensorflow/tensorflow/compiler/xla/map_util.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #ifndef TENSORFLOW_COMPILER_XLA_MAP_UTIL_H_
17 #define TENSORFLOW_COMPILER_XLA_MAP_UTIL_H_
18 
19 #include <functional>
20 #include <sstream>
21 
22 #include "absl/container/flat_hash_map.h"
23 #include "absl/container/flat_hash_set.h"
24 #include "tensorflow/compiler/xla/statusor.h"
25 #include "tensorflow/compiler/xla/util.h"
26 #include "tensorflow/core/platform/logging.h"
27 
28 namespace xla {
29 
30 // FindOrDie returns a const reference to the value associated with
31 // the given key if it exists. Crashes otherwise.
32 //
33 // This is intended as a replacement for operator[] as an rvalue (for reading)
34 // when the key is guaranteed to exist.
35 template <class Collection>
FindOrDie(const Collection & collection,const typename Collection::value_type::first_type & key)36 const typename Collection::value_type::second_type& FindOrDie(
37     const Collection& collection,
38     const typename Collection::value_type::first_type& key) {
39   typename Collection::const_iterator it = collection.find(key);
40   CHECK(it != collection.end()) << "Map key not found: " << key;
41   return it->second;
42 }
43 
44 // Same as above, but returns a non-const reference.
45 template <class Collection>
FindOrDie(Collection & collection,const typename Collection::value_type::first_type & key)46 typename Collection::value_type::second_type& FindOrDie(
47     Collection& collection,  // NOLINT
48     const typename Collection::value_type::first_type& key) {
49   typename Collection::iterator it = collection.find(key);
50   CHECK(it != collection.end()) << "Map key not found: " << key;
51   return it->second;
52 }
53 
54 // Like FindOrDie but returns an error instead of dying if `key` is not in
55 // `container`.
56 template <class Collection>
57 StatusOr<
58     std::reference_wrapper<const typename Collection::value_type::second_type>>
MaybeFind(const Collection & collection,const typename Collection::value_type::first_type & key)59 MaybeFind(const Collection& collection,
60           const typename Collection::value_type::first_type& key) {
61   typename Collection::const_iterator it = collection.find(key);
62   if (it == collection.end()) {
63     std::ostringstream os;
64     os << key;
65     return NotFound("key not found: %s", os.str());
66   }
67   return {it->second};
68 }
69 
70 // Returns a const reference to the value associated with the given key if it
71 // exists, otherwise returns a const reference to the provided default value.
72 //
73 // WARNING: If a temporary object is passed as the default "value,"
74 // this function will return a reference to that temporary object,
75 // which will be destroyed at the end of the statement. A common
76 // example: if you have a map with string values, and you pass a char*
77 // as the default "value," either use the returned value immediately
78 // or store it in a string (not string&).
79 template <class Collection>
FindOrDefault(const Collection & collection,const typename Collection::value_type::first_type & key,const typename Collection::value_type::second_type & value)80 const typename Collection::value_type::second_type& FindOrDefault(
81     const Collection& collection,
82     const typename Collection::value_type::first_type& key,
83     const typename Collection::value_type::second_type& value) {
84   auto it = collection.find(key);
85   if (it != collection.end()) return it->second;
86   return value;
87 }
88 
89 // Inserts the key-value pair into the collection. Dies if key was already
90 // present.
91 template <class Collection, class Key, class Value>
InsertOrDie(Collection * const collection,Key && key,Value && value)92 void InsertOrDie(Collection* const collection, Key&& key, Value&& value) {
93   auto p = collection->insert(
94       std::make_pair(std::forward<Key>(key), std::forward<Value>(value)));
95   CHECK(p.second) << "duplicate key: " << key;
96 }
97 
98 // Returns true if and only if the given collection contains the given key.
99 template <class Collection, class Key>
ContainsKey(const Collection & collection,const Key & key)100 bool ContainsKey(const Collection& collection, const Key& key) {
101   return collection.find(key) != collection.end();
102 }
103 
104 // Returns a function that returns whether the map contains the given key.
105 template <class Key, class Value>
IsKeyIn(const absl::flat_hash_map<Key,Value> & map)106 auto IsKeyIn(const absl::flat_hash_map<Key, Value>& map) {
107   return [&](const Key& key) { return map.contains(key); };
108 }
109 
110 // Returns a function that returns whether the set contains the given value.
111 template <class T>
IsValueIn(const absl::flat_hash_set<T> & set)112 auto IsValueIn(const absl::flat_hash_set<T>& set) {
113   return [&](const T& value) { return set.contains(value); };
114 }
115 
116 // Inserts `value` into `set`. Dies if it was already present.
117 template <class Set, class Value>
InsertOrDie(Set * const set,Value && value)118 void InsertOrDie(Set* const set, Value&& value) {
119   CHECK(set->insert(std::forward<Value>(value)).second)
120       << "duplicate value: " << value;
121 }
122 
123 }  // namespace xla
124 
125 #endif  // TENSORFLOW_COMPILER_XLA_MAP_UTIL_H_
126