Chromium Code Reviews| Index: src/pdf/SkSinglyLinkedList.h |
| diff --git a/src/pdf/SkSinglyLinkedList.h b/src/pdf/SkSinglyLinkedList.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ca23bb7e01bcd2dff650eee3bdccd7c9a187ad19 |
| --- /dev/null |
| +++ b/src/pdf/SkSinglyLinkedList.h |
| @@ -0,0 +1,95 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| +#ifndef SkSinglyLinkedList_DEFINED |
| +#define SkSinglyLinkedList_DEFINED |
| + |
| +#include <new> |
| +#include <utility> |
| + |
| +#include "SkTypes.h" |
| + |
| +template <typename T> class SkSinglyLinkedList { |
| + struct Node; |
| +public: |
| + SkSinglyLinkedList() : fHead(nullptr), fTail(nullptr) {} |
| + ~SkSinglyLinkedList() { |
| + SkASSERT(fHead != nullptr || nullptr == fTail); |
| + Node* node = fHead; |
| + while (node) { |
| + Node* next = node->fNext; |
| + SkASSERT(next != nullptr || node == fTail); |
| + delete node; |
| + node = next; |
| + } |
| + } |
| + void reset() { |
| + this->~SkSinglyLinkedList(); |
| + new (this) SkSinglyLinkedList<T>(); |
|
bungeman-skia
2016/03/28 16:28:18
Instead of doing it this way, put the clearing cod
hal.canary
2016/03/28 17:13:30
Done.
|
| + } |
| + T* back() { return fTail ? &fTail->fData : nullptr; } |
| + T* front() { return fHead ? &fHead->fData : nullptr; } |
| + int count() { |
|
bungeman-skia
2016/03/28 16:28:17
Is it expected that count will be O(n)?
hal.canary
2016/03/28 16:31:22
only used in asserts.
|
| + int count = 0; |
| + for (Node* node = fHead; node; node = node->fNext) { |
| + ++count; |
| + } |
| + return count; |
| + } |
| + void pop_front() { |
| + if (Node* node = fHead) { |
| + fHead = node->fNext; |
| + delete node; |
| + if (fHead == nullptr) { |
| + fTail = nullptr; |
| + } |
| + } |
| + } |
| + template <class... Args> T* emplace_front(Args&&... args) { |
| + Node* n = new Node(std::forward<Args>(args)...); |
| + n->fNext = fHead; |
| + if (!fTail) { |
| + fTail = n; |
| + SkASSERT(!fHead); |
| + } |
| + fHead = n; |
| + return &n->fData; |
| + } |
| + template <class... Args> T* emplace_back(Args&&... args) { |
| + Node* n = new Node(std::forward<Args>(args)...); |
| + if (fTail) { |
| + fTail->fNext = n; |
| + } else { |
| + fHead = n; |
| + } |
| + fTail = n; |
| + return &n->fData; |
| + } |
| + class ConstIter { |
| + public: |
| + void operator++() { fNode = fNode->fNext; } |
| + const T& operator*() const { return fNode->fData; } |
| + bool operator!=(const ConstIter& rhs) const { return fNode != rhs.fNode; } |
| + ConstIter(const Node* n) : fNode(n) {} |
| + private: |
| + const Node* fNode; |
| + }; |
| + ConstIter begin() const { return ConstIter(fHead); } |
| + ConstIter end() const { return ConstIter(nullptr); } |
| + |
| +private: |
| + struct Node { |
| + T fData; |
| + Node* fNext; |
| + template <class... Args> |
| + Node(Args&&... args) : fData(std::forward<Args>(args)...), fNext(nullptr) {} |
| + }; |
| + Node* fHead; |
| + Node* fTail; |
| + SkSinglyLinkedList(const SkSinglyLinkedList<T>&) = delete; |
| + SkSinglyLinkedList& operator=(const SkSinglyLinkedList<T>&) = delete; |
| +}; |
| +#endif // SkSinglyLinkedList_DEFINED |