// Copyright 2002 Google Inc.
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// ---
//
//
// STL utility functions.  Usually, these replace built-in, but slow(!),
// STL functions with more efficient versions or provide a more convenient
// and Google friendly API.
//

#ifndef UTIL_GTL_STL_UTIL_H_
#define UTIL_GTL_STL_UTIL_H_

#include <stddef.h>
#include <string.h>  // for memcpy
#include <algorithm>
using std::copy;
using std::max;
using std::min;
using std::reverse;
using std::sort;
using std::swap;
#include <cassert>
#include <deque>
using std::deque;
#include <functional>
using std::binary_function;
using std::less;
#include <iterator>
using std::back_insert_iterator;
using std::iterator_traits;
#include <memory>
#include <string>
using std::string;
#include <vector>
using std::vector;

#include "gutil/integral_types.h"
#include "gutil/macros.h"
#include "gutil/port.h"

// Sort and remove duplicates of an STL vector or deque.
template<class T>
void STLSortAndRemoveDuplicates(T *v) {
  sort(v->begin(), v->end());
  v->erase(unique(v->begin(), v->end()), v->end());
}

// Clear internal memory of an STL object.
// STL clear()/reserve(0) does not always free internal memory allocated
// This function uses swap/destructor to ensure the internal memory is freed.
template<class T> void STLClearObject(T* obj) {
  T tmp;
  tmp.swap(*obj);
  obj->reserve(0);  // this is because sometimes "T tmp" allocates objects with
                    // memory (arena implementation?).  use reserve()
                    // to clear() even if it doesn't always work
}

// Specialization for deque. Same as STLClearObject but doesn't call reserve
// since deque doesn't have reserve.
template <class T, class A>
void STLClearObject(deque<T, A>* obj) {
  deque<T, A> tmp;
  tmp.swap(*obj);
}

// Reduce memory usage on behalf of object if its capacity is greater
// than or equal to "limit", which defaults to 2^20.
template <class T> inline void STLClearIfBig(T* obj, size_t limit = 1<<20) {
  if (obj->capacity() >= limit) {
    STLClearObject(obj);
  } else {
    obj->clear();
  }
}

// Specialization for deque, which doesn't implement capacity().
template <class T, class A>
inline void STLClearIfBig(deque<T, A>* obj, size_t limit = 1<<20) {
  if (obj->size() >= limit) {
    STLClearObject(obj);
  } else {
    obj->clear();
  }
}

// Reduce the number of buckets in a hash_set or hash_map back to the
// default if the current number of buckets is "limit" or more.
//
// Suppose you repeatedly fill and clear a hash_map or hash_set.  If
// you ever insert a lot of items, then your hash table will have lots
// of buckets thereafter.  (The number of buckets is not reduced when
// the table is cleared.)  Having lots of buckets is good if you
// insert comparably many items in every iteration, because you'll
// reduce collisions and table resizes.  But having lots of buckets is
// bad if you insert few items in most subsequent iterations, because
// repeatedly clearing out all those buckets can get expensive.
//
// One solution is to call STLClearHashIfBig() with a "limit" value
// that is a small multiple of the typical number of items in your
// table.  In the common case, this is equivalent to an ordinary
// clear.  In the rare case where you insert a lot of items, the
// number of buckets is reset to the default to keep subsequent clear
// operations cheap.  Note that the default number of buckets is 193
// in the Gnu library implementation as of Jan '08.
template <class T> inline void STLClearHashIfBig(T *obj, size_t limit) {
  if (obj->bucket_count() >= limit) {
    T tmp;
    tmp.swap(*obj);
  } else {
    obj->clear();
  }
}

// Reserve space for STL object.
// STL's reserve() will always copy.
// This function avoid the copy if we already have capacity
template<class T> void STLReserveIfNeeded(T* obj, int new_size) {
  if (obj->capacity() < new_size)   // increase capacity
    obj->reserve(new_size);
  else if (obj->size() > new_size)  // reduce size
    obj->resize(new_size);
}

