1 // Copyright 2015 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_LIST_CONTAINER_HELPER_H_
6 #define CC_BASE_LIST_CONTAINER_HELPER_H_
7 
8 #include <stddef.h>
9 
10 #include <memory>
11 
12 #include "cc/base/base_export.h"
13 
14 namespace cc {
15 
16 // Helper class for ListContainer non-templated logic. All methods are private,
17 // and only exposed to friend classes.
18 // For usage, see comments in ListContainer (list_container.h).
19 class CC_BASE_EXPORT ListContainerHelper final {
20  private:
21   template <typename T>
22   friend class ListContainer;
23 
24   explicit ListContainerHelper(size_t alignment,
25                                size_t max_size_for_derived_class,
26                                size_t num_of_elements_to_reserve_for);
27   ListContainerHelper(const ListContainerHelper&) = delete;
28   ~ListContainerHelper();
29 
30   ListContainerHelper& operator=(const ListContainerHelper&) = delete;
31 
32   // This class deals only with char* and void*. It does allocation and passing
33   // out raw pointers, as well as memory deallocation when being destroyed.
34   class CharAllocator;
35 
36   // This class points to a certain position inside memory of
37   // CharAllocator. It is a base class for ListContainer iterators.
38   struct CC_BASE_EXPORT PositionInCharAllocator {
39     CharAllocator* ptr_to_container;
40     size_t vector_index;
41     char* item_iterator;
42 
43     PositionInCharAllocator(const PositionInCharAllocator& other);
44 
45     PositionInCharAllocator(CharAllocator* container,
46                             size_t vector_ind,
47                             char* item_iter);
48 
49     bool operator==(const PositionInCharAllocator& other) const;
50     bool operator!=(const PositionInCharAllocator& other) const;
51 
52     PositionInCharAllocator Increment();
53     PositionInCharAllocator ReverseIncrement();
54   };
55 
56   // Iterator classes that can be used to access data.
57   /////////////////////////////////////////////////////////////////
58   class CC_BASE_EXPORT Iterator : public PositionInCharAllocator {
59     // This class is only defined to forward iterate through
60     // CharAllocator.
61    public:
62     Iterator(CharAllocator* container,
63              size_t vector_ind,
64              char* item_iter,
65              size_t index);
66     ~Iterator();
67 
68     size_t index() const;
69 
70    protected:
71     // This is used to track how many increment has happened since begin(). It
72     // is used to avoid double increment at places an index reference is
73     // needed. For iterator this means begin() corresponds to index 0 and end()
74     // corresponds to index |size|.
75     size_t index_;
76   };
77 
78   class CC_BASE_EXPORT ConstIterator : public PositionInCharAllocator {
79     // This class is only defined to forward iterate through
80     // CharAllocator.
81    public:
82     ConstIterator(CharAllocator* container,
83                   size_t vector_ind,
84                   char* item_iter,
85                   size_t index);
86     ConstIterator(const Iterator& other);  // NOLINT
87     ~ConstIterator();
88 
89     size_t index() const;
90 
91    protected:
92     // This is used to track how many increment has happened since begin(). It
93     // is used to avoid double increment at places an index reference is
94     // needed. For iterator this means begin() corresponds to index 0 and end()
95     // corresponds to index |size|.
96     size_t index_;
97   };
98 
99   class CC_BASE_EXPORT ReverseIterator : public PositionInCharAllocator {
100     // This class is only defined to reverse iterate through
101     // CharAllocator.
102    public:
103     ReverseIterator(CharAllocator* container,
104                     size_t vector_ind,
105                     char* item_iter,
106                     size_t index);
107     ~ReverseIterator();
108 
109     size_t index() const;
110 
111    protected:
112     // This is used to track how many increment has happened since rbegin(). It
113     // is used to avoid double increment at places an index reference is
114     // needed. For reverse iterator this means rbegin() corresponds to index 0
115     // and rend() corresponds to index |size|.
116     size_t index_;
117   };
118 
119   class CC_BASE_EXPORT ConstReverseIterator : public PositionInCharAllocator {
120     // This class is only defined to reverse iterate through
121     // CharAllocator.
122    public:
123     ConstReverseIterator(CharAllocator* container,
124                          size_t vector_ind,
125                          char* item_iter,
126                          size_t index);
127     ConstReverseIterator(const ReverseIterator& other);  // NOLINT
128     ~ConstReverseIterator();
129 
130     size_t index() const;
131 
132    protected:
133     // This is used to track how many increment has happened since rbegin(). It
134     // is used to avoid double increment at places an index reference is
135     // needed. For reverse iterator this means rbegin() corresponds to index 0
136     // and rend() corresponds to index |size|.
137     size_t index_;
138   };
139 
140   // Unlike the ListContainer methods, these do not invoke element destructors.
141   void RemoveLast();
142   void EraseAndInvalidateAllPointers(Iterator* position);
143   void InsertBeforeAndInvalidateAllPointers(Iterator* position,
144                                             size_t number_of_elements);
145 
146   ConstReverseIterator crbegin() const;
147   ConstReverseIterator crend() const;
148   ReverseIterator rbegin();
149   ReverseIterator rend();
150   ConstIterator cbegin() const;
151   ConstIterator cend() const;
152   Iterator begin();
153   Iterator end();
154 
155   Iterator IteratorAt(size_t index);
156   ConstIterator IteratorAt(size_t index) const;
157 
158   size_t size() const;
159   bool empty() const;
160 
161   size_t MaxSizeForDerivedClass() const;
162 
163   size_t GetCapacityInBytes() const;
164 
165   // Unlike the ListContainer method, this one does not invoke element
166   // destructors.
167   void clear();
168 
169   size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
170 
171   // Hands out memory location for an element at the end of data structure.
172   void* Allocate(size_t alignment, size_t size_of_actual_element_in_bytes);
173 
174   std::unique_ptr<CharAllocator> data_;
175 };
176 
177 }  // namespace cc
178 
179 #endif  // CC_BASE_LIST_CONTAINER_HELPER_H_
180