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