1 /*
2 * Copyright 2011 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
8 #include "include/core/SkRefCnt.h"
9 #include "include/utils/SkRandom.h"
10 #include "src/core/SkSpan.h"
11 #include "src/core/SkTSearch.h"
12 #include "src/core/SkTSort.h"
13 #include "tests/Test.h"
14
15 #include <array>
16 #include <vector>
17
18 class RefClass : public SkRefCnt {
19 public:
RefClass(int n)20 RefClass(int n) : fN(n) {}
get() const21 int get() const { return fN; }
22
23 private:
24 int fN;
25
26 typedef SkRefCnt INHERITED;
27 };
28
test_autounref(skiatest::Reporter * reporter)29 static void test_autounref(skiatest::Reporter* reporter) {
30 RefClass obj(0);
31 REPORTER_ASSERT(reporter, obj.unique());
32
33 sk_sp<RefClass> tmp(&obj);
34 REPORTER_ASSERT(reporter, &obj == tmp.get());
35 REPORTER_ASSERT(reporter, obj.unique());
36
37 REPORTER_ASSERT(reporter, &obj == tmp.release());
38 REPORTER_ASSERT(reporter, obj.unique());
39 REPORTER_ASSERT(reporter, nullptr == tmp.release());
40 REPORTER_ASSERT(reporter, nullptr == tmp.get());
41
42 obj.ref();
43 REPORTER_ASSERT(reporter, !obj.unique());
44 {
45 sk_sp<RefClass> tmp2(&obj);
46 }
47 REPORTER_ASSERT(reporter, obj.unique());
48 }
49
test_autostarray(skiatest::Reporter * reporter)50 static void test_autostarray(skiatest::Reporter* reporter) {
51 RefClass obj0(0);
52 RefClass obj1(1);
53 REPORTER_ASSERT(reporter, obj0.unique());
54 REPORTER_ASSERT(reporter, obj1.unique());
55
56 {
57 SkAutoSTArray<2, sk_sp<RefClass> > tmp;
58 REPORTER_ASSERT(reporter, 0 == tmp.count());
59
60 tmp.reset(0); // test out reset(0) when already at 0
61 tmp.reset(4); // this should force a new allocation
62 REPORTER_ASSERT(reporter, 4 == tmp.count());
63 tmp[0].reset(SkRef(&obj0));
64 tmp[1].reset(SkRef(&obj1));
65 REPORTER_ASSERT(reporter, !obj0.unique());
66 REPORTER_ASSERT(reporter, !obj1.unique());
67
68 // test out reset with data in the array (and a new allocation)
69 tmp.reset(0);
70 REPORTER_ASSERT(reporter, 0 == tmp.count());
71 REPORTER_ASSERT(reporter, obj0.unique());
72 REPORTER_ASSERT(reporter, obj1.unique());
73
74 tmp.reset(2); // this should use the preexisting allocation
75 REPORTER_ASSERT(reporter, 2 == tmp.count());
76 tmp[0].reset(SkRef(&obj0));
77 tmp[1].reset(SkRef(&obj1));
78 }
79
80 // test out destructor with data in the array (and using existing allocation)
81 REPORTER_ASSERT(reporter, obj0.unique());
82 REPORTER_ASSERT(reporter, obj1.unique());
83
84 {
85 // test out allocating ctor (this should allocate new memory)
86 SkAutoSTArray<2, sk_sp<RefClass> > tmp(4);
87 REPORTER_ASSERT(reporter, 4 == tmp.count());
88
89 tmp[0].reset(SkRef(&obj0));
90 tmp[1].reset(SkRef(&obj1));
91 REPORTER_ASSERT(reporter, !obj0.unique());
92 REPORTER_ASSERT(reporter, !obj1.unique());
93
94 // Test out resut with data in the array and malloced storage
95 tmp.reset(0);
96 REPORTER_ASSERT(reporter, obj0.unique());
97 REPORTER_ASSERT(reporter, obj1.unique());
98
99 tmp.reset(2); // this should use the preexisting storage
100 tmp[0].reset(SkRef(&obj0));
101 tmp[1].reset(SkRef(&obj1));
102 REPORTER_ASSERT(reporter, !obj0.unique());
103 REPORTER_ASSERT(reporter, !obj1.unique());
104
105 tmp.reset(4); // this should force a new malloc
106 REPORTER_ASSERT(reporter, obj0.unique());
107 REPORTER_ASSERT(reporter, obj1.unique());
108
109 tmp[0].reset(SkRef(&obj0));
110 tmp[1].reset(SkRef(&obj1));
111 REPORTER_ASSERT(reporter, !obj0.unique());
112 REPORTER_ASSERT(reporter, !obj1.unique());
113 }
114
115 REPORTER_ASSERT(reporter, obj0.unique());
116 REPORTER_ASSERT(reporter, obj1.unique());
117 }
118
119 /////////////////////////////////////////////////////////////////////////////
120
121 #define kSEARCH_COUNT 91
122
test_search(skiatest::Reporter * reporter)123 static void test_search(skiatest::Reporter* reporter) {
124 int i, array[kSEARCH_COUNT];
125 SkRandom rand;
126
127 for (i = 0; i < kSEARCH_COUNT; i++) {
128 array[i] = rand.nextS();
129 }
130
131 SkTHeapSort<int>(array, kSEARCH_COUNT);
132 // make sure we got sorted properly
133 for (i = 1; i < kSEARCH_COUNT; i++) {
134 REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
135 }
136
137 // make sure we can find all of our values
138 for (i = 0; i < kSEARCH_COUNT; i++) {
139 int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
140 REPORTER_ASSERT(reporter, index == i);
141 }
142
143 // make sure that random values are either found, or the correct
144 // insertion index is returned
145 for (i = 0; i < 10000; i++) {
146 int value = rand.nextS();
147 int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));
148
149 if (index >= 0) {
150 REPORTER_ASSERT(reporter,
151 index < kSEARCH_COUNT && array[index] == value);
152 } else {
153 index = ~index;
154 REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
155 if (index < kSEARCH_COUNT) {
156 REPORTER_ASSERT(reporter, value < array[index]);
157 if (index > 0) {
158 REPORTER_ASSERT(reporter, value > array[index - 1]);
159 }
160 } else {
161 // we should append the new value
162 REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
163 }
164 }
165 }
166 }
167
DEF_TEST(Utils,reporter)168 DEF_TEST(Utils, reporter) {
169 test_search(reporter);
170 test_autounref(reporter);
171 test_autostarray(reporter);
172 }
173
DEF_TEST(SkMakeSpan,reporter)174 DEF_TEST(SkMakeSpan, reporter) {
175 // Test constness preservation for SkMakeSpan.
176 {
177 std::vector<int> v = {{1, 2, 3, 4, 5}};
178 auto s = SkMakeSpan(v);
179 REPORTER_ASSERT(reporter, s[3] == 4);
180 s[3] = 100;
181 REPORTER_ASSERT(reporter, s[3] == 100);
182 }
183
184 {
185 std::vector<int> t = {{1, 2, 3, 4, 5}};
186 const std::vector<int>& v = t;
187 auto s = SkMakeSpan(v);
188 //s[3] = 100; // Should fail to compile
189 REPORTER_ASSERT(reporter, s[3] == 4);
190 REPORTER_ASSERT(reporter, t[3] == 4);
191 t[3] = 100;
192 REPORTER_ASSERT(reporter, s[3] == 100);
193 }
194
195 {
196 std::array<int, 5> v = {{1, 2, 3, 4, 5}};
197 auto s = SkMakeSpan(v);
198 REPORTER_ASSERT(reporter, s[3] == 4);
199 s[3] = 100;
200 REPORTER_ASSERT(reporter, s[3] == 100);
201 }
202
203 {
204 std::array<int, 5> t = {{1, 2, 3, 4, 5}};
205 const std::array<int, 5>& v = t;
206 auto s = SkMakeSpan(v);
207 //s[3] = 100; // Should fail to compile
208 REPORTER_ASSERT(reporter, s[3] == 4);
209 REPORTER_ASSERT(reporter, t[3] == 4);
210 t[3] = 100;
211 REPORTER_ASSERT(reporter, s[3] == 100);
212 }
213 }
214