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"
15 class SharedQuadState
;
17 // This class is a container type that handles allocating contiguous memory for
18 // new elements and traversing through elements with either iterator or reverse
19 // iterator. Since this container hands out raw pointers of its elements, it is
20 // very important that this container never reallocate its memory so those raw
21 // pointer will continue to be valid. This class is used to contain
22 // SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, to hold
23 // DrawQuads, the allocations size of each element in this class is
24 // LargestDrawQuadSize while BaseElementType is DrawQuad.
25 template <class BaseElementType
>
26 class CC_EXPORT ListContainer
{
28 // BaseElementType is the type of raw pointers this class hands out; however,
29 // its derived classes might require different memory sizes.
30 // max_size_for_derived_class the largest memory size required for all the
31 // derived classes to use for allocation.
32 explicit ListContainer(size_t max_size_for_derived_class
);
33 // This constructor omits input variable for max_size_for_derived_class. This
34 // is used when there is no derived classes from BaseElementType we need to
35 // worry about, and allocation size is just sizeof(BaseElementType).
37 // This constructor reserves the requested memory up front so only single
38 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
40 ListContainer(size_t max_size_for_derived_class
,
41 size_t num_of_elements_to_reserve_for
);
45 // This class deals only with char* and void*. It does allocation and passing
46 // out raw pointers, as well as memory deallocation when being destroyed.
47 class CC_EXPORT ListContainerCharAllocator
;
49 // This class points to a certain position inside memory of
50 // ListContainerCharAllocator. It is a base class for ListContainer iterators.
51 struct CC_EXPORT PositionInListContainerCharAllocator
{
52 ListContainerCharAllocator
* ptr_to_container
;
56 PositionInListContainerCharAllocator(
57 const PositionInListContainerCharAllocator
& other
);
59 PositionInListContainerCharAllocator(ListContainerCharAllocator
* container
,
63 bool operator==(const PositionInListContainerCharAllocator
& other
) const;
64 bool operator!=(const PositionInListContainerCharAllocator
& other
) const;
66 PositionInListContainerCharAllocator
Increment();
67 PositionInListContainerCharAllocator
ReverseIncrement();
70 // Iterator classes that can be used to access data.
71 /////////////////////////////////////////////////////////////////
72 class CC_EXPORT Iterator
: public PositionInListContainerCharAllocator
{
73 // This class is only defined to forward iterate through
74 // ListContainerCharAllocator.
76 Iterator(ListContainerCharAllocator
* container
,
81 BaseElementType
* operator->() const;
82 BaseElementType
* operator*() const;
83 Iterator
operator++(int unused_post_increment
);
84 Iterator
& operator++();
89 // This is used to track how many increment has happened since begin(). It
90 // is used to avoid double increment at places an index reference is
91 // needed. For iterator this means begin() corresponds to index 0 and end()
92 // corresponds to index |size|.
96 class CC_EXPORT ConstIterator
: public PositionInListContainerCharAllocator
{
97 // This class is only defined to forward iterate through
98 // ListContainerCharAllocator.
100 ConstIterator(ListContainerCharAllocator
* container
,
104 ConstIterator(const Iterator
& other
); // NOLINT
106 const BaseElementType
* operator->() const;
107 const BaseElementType
* operator*() const;
108 ConstIterator
operator++(int unused_post_increment
);
109 ConstIterator
& operator++();
111 size_t index() const;
114 // This is used to track how many increment has happened since begin(). It
115 // is used to avoid double increment at places an index reference is
116 // needed. For iterator this means begin() corresponds to index 0 and end()
117 // corresponds to index |size|.
121 class CC_EXPORT ReverseIterator
122 : public PositionInListContainerCharAllocator
{
123 // This class is only defined to reverse iterate through
124 // ListContainerCharAllocator.
126 ReverseIterator(ListContainerCharAllocator
* container
,
131 BaseElementType
* operator->() const;
132 BaseElementType
* operator*() const;
133 ReverseIterator
operator++(int unused_post_increment
);
134 ReverseIterator
& operator++();
136 size_t index() const;
139 // This is used to track how many increment has happened since rbegin(). It
140 // is used to avoid double increment at places an index reference is
141 // needed. For reverse iterator this means rbegin() corresponds to index 0
142 // and rend() corresponds to index |size|.
146 class CC_EXPORT ConstReverseIterator
147 : public PositionInListContainerCharAllocator
{
148 // This class is only defined to reverse iterate through
149 // ListContainerCharAllocator.
151 ConstReverseIterator(ListContainerCharAllocator
* container
,
155 ConstReverseIterator(const ReverseIterator
& other
); // NOLINT
156 ~ConstReverseIterator();
157 const BaseElementType
* operator->() const;
158 const BaseElementType
* operator*() const;
159 ConstReverseIterator
operator++(int unused_post_increment
);
160 ConstReverseIterator
& operator++();
162 size_t index() const;
165 // This is used to track how many increment has happened since rbegin(). It
166 // is used to avoid double increment at places an index reference is
167 // needed. For reverse iterator this means rbegin() corresponds to index 0
168 // and rend() corresponds to index |size|.
172 // When called, all raw pointers that have been handed out are no longer
173 // valid. Use with caution.
174 // This function does not deallocate memory.
175 void EraseAndInvalidateAllPointers(Iterator position
);
177 ConstReverseIterator
crbegin() const;
178 ConstReverseIterator
crend() const;
179 ConstReverseIterator
rbegin() const;
180 ConstReverseIterator
rend() const;
181 ReverseIterator
rbegin();
182 ReverseIterator
rend();
183 ConstIterator
cbegin() const;
184 ConstIterator
cend() const;
185 ConstIterator
begin() const;
186 ConstIterator
end() const;
190 // TODO(weiliangc): front(), back() and ElementAt() function should return
191 // reference, consistent with container-of-object.
192 BaseElementType
* front();
193 BaseElementType
* back();
194 const BaseElementType
* front() const;
195 const BaseElementType
* back() const;
197 BaseElementType
* ElementAt(size_t index
);
198 const BaseElementType
* ElementAt(size_t index
) const;
200 // Take in derived element type and construct it at location generated by
202 template <typename DerivedElementType
>
203 DerivedElementType
* AllocateAndConstruct() {
204 return new (Allocate(sizeof(DerivedElementType
))) DerivedElementType
;
206 // Take in derived element type and copy construct it at location generated by
208 template <typename DerivedElementType
>
209 DerivedElementType
* AllocateAndCopyFrom(const DerivedElementType
* source
) {
210 return new (Allocate(sizeof(DerivedElementType
)))
211 DerivedElementType(*source
);
213 // Construct a new element on top of an existing one.
214 template <typename DerivedElementType
>
215 DerivedElementType
* ReplaceExistingElement(Iterator at
) {
216 at
->~BaseElementType();
217 return new (*at
) DerivedElementType();
224 size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
227 // Hands out memory location for an element at the end of data structure.
228 void* Allocate(size_t size_of_actual_element_in_bytes
);
230 scoped_ptr
<ListContainerCharAllocator
> data_
;
232 DISALLOW_COPY_AND_ASSIGN(ListContainer
);
235 #if !defined(COMPILER_MSVC)
236 extern template class ListContainer
<SharedQuadState
>;
237 extern template class ListContainer
<DrawQuad
>;
238 extern template class ListContainer
<DisplayItem
>;
242 #endif // CC_QUADS_LIST_CONTAINER_H_