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)65T& 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