|  | /* | 
|  | * Copyright 2015 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #include "include/private/SkTemplates.h" | 
|  | #include "tests/Test.h" | 
|  |  | 
|  | // Tests for some of the helpers in SkTemplates.h | 
|  | static void test_automalloc_realloc(skiatest::Reporter* reporter) { | 
|  | SkAutoSTMalloc<1, int> array; | 
|  |  | 
|  | // test we have a valid pointer, should not crash | 
|  | array[0] = 1; | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  |  | 
|  | // using realloc for init | 
|  | array.realloc(1); | 
|  |  | 
|  | array[0] = 1; | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  |  | 
|  | // verify realloc can grow | 
|  | array.realloc(2); | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  |  | 
|  | // realloc can shrink | 
|  | array.realloc(1); | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  |  | 
|  | // should not crash | 
|  | array.realloc(0); | 
|  |  | 
|  | // grow and shrink again | 
|  | array.realloc(10); | 
|  | for (int i = 0; i < 10; i++) { | 
|  | array[i] = 10 - i; | 
|  | } | 
|  | array.realloc(20); | 
|  | for (int i = 0; i < 10; i++) { | 
|  | REPORTER_ASSERT(reporter, array[i] == 10 - i); | 
|  | } | 
|  | array.realloc(10); | 
|  | for (int i = 0; i < 10; i++) { | 
|  | REPORTER_ASSERT(reporter, array[i] == 10 - i); | 
|  | } | 
|  |  | 
|  | array.realloc(1); | 
|  | REPORTER_ASSERT(reporter, array[0] = 10); | 
|  |  | 
|  | // resets mixed with realloc, below stack alloc size | 
|  | array.reset(0); | 
|  | array.realloc(1); | 
|  | array.reset(1); | 
|  |  | 
|  | array[0] = 1; | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  |  | 
|  | // reset and realloc > stack size | 
|  | array.reset(2); | 
|  | array.realloc(3); | 
|  | array[0] = 1; | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  | array.realloc(1); | 
|  | REPORTER_ASSERT(reporter, array[0] == 1); | 
|  | } | 
|  |  | 
|  | DEF_TEST(Templates, reporter) { | 
|  | test_automalloc_realloc(reporter); | 
|  | } | 
|  |  | 
|  | constexpr int static kStackPreallocCount = 10; | 
|  |  | 
|  | // Ensures the containers in SkTemplates.h all have a consistent api. | 
|  | template<typename TContainer, typename TCount> | 
|  | static void test_container_apis(skiatest::Reporter* reporter) { | 
|  | REPORTER_ASSERT(reporter, !TContainer((TCount)0).get()); | 
|  | REPORTER_ASSERT(reporter, !TContainer((TCount)0).data()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)1).get()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)1).data()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).get()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount).data()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).get()); | 
|  | REPORTER_ASSERT(reporter, TContainer((TCount)kStackPreallocCount + 1).data()); | 
|  |  | 
|  | TContainer container; | 
|  | // The default constructor may or may not init to empty, depending on the type of container. | 
|  |  | 
|  | container.reset((TCount)1); | 
|  | REPORTER_ASSERT(reporter, container.get()); | 
|  | REPORTER_ASSERT(reporter, container.get() == container.data()); | 
|  |  | 
|  | container.reset((TCount)kStackPreallocCount); | 
|  | REPORTER_ASSERT(reporter, container.get()); | 
|  | REPORTER_ASSERT(reporter, container.get() == container.data()); | 
|  |  | 
|  | container.reset((TCount)kStackPreallocCount + 1); | 
|  | REPORTER_ASSERT(reporter, container.get()); | 
|  | REPORTER_ASSERT(reporter, container.get() == container.data()); | 
|  |  | 
|  | container.reset((TCount)0); | 
|  | REPORTER_ASSERT(reporter, !container.get()); | 
|  | REPORTER_ASSERT(reporter, !container.data()); | 
|  | } | 
|  |  | 
|  | DEF_TEST(TemplateContainerAPIs, reporter) { | 
|  | test_container_apis<SkAutoTArray<int>, int>(reporter); | 
|  | test_container_apis<SkAutoSTArray<kStackPreallocCount, int>, int>(reporter); | 
|  | test_container_apis<SkAutoTMalloc<int>, size_t>(reporter); | 
|  | test_container_apis<SkAutoSTMalloc<kStackPreallocCount, int>, size_t>(reporter); | 
|  | } | 
|  |  | 
|  | // Ensures that realloc(0) results in a null pointer. | 
|  | template<typename TAutoMalloc> static void test_realloc_to_zero(skiatest::Reporter* reporter) { | 
|  | TAutoMalloc autoMalloc(kStackPreallocCount); | 
|  | REPORTER_ASSERT(reporter, autoMalloc.get()); | 
|  |  | 
|  | autoMalloc.realloc(0); | 
|  | REPORTER_ASSERT(reporter, !autoMalloc.get()); | 
|  |  | 
|  | autoMalloc.realloc(kStackPreallocCount + 1); | 
|  | REPORTER_ASSERT(reporter, autoMalloc.get()); | 
|  |  | 
|  | autoMalloc.realloc(0); | 
|  | REPORTER_ASSERT(reporter, !autoMalloc.get()); | 
|  |  | 
|  | autoMalloc.realloc(kStackPreallocCount); | 
|  | REPORTER_ASSERT(reporter, autoMalloc.get()); | 
|  | } | 
|  |  | 
|  | DEF_TEST(AutoReallocToZero, reporter) { | 
|  | test_realloc_to_zero<SkAutoTMalloc<int> >(reporter); | 
|  | test_realloc_to_zero<SkAutoSTMalloc<kStackPreallocCount, int> >(reporter); | 
|  | } | 
|  |  | 
|  | DEF_TEST(SkAutoTMallocSelfMove, r) { | 
|  | #if defined(__clang__) | 
|  | #pragma clang diagnostic push | 
|  | #pragma clang diagnostic ignored "-Wself-move" | 
|  | #endif | 
|  |  | 
|  | SkAutoTMalloc<int> foo(20); | 
|  | REPORTER_ASSERT(r, foo.get()); | 
|  |  | 
|  | foo = std::move(foo); | 
|  | REPORTER_ASSERT(r, foo.get());  // NOLINT(bugprone-use-after-move) | 
|  |  | 
|  | #if defined(__clang__) | 
|  | #pragma clang diagnostic pop | 
|  | #endif | 
|  | } |