// STLDeleteContainerPointers()
//  For a range within a container of pointers, calls delete
//  (non-array version) on these pointers.
// NOTE: for these three functions, we could just implement a DeleteObject
// functor and then call for_each() on the range and functor, but this
// requires us to pull in all of <algorithm>, which seems expensive.
// For hash_[multi]set, it is important that this deletes behind the iterator
// because the hash_set may call the hash function on the iterator when it is
// advanced, which could result in the hash function trying to deference a
// stale pointer.
// NOTE: If you're calling this on an entire container, you probably want
// to call STLDeleteElements(&container) instead, or use an ElementDeleter.
template <class ForwardIterator>
void STLDeleteContainerPointers(ForwardIterator begin,
                                ForwardIterator end) {
  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;
    delete *temp;
  }
}

// STLDeleteContainerPairPointers()
//  For a range within a container of pairs, calls delete
//  (non-array version) on BOTH items in the pairs.
// NOTE: Like STLDeleteContainerPointers, it is important that this deletes
// behind the iterator because if both the key and value are deleted, the
// container may call the hash function on the iterator when it is advanced,
// which could result in the hash function trying to dereference a stale
// pointer.
template <class ForwardIterator>
void STLDeleteContainerPairPointers(ForwardIterator begin,
                                    ForwardIterator end) {
  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;
    delete temp->first;
    delete temp->second;
  }
}

// STLDeleteContainerPairFirstPointers()
//  For a range within a container of pairs, calls delete (non-array version)
//  on the FIRST item in the pairs.
// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
template <class ForwardIterator>
void STLDeleteContainerPairFirstPointers(ForwardIterator begin,
                                         ForwardIterator end) {
  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;
    delete temp->first;
  }
}

// STLDeleteContainerPairSecondPointers()
//  For a range within a container of pairs, calls delete
//  (non-array version) on the SECOND item in the pairs.
// NOTE: Like STLDeleteContainerPointers, deleting behind the iterator.
// Deleting the value does not always invalidate the iterator, but it may
// do so if the key is a pointer into the value object.
// NOTE: If you're calling this on an entire container, you probably want
// to call STLDeleteValues(&container) instead, or use ValueDeleter.
template <class ForwardIterator>
void STLDeleteContainerPairSecondPointers(ForwardIterator begin,
                                          ForwardIterator end) {
  while (begin != end) {
    ForwardIterator temp = begin;
    ++begin;
    delete temp->second;
  }
}

template<typename T>
inline void STLAssignToVector(vector<T>* vec,
                              const T* ptr,
                              size_t n) {
  vec->resize(n);
  if (n == 0) return;
  memcpy(&vec->front(), ptr, n*sizeof(T));
}

// Not faster; but we need the specialization so the function works at all
// on the vector<bool> specialization.
template<>
inline void STLAssignToVector(vector<bool>* vec,
                              const bool* ptr,
                              size_t n) {
  vec->clear();
  if (n == 0) return;
  vec->insert(vec->begin(), ptr, ptr + n);
}

/***** Hack to allow faster assignment to a vector *****/

// This routine speeds up an assignment of 32 bytes to a vector from
// about 250 cycles per assignment to about 140 cycles.
//
// Usage:
//      STLAssignToVectorChar(&vec, ptr, size);
//      STLAssignToString(&str, ptr, size);

inline void STLAssignToVectorChar(vector<char>* vec,
                                  const char* ptr,
                                  size_t n) {
  STLAssignToVector(vec, ptr, n);
}

// A struct that mirrors the GCC4 implementation of a string. See:
// /usr/crosstool/v8/gcc-4.1.0-glibc-2.2.2/i686-unknown-linux-gnu/include/c++/4.1.0/ext/sso_string_base.h
struct InternalStringRepGCC4 {
  char*  _M_data;
  size_t _M_string_length;

  enum { _S_local_capacity = 15 };

  union {
    char             _M_local_data[_S_local_capacity + 1];
    size_t           _M_allocated_capacity;
  };
};

