Home | History | Annotate | Download | only in base
      1 // Copyright 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CC_BASE_SCOPED_PTR_VECTOR_H_
      6 #define CC_BASE_SCOPED_PTR_VECTOR_H_
      7 
      8 #include <algorithm>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/logging.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/stl_util.h"
     15 
     16 namespace cc {
     17 
     18 // This type acts like a vector<scoped_ptr> based on top of std::vector. The
     19 // ScopedPtrVector has ownership of all elements in the vector.
     20 template <typename T>
     21 class ScopedPtrVector {
     22  public:
     23   typedef typename std::vector<T*>::const_iterator const_iterator;
     24   typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
     25   typedef typename std::vector<T*>::const_reverse_iterator
     26       const_reverse_iterator;
     27 
     28 #if defined(OS_ANDROID)
     29   // On Android the iterator is not a class, so we can't block assignment.
     30   typedef typename std::vector<T*>::iterator iterator;
     31 #else
     32   // Ban setting values on the iterator directly. New pointers must be passed
     33   // to methods on the ScopedPtrVector class to appear in the vector.
     34   class iterator : public std::vector<T*>::iterator {
     35    public:
     36     iterator(const typename std::vector<T*>::iterator& other) // NOLINT
     37         : std::vector<T*>::iterator(other) {}
     38     T* const& operator*() { return std::vector<T*>::iterator::operator*(); }
     39   };
     40 #endif
     41 
     42   ScopedPtrVector() {}
     43 
     44   ~ScopedPtrVector() { clear(); }
     45 
     46   size_t size() const {
     47     return data_.size();
     48   }
     49 
     50   T* at(size_t index) const {
     51     DCHECK(index < size());
     52     return data_[index];
     53   }
     54 
     55   T* operator[](size_t index) const {
     56     return at(index);
     57   }
     58 
     59   T* front() const {
     60     DCHECK(!empty());
     61     return at(0);
     62   }
     63 
     64   T* back() const {
     65     DCHECK(!empty());
     66     return at(size() - 1);
     67   }
     68 
     69   bool empty() const {
     70     return data_.empty();
     71   }
     72 
     73   scoped_ptr<T> take(iterator position) {
     74     if (position == end())
     75       return scoped_ptr<T>();
     76     DCHECK(position < end());
     77 
     78     typename std::vector<T*>::iterator writable_position = position;
     79     scoped_ptr<T> ret(*writable_position);
     80     *writable_position = NULL;
     81     return ret.Pass();
     82   }
     83 
     84   scoped_ptr<T> take_back() {
     85     DCHECK(!empty());
     86     if (empty())
     87       return scoped_ptr<T>(NULL);
     88     return take(end() - 1);
     89   }
     90 
     91   void erase(iterator position) {
     92     if (position == end())
     93       return;
     94     typename std::vector<T*>::iterator writable_position = position;
     95     delete *writable_position;
     96     data_.erase(position);
     97   }
     98 
     99   void erase(iterator first, iterator last) {
    100     DCHECK(first <= last);
    101     for (iterator it = first; it != last; ++it) {
    102       DCHECK(it < end());
    103 
    104       typename std::vector<T*>::iterator writable_it = it;
    105       delete *writable_it;
    106     }
    107     data_.erase(first, last);
    108   }
    109 
    110   void reserve(size_t size) {
    111     data_.reserve(size);
    112   }
    113 
    114   void clear() {
    115     STLDeleteElements(&data_);
    116   }
    117 
    118   void push_back(scoped_ptr<T> item) {
    119     data_.push_back(item.release());
    120   }
    121 
    122   void pop_back() {
    123     delete data_.back();
    124     data_.pop_back();
    125   }
    126 
    127   void insert(iterator position, scoped_ptr<T> item) {
    128     DCHECK(position <= end());
    129     data_.insert(position, item.release());
    130   }
    131 
    132   void insert_and_take(iterator position,
    133                        ScopedPtrVector<T>& other) {
    134     std::vector<T*> tmp_data;
    135     for (ScopedPtrVector<T>::iterator it = other.begin();
    136          it != other.end();
    137          ++it) {
    138       tmp_data.push_back(other.take(it).release());
    139     }
    140     data_.insert(position, tmp_data.begin(), tmp_data.end());
    141   }
    142 
    143   template <typename Predicate>
    144   iterator partition(Predicate predicate) {
    145     typename std::vector<T*>::iterator first = begin();
    146     typename std::vector<T*>::iterator last = end();
    147     return static_cast<iterator>(std::partition(first, last, predicate));
    148   }
    149 
    150   void swap(ScopedPtrVector<T>& other) {
    151     data_.swap(other.data_);
    152   }
    153 
    154   void swap(iterator a, iterator b) {
    155     DCHECK(a < end());
    156     DCHECK(b < end());
    157     if (a == end() || b == end() || a == b)
    158       return;
    159     typename std::vector<T*>::iterator writable_a = a;
    160     typename std::vector<T*>::iterator writable_b = b;
    161     std::swap(*writable_a, *writable_b);
    162   }
    163 
    164   template<class Compare>
    165   inline void sort(Compare comp) {
    166     std::sort(data_.begin(), data_.end(), comp);
    167   }
    168 
    169   iterator begin() { return static_cast<iterator>(data_.begin()); }
    170   const_iterator begin() const { return data_.begin(); }
    171   iterator end() { return static_cast<iterator>(data_.end()); }
    172   const_iterator end() const { return data_.end(); }
    173 
    174   reverse_iterator rbegin() { return data_.rbegin(); }
    175   const_reverse_iterator rbegin() const { return data_.rbegin(); }
    176   reverse_iterator rend() { return data_.rend(); }
    177   const_reverse_iterator rend() const { return data_.rend(); }
    178 
    179  private:
    180   std::vector<T*> data_;
    181 
    182   DISALLOW_COPY_AND_ASSIGN(ScopedPtrVector);
    183 };
    184 
    185 }  // namespace cc
    186 
    187 #endif  // CC_BASE_SCOPED_PTR_VECTOR_H_
    188