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 |