// Like str->resize(new_size), except any new characters added to
// "*str" as a result of resizing may be left uninitialized, rather
// than being filled with '0' bytes.  Typically used when code is then
// going to overwrite the backing store of the string with known data.
inline void STLStringResizeUninitialized(string* s, size_t new_size) {
  if (sizeof(*s) == sizeof(InternalStringRepGCC4)) {
    if (new_size > s->capacity()) {
      s->reserve(new_size);
    }
    // The line below depends on the layout of 'string'.  THIS IS
    // NON-PORTABLE CODE.  If our STL implementation changes, we will
    // need to change this as well.
    InternalStringRepGCC4* rep = reinterpret_cast<InternalStringRepGCC4*>(s);
    assert(rep->_M_data == s->data());
    assert(rep->_M_string_length == s->size());

    // We have to null-terminate the string for c_str() to work properly.
    // So we leave the actual contents of the string uninitialized, but
    // we set the byte one past the new end of the string to '\0'
    const_cast<char*>(s->data())[new_size] = '\0';
    rep->_M_string_length = new_size;
  } else {
    // Slow path: have to reallocate stuff, or an unknown string rep
    s->resize(new_size);
  }
}

// Returns true if the string implementation supports a resize where
// the new characters added to the string are left untouched.
inline bool STLStringSupportsNontrashingResize(const string& s) {
  return (sizeof(s) == sizeof(InternalStringRepGCC4));
}

inline void STLAssignToString(string* str, const char* ptr, size_t n) {
  STLStringResizeUninitialized(str, n);
  if (n == 0) return;
  memcpy(&*str->begin(), ptr, n);
}

inline void STLAppendToString(string* str, const char* ptr, size_t n) {
  if (n == 0) return;
  size_t old_size = str->size();
  STLStringResizeUninitialized(str, old_size + n);
  memcpy(&*str->begin() + old_size, ptr, n);
}

// To treat a possibly-empty vector as an array, use these functions.
// If you know the array will never be empty, you can use &*v.begin()
// directly, but that is allowed to dump core if v is empty.  This
// function is the most efficient code that will work, taking into
// account how our STL is actually implemented.  THIS IS NON-PORTABLE
// CODE, so call us instead of repeating the nonportable code
// everywhere.  If our STL implementation changes, we will need to
// change this as well.

template<typename T, typename Allocator>
inline T* vector_as_array(vector<T, Allocator>* v) {
# ifdef NDEBUG
  return &*v->begin();
# else
  return v->empty() ? NULL : &*v->begin();
# endif
}

template<typename T, typename Allocator>
inline const T* vector_as_array(const vector<T, Allocator>* v) {
# ifdef NDEBUG
  return &*v->begin();
# else
  return v->empty() ? NULL : &*v->begin();
# endif
}

// Return a mutable char* pointing to a string's internal buffer,
// which may not be null-terminated. Writing through this pointer will
// modify the string.
//
// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
// next call to a string method that invalidates iterators.
//
// Prior to C++11, there was no standard-blessed way of getting a mutable
// reference to a string's internal buffer. The requirement that string be
// contiguous is officially part of the C++11 standard [string.require]/5.
// According to Matt Austern, this should already work on all current C++98
// implementations.
inline char* string_as_array(string* str) {
  // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
  return str->empty() ? NULL : &*str->begin();
}

// These are methods that test two hash maps/sets for equality.  These exist
// because the == operator in the STL can return false when the maps/sets
// contain identical elements.  This is because it compares the internal hash
// tables which may be different if the order of insertions and deletions
// differed.

template <class HashSet>
inline bool
HashSetEquality(const HashSet& set_a,
                const HashSet& set_b) {
  if (set_a.size() != set_b.size()) return false;
  for (typename HashSet::const_iterator i = set_a.begin();
       i != set_a.end();
       ++i)
    if (set_b.find(*i) == set_b.end()) return false;
  return true;
}

template <class HashMap>
inline bool
HashMapEquality(const HashMap& map_a,
                const HashMap& map_b) {
  if (map_a.size() != map_b.size()) return false;
  for (typename HashMap::const_iterator i = map_a.begin();
       i != map_a.end(); ++i) {
    typename HashMap::const_iterator j = map_b.find(i->first);
    if (j == map_b.end()) return false;
    if (i->second != j->second) return false;
  }
  return true;
}

