SkArenaAllocList.h 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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. #ifndef SkArenaAllocList_DEFINED
  8. #define SkArenaAllocList_DEFINED
  9. #include "include/core/SkTypes.h"
  10. #include "src/core/SkArenaAlloc.h"
  11. /**
  12. * A singly linked list of Ts stored in a SkArenaAlloc. The arena rather than the list owns
  13. * the elements. This supports forward iteration and range based for loops.
  14. */
  15. template <typename T>
  16. class SkArenaAllocList {
  17. private:
  18. struct Node;
  19. public:
  20. SkArenaAllocList() = default;
  21. void reset() { fHead = fTail = nullptr; }
  22. template <typename... Args>
  23. inline T& append(SkArenaAlloc* arena, Args... args);
  24. class Iter {
  25. public:
  26. Iter() = default;
  27. inline Iter& operator++();
  28. T& operator*() const { return fCurr->fT; }
  29. T* operator->() const { return &fCurr->fT; }
  30. bool operator==(const Iter& that) const { return fCurr == that.fCurr; }
  31. bool operator!=(const Iter& that) const { return !(*this == that); }
  32. private:
  33. friend class SkArenaAllocList;
  34. explicit Iter(Node* node) : fCurr(node) {}
  35. Node* fCurr = nullptr;
  36. };
  37. Iter begin() { return Iter(fHead); }
  38. Iter end() { return Iter(); }
  39. Iter tail() { return Iter(fTail); }
  40. private:
  41. struct Node {
  42. template <typename... Args>
  43. Node(Args... args) : fT(std::forward<Args>(args)...) {}
  44. T fT;
  45. Node* fNext = nullptr;
  46. };
  47. Node* fHead = nullptr;
  48. Node* fTail = nullptr;
  49. };
  50. template <typename T>
  51. template <typename... Args>
  52. T& SkArenaAllocList<T>::append(SkArenaAlloc* arena, Args... args) {
  53. SkASSERT(!fHead == !fTail);
  54. auto* n = arena->make<Node>(std::forward<Args>(args)...);
  55. if (!fTail) {
  56. fHead = fTail = n;
  57. } else {
  58. fTail = fTail->fNext = n;
  59. }
  60. return fTail->fT;
  61. }
  62. template <typename T>
  63. typename SkArenaAllocList<T>::Iter& SkArenaAllocList<T>::Iter::operator++() {
  64. fCurr = fCurr->fNext;
  65. return *this;
  66. }
  67. #endif