From bfbeee98f9311ae408372f84e340beb08de06978 Mon Sep 17 00:00:00 2001 From: Lene Preuss Date: Fri, 28 Mar 2014 16:38:13 +0100 Subject: [PATCH] added more functions to arraylist and more tests while developing the proper test for FacePolygon::operator== (#30) --- src/Displayable/Object/FacePolygon.impl.h | 2 +- src/VecMath/ArrayList.h | 20 +++++++++ src/VecMath/ArrayList.impl.h | 55 ++++++++++++++++++++++- tests/Test_ArrayList.cpp | 35 +++++++++++++-- tests/Test_ArrayList.h | 11 +++-- tests/main.cpp | 1 + 6 files changed, 114 insertions(+), 10 deletions(-) diff --git a/src/Displayable/Object/FacePolygon.impl.h b/src/Displayable/Object/FacePolygon.impl.h index 7caea759..0849bb68 100644 --- a/src/Displayable/Object/FacePolygon.impl.h +++ b/src/Displayable/Object/FacePolygon.impl.h @@ -75,7 +75,7 @@ FacePolygon::index(unsigned i) const { template bool FacePolygon::operator==(const FacePolygon &other) const { - if (!isPermutation( + if (!isCircularPermutation( ArrayList(_indices), ArrayList(other._indices))) { return false; diff --git a/src/VecMath/ArrayList.h b/src/VecMath/ArrayList.h index 7f1ea8b0..97e19987 100644 --- a/src/VecMath/ArrayList.h +++ b/src/VecMath/ArrayList.h @@ -56,6 +56,11 @@ template class ArrayList { ArrayList minusElement(unsigned i) const; bool contains(const T &x) const; + + bool operator==(const ArrayList &other) const; + + ArrayList &shift(int amount = 1); + ArrayList &reverse(); /// String representation. std::string toString() const; @@ -94,6 +99,8 @@ template class ArrayList<1, T> { ArrayList<0, T> minusElement(unsigned) const; bool contains (const T &x) const; + + bool operator==(const ArrayList<1, T> &other) const; /// Empty String. std::string toString() const; @@ -121,11 +128,24 @@ template class ArrayList<0, T> { }; +template +std::ostream &operator<<(std::ostream &o, const ArrayList &list) { + o << list.toString(); + return o; +} + template bool isPermutation(const ArrayList &list1, const ArrayList &list2); template bool isPermutation(const ArrayList<1, T> &list1, const ArrayList<1, T> &list2); +template +bool isCircularPermutation(const ArrayList &list1, const ArrayList &list2); +template +bool isCircularPermutation(const ArrayList<2, T> &list1, const ArrayList<2, T> &list2); +template +bool isCircularPermutation(const ArrayList<1, T> &list1, const ArrayList<1, T> &list2); + template ArrayList<1, T> makeArrayList(const T &x0); template diff --git a/src/VecMath/ArrayList.impl.h b/src/VecMath/ArrayList.impl.h index 36e5f635..476ce884 100644 --- a/src/VecMath/ArrayList.impl.h +++ b/src/VecMath/ArrayList.impl.h @@ -72,7 +72,7 @@ template T &ArrayList::operator[](unsigned i) { assert(i < size); if (i == 0) return head(); - ArrayList _tail = tail(); + ArrayList &_tail = tail(); return _tail.operator[](i-1); } @@ -98,6 +98,30 @@ bool ArrayList::contains (const T &x) const { return tail().contains(x); } +template +bool ArrayList::operator==(const ArrayList &other) const { + return head() == other.head() && tail() == other.tail(); +} + +template +ArrayList &ArrayList::shift(int amount) { + assert(amount == 1); + T temp = operator[](0); + for (unsigned i = 1; i < size; ++i) { + operator[](i-1) = operator[](i); + } + operator[](size-1) = temp; + return *this; +} + +template +ArrayList &ArrayList::reverse() { + for (unsigned i = 0; i < size/2; ++i) { + std::swap(operator[](i), operator[](size-1-i)); + } + return *this; +} + template std::string ArrayList::toString() const { std::ostringstream o; @@ -158,6 +182,11 @@ bool ArrayList<1, T>::contains (const T &x) const { return head() == x; } +template +bool ArrayList<1, T>::operator==(const ArrayList<1, T> &other) const { + return head() == other.head(); +} + template std::string ArrayList<1, T>::toString() const { std::ostringstream o; @@ -194,6 +223,30 @@ bool isPermutation(const ArrayList<1, T> &list1, const ArrayList<1, T> &list2) { return list1.head() == list2.head(); } +template +bool isCircularPermutation(const ArrayList &list1, const ArrayList &list2) { + ArrayList shifted = list2; + ArrayList reversed = list2; + reversed.reverse(); + for (unsigned shift = 0; shift < size-1; ++shift) { + if (list1 == shifted) return true; + if (list1 == reversed) return true; + shifted.shift(); + reversed.shift(); + } + return false; +} + +template +bool isCircularPermutation(const ArrayList<2, T> &list1, const ArrayList<2, T> &list2) { + return isPermutation(list1, list2); +} + +template +bool isCircularPermutation(const ArrayList<1, T> &list1, const ArrayList<1, T> &list2) { + return list1.head() == list2.head(); +} + //////////////////////////////////////////////////////////////////////////////// template diff --git a/tests/Test_ArrayList.cpp b/tests/Test_ArrayList.cpp index d3a72c42..6025616d 100644 --- a/tests/Test_ArrayList.cpp +++ b/tests/Test_ArrayList.cpp @@ -102,7 +102,7 @@ void Test_ArrayList::minusElement3() { } -void Test_ArrayList::test_isPermutation2() { +void Test_ArrayList::isPermutation2() { ArrayList<2, int> original = makeArrayList(0, 1); @@ -111,7 +111,7 @@ void Test_ArrayList::test_isPermutation2() { QVERIFY(!isPermutation(original, makeArrayList(1, 1))); } -void Test_ArrayList::test_isPermutation3() { +void Test_ArrayList::isPermutation3() { ArrayList<3, int> original2 = makeArrayList(0, 1, 2); @@ -127,7 +127,7 @@ void Test_ArrayList::test_isPermutation3() { QVERIFY(!isPermutation(original2, makeArrayList(0, 1, 3))); } -void Test_ArrayList::test_isPermutation5() { +void Test_ArrayList::isPermutation5() { ArrayList<5, int> original3 = makeArrayList(0, 1, 2, 3, 4); @@ -137,7 +137,7 @@ void Test_ArrayList::test_isPermutation5() { QVERIFY(!isPermutation(original3, makeArrayList(5, 3, 2, 1, 0))); } -void Test_ArrayList::test_isPermutation10() { +void Test_ArrayList::isPermutation10() { ArrayList<10, int> original4 = makeArrayList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); @@ -179,3 +179,30 @@ void Test_ArrayList::test_isPermutation10() { } } #endif + +void Test_ArrayList::shift() { + test(makeArrayList(1,2,3).shift() == makeArrayList(2, 3, 1), std::string("shift?")); +} + +void Test_ArrayList::reverse() { + test(makeArrayList(1,2,3).reverse() == makeArrayList(3, 2, 1), std::string("reverse (odd number of elements)")); + test(makeArrayList(1,2,3,4).reverse() == makeArrayList(4, 3, 2, 1), std::string("reverse (even number of elements)")); +} + + +void Test_ArrayList::circularPermutation() { + test(isCircularPermutation(makeArrayList(1), makeArrayList(1)), std::string("one element, equal")); + test(!isCircularPermutation(makeArrayList(1), makeArrayList(2)), std::string("one element, not equal")); + test(isCircularPermutation(makeArrayList(1,2), makeArrayList(1,2)), std::string("two elements, equal")); + test(isCircularPermutation(makeArrayList(1,2), makeArrayList(2,1)), std::string("two elements, swapped")); + test(!isCircularPermutation(makeArrayList(1,2), makeArrayList(1,3)), std::string("two elements, not equal")); + test(isCircularPermutation(makeArrayList(1,2,3), makeArrayList(1,2,3)), std::string("three elements, equal")); + test(isCircularPermutation(makeArrayList(1,2,3), makeArrayList(3,1,2)), std::string("three elements, shifted")); + test(isCircularPermutation(makeArrayList(1,2,3), makeArrayList(3,2,1)), std::string("three elements, reversed")); + test(!isCircularPermutation(makeArrayList(1,2,3), makeArrayList(4,2,1)), std::string("three elements, not equal")); + test(isCircularPermutation(makeArrayList(1,2,3,4), makeArrayList(1,2,3,4)), std::string("four elements, equal")); + test(isCircularPermutation(makeArrayList(1,2,3,4), makeArrayList(4,1,2,3)), std::string("four elements, shifted")); + test(isCircularPermutation(makeArrayList(1,2,3,4), makeArrayList(4,3,2,1)), std::string("four elements, reversed")); + test(!isCircularPermutation(makeArrayList(1,2,3,4), makeArrayList(1,2,4,3)), std::string("four elements, garbled")); + +} \ No newline at end of file diff --git a/tests/Test_ArrayList.h b/tests/Test_ArrayList.h index 5f2b3d38..69397e94 100644 --- a/tests/Test_ArrayList.h +++ b/tests/Test_ArrayList.h @@ -39,10 +39,13 @@ private slots: void makeListRuns(); void minusElement2(); void minusElement3(); - void test_isPermutation2(); - void test_isPermutation3(); - void test_isPermutation5(); - void test_isPermutation10(); + void isPermutation2(); + void isPermutation3(); + void isPermutation5(); + void isPermutation10(); + void shift(); + void reverse(); + void circularPermutation(); # ifdef TEST_ACCESS_OPERATOR void accessOperator2(); diff --git a/tests/main.cpp b/tests/main.cpp index 96e79236..507bad08 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -98,6 +98,7 @@ int main(int argc, char **argv) { runner.run(test.second); } # else + runner.run(new Test_ArrayList); runner.run(new Test_FacePolygon); # endif } else {