// The following functions are useful for cleaning up STL containers
// whose elements point to allocated memory.

// STLDeleteElements() deletes all the elements in an STL container and clears
// the container.  This function is suitable for use with a vector, set,
// hash_set, or any other STL container which defines sensible begin(), end(),
// and clear() methods.
//
// If container is NULL, this function is a no-op.
//
// As an alternative to calling STLDeleteElements() directly, consider
// ElementDeleter (defined below), which ensures that your container's elements
// are deleted when the ElementDeleter goes out of scope.
template <class T>
void STLDeleteElements(T *container) {
  if (!container) return;
  STLDeleteContainerPointers(container->begin(), container->end());
  container->clear();
}

// Given an STL container consisting of (key, value) pairs, STLDeleteValues
// deletes all the "value" components and clears the container.  Does nothing
// in the case it's given a NULL pointer.
template <class T>
void STLDeleteValues(T *v) {
  if (!v) return;
  STLDeleteContainerPairSecondPointers(v->begin(), v->end());
  v->clear();
}


// ElementDeleter and ValueDeleter provide a convenient way to delete all
// elements or values from STL containers when they go out of scope.  This
// greatly simplifies code that creates temporary objects and has multiple
// return statements.  Example:
//
// vector<MyProto *> tmp_proto;
// ElementDeleter d(&tmp_proto);
// if (...) return false;
// ...
// return success;

// A very simple interface that simply provides a virtual destructor.  It is
// used as a non-templated base class for the TemplatedElementDeleter and
// TemplatedValueDeleter classes.  Clients should not typically use this class
// directly.
class BaseDeleter {
 public:
  virtual ~BaseDeleter() {}

 protected:
  BaseDeleter() {}

 private:
  DISALLOW_EVIL_CONSTRUCTORS(BaseDeleter);
};

// Given a pointer to an STL container, this class will delete all the element
// pointers when it goes out of scope.  Clients should typically use
// ElementDeleter rather than invoking this class directly.
template<class STLContainer>
class TemplatedElementDeleter : public BaseDeleter {
 public:
  explicit TemplatedElementDeleter<STLContainer>(STLContainer *ptr)
      : container_ptr_(ptr) {
  }

  virtual ~TemplatedElementDeleter<STLContainer>() {
    STLDeleteElements(container_ptr_);
  }

 private:
  STLContainer *container_ptr_;

  DISALLOW_EVIL_CONSTRUCTORS(TemplatedElementDeleter);
};

// Like TemplatedElementDeleter, this class will delete element pointers from a
// container when it goes out of scope.  However, it is much nicer to use,
// since the class itself is not templated.
class ElementDeleter {
 public:
  template <class STLContainer>
  explicit ElementDeleter(STLContainer *ptr)
      : deleter_(new TemplatedElementDeleter<STLContainer>(ptr)) {
  }

  ~ElementDeleter() {
    delete deleter_;
  }

 private:
  BaseDeleter *deleter_;

  DISALLOW_EVIL_CONSTRUCTORS(ElementDeleter);
};

// Given a pointer to an STL container this class will delete all the value
// pointers when it goes out of scope.  Clients should typically use
// ValueDeleter rather than invoking this class directly.
template<class STLContainer>
class TemplatedValueDeleter : public BaseDeleter {
 public:
  explicit TemplatedValueDeleter<STLContainer>(STLContainer *ptr)
      : container_ptr_(ptr) {
  }

  virtual ~TemplatedValueDeleter<STLContainer>() {
    STLDeleteValues(container_ptr_);
  }

 private:
  STLContainer *container_ptr_;

  DISALLOW_EVIL_CONSTRUCTORS(TemplatedValueDeleter);
};

// Similar to ElementDeleter, but wraps a TemplatedValueDeleter rather than an
// TemplatedElementDeleter.
class ValueDeleter {
 public:
  template <class STLContainer>
  explicit ValueDeleter(STLContainer *ptr)
      : deleter_(new TemplatedValueDeleter<STLContainer>(ptr)) {
  }

  ~ValueDeleter() {
    delete deleter_;
  }

 private:
  BaseDeleter *deleter_;

