aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/tests.gypi1
-rw-r--r--include/core/SkTArray.h23
-rw-r--r--tests/TArrayTest.cpp64
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);
+}