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_DEQUE_H_ 6 #define CC_BASE_SCOPED_PTR_DEQUE_H_ 7 8 #include <algorithm> 9 #include <deque> 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 deque<scoped_ptr> based on top of std::deque. The 19 // ScopedPtrDeque has ownership of all elements in the deque. 20 template <typename T> 21 class ScopedPtrDeque { 22 public: 23 typedef typename std::deque<T*>::const_iterator const_iterator; 24 typedef typename std::deque<T*>::reverse_iterator reverse_iterator; 25 typedef typename std::deque<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::deque<T*>::iterator iterator; 31 #else 32 // Ban setting values on the iterator directly. New pointers must be passed 33 // to methods on the ScopedPtrDeque class to appear in the deque. 34 class iterator : public std::deque<T*>::iterator { 35 public: 36 explicit iterator(const typename std::deque<T*>::iterator& other) 37 : std::deque<T*>::iterator(other) {} 38 T* const& operator*() { return std::deque<T*>::iterator::operator*(); } 39 }; 40 #endif 41 42 ScopedPtrDeque() {} 43 44 ~ScopedPtrDeque() { 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_front() { 74 scoped_ptr<T> ret(front()); 75 data_.pop_front(); 76 return ret.Pass(); 77 } 78 79 scoped_ptr<T> take_back() { 80 scoped_ptr<T> ret(back()); 81 data_.pop_back(); 82 return ret.Pass(); 83 } 84 85 void clear() { 86 STLDeleteElements(&data_); 87 } 88 89 void push_front(scoped_ptr<T> item) { 90 data_.push_front(item.release()); 91 } 92 93 void push_back(scoped_ptr<T> item) { 94 data_.push_back(item.release()); 95 } 96 97 void insert(iterator position, scoped_ptr<T> item) { 98 DCHECK(position <= end()); 99 data_.insert(position, item.release()); 100 } 101 102 scoped_ptr<T> take(iterator position) { 103 DCHECK(position < end()); 104 scoped_ptr<T> ret(*position); 105 data_.erase(position); 106 return ret.Pass(); 107 } 108 109 void swap(iterator a, iterator b) { 110 DCHECK(a < end()); 111 DCHECK(b < end()); 112 if (a == end() || b == end() || a == b) 113 return; 114 typename std::deque<T*>::iterator writable_a = a; 115 typename std::deque<T*>::iterator writable_b = b; 116 std::swap(*writable_a, *writable_b); 117 } 118 119 iterator begin() { return static_cast<iterator>(data_.begin()); } 120 const_iterator begin() const { return data_.begin(); } 121 iterator end() { return static_cast<iterator>(data_.end()); } 122 const_iterator end() const { return data_.end(); } 123 124 reverse_iterator rbegin() { return data_.rbegin(); } 125 const_reverse_iterator rbegin() const { return data_.rbegin(); } 126 reverse_iterator rend() { return data_.rend(); } 127 const_reverse_iterator rend() const { return data_.rend(); } 128 129 private: 130 std::deque<T*> data_; 131 132 DISALLOW_COPY_AND_ASSIGN(ScopedPtrDeque); 133 }; 134 135 } // namespace cc 136 137 #endif // CC_BASE_SCOPED_PTR_DEQUE_H_ 138