  DISALLOW_EVIL_CONSTRUCTORS(ValueDeleter);
};


// STLElementDeleter and STLValueDeleter are similar to ElementDeleter and
// ValueDeleter, except that:
// - The classes are templated, making them less convenient to use.
// - Their destructors are not virtual, making them potentially more efficient.
// New code should typically use ElementDeleter and ValueDeleter unless
// efficiency is a large concern.

template<class STLContainer> class STLElementDeleter {
 public:
  STLElementDeleter<STLContainer>(STLContainer *ptr) : container_ptr_(ptr) {}
  ~STLElementDeleter<STLContainer>() { STLDeleteElements(container_ptr_); }
 private:
  STLContainer *container_ptr_;
};

template<class STLContainer> class STLValueDeleter {
 public:
  STLValueDeleter<STLContainer>(STLContainer *ptr) : container_ptr_(ptr) {}
  ~STLValueDeleter<STLContainer>() { STLDeleteValues(container_ptr_); }
 private:
  STLContainer *container_ptr_;
};


// STLSet{Difference,SymmetricDifference,Union,Intersection}(A a, B b, C *c)
// *APPEND* the set {difference, symmetric difference, union, intersection} of
// the two sets a and b to c.
// STLSet{Difference,SymmetricDifference,Union,Intersection}(T a, T b) do the
// same but return the result by value rather than by the third pointer
// argument.  The result type is the same as both of the inputs in the two
// argument case.
//
// Requires:
//   a and b must be STL like containers that contain sorted data (as defined
//   by the < operator).
//   For the 3 argument version &a == c or &b == c are disallowed.  In those
//   cases the 2 argument version is probably what you want anyway:
//   a = STLSetDifference(a, b);
//
// These function are convenience functions.  The code they implement is
// trivial (at least for now).  The STL incantations they wrap are just too
// verbose for programmers to use then and they are unpleasant to the eye.
// Without these convenience versions people will simply keep writing one-off
// for loops which are harder to read and more error prone.
//
// Note that for initial construction of an object it is just as efficient to
// use the 2 argument version as the 3 version due to RVO (return value
// optimization) of modern C++ compilers:
//   set<int> c = STLSetDifference(a, b);
// is an example of where RVO comes into play.

template<typename SortedSTLContainerA,
         typename SortedSTLContainerB,
         typename SortedSTLContainerC>
void STLSetDifference(const SortedSTLContainerA &a,
                      const SortedSTLContainerB &b,
                      SortedSTLContainerC *c) {
  // The qualified name avoids an ambiguity error, particularly with C++11:
  assert(std::is_sorted(a.begin(), a.end()));
  assert(std::is_sorted(b.begin(), b.end()));
  assert(static_cast<const void *>(&a) !=
         static_cast<const void *>(c));
  assert(static_cast<const void *>(&b) !=
         static_cast<const void *>(c));
  std::set_difference(a.begin(), a.end(), b.begin(), b.end(),
                      std::inserter(*c, c->end()));
}

template<typename SortedSTLContainer>
SortedSTLContainer STLSetDifference(const SortedSTLContainer &a,
                                    const SortedSTLContainer &b) {
  SortedSTLContainer c;
  STLSetDifference(a, b, &c);
  return c;
}

template<typename SortedSTLContainerA,
         typename SortedSTLContainerB,
         typename SortedSTLContainerC>
void STLSetUnion(const SortedSTLContainerA &a,
                 const SortedSTLContainerB &b,
                 SortedSTLContainerC *c) {
  assert(std::is_sorted(a.begin(), a.end()));
  assert(std::is_sorted(b.begin(), b.end()));
  assert(static_cast<const void *>(&a) !=
         static_cast<const void *>(c));
  assert(static_cast<const void *>(&b) !=
         static_cast<const void *>(c));
  std::set_union(a.begin(), a.end(), b.begin(), b.end(),
                 std::inserter(*c, c->end()));
}

template<typename SortedSTLContainerA,
         typename SortedSTLContainerB,
         typename SortedSTLContainerC>
