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