1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Protocol Buffers - Google's data interchange format
2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2008 Google Inc.  All rights reserved.
3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// http://code.google.com/p/protobuf/
4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Redistribution and use in source and binary forms, with or without
6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// modification, are permitted provided that the following conditions are
7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// met:
8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     * Redistributions of source code must retain the above copyright
10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// notice, this list of conditions and the following disclaimer.
11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     * Redistributions in binary form must reproduce the above
12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// copyright notice, this list of conditions and the following disclaimer
13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// in the documentation and/or other materials provided with the
14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// distribution.
15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// contributors may be used to endorse or promote products derived from
17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// this software without specific prior written permission.
18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
31ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// from google3/util/gtl/stl_util.h
32ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
33ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
34ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
35ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
36ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/common.h>
37ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
38ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace google {
39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace protobuf {
40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// STLDeleteContainerPointers()
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  For a range within a container of pointers, calls delete
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//  (non-array version) on these pointers.
44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// NOTE: for these three functions, we could just implement a DeleteObject
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// functor and then call for_each() on the range and functor, but this
46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// requires us to pull in all of algorithm.h, which seems expensive.
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// For hash_[multi]set, it is important that this deletes behind the iterator
48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// because the hash_set may call the hash function on the iterator when it is
49ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// advanced, which could result in the hash function trying to deference a
50ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// stale pointer.
51ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class ForwardIterator>
52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid STLDeleteContainerPointers(ForwardIterator begin,
53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                ForwardIterator end) {
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  while (begin != end) {
55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ForwardIterator temp = begin;
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ++begin;
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    delete *temp;
58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Inside Google, this function implements a horrible, disgusting hack in which
62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// we reach into the string's private implementation and resize it without
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// initializing the new bytes.  In some cases doing this can significantly
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// improve performance.  However, since it's totally non-portable it has no
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// place in open source code.  Feel free to fill this function in with your
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// own disgusting hack if you want the perf boost.
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochinline void STLStringResizeUninitialized(string* s, size_t new_size) {
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  s->resize(new_size);
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Return a mutable char* pointing to a string's internal buffer,
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// which may not be null-terminated. Writing through this pointer will
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// modify the string.
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// next call to a string method that invalidates iterators.
77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// As of 2006-04, there is no standard-blessed way of getting a
79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// mutable reference to a string's internal buffer. However, issue 530
80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// proposes this as the method. According to Matt Austern, this should
82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// already work on all current implementations.
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochinline char* string_as_array(string* str) {
84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return str->empty() ? NULL : &*str->begin();
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// STLDeleteElements() deletes all the elements in an STL container and clears
89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// the container.  This function is suitable for use with a vector, set,
90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// hash_set, or any other STL container which defines sensible begin(), end(),
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// and clear() methods.
92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// If container is NULL, this function is a no-op.
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// As an alternative to calling STLDeleteElements() directly, consider
96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// ElementDeleter (defined below), which ensures that your container's elements
97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// are deleted when the ElementDeleter goes out of scope.
98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T>
99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid STLDeleteElements(T *container) {
100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!container) return;
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  STLDeleteContainerPointers(container->begin(), container->end());
102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  container->clear();
103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Given an STL container consisting of (key, value) pairs, STLDeleteValues
106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// deletes all the "value" components and clears the container.  Does nothing
107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// in the case it's given a NULL pointer.
108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochtemplate <class T>
110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid STLDeleteValues(T *v) {
111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!v) return;
112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    delete i->second;
114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  v->clear();
116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace protobuf
119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace google
120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif  // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
122