void STLSetSymmetricDifference(const SortedSTLContainerA &a,
                               const SortedSTLContainerB &b,
                               SortedSTLContainerC *c) {
  assert(std::is_sorted(a.begin(), a.end()));
  assert(std::is_sorted(b.begin(), b.end()));
  assert(static_cast<const void *>(&a) !=
         static_cast<const void *>(c));
  assert(static_cast<const void *>(&b) !=
         static_cast<const void *>(c));
  std::set_symmetric_difference(a.begin(), a.end(), b.begin(), b.end(),
                                std::inserter(*c, c->end()));
}

template<typename SortedSTLContainer>
SortedSTLContainer STLSetSymmetricDifference(const SortedSTLContainer &a,
                                             const SortedSTLContainer &b) {
  SortedSTLContainer c;
  STLSetSymmetricDifference(a, b, &c);
  return c;
}

template<typename SortedSTLContainer>
SortedSTLContainer STLSetUnion(const SortedSTLContainer &a,
                               const SortedSTLContainer &b) {
  SortedSTLContainer c;
  STLSetUnion(a, b, &c);
  return c;
}

template<typename SortedSTLContainerA,
         typename SortedSTLContainerB,
         typename SortedSTLContainerC>
void STLSetIntersection(const SortedSTLContainerA &a,
                        const SortedSTLContainerB &b,
                        SortedSTLContainerC *c) {
  assert(std::is_sorted(a.begin(), a.end()));
  assert(std::is_sorted(b.begin(), b.end()));
  assert(static_cast<const void *>(&a) !=
         static_cast<const void *>(c));
  assert(static_cast<const void *>(&b) !=
         static_cast<const void *>(c));
  std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
                        std::inserter(*c, c->end()));
}

template<typename SortedSTLContainer>
SortedSTLContainer STLSetIntersection(const SortedSTLContainer &a,
                                      const SortedSTLContainer &b) {
  SortedSTLContainer c;
  STLSetIntersection(a, b, &c);
  return c;
}

// Similar to STLSet{Union,Intesection,etc}, but simpler because the result is
// always bool.
template<typename SortedSTLContainerA,
         typename SortedSTLContainerB>
bool STLIncludes(const SortedSTLContainerA &a,
                 const SortedSTLContainerB &b) {
  assert(std::is_sorted(a.begin(), a.end()));
  assert(std::is_sorted(b.begin(), b.end()));
  return std::includes(a.begin(), a.end(),
                       b.begin(), b.end());
}

// Functors that compose arbitrary unary and binary functions with a
// function that "projects" one of the members of a pair.
// Specifically, if p1 and p2, respectively, are the functions that
// map a pair to its first and second, respectively, members, the
// table below summarizes the functions that can be constructed:
//
// * UnaryOperate1st<pair>(f) returns the function x -> f(p1(x))
// * UnaryOperate2nd<pair>(f) returns the function x -> f(p2(x))
// * BinaryOperate1st<pair>(f) returns the function (x,y) -> f(p1(x),p1(y))
// * BinaryOperate2nd<pair>(f) returns the function (x,y) -> f(p2(x),p2(y))
//
// A typical usage for these functions would be when iterating over
// the contents of an STL map. For other sample usage, see the unittest.

template<typename Pair, typename UnaryOp>
class UnaryOperateOnFirst
    : public std::unary_function<Pair, typename UnaryOp::result_type> {
 public:
  UnaryOperateOnFirst() {
  }

  UnaryOperateOnFirst(const UnaryOp& f) : f_(f) {  // TODO(user): explicit?
  }

  typename UnaryOp::result_type operator()(const Pair& p) const {
    return f_(p.first);
  }

 private:
  UnaryOp f_;
};

template<typename Pair, typename UnaryOp>
UnaryOperateOnFirst<Pair, UnaryOp> UnaryOperate1st(const UnaryOp& f) {
  return UnaryOperateOnFirst<Pair, UnaryOp>(f);
}

template<typename Pair, typename UnaryOp>
class UnaryOperateOnSecond
    : public std::unary_function<Pair, typename UnaryOp::result_type> {
 public:
  UnaryOperateOnSecond() {
  }

  UnaryOperateOnSecond(const UnaryOp& f) : f_(f) {  // TODO(user): explicit?
  }

  typename UnaryOp::result_type operator()(const Pair& p) const {
    return f_(p.second);
  }

 private:
  UnaryOp f_;
};

