// This file provides utility functions for use with STL map-like data // structures, such as std::map and hash_map. Some functions will also work with // sets, such as ContainsKey(). #ifndef TENSORFLOW_LIB_GTL_MAP_UTIL_H_ #define TENSORFLOW_LIB_GTL_MAP_UTIL_H_ #include #include #include #include #include #include namespace tensorflow { namespace gtl { // Returns a pointer to the const value associated with the given key if it // exists, or NULL otherwise. template const typename Collection::value_type::second_type* FindOrNull( const Collection& collection, const typename Collection::value_type::first_type& key) { typename Collection::const_iterator it = collection.find(key); if (it == collection.end()) { return 0; } return &it->second; } // Same as above but returns a pointer to the non-const value. template typename Collection::value_type::second_type* FindOrNull( Collection& collection, // NOLINT const typename Collection::value_type::first_type& key) { typename Collection::iterator it = collection.find(key); if (it == collection.end()) { return 0; } return &it->second; } // 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. // // This function does not distinguish between a missing key and a key mapped // to a NULL value. template typename Collection::value_type::second_type FindPtrOrNull( const Collection& collection, const typename Collection::value_type::first_type& key) { typename Collection::const_iterator it = collection.find(key); if (it == collection.end()) { return typename Collection::value_type::second_type(); } return it->second; } // Returns a const reference to the value associated with the given key if it // exists, otherwise returns a const reference to the provided default value. // // WARNING: If a temporary object is passed as the default "value," // this function will return a reference to that temporary object, // which will be destroyed at the end of the statement. A common // example: if you have a map with string values, and you pass a char* // as the default "value," either use the returned value immediately // or store it in a string (not string&). template const typename Collection::value_type::second_type& FindWithDefault( const Collection& collection, const typename Collection::value_type::first_type& key, const typename Collection::value_type::second_type& value) { typename Collection::const_iterator it = collection.find(key); if (it == collection.end()) { return value; } return it->second; } // Inserts the given key and value into the given collection if and only if the // given key did NOT already exist in the collection. If the key previously // existed in the collection, the value is not changed. Returns true if the // key-value pair was inserted; returns false if the key was already present. template bool InsertIfNotPresent(Collection* const collection, const typename Collection::value_type& vt) { return collection->insert(vt).second; } // Same as above except the key and value are passed separately. template bool InsertIfNotPresent( Collection* const collection, const typename Collection::value_type::first_type& key, const typename Collection::value_type::second_type& value) { return InsertIfNotPresent(collection, typename Collection::value_type(key, value)); } // Looks up a given key and value pair in a collection and inserts the key-value // pair if it's not already present. Returns a reference to the value associated // with the key. template typename Collection::value_type::second_type& LookupOrInsert( Collection* const collection, const typename Collection::value_type& vt) { return collection->insert(vt).first->second; } // Same as above except the key-value are passed separately. template typename Collection::value_type::second_type& LookupOrInsert( Collection* const collection, const typename Collection::value_type::first_type& key, const typename Collection::value_type::second_type& value) { return LookupOrInsert(collection, typename Collection::value_type(key, value)); } } // namespace gtl } // namespace tensorflow #endif // TENSORFLOW_LIB_GTL_MAP_UTIL_H_