/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkRefCnt.h" #include "include/utils/SkRandom.h" #include "src/core/SkSpan.h" #include "src/core/SkTSearch.h" #include "src/core/SkTSort.h" #include "tests/Test.h" #include #include class RefClass : public SkRefCnt { public: RefClass(int n) : fN(n) {} int get() const { return fN; } private: int fN; typedef SkRefCnt INHERITED; }; static void test_autounref(skiatest::Reporter* reporter) { RefClass obj(0); REPORTER_ASSERT(reporter, obj.unique()); sk_sp tmp(&obj); REPORTER_ASSERT(reporter, &obj == tmp.get()); REPORTER_ASSERT(reporter, obj.unique()); REPORTER_ASSERT(reporter, &obj == tmp.release()); REPORTER_ASSERT(reporter, obj.unique()); REPORTER_ASSERT(reporter, nullptr == tmp.release()); REPORTER_ASSERT(reporter, nullptr == tmp.get()); obj.ref(); REPORTER_ASSERT(reporter, !obj.unique()); { sk_sp tmp2(&obj); } REPORTER_ASSERT(reporter, obj.unique()); } static void test_autostarray(skiatest::Reporter* reporter) { RefClass obj0(0); RefClass obj1(1); REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); { SkAutoSTArray<2, sk_sp > tmp; REPORTER_ASSERT(reporter, 0 == tmp.count()); tmp.reset(0); // test out reset(0) when already at 0 tmp.reset(4); // this should force a new allocation REPORTER_ASSERT(reporter, 4 == tmp.count()); tmp[0].reset(SkRef(&obj0)); tmp[1].reset(SkRef(&obj1)); REPORTER_ASSERT(reporter, !obj0.unique()); REPORTER_ASSERT(reporter, !obj1.unique()); // test out reset with data in the array (and a new allocation) tmp.reset(0); REPORTER_ASSERT(reporter, 0 == tmp.count()); REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); tmp.reset(2); // this should use the preexisting allocation REPORTER_ASSERT(reporter, 2 == tmp.count()); tmp[0].reset(SkRef(&obj0)); tmp[1].reset(SkRef(&obj1)); } // test out destructor with data in the array (and using existing allocation) REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); { // test out allocating ctor (this should allocate new memory) SkAutoSTArray<2, sk_sp > tmp(4); REPORTER_ASSERT(reporter, 4 == tmp.count()); tmp[0].reset(SkRef(&obj0)); tmp[1].reset(SkRef(&obj1)); REPORTER_ASSERT(reporter, !obj0.unique()); REPORTER_ASSERT(reporter, !obj1.unique()); // Test out resut with data in the array and malloced storage tmp.reset(0); REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); tmp.reset(2); // this should use the preexisting storage tmp[0].reset(SkRef(&obj0)); tmp[1].reset(SkRef(&obj1)); REPORTER_ASSERT(reporter, !obj0.unique()); REPORTER_ASSERT(reporter, !obj1.unique()); tmp.reset(4); // this should force a new malloc REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); tmp[0].reset(SkRef(&obj0)); tmp[1].reset(SkRef(&obj1)); REPORTER_ASSERT(reporter, !obj0.unique()); REPORTER_ASSERT(reporter, !obj1.unique()); } REPORTER_ASSERT(reporter, obj0.unique()); REPORTER_ASSERT(reporter, obj1.unique()); } ///////////////////////////////////////////////////////////////////////////// #define kSEARCH_COUNT 91 static void test_search(skiatest::Reporter* reporter) { int i, array[kSEARCH_COUNT]; SkRandom rand; for (i = 0; i < kSEARCH_COUNT; i++) { array[i] = rand.nextS(); } SkTHeapSort(array, kSEARCH_COUNT); // make sure we got sorted properly for (i = 1; i < kSEARCH_COUNT; i++) { REPORTER_ASSERT(reporter, array[i-1] <= array[i]); } // make sure we can find all of our values for (i = 0; i < kSEARCH_COUNT; i++) { int index = SkTSearch(array, kSEARCH_COUNT, array[i], sizeof(int)); REPORTER_ASSERT(reporter, index == i); } // make sure that random values are either found, or the correct // insertion index is returned for (i = 0; i < 10000; i++) { int value = rand.nextS(); int index = SkTSearch(array, kSEARCH_COUNT, value, sizeof(int)); if (index >= 0) { REPORTER_ASSERT(reporter, index < kSEARCH_COUNT && array[index] == value); } else { index = ~index; REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT); if (index < kSEARCH_COUNT) { REPORTER_ASSERT(reporter, value < array[index]); if (index > 0) { REPORTER_ASSERT(reporter, value > array[index - 1]); } } else { // we should append the new value REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]); } } } } DEF_TEST(Utils, reporter) { test_search(reporter); test_autounref(reporter); test_autostarray(reporter); } DEF_TEST(SkMakeSpan, reporter) { // Test constness preservation for SkMakeSpan. { std::vector v = {{1, 2, 3, 4, 5}}; auto s = SkMakeSpan(v); REPORTER_ASSERT(reporter, s[3] == 4); s[3] = 100; REPORTER_ASSERT(reporter, s[3] == 100); } { std::vector t = {{1, 2, 3, 4, 5}}; const std::vector& v = t; auto s = SkMakeSpan(v); //s[3] = 100; // Should fail to compile REPORTER_ASSERT(reporter, s[3] == 4); REPORTER_ASSERT(reporter, t[3] == 4); t[3] = 100; REPORTER_ASSERT(reporter, s[3] == 100); } { std::array v = {{1, 2, 3, 4, 5}}; auto s = SkMakeSpan(v); REPORTER_ASSERT(reporter, s[3] == 4); s[3] = 100; REPORTER_ASSERT(reporter, s[3] == 100); } { std::array t = {{1, 2, 3, 4, 5}}; const std::array& v = t; auto s = SkMakeSpan(v); //s[3] = 100; // Should fail to compile REPORTER_ASSERT(reporter, s[3] == 4); REPORTER_ASSERT(reporter, t[3] == 4); t[3] = 100; REPORTER_ASSERT(reporter, s[3] == 100); } }