template<typename Pair, typename UnaryOp>
UnaryOperateOnSecond<Pair, UnaryOp> UnaryOperate2nd(const UnaryOp& f) {
  return UnaryOperateOnSecond<Pair, UnaryOp>(f);
}

template<typename Pair, typename BinaryOp>
class BinaryOperateOnFirst
    : public std::binary_function<Pair, Pair, typename BinaryOp::result_type> {
 public:
  BinaryOperateOnFirst() {
  }

  BinaryOperateOnFirst(const BinaryOp& f) : f_(f) {  // TODO(user): explicit?
  }

  typename BinaryOp::result_type operator()(const Pair& p1,
                                            const Pair& p2) const {
    return f_(p1.first, p2.first);
  }

 private:
  BinaryOp f_;
};

// TODO(user): explicit?
template<typename Pair, typename BinaryOp>
BinaryOperateOnFirst<Pair, BinaryOp> BinaryOperate1st(const BinaryOp& f) {
  return BinaryOperateOnFirst<Pair, BinaryOp>(f);
}

template<typename Pair, typename BinaryOp>
class BinaryOperateOnSecond
    : public std::binary_function<Pair, Pair, typename BinaryOp::result_type> {
 public:
  BinaryOperateOnSecond() {
  }

  BinaryOperateOnSecond(const BinaryOp& f) : f_(f) {
  }

  typename BinaryOp::result_type operator()(const Pair& p1,
                                            const Pair& p2) const {
    return f_(p1.second, p2.second);
  }

 private:
  BinaryOp f_;
};

template<typename Pair, typename BinaryOp>
BinaryOperateOnSecond<Pair, BinaryOp> BinaryOperate2nd(const BinaryOp& f) {
  return BinaryOperateOnSecond<Pair, BinaryOp>(f);
}

// Functor that composes a binary functor h from an arbitrary binary functor
// f and two unary functors g1, g2, so that:
//
// BinaryCompose1(f, g) returns function (x, y) -> f(g(x), g(y))
// BinaryCompose2(f, g1, g2) returns function (x, y) -> f(g1(x), g2(y))
//
// This is a generalization of the BinaryOperate* functors for types other
// than pairs.
//
// For sample usage, see the unittest.
//
// F has to be a model of AdaptableBinaryFunction.
// G1 and G2 have to be models of AdabtableUnaryFunction.
template<typename F, typename G1, typename G2>
class BinaryComposeBinary : public binary_function<typename G1::argument_type,
                                                   typename G2::argument_type,
                                                   typename F::result_type> {
 public:
  BinaryComposeBinary(F f, G1 g1, G2 g2) : f_(f), g1_(g1), g2_(g2) { }

  typename F::result_type operator()(typename G1::argument_type x,
                                     typename G2::argument_type y) const {
    return f_(g1_(x), g2_(y));
  }

 private:
  F f_;
  G1 g1_;
  G2 g2_;
};

template<typename F, typename G>
BinaryComposeBinary<F, G, G> BinaryCompose1(F f, G g) {
  return BinaryComposeBinary<F, G, G>(f, g, g);
}

template<typename F, typename G1, typename G2>
BinaryComposeBinary<F, G1, G2> BinaryCompose2(F f, G1 g1, G2 g2) {
  return BinaryComposeBinary<F, G1, G2>(f, g1, g2);
}

// This is a wrapper for an STL allocator which keeps a count of the
// active bytes allocated by this class of allocators.  This is NOT
// THREAD SAFE.  This should only be used in situations where you can
// ensure that only a single thread performs allocation and
// deallocation.
template <typename T, typename Alloc = std::allocator<T> >
class STLCountingAllocator : public Alloc {
 public:
  typedef typename Alloc::pointer pointer;
  typedef typename Alloc::size_type size_type;

  STLCountingAllocator() : bytes_used_(NULL) { }
  STLCountingAllocator(int64* b) : bytes_used_(b) {}  // TODO(user): explicit?

