security/sandbox/chromium/base/stl_util.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/chromium/base/stl_util.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,223 @@
     1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +// Derived from google3/util/gtl/stl_util.h
     1.9 +
    1.10 +#ifndef BASE_STL_UTIL_H_
    1.11 +#define BASE_STL_UTIL_H_
    1.12 +
    1.13 +#include <algorithm>
    1.14 +#include <functional>
    1.15 +#include <iterator>
    1.16 +#include <string>
    1.17 +#include <vector>
    1.18 +
    1.19 +#include "base/logging.h"
    1.20 +
    1.21 +// Clears internal memory of an STL object.
    1.22 +// STL clear()/reserve(0) does not always free internal memory allocated
    1.23 +// This function uses swap/destructor to ensure the internal memory is freed.
    1.24 +template<class T>
    1.25 +void STLClearObject(T* obj) {
    1.26 +  T tmp;
    1.27 +  tmp.swap(*obj);
    1.28 +  // Sometimes "T tmp" allocates objects with memory (arena implementation?).
    1.29 +  // Hence using additional reserve(0) even if it doesn't always work.
    1.30 +  obj->reserve(0);
    1.31 +}
    1.32 +
    1.33 +// For a range within a container of pointers, calls delete (non-array version)
    1.34 +// on these pointers.
    1.35 +// NOTE: for these three functions, we could just implement a DeleteObject
    1.36 +// functor and then call for_each() on the range and functor, but this
    1.37 +// requires us to pull in all of algorithm.h, which seems expensive.
    1.38 +// For hash_[multi]set, it is important that this deletes behind the iterator
    1.39 +// because the hash_set may call the hash function on the iterator when it is
    1.40 +// advanced, which could result in the hash function trying to deference a
    1.41 +// stale pointer.
    1.42 +template <class ForwardIterator>
    1.43 +void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end) {
    1.44 +  while (begin != end) {
    1.45 +    ForwardIterator temp = begin;
    1.46 +    ++begin;
    1.47 +    delete *temp;
    1.48 +  }
    1.49 +}
    1.50 +
    1.51 +// For a range within a container of pairs, calls delete (non-array version) on
    1.52 +// BOTH items in the pairs.
    1.53 +// NOTE: Like STLDeleteContainerPointers, it is important that this deletes
    1.54 +// behind the iterator because if both the key and value are deleted, the
    1.55 +// container may call the hash function on the iterator when it is advanced,
    1.56 +// which could result in the hash function trying to dereference a stale
    1.57 +// pointer.
    1.58 +template <class ForwardIterator>
    1.59 +void STLDeleteContainerPairPointers(ForwardIterator begin,
    1.60 +                                    ForwardIterator end) {
    1.61 +  while (begin != end) {
    1.62 +    ForwardIterator temp = begin;
    1.63 +    ++begin;
    1.64 +    delete temp->first;
    1.65 +    delete temp->second;
    1.66 +  }
    1.67 +}
    1.68 +
    1.69 +// For a range within a container of pairs, calls delete (non-array version) on
    1.70 +// the FIRST item in the pairs.
    1.71 +// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
    1.72 +template <class ForwardIterator>
    1.73 +void STLDeleteContainerPairFirstPointers(ForwardIterator begin,
    1.74 +                                         ForwardIterator end) {
    1.75 +  while (begin != end) {
    1.76 +    ForwardIterator temp = begin;
    1.77 +    ++begin;
    1.78 +    delete temp->first;
    1.79 +  }
    1.80 +}
    1.81 +
    1.82 +// For a range within a container of pairs, calls delete.
    1.83 +// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
    1.84 +// Deleting the value does not always invalidate the iterator, but it may
    1.85 +// do so if the key is a pointer into the value object.
    1.86 +template <class ForwardIterator>
    1.87 +void STLDeleteContainerPairSecondPointers(ForwardIterator begin,
    1.88 +                                          ForwardIterator end) {
    1.89 +  while (begin != end) {
    1.90 +    ForwardIterator temp = begin;
    1.91 +    ++begin;
    1.92 +    delete temp->second;
    1.93 +  }
    1.94 +}
    1.95 +
    1.96 +// To treat a possibly-empty vector as an array, use these functions.
    1.97 +// If you know the array will never be empty, you can use &*v.begin()
    1.98 +// directly, but that is undefined behaviour if |v| is empty.
    1.99 +template<typename T>
   1.100 +inline T* vector_as_array(std::vector<T>* v) {
   1.101 +  return v->empty() ? NULL : &*v->begin();
   1.102 +}
   1.103 +
   1.104 +template<typename T>
   1.105 +inline const T* vector_as_array(const std::vector<T>* v) {
   1.106 +  return v->empty() ? NULL : &*v->begin();
   1.107 +}
   1.108 +
   1.109 +// Return a mutable char* pointing to a string's internal buffer,
   1.110 +// which may not be null-terminated. Writing through this pointer will
   1.111 +// modify the string.
   1.112 +//
   1.113 +// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
   1.114 +// next call to a string method that invalidates iterators.
   1.115 +//
   1.116 +// As of 2006-04, there is no standard-blessed way of getting a
   1.117 +// mutable reference to a string's internal buffer. However, issue 530
   1.118 +// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
   1.119 +// proposes this as the method. According to Matt Austern, this should
   1.120 +// already work on all current implementations.
   1.121 +inline char* string_as_array(std::string* str) {
   1.122 +  // DO NOT USE const_cast<char*>(str->data())
   1.123 +  return str->empty() ? NULL : &*str->begin();
   1.124 +}
   1.125 +
   1.126 +// The following functions are useful for cleaning up STL containers whose
   1.127 +// elements point to allocated memory.
   1.128 +
   1.129 +// STLDeleteElements() deletes all the elements in an STL container and clears
   1.130 +// the container.  This function is suitable for use with a vector, set,
   1.131 +// hash_set, or any other STL container which defines sensible begin(), end(),
   1.132 +// and clear() methods.
   1.133 +//
   1.134 +// If container is NULL, this function is a no-op.
   1.135 +//
   1.136 +// As an alternative to calling STLDeleteElements() directly, consider
   1.137 +// STLElementDeleter (defined below), which ensures that your container's
   1.138 +// elements are deleted when the STLElementDeleter goes out of scope.
   1.139 +template <class T>
   1.140 +void STLDeleteElements(T* container) {
   1.141 +  if (!container)
   1.142 +    return;
   1.143 +  STLDeleteContainerPointers(container->begin(), container->end());
   1.144 +  container->clear();
   1.145 +}
   1.146 +
   1.147 +// Given an STL container consisting of (key, value) pairs, STLDeleteValues
   1.148 +// deletes all the "value" components and clears the container.  Does nothing
   1.149 +// in the case it's given a NULL pointer.
   1.150 +template <class T>
   1.151 +void STLDeleteValues(T* container) {
   1.152 +  if (!container)
   1.153 +    return;
   1.154 +  for (typename T::iterator i(container->begin()); i != container->end(); ++i)
   1.155 +    delete i->second;
   1.156 +  container->clear();
   1.157 +}
   1.158 +
   1.159 +
   1.160 +// The following classes provide a convenient way to delete all elements or
   1.161 +// values from STL containers when they goes out of scope.  This greatly
   1.162 +// simplifies code that creates temporary objects and has multiple return
   1.163 +// statements.  Example:
   1.164 +//
   1.165 +// vector<MyProto *> tmp_proto;
   1.166 +// STLElementDeleter<vector<MyProto *> > d(&tmp_proto);
   1.167 +// if (...) return false;
   1.168 +// ...
   1.169 +// return success;
   1.170 +
   1.171 +// Given a pointer to an STL container this class will delete all the element
   1.172 +// pointers when it goes out of scope.
   1.173 +template<class T>
   1.174 +class STLElementDeleter {
   1.175 + public:
   1.176 +  STLElementDeleter<T>(T* container) : container_(container) {}
   1.177 +  ~STLElementDeleter<T>() { STLDeleteElements(container_); }
   1.178 +
   1.179 + private:
   1.180 +  T* container_;
   1.181 +};
   1.182 +
   1.183 +// Given a pointer to an STL container this class will delete all the value
   1.184 +// pointers when it goes out of scope.
   1.185 +template<class T>
   1.186 +class STLValueDeleter {
   1.187 + public:
   1.188 +  STLValueDeleter<T>(T* container) : container_(container) {}
   1.189 +  ~STLValueDeleter<T>() { STLDeleteValues(container_); }
   1.190 +
   1.191 + private:
   1.192 +  T* container_;
   1.193 +};
   1.194 +
   1.195 +// Test to see if a set, map, hash_set or hash_map contains a particular key.
   1.196 +// Returns true if the key is in the collection.
   1.197 +template <typename Collection, typename Key>
   1.198 +bool ContainsKey(const Collection& collection, const Key& key) {
   1.199 +  return collection.find(key) != collection.end();
   1.200 +}
   1.201 +
   1.202 +namespace base {
   1.203 +
   1.204 +// Returns true if the container is sorted.
   1.205 +template <typename Container>
   1.206 +bool STLIsSorted(const Container& cont) {
   1.207 +  return std::adjacent_find(cont.begin(), cont.end(),
   1.208 +                            std::greater<typename Container::value_type>())
   1.209 +      == cont.end();
   1.210 +}
   1.211 +
   1.212 +// Returns a new ResultType containing the difference of two sorted containers.
   1.213 +template <typename ResultType, typename Arg1, typename Arg2>
   1.214 +ResultType STLSetDifference(const Arg1& a1, const Arg2& a2) {
   1.215 +  DCHECK(STLIsSorted(a1));
   1.216 +  DCHECK(STLIsSorted(a2));
   1.217 +  ResultType difference;
   1.218 +  std::set_difference(a1.begin(), a1.end(),
   1.219 +                      a2.begin(), a2.end(),
   1.220 +                      std::inserter(difference, difference.end()));
   1.221 +  return difference;
   1.222 +}
   1.223 +
   1.224 +}  // namespace base
   1.225 +
   1.226 +#endif  // BASE_STL_UTIL_H_

mercurial