Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: ui/base/models/list_model.h

Issue 2379863002: Fix object ownership in ui/base/models. (Closed)
Patch Set: fix Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef UI_BASE_MODELS_LIST_MODEL_H_ 5 #ifndef UI_BASE_MODELS_LIST_MODEL_H_
6 #define UI_BASE_MODELS_LIST_MODEL_H_ 6 #define UI_BASE_MODELS_LIST_MODEL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <memory> 10 #include <memory>
11 #include <utility> 11 #include <utility>
12 #include <vector>
12 13
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/macros.h" 15 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/observer_list.h" 17 #include "base/observer_list.h"
18 #include "ui/base/models/list_model_observer.h" 18 #include "ui/base/models/list_model_observer.h"
19 19
20 namespace ui { 20 namespace ui {
21 21
22 // A list model that manages a list of ItemType pointers. Items added to the 22 // A list model that manages a list of ItemType pointers. Items added to the
23 // model are owned by the model. An item can be taken out of the model by 23 // model are owned by the model. An item can be taken out of the model by
24 // RemoveAt. 24 // RemoveAt.
25 template <class ItemType> 25 template <class ItemType>
26 class ListModel { 26 class ListModel {
27 public: 27 public:
28 using ItemList = std::vector<std::unique_ptr<ItemType>>;
29
28 ListModel() {} 30 ListModel() {}
29 ~ListModel() {} 31 ~ListModel() {}
30 32
31 // Adds |item| at the |index| into |items_|. Takes ownership of |item|. 33 // Adds |item| at the |index| into |items_|. Returns a raw pointer.
32 void AddAt(size_t index, ItemType* item) { 34 ItemType* AddAt(size_t index, std::unique_ptr<ItemType> item) {
33 DCHECK_LE(index, item_count()); 35 DCHECK_LE(index, item_count());
34 items_.insert(items_.begin() + index, item); 36 ItemType* item_ptr = item.get();
37 items_.insert(items_.begin() + index, std::move(item));
35 NotifyItemsAdded(index, 1); 38 NotifyItemsAdded(index, 1);
39 return item_ptr;
36 } 40 }
37 41
38 // Convenience function to append an item to the model. 42 // Convenience function to append an item to the model.
39 void Add(ItemType* item) { 43 ItemType* Add(std::unique_ptr<ItemType> item) {
40 AddAt(item_count(), item); 44 return AddAt(item_count(), std::move(item));
41 } 45 }
42 46
43 // Removes the item at |index| from |items_| without deleting it. 47 // Removes the item at |index| from |items_| without deleting it.
44 // Returns a scoped pointer containing the removed item. 48 // Returns a scoped pointer containing the removed item.
45 std::unique_ptr<ItemType> RemoveAt(size_t index) { 49 std::unique_ptr<ItemType> RemoveAt(size_t index) {
46 DCHECK_LT(index, item_count()); 50 DCHECK_LT(index, item_count());
47 ItemType* item = items_[index]; 51 std::unique_ptr<ItemType> item = std::move(items_[index]);
48 items_.weak_erase(items_.begin() + index); 52 items_.erase(items_.begin() + index);
49 NotifyItemsRemoved(index, 1); 53 NotifyItemsRemoved(index, 1);
50 return base::WrapUnique<ItemType>(item); 54 return item;
51 } 55 }
52 56
53 // Removes all items from the model. This does NOT delete the items. 57 // Removes all items from the model without deleting them.
54 void RemoveAll() { 58 // Returns a vector containing the removed items.
55 size_t count = item_count(); 59 ItemList RemoveAll() {
56 items_.weak_clear(); 60 ItemList result;
57 NotifyItemsRemoved(0, count); 61 result.swap(items_);
62 NotifyItemsRemoved(0, result.size());
63 return result;
58 } 64 }
59 65
60 // Removes the item at |index| from |items_| and deletes it. 66 // Removes the item at |index| from |items_| and deletes it.
61 void DeleteAt(size_t index) { 67 void DeleteAt(size_t index) {
62 std::unique_ptr<ItemType> item = RemoveAt(index); 68 std::unique_ptr<ItemType> item = RemoveAt(index);
63 // |item| will be deleted on destruction. 69 // |item| will be deleted on destruction.
64 } 70 }
65 71
66 // Removes and deletes all items from the model. 72 // Removes and deletes all items from the model.
67 void DeleteAll() { 73 void DeleteAll() {
68 ScopedVector<ItemType> to_be_deleted(std::move(items_)); 74 ItemList to_be_deleted;
75 to_be_deleted.swap(items_);
69 NotifyItemsRemoved(0, to_be_deleted.size()); 76 NotifyItemsRemoved(0, to_be_deleted.size());
70 } 77 }
71 78
72 // Moves the item at |index| to |target_index|. |target_index| is in terms 79 // Moves the item at |index| to |target_index|. |target_index| is in terms
73 // of the model *after* the item at |index| is removed. 80 // of the model *after* the item at |index| is removed.
74 void Move(size_t index, size_t target_index) { 81 void Move(size_t index, size_t target_index) {
75 DCHECK_LT(index, item_count()); 82 DCHECK_LT(index, item_count());
76 DCHECK_LT(target_index, item_count()); 83 DCHECK_LT(target_index, item_count());
77 84
78 if (index == target_index) 85 if (index == target_index)
79 return; 86 return;
80 87
81 ItemType* item = items_[index]; 88 std::unique_ptr<ItemType> item = std::move(items_[index]);
82 items_.weak_erase(items_.begin() + index); 89 items_.erase(items_.begin() + index);
83 items_.insert(items_.begin() + target_index, item); 90 items_.insert(items_.begin() + target_index, std::move(item));
84 NotifyItemMoved(index, target_index); 91 NotifyItemMoved(index, target_index);
85 } 92 }
86 93
87 void AddObserver(ListModelObserver* observer) { 94 void AddObserver(ListModelObserver* observer) {
88 observers_.AddObserver(observer); 95 observers_.AddObserver(observer);
89 } 96 }
90 97
91 void RemoveObserver(ListModelObserver* observer) { 98 void RemoveObserver(ListModelObserver* observer) {
92 observers_.RemoveObserver(observer); 99 observers_.RemoveObserver(observer);
93 } 100 }
(...skipping 19 matching lines...) Expand all
113 void NotifyItemsChanged(size_t start, size_t count) { 120 void NotifyItemsChanged(size_t start, size_t count) {
114 FOR_EACH_OBSERVER(ListModelObserver, 121 FOR_EACH_OBSERVER(ListModelObserver,
115 observers_, 122 observers_,
116 ListItemsChanged(start, count)); 123 ListItemsChanged(start, count));
117 } 124 }
118 125
119 size_t item_count() const { return items_.size(); } 126 size_t item_count() const { return items_.size(); }
120 127
121 const ItemType* GetItemAt(size_t index) const { 128 const ItemType* GetItemAt(size_t index) const {
122 DCHECK_LT(index, item_count()); 129 DCHECK_LT(index, item_count());
123 return items_[index]; 130 return items_[index].get();
124 } 131 }
125 ItemType* GetItemAt(size_t index) { 132 ItemType* GetItemAt(size_t index) {
126 return const_cast<ItemType*>( 133 return const_cast<ItemType*>(
127 const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index)); 134 const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index));
128 } 135 }
129 136
130 // Iteration interface. 137 // Iteration interface.
131 typename ScopedVector<ItemType>::iterator begin() { return items_.begin(); } 138 typename ItemList::iterator begin() { return items_.begin(); }
132 typename ScopedVector<ItemType>::const_iterator begin() const { 139 typename ItemList::const_iterator begin() const { return items_.begin(); }
133 return items_.begin(); 140 typename ItemList::iterator end() { return items_.end(); }
134 } 141 typename ItemList::const_iterator end() const { return items_.end(); }
135 typename ScopedVector<ItemType>::iterator end() { return items_.end(); }
136 typename ScopedVector<ItemType>::const_iterator end() const {
137 return items_.end();
138 }
139 142
140 private: 143 private:
141 ScopedVector<ItemType> items_; 144 ItemList items_;
142 base::ObserverList<ListModelObserver> observers_; 145 base::ObserverList<ListModelObserver> observers_;
143 146
144 DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>); 147 DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>);
145 }; 148 };
146 149
147 } // namespace ui 150 } // namespace ui
148 151
149 #endif // UI_BASE_MODELS_LIST_MODEL_H_ 152 #endif // UI_BASE_MODELS_LIST_MODEL_H_
OLDNEW
« no previous file with comments | « ui/app_list/views/search_result_page_view_unittest.cc ('k') | ui/base/models/list_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698