diff options
-rw-r--r-- | gyp/tests.gypi | 1 | ||||
-rw-r--r-- | include/core/SkTArray.h | 23 | ||||
-rw-r--r-- | tests/TArrayTest.cpp | 64 |
3 files changed, 86 insertions, 2 deletions
diff --git a/gyp/tests.gypi b/gyp/tests.gypi index a036dbd4d8..ccfa47dfc2 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -154,6 +154,7 @@ '../tests/StringTest.cpp', '../tests/StrokeTest.cpp', '../tests/SurfaceTest.cpp', + '../tests/TArrayTest.cpp', '../tests/TLSTest.cpp', '../tests/TSetTest.cpp', '../tests/TestSize.cpp', diff --git a/include/core/SkTArray.h b/include/core/SkTArray.h index f7bdc5a158..31bcabae18 100644 --- a/include/core/SkTArray.h +++ b/include/core/SkTArray.h @@ -17,6 +17,10 @@ template <typename T, bool MEM_COPY = false> class SkTArray; namespace SkTArrayExt { template<typename T> +inline void copy(SkTArray<T, true>* self, int dst, int src) { + memcpy(&self->fItemArray[dst], &self->fItemArray[src], sizeof(T)); +} +template<typename T> inline void copy(SkTArray<T, true>* self, const T* array) { memcpy(self->fMemArray, array, self->fCount * sizeof(T)); } @@ -26,6 +30,10 @@ inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) { } template<typename T> +inline void copy(SkTArray<T, false>* self, int dst, int src) { + SkNEW_PLACEMENT_ARGS(&self->fItemArray[dst], T, (self->fItemArray[src])); +} +template<typename T> inline void copy(SkTArray<T, false>* self, const T* array) { for (int i = 0; i < self->fCount; ++i) { SkNEW_PLACEMENT_ARGS(self->fItemArray + i, T, (array[i])); @@ -140,8 +148,17 @@ public: int delta = count - fCount; this->checkRealloc(delta); fCount = count; - for (int i = 0; i < count; ++i) { - SkTArrayExt::copy(this, array); + SkTArrayExt::copy(this, array); + } + + void removeShuffle(int n) { + SkASSERT(n < fCount); + int newCount = fCount - 1; + fCount = newCount; + fItemArray[n].~T(); + if (n != newCount) { + SkTArrayExt::copy(this, n, newCount); + fItemArray[newCount].~T(); } } @@ -427,9 +444,11 @@ private: friend void* operator new<T>(size_t, SkTArray*, int); + template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, int dst, int src); template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*); template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*); + template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, int dst, int src); template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*); template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, false>* that, char*); diff --git a/tests/TArrayTest.cpp b/tests/TArrayTest.cpp new file mode 100644 index 0000000000..f86cfe40f7 --- /dev/null +++ b/tests/TArrayTest.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkTArray.h" +#include "Test.h" + +// Tests the SkTArray<T> class template. + +template <bool MEM_COPY> +static void TestTSet_basic(skiatest::Reporter* reporter) { + SkTArray<int, MEM_COPY> a; + + // Starts empty. + REPORTER_ASSERT(reporter, a.empty()); + REPORTER_ASSERT(reporter, a.count() == 0); + + // { }, add a default constructed element + REPORTER_ASSERT(reporter, a.push_back()); + REPORTER_ASSERT(reporter, !a.empty()); + REPORTER_ASSERT(reporter, a.count() == 1); + + // { 0 }, removeShuffle the only element. + a.removeShuffle(0); + REPORTER_ASSERT(reporter, a.empty()); + REPORTER_ASSERT(reporter, a.count() == 0); + + // { }, add a default, add a 1, remove first + REPORTER_ASSERT(reporter, a.push_back()); + REPORTER_ASSERT(reporter, a.push_back() = 1); + a.removeShuffle(0); + REPORTER_ASSERT(reporter, !a.empty()); + REPORTER_ASSERT(reporter, a.count() == 1); + REPORTER_ASSERT(reporter, a[0] == 1); + + // { 1 }, replace with new array + int b[5] = { 0, 1, 2, 3, 4 }; + a.reset(b, SK_ARRAY_COUNT(b)); + REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b)); + REPORTER_ASSERT(reporter, a[2] == 2); + REPORTER_ASSERT(reporter, a[4] == 4); + + // { 0, 1, 2, 3, 4 }, removeShuffle the last + a.removeShuffle(4); + REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b) - 1); + REPORTER_ASSERT(reporter, a[3] == 3); + + // { 0, 1, 2, 3 }, remove a middle, note shuffle + a.removeShuffle(1); + REPORTER_ASSERT(reporter, a.count() == SK_ARRAY_COUNT(b) - 2); + REPORTER_ASSERT(reporter, a[0] == 0); + REPORTER_ASSERT(reporter, a[1] == 3); + REPORTER_ASSERT(reporter, a[2] == 2); + + // {0, 3, 2 } +} + +DEF_TEST(TArray, reporter) { + TestTSet_basic<true>(reporter); + TestTSet_basic<false>(reporter); +} |