scoped_ptr_vector.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// Copyright 2012 The Chromium Authors. All rights reserved.
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// Use of this source code is governed by a BSD-style license that can be
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// found in the LICENSE file.
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#ifndef CC_BASE_SCOPED_PTR_VECTOR_H_
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define CC_BASE_SCOPED_PTR_VECTOR_H_
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "base/basictypes.h"
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "base/logging.h"
10d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "base/memory/scoped_ptr.h"
11d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "base/stl_util.h"
12d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
13d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgnamespace cc {
14d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
15d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// This type acts like a vector<scoped_ptr> based on top of std::vector. The
16dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org// ScopedPtrVector has ownership of all elements in the vector.
17d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgtemplate <typename T>
18d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgclass ScopedPtrVector {
19d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org public:
20d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  typedef typename std::vector<T*>::const_iterator const_iterator;
21d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
22d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  typedef typename std::vector<T*>::const_reverse_iterator
23d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      const_reverse_iterator;
24d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
25d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#if defined(OS_ANDROID)
26d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // On Android the iterator is not a class, so we can't block assignment.
27d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  typedef typename std::vector<T*>::iterator iterator;
28d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#else
29d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Ban setting values on the iterator directly. New pointers must be passed
30d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // to methods on the ScopedPtrVector class to appear in the vector.
31d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  class iterator : public std::vector<T*>::iterator {
32d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org   public:
33d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    iterator(const typename std::vector<T*>::iterator& other)
34d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        : std::vector<T*>::iterator(other) {}
35d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    T* const& operator*() { return std::vector<T*>::iterator::operator*(); }
36d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  };
37d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#endif
38d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  ScopedPtrVector() {}
40d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
41d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  ~ScopedPtrVector() { clear(); }
42d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
43d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  size_t size() const {
44d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return data_.size();
45d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
47d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  T* at(size_t index) const {
48d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(index < size());
49d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return data_[index];
50d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
51d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
52d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  T* operator[](size_t index) const {
53d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return at(index);
54d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
55d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
56d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  T* front() const {
57d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(!empty());
58d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return at(0);
59d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
60d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
61d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  T* back() const {
62d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(!empty());
63d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return at(size() - 1);
64d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
65d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
66d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  bool empty() const {
67dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return data_.empty();
68dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
69d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
70d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  scoped_ptr<T> take(iterator position) {
71d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    if (position == end())
72d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      return scoped_ptr<T>(NULL);
73d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(position < end());
74d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
75d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    typename std::vector<T*>::iterator writable_position = position;
76d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    scoped_ptr<T> ret(*writable_position);
77d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    *writable_position = NULL;
78d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return ret.Pass();
79d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
80d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
81d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  scoped_ptr<T> take_back() {
82d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(!empty());
83d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    if (empty())
84d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      return scoped_ptr<T>(NULL);
85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return take(end() - 1);
86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
87d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
88d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  void erase(iterator position) {
89d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    if (position == end())
90d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      return;
91d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    typename std::vector<T*>::iterator writable_position = position;
92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    delete *writable_position;
93d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    data_.erase(position);
94d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
95d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  void erase(iterator first, iterator last) {
97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    DCHECK(first <= last);
98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    for (iterator it = first; it != last; ++it) {
99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      DCHECK(it < end());
100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      typename std::vector<T*>::iterator writable_it = it;
102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      delete *writable_it;
103d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
104d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    data_.erase(first, last);
105d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
107d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  void reserve(size_t size) {
108474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    data_.reserve(size);
109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org  }
1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org  void clear() {
112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    STLDeleteElements(&data_);
113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
114d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
115d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  void push_back(scoped_ptr<T> item) {
116dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    data_.push_back(item.release());
117dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
118d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
119d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  void pop_back() {
120d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    delete data_.back();
121d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    data_.pop_back();
122d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
12376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
12476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  void insert(iterator position, scoped_ptr<T> item) {
12576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    DCHECK(position <= end());
12676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    data_.insert(position, item.release());
12776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
12876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
12976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  void swap(ScopedPtrVector<T>& other) {
13076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    data_.swap(other.data_);
13176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
13276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
13376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  void swap(iterator a, iterator b) {
13476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    DCHECK(a < end());
13576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    DCHECK(b < end());
13676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (a == end() || b == end() || a == b)
137dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      return;
138dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    typename std::vector<T*>::iterator writable_a = a;
139dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    typename std::vector<T*>::iterator writable_b = b;
14076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    std::swap(*writable_a, *writable_b);
14176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
142dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
14376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  template<class Compare>
144dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  inline void sort(Compare comp) {
145411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org   std::sort(data_.begin(), data_.end(), comp);
146411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  }
147d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
148d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  iterator begin() { return static_cast<iterator>(data_.begin()); }
149474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org  const_iterator begin() const { return data_.begin(); }
150d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  iterator end() { return static_cast<iterator>(data_.end()); }
151d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const_iterator end() const { return data_.end(); }
152
153  reverse_iterator rbegin() { return data_.rbegin(); }
154  const_reverse_iterator rbegin() const { return data_.rbegin(); }
155  reverse_iterator rend() { return data_.rend(); }
156  const_reverse_iterator rend() const { return data_.rend(); }
157
158 private:
159  std::vector<T*> data_;
160
161  DISALLOW_COPY_AND_ASSIGN(ScopedPtrVector);
162};
163
164}  // namespace cc
165
166#endif  // CC_BASE_SCOPED_PTR_VECTOR_H_
167