blob: 039b06e383b3343b66cc28882547f80789a6ae43 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrCCSTLList_DEFINED
#define GrCCSTLList_DEFINED
#include "SkArenaAlloc.h"
#include <new>
/**
* A singly-linked list whose head element is a local class member. This is required by
* GrCCDrawPathsOp because the owning opList is unknown at the time of creation, so we can't use its
* associated allocator to create the first element.
*/
template<typename T> class GrCCSTLList {
public:
template <typename ...Args>
GrCCSTLList(Args&&... args) : fHead(std::forward<Args>(args)...) {}
~GrCCSTLList() {
T* draw = fHead.fNext; // fHead will be destructed automatically.
while (draw) {
T* next = draw->fNext;
draw->~T();
draw = next;
}
}
const T& head() const { return fHead; }
T& head() { return fHead; }
void append(GrCCSTLList&& right, SkArenaAlloc* alloc) {
T* nextTail = (&right.fHead == right.fTail) ? nullptr : right.fTail;
T* newRightHead =
new (alloc->makeBytesAlignedTo(sizeof(T), alignof(T))) T(std::move(right.fHead));
// Finish the move of right.fHead.
right.fHead.fNext = nullptr;
right.fTail = &right.fHead;
fTail->fNext = newRightHead;
fTail = !nextTail ? newRightHead : nextTail;
}
template<typename U> struct Iter {
bool operator!=(const Iter& that) { return fCurr != that.fCurr; }
U& operator*() { return *fCurr; }
void operator++() { fCurr = fCurr->fNext; }
U* fCurr;
};
Iter<const T> begin() const { return Iter<const T>{&fHead}; }
Iter<const T> end() const { return Iter<const T>{nullptr}; }
Iter<T> begin() { return Iter<T>{&fHead}; }
Iter<T> end() { return Iter<T>{nullptr}; }
private:
T fHead;
T* fTail = &fHead;
};
#endif
|