1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
12*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
13*c8dee2aaSAndroid Build Coastguard Worker
14*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
15*c8dee2aaSAndroid Build Coastguard Worker
16*c8dee2aaSAndroid Build Coastguard Worker // Tests for some of the helpers in SkTemplates.h
test_automalloc_realloc(skiatest::Reporter * reporter)17*c8dee2aaSAndroid Build Coastguard Worker static void test_automalloc_realloc(skiatest::Reporter* reporter) {
18*c8dee2aaSAndroid Build Coastguard Worker AutoSTMalloc<1, int> array;
19*c8dee2aaSAndroid Build Coastguard Worker
20*c8dee2aaSAndroid Build Coastguard Worker // test we have a valid pointer, should not crash
21*c8dee2aaSAndroid Build Coastguard Worker array[0] = 1;
22*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
23*c8dee2aaSAndroid Build Coastguard Worker
24*c8dee2aaSAndroid Build Coastguard Worker // using realloc for init
25*c8dee2aaSAndroid Build Coastguard Worker array.realloc(1);
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker array[0] = 1;
28*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker // verify realloc can grow
31*c8dee2aaSAndroid Build Coastguard Worker array.realloc(2);
32*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker // realloc can shrink
35*c8dee2aaSAndroid Build Coastguard Worker array.realloc(1);
36*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
37*c8dee2aaSAndroid Build Coastguard Worker
38*c8dee2aaSAndroid Build Coastguard Worker // should not crash
39*c8dee2aaSAndroid Build Coastguard Worker array.realloc(0);
40*c8dee2aaSAndroid Build Coastguard Worker
41*c8dee2aaSAndroid Build Coastguard Worker // grow and shrink again
42*c8dee2aaSAndroid Build Coastguard Worker array.realloc(10);
43*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) {
44*c8dee2aaSAndroid Build Coastguard Worker array[i] = 10 - i;
45*c8dee2aaSAndroid Build Coastguard Worker }
46*c8dee2aaSAndroid Build Coastguard Worker array.realloc(20);
47*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) {
48*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[i] == 10 - i);
49*c8dee2aaSAndroid Build Coastguard Worker }
50*c8dee2aaSAndroid Build Coastguard Worker array.realloc(10);
51*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) {
52*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[i] == 10 - i);
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker array.realloc(1);
56*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] = 10);
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker // resets mixed with realloc, below stack alloc size
59*c8dee2aaSAndroid Build Coastguard Worker array.reset(0);
60*c8dee2aaSAndroid Build Coastguard Worker array.realloc(1);
61*c8dee2aaSAndroid Build Coastguard Worker array.reset(1);
62*c8dee2aaSAndroid Build Coastguard Worker
63*c8dee2aaSAndroid Build Coastguard Worker array[0] = 1;
64*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker // reset and realloc > stack size
67*c8dee2aaSAndroid Build Coastguard Worker array.reset(2);
68*c8dee2aaSAndroid Build Coastguard Worker array.realloc(3);
69*c8dee2aaSAndroid Build Coastguard Worker array[0] = 1;
70*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
71*c8dee2aaSAndroid Build Coastguard Worker array.realloc(1);
72*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, array[0] == 1);
73*c8dee2aaSAndroid Build Coastguard Worker }
74*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(Templates,reporter)75*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(Templates, reporter) {
76*c8dee2aaSAndroid Build Coastguard Worker test_automalloc_realloc(reporter);
77*c8dee2aaSAndroid Build Coastguard Worker }
78*c8dee2aaSAndroid Build Coastguard Worker
79*c8dee2aaSAndroid Build Coastguard Worker constexpr int static kStackPreallocCount = 10;
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker // Ensures the containers in SkTemplates.h all have a consistent api.
82*c8dee2aaSAndroid Build Coastguard Worker template<typename TContainer, typename TCount>
test_container_apis(skiatest::Reporter * reporter)83*c8dee2aaSAndroid Build Coastguard Worker static void test_container_apis(skiatest::Reporter* reporter) {
84*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !TContainer((TCount)0).get());
85*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !TContainer((TCount)0).data());
86*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)1).get());
87*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)1).data());
88*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).get());
89*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).data());
90*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).get());
91*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).data());
92*c8dee2aaSAndroid Build Coastguard Worker
93*c8dee2aaSAndroid Build Coastguard Worker TContainer container;
94*c8dee2aaSAndroid Build Coastguard Worker // The default constructor may or may not init to empty, depending on the type of container.
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker container.reset((TCount)1);
97*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get());
98*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get() == container.data());
99*c8dee2aaSAndroid Build Coastguard Worker
100*c8dee2aaSAndroid Build Coastguard Worker container.reset((TCount)kStackPreallocCount);
101*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get());
102*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get() == container.data());
103*c8dee2aaSAndroid Build Coastguard Worker
104*c8dee2aaSAndroid Build Coastguard Worker container.reset((TCount)kStackPreallocCount + 1);
105*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get());
106*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, container.get() == container.data());
107*c8dee2aaSAndroid Build Coastguard Worker
108*c8dee2aaSAndroid Build Coastguard Worker container.reset((TCount)0);
109*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !container.get());
110*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !container.data());
111*c8dee2aaSAndroid Build Coastguard Worker }
112*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(TemplateContainerAPIs,reporter)113*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(TemplateContainerAPIs, reporter) {
114*c8dee2aaSAndroid Build Coastguard Worker test_container_apis<AutoTArray<int>, int>(reporter);
115*c8dee2aaSAndroid Build Coastguard Worker test_container_apis<AutoSTArray<kStackPreallocCount, int>, int>(reporter);
116*c8dee2aaSAndroid Build Coastguard Worker test_container_apis<AutoTMalloc<int>, size_t>(reporter);
117*c8dee2aaSAndroid Build Coastguard Worker test_container_apis<AutoSTMalloc<kStackPreallocCount, int>, size_t>(reporter);
118*c8dee2aaSAndroid Build Coastguard Worker }
119*c8dee2aaSAndroid Build Coastguard Worker
120*c8dee2aaSAndroid Build Coastguard Worker // Ensures that realloc(0) results in a null pointer.
test_realloc_to_zero(skiatest::Reporter * reporter)121*c8dee2aaSAndroid Build Coastguard Worker template<typename TAutoMalloc> static void test_realloc_to_zero(skiatest::Reporter* reporter) {
122*c8dee2aaSAndroid Build Coastguard Worker TAutoMalloc autoMalloc(kStackPreallocCount);
123*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, autoMalloc.get());
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker autoMalloc.realloc(0);
126*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !autoMalloc.get());
127*c8dee2aaSAndroid Build Coastguard Worker
128*c8dee2aaSAndroid Build Coastguard Worker autoMalloc.realloc(kStackPreallocCount + 1);
129*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, autoMalloc.get());
130*c8dee2aaSAndroid Build Coastguard Worker
131*c8dee2aaSAndroid Build Coastguard Worker autoMalloc.realloc(0);
132*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !autoMalloc.get());
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker autoMalloc.realloc(kStackPreallocCount);
135*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, autoMalloc.get());
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(AutoReallocToZero,reporter)138*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(AutoReallocToZero, reporter) {
139*c8dee2aaSAndroid Build Coastguard Worker test_realloc_to_zero<AutoTMalloc<int> >(reporter);
140*c8dee2aaSAndroid Build Coastguard Worker test_realloc_to_zero<AutoSTMalloc<kStackPreallocCount, int> >(reporter);
141*c8dee2aaSAndroid Build Coastguard Worker }
142*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(AutoTMallocSelfMove,r)143*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(AutoTMallocSelfMove, r) {
144*c8dee2aaSAndroid Build Coastguard Worker #if defined(__clang__)
145*c8dee2aaSAndroid Build Coastguard Worker #pragma clang diagnostic push
146*c8dee2aaSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wself-move"
147*c8dee2aaSAndroid Build Coastguard Worker #elif defined(__GNUC__) && __GNUC__ >= 13
148*c8dee2aaSAndroid Build Coastguard Worker #pragma GCC diagnostic push
149*c8dee2aaSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wself-move"
150*c8dee2aaSAndroid Build Coastguard Worker #endif
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker AutoTMalloc<int> foo(20);
153*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, foo.get());
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker foo = std::move(foo);
156*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(r, foo.get()); // NOLINT(bugprone-use-after-move)
157*c8dee2aaSAndroid Build Coastguard Worker
158*c8dee2aaSAndroid Build Coastguard Worker #if defined(__clang__)
159*c8dee2aaSAndroid Build Coastguard Worker #pragma clang diagnostic pop
160*c8dee2aaSAndroid Build Coastguard Worker #elif defined(__GNUC__) && __GNUC__ >= 13
161*c8dee2aaSAndroid Build Coastguard Worker #pragma GCC diagnostic pop
162*c8dee2aaSAndroid Build Coastguard Worker #endif
163*c8dee2aaSAndroid Build Coastguard Worker }
164