1 // Copyright 2014 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.
5 #ifndef CC_QUADS_LIST_CONTAINER_H_
6 #define CC_QUADS_LIST_CONTAINER_H_
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "cc/base/cc_export.h"
13 class SharedQuadState
;
16 // This class is a container type that handles allocating contiguous memory for
17 // new elements and traversing through elements with either iterator or reverse
18 // iterator. Since this container hands out raw pointers of its elements, it is
19 // very important that this container never reallocate its memory so those raw
20 // pointer will continue to be valid. This class is used to contain
21 // SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, to hold
22 // DrawQuads, the allocations size of each element in this class is
23 // LargestDrawQuadSize while BaseElementType is DrawQuad.
24 template <class BaseElementType
>
25 class CC_EXPORT ListContainer
{
27 // BaseElementType is the type of raw pointers this class hands out; however,
28 // its derived classes might require different memory sizes.
29 // max_size_for_derived_class the largest memory size required for all the
30 // derived classes to use for allocation.
31 explicit ListContainer(size_t max_size_for_derived_class
);
32 // This constructor omits input variable for max_size_for_derived_class. This
33 // is used when there is no derived classes from BaseElementType we need to
34 // worry about, and allocation size is just sizeof(BaseElementType).
36 // This constructor reserves the requested memory up front so only single
37 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
39 ListContainer(size_t max_size_for_derived_class
,
40 size_t num_of_elements_to_reserve_for
);
44 // This class deals only with char* and void*. It does allocation and passing
45 // out raw pointers, as well as memory deallocation when being destroyed.
46 class CC_EXPORT ListContainerCharAllocator
;
48 // This class points to a certain position inside memory of
49 // ListContainerCharAllocator. It is a base class for ListContainer iterators.
50 struct CC_EXPORT PositionInListContainerCharAllocator
{
51 ListContainerCharAllocator
* ptr_to_container
;
55 PositionInListContainerCharAllocator(
56 const PositionInListContainerCharAllocator
& other
);
58 PositionInListContainerCharAllocator(ListContainerCharAllocator
* container
,
62 bool operator==(const PositionInListContainerCharAllocator
& other
) const;
63 bool operator!=(const PositionInListContainerCharAllocator
& other
) const;
65 PositionInListContainerCharAllocator
Increment();
66 PositionInListContainerCharAllocator
ReverseIncrement();
69 // Iterator classes that can be used to access data.
70 /////////////////////////////////////////////////////////////////
71 class CC_EXPORT Iterator
: public PositionInListContainerCharAllocator
{
72 // This class is only defined to forward iterate through
73 // ListContainerCharAllocator.
75 Iterator(ListContainerCharAllocator
* container
,
80 BaseElementType
* operator->() const;
81 BaseElementType
* operator*() const;
82 Iterator
operator++(int unused_post_increment
);
83 Iterator
& operator++();
88 // This is used to track how many increment has happened since begin(). It
89 // is used to avoid double increment at places an index reference is
90 // needed. For iterator this means begin() corresponds to index 0 and end()
91 // corresponds to index |size|.
95 class CC_EXPORT ConstIterator
: public PositionInListContainerCharAllocator
{
96 // This class is only defined to forward iterate through
97 // ListContainerCharAllocator.
99 ConstIterator(ListContainerCharAllocator
* container
,
103 ConstIterator(const Iterator
& other
); // NOLINT
105 const BaseElementType
* operator->() const;
106 const BaseElementType
* operator*() const;
107 ConstIterator
operator++(int unused_post_increment
);
108 ConstIterator
& operator++();
110 size_t index() const;
113 // This is used to track how many increment has happened since begin(). It
114 // is used to avoid double increment at places an index reference is
115 // needed. For iterator this means begin() corresponds to index 0 and end()
116 // corresponds to index |size|.
120 class CC_EXPORT ReverseIterator
121 : public PositionInListContainerCharAllocator
{
122 // This class is only defined to reverse iterate through
123 // ListContainerCharAllocator.
125 ReverseIterator(ListContainerCharAllocator
* container
,
130 BaseElementType
* operator->() const;
131 BaseElementType
* operator*() const;
132 ReverseIterator
operator++(int unused_post_increment
);
133 ReverseIterator
& operator++();
135 size_t index() const;
138 // This is used to track how many increment has happened since rbegin(). It
139 // is used to avoid double increment at places an index reference is
140 // needed. For reverse iterator this means rbegin() corresponds to index 0
141 // and rend() corresponds to index |size|.
145 class CC_EXPORT ConstReverseIterator
146 : public PositionInListContainerCharAllocator
{
147 // This class is only defined to reverse iterate through
148 // ListContainerCharAllocator.
150 ConstReverseIterator(ListContainerCharAllocator
* container
,
154 ConstReverseIterator(const ReverseIterator
& other
); // NOLINT
155 ~ConstReverseIterator();
156 const BaseElementType
* operator->() const;
157 const BaseElementType
* operator*() const;
158 ConstReverseIterator
operator++(int unused_post_increment
);
159 ConstReverseIterator
& operator++();
161 size_t index() const;
164 // This is used to track how many increment has happened since rbegin(). It
165 // is used to avoid double increment at places an index reference is
166 // needed. For reverse iterator this means rbegin() corresponds to index 0
167 // and rend() corresponds to index |size|.
171 // When called, all raw pointers that have been handed out are no longer
172 // valid. Use with caution.
173 // This function does not deallocate memory.
174 void EraseAndInvalidateAllPointers(Iterator position
);
176 ConstReverseIterator
crbegin() const;
177 ConstReverseIterator
crend() const;
178 ConstReverseIterator
rbegin() const;
179 ConstReverseIterator
rend() const;
180 ReverseIterator
rbegin();
181 ReverseIterator
rend();
182 ConstIterator
cbegin() const;
183 ConstIterator
cend() const;
184 ConstIterator
begin() const;
185 ConstIterator
end() const;
189 // TODO(weiliangc): front(), back() and ElementAt() function should return
190 // reference, consistent with container-of-object.
191 BaseElementType
* front();
192 BaseElementType
* back();
193 const BaseElementType
* front() const;
194 const BaseElementType
* back() const;
196 BaseElementType
* ElementAt(size_t index
);
197 const BaseElementType
* ElementAt(size_t index
) const;
199 // Take in derived element type and construct it at location generated by
201 template <typename DerivedElementType
>
202 DerivedElementType
* AllocateAndConstruct() {
203 return new (Allocate(sizeof(DerivedElementType
))) DerivedElementType
;
205 // Take in derived element type and copy construct it at location generated by
207 template <typename DerivedElementType
>
208 DerivedElementType
* AllocateAndCopyFrom(const DerivedElementType
* source
) {
209 return new (Allocate(sizeof(DerivedElementType
)))
210 DerivedElementType(*source
);
212 // Construct a new element on top of an existing one.
213 template <typename DerivedElementType
>
214 DerivedElementType
* ReplaceExistingElement(Iterator at
) {
215 at
->~BaseElementType();
216 return new (*at
) DerivedElementType();
223 size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
226 // Hands out memory location for an element at the end of data structure.
227 void* Allocate(size_t size_of_actual_element_in_bytes
);
229 scoped_ptr
<ListContainerCharAllocator
> data_
;
231 DISALLOW_COPY_AND_ASSIGN(ListContainer
);
234 #if !defined(COMPILER_MSVC)
235 extern template class ListContainer
<SharedQuadState
>;
236 extern template class ListContainer
<DrawQuad
>;
240 #endif // CC_QUADS_LIST_CONTAINER_H_