/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkArenaAllocList_DEFINED #define SkArenaAllocList_DEFINED #include "SkArenaAlloc.h" /** * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns * the elements. This supports forward iteration and range based for loops. */ template class SkArenaAllocList { private: struct Node; public: SkArenaAllocList() = default; void reset() { fHead = fTail = nullptr; } template inline T& append(SkArenaAlloc* arena, Args... args); class Iter { public: Iter() = default; inline Iter& operator++(); T& operator*() const { return fCurr->fT; } T* operator->() const { return &fCurr->fT; } bool operator==(const Iter& that) const { return fCurr == that.fCurr; } bool operator!=(const Iter& that) const { return !(*this == that); } private: friend class SkArenaAllocList; explicit Iter(Node* node) : fCurr(node) {} Node* fCurr = nullptr; }; Iter begin() { return Iter(fHead); } Iter end() { return Iter(); } Iter tail() { return Iter(fTail); } private: struct Node { template Node(Args... args) : fT(std::forward(args)...) {} T fT; Node* fNext = nullptr; }; Node* fHead = nullptr; Node* fTail = nullptr; }; template template T& SkArenaAllocList::append(SkArenaAlloc* arena, Args... args) { SkASSERT(!fHead == !fTail); auto* n = arena->make(std::forward(args)...); if (!fTail) { fHead = fTail = n; } else { fTail = fTail->fNext = n; } return fTail->fT; } template typename SkArenaAllocList::Iter& SkArenaAllocList::Iter::operator++() { fCurr = fCurr->fNext; return *this; } #endif