15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from google3/util/gtl/map-util.h
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: Anton Carver
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Perform a lookup in a map or hash_map.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the key is present in the map then the value associated with that
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// key is returned, otherwise the value passed as a default is returned.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Collection>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const typename Collection::value_type::second_type&
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindWithDefault(const Collection& collection,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const typename Collection::value_type::first_type& key,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const typename Collection::value_type::second_type& value) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typename Collection::const_iterator it = collection.find(key);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == collection.end()) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Perform a lookup in a map or hash_map.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the key is present a const pointer to the associated value is returned,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise a NULL pointer is returned.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Collection>
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const typename Collection::value_type::second_type*
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindOrNull(const Collection& collection,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           const typename Collection::value_type::first_type& key) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typename Collection::const_iterator it = collection.find(key);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == collection.end()) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &it->second;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Perform a lookup in a map or hash_map, assuming that the key exists.
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Crash if it does not.
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This is intended as a replacement for operator[] as an rvalue (for reading)
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// when the key is guaranteed to exist.
76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// operator[] is discouraged for several reasons:
78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  * It has a side-effect of inserting missing keys
79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  * It is not thread-safe (even when it is not inserting, it can still
80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//      choose to resize the underlying storage)
81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  * It invalidates iterators (when it chooses to resize)
82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  * It default constructs a value object even if it doesn't need to
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This version assumes the key is printable, and includes it in the fatal log
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// message.
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class Collection>
87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst typename Collection::value_type::second_type&
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFindOrDie(const Collection& collection,
89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          const typename Collection::value_type::first_type& key) {
90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  typename Collection::const_iterator it = collection.find(key);
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return it->second;
93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Perform a lookup in a map or hash_map whose values are pointers.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the key is present a const pointer to the associated value is returned,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise a NULL pointer is returned.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function does not distinguish between a missing key and a key mapped
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a NULL value.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Collection>
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const typename Collection::value_type::second_type
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindPtrOrNull(const Collection& collection,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const typename Collection::value_type::first_type& key) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typename Collection::const_iterator it = collection.find(key);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == collection.end()) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Change the value associated with a particular key in a map or hash_map.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the key is not present in the map the key and value are inserted,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// otherwise the value is updated to be a copy of the value provided.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// True indicates that an insert took place, false indicates an update.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Collection, class Key, class Value>
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InsertOrUpdate(Collection * const collection,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   const Key& key, const Value& value) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pair<typename Collection::iterator, bool> ret =
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    collection->insert(typename Collection::value_type(key, value));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ret.second) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // update
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret.first->second = value;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Insert a new key and value into a map or hash_map.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the key is not present in the map the key and value are
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// inserted, otherwise nothing happens. True indicates that an insert
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// took place, false indicates the key was already present.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class Collection, class Key, class Value>
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InsertIfNotPresent(Collection * const collection,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const Key& key, const Value& value) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pair<typename Collection::iterator, bool> ret =
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    collection->insert(typename Collection::value_type(key, value));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret.second;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
144