xref: /aosp_15_r20/external/skia/src/base/SkArenaAllocList.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2017 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkArenaAllocList_DEFINED
9 #define SkArenaAllocList_DEFINED
10 
11 #include "include/private/base/SkAssert.h"
12 #include "src/base/SkArenaAlloc.h" // IWYU pragma: keep
13 
14 #include <utility>
15 
16 /**
17  * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns
18  * the elements. This supports forward iteration and range based for loops.
19  */
20 template <typename T>
21 class SkArenaAllocList {
22 private:
23     struct Node;
24 
25 public:
26     SkArenaAllocList() = default;
27 
reset()28     void reset() { fHead = fTail = nullptr; }
29 
30     template <typename... Args>
31     inline T& append(SkArenaAlloc* arena, Args... args);
32 
33     class Iter {
34     public:
35         Iter() = default;
36         inline Iter& operator++();
37         T& operator*() const { return fCurr->fT; }
38         T* operator->() const { return &fCurr->fT; }
39         bool operator==(const Iter& that) const { return fCurr == that.fCurr; }
40         bool operator!=(const Iter& that) const { return !(*this == that); }
41 
42     private:
43         friend class SkArenaAllocList;
Iter(Node * node)44         explicit Iter(Node* node) : fCurr(node) {}
45         Node* fCurr = nullptr;
46     };
47 
begin()48     Iter begin() { return Iter(fHead); }
end()49     Iter end() { return Iter(); }
tail()50     Iter tail() { return Iter(fTail); }
51 
52 private:
53     struct Node {
54         template <typename... Args>
NodeNode55         Node(Args... args) : fT(std::forward<Args>(args)...) {}
56         T fT;
57         Node* fNext = nullptr;
58     };
59     Node* fHead = nullptr;
60     Node* fTail = nullptr;
61 };
62 
63 template <typename T>
64 template <typename... Args>
append(SkArenaAlloc * arena,Args...args)65 T& SkArenaAllocList<T>::append(SkArenaAlloc* arena, Args... args) {
66     SkASSERT(!fHead == !fTail);
67     auto* n = arena->make<Node>(std::forward<Args>(args)...);
68     if (!fTail) {
69         fHead = fTail = n;
70     } else {
71         fTail = fTail->fNext = n;
72     }
73     return fTail->fT;
74 }
75 
76 template <typename T>
77 typename SkArenaAllocList<T>::Iter& SkArenaAllocList<T>::Iter::operator++() {
78     fCurr = fCurr->fNext;
79     return *this;
80 }
81 
82 #endif
83