// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_BASE_SCOPED_PTR_VECTOR_H_
#define CC_BASE_SCOPED_PTR_VECTOR_H_

#include <algorithm>
#include <vector>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"

namespace cc {

// This type acts like a vector<scoped_ptr> based on top of std::vector. The
// ScopedPtrVector has ownership of all elements in the vector.
template <typename T>
class ScopedPtrVector {
 public:
  typedef typename std::vector<T*>::const_iterator const_iterator;
  typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
  typedef typename std::vector<T*>::const_reverse_iterator
      const_reverse_iterator;

#if defined(OS_ANDROID)
  // On Android the iterator is not a class, so we can't block assignment.
  typedef typename std::vector<T*>::iterator iterator;
#else
  // Ban setting values on the iterator directly. New pointers must be passed
  // to methods on the ScopedPtrVector class to appear in the vector.
  class iterator : public std::vector<T*>::iterator {
   public:
    iterator(const typename std::vector<T*>::iterator& other) // NOLINT
        : std::vector<T*>::iterator(other) {}
    T* const& operator*() { return std::vector<T*>::iterator::operator*(); }
  };
#endif

  ScopedPtrVector() {}

  ~ScopedPtrVector() { clear(); }

  size_t size() const {
    return data_.size();
  }

  T* at(size_t index) const {
    DCHECK(index < size());
    return data_[index];
  }

  T* operator[](size_t index) const {
    return at(index);
  }

  T* front() const {
    DCHECK(!empty());
    return at(0);
  }

  T* back() const {
    DCHECK(!empty());
    return at(size() - 1);
  }

  bool empty() const {
    return data_.empty();
  }

  scoped_ptr<T> take(iterator position) {
    if (position == end())
      return scoped_ptr<T>();
    DCHECK(position < end());

    typename std::vector<T*>::iterator writable_position = position;
    scoped_ptr<T> ret(*writable_position);
    *writable_position = NULL;
    return ret.Pass();
  }

  scoped_ptr<T> take_back() {
    DCHECK(!empty());
    if (empty())
      return scoped_ptr<T>(NULL);
    return take(end() - 1);
  }

  void erase(iterator position) {
    if (position == end())
      return;
    typename std::vector<T*>::iterator writable_position = position;
    delete *writable_position;
    data_.erase(position);
  }

  void erase(iterator first, iterator last) {
    DCHECK(first <= last);
    for (iterator it = first; it != last; ++it) {
      DCHECK(it < end());

      typename std::vector<T*>::iterator writable_it = it;
      delete *writable_it;
    }
    data_.erase(first, last);
  }

  void reserve(size_t size) {
    data_.reserve(size);
  }

  void clear() {
    STLDeleteElements(&data_);
  }

  void push_back(scoped_ptr<T> item) {
    data_.push_back(item.release());
  }

  void pop_back() {
    delete data_.back();
    data_.pop_back();
  }

  void insert(iterator position, scoped_ptr<T> item) {
    DCHECK(position <= end());
    data_.insert(position, item.release());
  }

  void insert_and_take(iterator position,
                       ScopedPtrVector<T>& other) {
    std::vector<T*> tmp_data;
    for (ScopedPtrVector<T>::iterator it = other.begin();
         it != other.end();
         ++it) {
      tmp_data.push_back(other.take(it).release());
    }
    data_.insert(position, tmp_data.begin(), tmp_data.end());
  }

  template <typename Predicate>
  iterator partition(Predicate predicate) {
    typename std::vector<T*>::iterator first = begin();
    typename std::vector<T*>::iterator last = end();
    return static_cast<iterator>(std::partition(first, last, predicate));
  }

  void swap(ScopedPtrVector<T>& other) {
    data_.swap(other.data_);
  }

  void swap(iterator a, iterator b) {
    DCHECK(a < end());
    DCHECK(b < end());
    if (a == end() || b == end() || a == b)
      return;
    typename std::vector<T*>::iterator writable_a = a;
    typename std::vector<T*>::iterator writable_b = b;
    std::swap(*writable_a, *writable_b);
  }

  template<class Compare>
  inline void sort(Compare comp) {
    std::sort(data_.begin(), data_.end(), comp);
  }

  iterator begin() { return static_cast<iterator>(data_.begin()); }
  const_iterator begin() const { return data_.begin(); }
  iterator end() { return static_cast<iterator>(data_.end()); }
  const_iterator end() const { return data_.end(); }

  reverse_iterator rbegin() { return data_.rbegin(); }
  const_reverse_iterator rbegin() const { return data_.rbegin(); }
  reverse_iterator rend() { return data_.rend(); }
  const_reverse_iterator rend() const { return data_.rend(); }

 private:
  std::vector<T*> data_;

  DISALLOW_COPY_AND_ASSIGN(ScopedPtrVector);
};

}  // namespace cc

#endif  // CC_BASE_SCOPED_PTR_VECTOR_H_
