Skip to content

Commit 838d71d

Browse files
Ethan NicholasSkia Commit-Bot
authored andcommitted
added SkSLNodeArrayWrapper
Not yet used as of this CL. Change-Id: Ic82ab5e2e2ca17fb11c16e22cfa6b7ad5ff74c77 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328657 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
1 parent d6e6a3c commit 838d71d

File tree

3 files changed

+333
-0
lines changed

3 files changed

+333
-0
lines changed

gn/tests.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ tests_sources = [
268268
"$_tests/SkSLInterpreterTest.cpp",
269269
"$_tests/SkSLMemoryLayoutTest.cpp",
270270
"$_tests/SkSLMetalTest.cpp",
271+
"$_tests/SkSLNodeArrayWrapperTest.cpp",
271272
"$_tests/SkSLSPIRVTest.cpp",
272273
"$_tests/SkScalerCacheTest.cpp",
273274
"$_tests/SkShaperJSONWriterTest.cpp",

src/sksl/ir/SkSLNodeArrayWrapper.h

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/*
2+
* Copyright 2020 Google LLC.
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+
8+
#include "include/private/SkTArray.h"
9+
10+
namespace SkSL {
11+
12+
class IRNode;
13+
14+
// Wraps an SkTArray<std::unique_ptr<Base>> and presents it as a collection of <T>
15+
// Once the rearchitecture is complete, Base will always be IRNode and thus we can remove that
16+
// parameter, but right now we have to worry about wrapping both ExpressionArray and StatementArray
17+
template<typename T, typename Base>
18+
class NodeArrayWrapper {
19+
public:
20+
class iterator {
21+
public:
22+
T& operator*() {
23+
return static_cast<T&>(**fBase);
24+
}
25+
26+
T* operator->() {
27+
return static_cast<T*>(fBase->get());
28+
}
29+
30+
iterator& operator++() {
31+
++fBase;
32+
return *this;
33+
}
34+
35+
bool operator==(const iterator& other) const {
36+
return fBase == other.fBase;
37+
}
38+
39+
bool operator!=(const iterator& other) const {
40+
return fBase != other.fBase;
41+
}
42+
43+
private:
44+
iterator(const std::unique_ptr<Base>* base)
45+
: fBase(base) {}
46+
47+
const std::unique_ptr<Base>* fBase;
48+
49+
friend class NodeArrayWrapper;
50+
};
51+
52+
class const_iterator {
53+
public:
54+
const T& operator*() {
55+
return static_cast<const T&>(**fBase);
56+
}
57+
58+
const T* operator->() {
59+
return static_cast<const T*>(fBase->get());
60+
}
61+
62+
const_iterator& operator++() {
63+
++fBase;
64+
return *this;
65+
}
66+
67+
bool operator==(const const_iterator& other) const {
68+
return fBase == other.fBase;
69+
}
70+
71+
bool operator!=(const const_iterator& other) const {
72+
return fBase != other.fBase;
73+
}
74+
75+
private:
76+
const_iterator(const std::unique_ptr<Base>* base)
77+
: fBase(base) {}
78+
79+
const std::unique_ptr<Base>* fBase;
80+
81+
friend class NodeArrayWrapper;
82+
};
83+
84+
NodeArrayWrapper(SkTArray<std::unique_ptr<Base>>* contents)
85+
: fContents(contents) {}
86+
87+
NodeArrayWrapper(const NodeArrayWrapper& other)
88+
: fContents(other.fContents) {}
89+
90+
NodeArrayWrapper& operator=(const NodeArrayWrapper& other) {
91+
fContents = other.fContents;
92+
}
93+
94+
void reset() {
95+
fContents->reset();
96+
}
97+
98+
void reserve_back(int n) {
99+
fContents->reserve_back(n);
100+
}
101+
102+
int count() const {
103+
return fContents->count();
104+
}
105+
106+
bool empty() const {
107+
return fContents->empty();
108+
}
109+
110+
111+
T& push_back(T* t) {
112+
return static_cast<T&>(*fContents->emplace_back(t));
113+
}
114+
115+
template<class... Args> T& emplace_back(Args&&... args) {
116+
return static_cast<T&>(*fContents->emplace_back(new T(std::forward<Args>(args)...)));
117+
}
118+
119+
void pop_back() {
120+
fContents->pop_back();
121+
}
122+
123+
iterator begin() {
124+
return iterator(fContents->begin());
125+
}
126+
127+
iterator end() {
128+
return iterator(fContents->end());
129+
}
130+
131+
const_iterator begin() const {
132+
return const_iterator(fContents->begin());
133+
}
134+
135+
const_iterator end() const {
136+
return const_iterator(fContents->end());
137+
}
138+
139+
T& operator[](int i) {
140+
SkASSERT(fContents->at(i));
141+
return fContents->at(i)->template as<T>();
142+
}
143+
144+
const T& operator[](int i) const {
145+
SkASSERT(fContents->at(i));
146+
return fContents->at(i)->template as<T>();
147+
}
148+
149+
T& front() {
150+
return fContents->front()->template as<T>();
151+
}
152+
153+
const T& front() const {
154+
return fContents->front()->template as<T>();
155+
}
156+
157+
T& back() {
158+
return fContents->back()->template as<T>();
159+
}
160+
161+
const T& back() const {
162+
return fContents->back()->template as<T>();
163+
}
164+
165+
int capacity() const {
166+
return fContents->capacity();
167+
}
168+
169+
private:
170+
SkTArray<std::unique_ptr<Base>>* fContents;
171+
};
172+
173+
template<typename T, typename Base>
174+
class ConstNodeArrayWrapper {
175+
public:
176+
class iterator {
177+
public:
178+
const T& operator*() {
179+
return static_cast<T&>(**fBase);
180+
}
181+
182+
const T* operator->() {
183+
return static_cast<T*>(fBase->get());
184+
}
185+
186+
iterator& operator++() {
187+
++fBase;
188+
return *this;
189+
}
190+
191+
bool operator==(const iterator& other) const {
192+
return fBase == other.fBase;
193+
}
194+
195+
bool operator!=(const iterator& other) const {
196+
return fBase != other.fBase;
197+
}
198+
199+
private:
200+
iterator(const std::unique_ptr<Base>* base)
201+
: fBase(base) {}
202+
203+
const std::unique_ptr<Base>* fBase;
204+
205+
friend class ConstNodeArrayWrapper;
206+
};
207+
208+
ConstNodeArrayWrapper(SkTArray<std::unique_ptr<Base>>* contents)
209+
: fContents(contents) {}
210+
211+
ConstNodeArrayWrapper(const ConstNodeArrayWrapper& other)
212+
: fContents(other.fContents) {}
213+
214+
int count() const {
215+
return fContents->count();
216+
}
217+
218+
bool empty() const {
219+
return fContents->empty();
220+
}
221+
222+
iterator begin() const {
223+
return iterator(fContents->begin());
224+
}
225+
226+
iterator end() const {
227+
return iterator(fContents->end());
228+
}
229+
230+
T& operator[](int i) {
231+
return fContents->at(i)->template as<T>();
232+
}
233+
234+
const T& operator[](int i) const {
235+
return fContents->at(i)->template as<T>();
236+
}
237+
238+
T& front() {
239+
return fContents->front()->template as<T>();
240+
}
241+
242+
const T& front() const {
243+
return fContents->front()->template as<T>();
244+
}
245+
246+
T& back() { return fContents->back()->template as<T>(); }
247+
248+
const T& back() const { return fContents->back()->template as<T>(); }
249+
250+
private:
251+
const SkTArray<std::unique_ptr<Base>>* fContents;
252+
};
253+
254+
} // namespace SkSL

tests/SkSLNodeArrayWrapperTest.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2020 Google LLC.
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+
8+
#include "src/sksl/ir/SkSLExpressionStatement.h"
9+
#include "src/sksl/ir/SkSLIRNode.h"
10+
#include "src/sksl/ir/SkSLIntLiteral.h"
11+
#include "src/sksl/ir/SkSLNodeArrayWrapper.h"
12+
13+
#include "tests/Test.h"
14+
15+
DEF_TEST(SkSLNodeArrayWrapper, r) {
16+
SkSL::ExpressionArray base;
17+
SkSL::NodeArrayWrapper<SkSL::IntLiteral, SkSL::Expression> wrapper(&base);
18+
REPORTER_ASSERT(r, wrapper.empty());
19+
base.emplace_back(new SkSL::IntLiteral(-1, 0));
20+
REPORTER_ASSERT(r, !wrapper.empty());
21+
base.emplace_back(new SkSL::IntLiteral(-1, 1));
22+
base.emplace_back(new SkSL::IntLiteral(-1, 2));
23+
REPORTER_ASSERT(r, wrapper.count() == 3);
24+
REPORTER_ASSERT(r, wrapper[0].value() == 0);
25+
REPORTER_ASSERT(r, wrapper[1].value() == 1);
26+
REPORTER_ASSERT(r, wrapper[2].value() == 2);
27+
wrapper.push_back(new SkSL::IntLiteral(-1, 3));
28+
REPORTER_ASSERT(r, base.count() == 4);
29+
REPORTER_ASSERT(r, wrapper.count() == 4);
30+
REPORTER_ASSERT(r, wrapper[3].value() == 3);
31+
auto iter = wrapper.begin();
32+
int i = 0;
33+
while (iter != wrapper.end()) {
34+
REPORTER_ASSERT(r, wrapper[i].value() == iter->value());
35+
++i;
36+
++iter;
37+
}
38+
39+
const SkSL::NodeArrayWrapper<SkSL::IntLiteral, SkSL::Expression> copy(wrapper);
40+
SkSL::NodeArrayWrapper<SkSL::IntLiteral, SkSL::Expression>::const_iterator constIter =
41+
copy.begin();
42+
i = 0;
43+
while (constIter != copy.end()) {
44+
REPORTER_ASSERT(r, copy[i].value() == constIter->value());
45+
++i;
46+
++constIter;
47+
}
48+
49+
REPORTER_ASSERT(r, wrapper.front().value() == 0);
50+
REPORTER_ASSERT(r, wrapper.back().value() == 3);
51+
wrapper.pop_back();
52+
REPORTER_ASSERT(r, wrapper.back().value() == 2);
53+
wrapper.reset();
54+
REPORTER_ASSERT(r, wrapper.empty());
55+
}
56+
57+
DEF_TEST(SkSLConstNodeArrayWrapper, r) {
58+
SkSL::ExpressionArray base;
59+
SkSL::ConstNodeArrayWrapper<SkSL::IntLiteral, SkSL::Expression> wrapper(&base);
60+
REPORTER_ASSERT(r, wrapper.empty());
61+
base.emplace_back(new SkSL::IntLiteral(-1, 0));
62+
REPORTER_ASSERT(r, !wrapper.empty());
63+
base.emplace_back(new SkSL::IntLiteral(-1, 1));
64+
base.emplace_back(new SkSL::IntLiteral(-1, 2));
65+
REPORTER_ASSERT(r, wrapper.count() == 3);
66+
REPORTER_ASSERT(r, wrapper[0].value() == 0);
67+
REPORTER_ASSERT(r, wrapper[1].value() == 1);
68+
REPORTER_ASSERT(r, wrapper[2].value() == 2);
69+
auto iter = wrapper.begin();
70+
int i = 0;
71+
while (iter != wrapper.end()) {
72+
REPORTER_ASSERT(r, wrapper[i].value() == iter->value());
73+
++i;
74+
++iter;
75+
}
76+
REPORTER_ASSERT(r, wrapper.front().value() == 0);
77+
REPORTER_ASSERT(r, wrapper.back().value() == 2);
78+
}

0 commit comments

Comments
 (0)