  // Constructor used for rebinding
  template <class U>
  STLCountingAllocator(const STLCountingAllocator<U>& x)
      : Alloc(x),
        bytes_used_(x.bytes_used()) {
  }

  pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0) {
    assert(bytes_used_ != NULL);
    *bytes_used_ += n * sizeof(T);
    return Alloc::allocate(n, hint);
  }

  void deallocate(pointer p, size_type n) {
    Alloc::deallocate(p, n);
    assert(bytes_used_ != NULL);
    *bytes_used_ -= n * sizeof(T);
  }

  // Rebind allows an allocator<T> to be used for a different type
  template <class U> struct rebind {
    typedef STLCountingAllocator<U,
                                 typename Alloc::template
                                 rebind<U>::other> other;
  };

  int64* bytes_used() const { return bytes_used_; }

 private:
  int64* bytes_used_;
};

// Even though a struct has no data members, it cannot have zero size
// according to the standard.  However, "empty base-class
// optimization" allows an empty parent class to add no additional
// size to the object.  STLEmptyBaseHandle is a handy way to "stuff"
// objects that are typically empty (e.g., allocators, compare
// objects) into other fields of an object without increasing the size
// of the object.
//
// struct Empty {
//   void Method() { }
// };
// struct OneInt {
//   STLEmptyBaseHandle<Empty, int> i;
// };
//
// In the example above, "i.data" refers to the integer field, whereas
// "i" refers to the empty base class.  sizeof(OneInt) == sizeof(int)
// despite the fact that sizeof(Empty) > 0.
template <typename Base, typename Data>
struct STLEmptyBaseHandle : public Base {
  template <typename U>
  STLEmptyBaseHandle(const U &b, const Data &d)
      : Base(b),
        data(d) {
  }
  Data data;
};

// These functions return true if there is some element in the sorted range
// [begin1, end) which is equal to some element in the sorted range [begin2,
// end2). The iterators do not have to be of the same type, but the value types
// must be less-than comparable. (Two elements a,b are considered equal if
// !(a < b) && !(b < a).
template<typename InputIterator1, typename InputIterator2>
bool SortedRangesHaveIntersection(InputIterator1 begin1, InputIterator1 end1,
                                  InputIterator2 begin2, InputIterator2 end2) {
  assert(std::is_sorted(begin1, end1));
  assert(std::is_sorted(begin2, end2));
  while (begin1 != end1 && begin2 != end2) {
    if (*begin1 < *begin2) {
      ++begin1;
    } else if (*begin2 < *begin1) {
      ++begin2;
    } else {
      return true;
    }
  }
  return false;
}

// This is equivalent to the function above, but using a custom comparison
// function.
template<typename InputIterator1, typename InputIterator2, typename Comp>
bool SortedRangesHaveIntersection(InputIterator1 begin1, InputIterator1 end1,
                                  InputIterator2 begin2, InputIterator2 end2,
                                  Comp comparator) {
  assert(std::is_sorted(begin1, end1, comparator));
  assert(std::is_sorted(begin2, end2, comparator));
  while (begin1 != end1 && begin2 != end2) {
    if (comparator(*begin1, *begin2)) {
      ++begin1;
    } else if (comparator(*begin2, *begin1)) {
      ++begin2;
    } else {
      return true;
    }
  }
  return false;
}

// release_ptr is intended to help remove systematic use of gscoped_ptr
// in cases like:
//
// vector<Foo *> v;
// ElementDeleter d(&v);
// ... {
//   int remove_idx = f(v);
//   gscoped_ptr<Foo> t(v[remove_idx]);
//   v[remove_idx] = NULL;  // Save from deleter.
//   return t.release();
// }
//
// This would be replaced by:
// ... {
//   int remove_idx = f(v);
//   return release_ptr(&v[remove_idx]);
// }
template<typename T> T* release_ptr(T **ptr) MUST_USE_RESULT;
template<typename T> T* release_ptr(T **ptr) {
  assert(ptr);
  T *tmp = *ptr;
  *ptr = NULL;
  return tmp;
}


#endif  // UTIL_GTL_STL_UTIL_H_
