/*! * \file ring_iterator.cpp * \brief * Unit tests for ring_iterator * * \copyright Copyright (C) 2020 Christos Choutouridis * *
License
* The MIT License (MIT) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *
* */ #include #include #include #include namespace Tring_iterator { using namespace utl; // Test construction TEST(Tring_iterator, construct) { int A[10]; //default constructor ring_iterator i1; EXPECT_EQ(nullptr, i1.base()); EXPECT_EQ(nullptr, i1.iter()); EXPECT_EQ(10UL, i1.size()); // implementation specific (you can remove it freely) EXPECT_EQ(2*sizeof(int*), sizeof(i1)); // basic ring_iterator i2(A); EXPECT_EQ(A, i2.base()); EXPECT_EQ(A, i2.iter()); EXPECT_EQ(10UL, i2.size()); // basic from assignment ring_iterator i3 = A; EXPECT_EQ(A, i3.base()); EXPECT_EQ(A, i3.iter()); EXPECT_EQ(10UL, i3.size()); // basic with offset ring_iterator i4(A, 5); EXPECT_EQ(A, i4.base()); EXPECT_EQ(&A[5], i4.iter()); EXPECT_EQ(10UL, i4.size()); // copy (Legacy iterator) auto i5 = i2; EXPECT_EQ(A, i5.base()); EXPECT_EQ(A, i5.iter()); EXPECT_EQ(10UL, i5.size()); // arbitrary type struct TT { int a,b,c; }; std::array t; ring_iterator it(t.data(), 2); EXPECT_EQ(t.begin(), it.base()); EXPECT_EQ(&t[2], it.iter()); EXPECT_EQ(10UL, it.size()); } // Legacy iterator TEST(Tring_iterator, LegacyIterator) { EXPECT_EQ(true, (std::is_same::value_type>::value)); EXPECT_EQ(true, (std::is_same::difference_type>::value)); EXPECT_EQ(true, (std::is_same::reference>::value)); EXPECT_EQ(true, (std::is_same::pointer>::value)); EXPECT_EQ(true, (std::is_same::iterator_category>::value)); int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator i1(A); // copy constructible/assignable auto i2 = i1; EXPECT_EQ(A, i2.base()); EXPECT_EQ(A, i2.iter()); EXPECT_EQ(10UL, i2.size()); // dereferenceable - incrementable ring_iterator i3(A); EXPECT_EQ(true, (std::is_reference::value)); EXPECT_EQ(true, (std::is_same&, decltype(++i3)>::value)); EXPECT_EQ(true, (std::is_reference::value)); // more practical ring_iterator i4(A); ring_iterator i5(A, 9); EXPECT_EQ(A[0], *i4); EXPECT_EQ(&A[1], (++i4).iter()); // check loop EXPECT_EQ(A[9], *i5); EXPECT_EQ(&A[0], (++i5).iter()); } // Legacy input iterator TEST(Tring_iterator, LegacyInputIterator) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator i1(A), i2(A), i3(A, 1); struct T { int m; }; T B[5] { {0}, {1}, {2}, {3}, {4}}; ring_iterator it(B); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_samem)>::value)); EXPECT_EQ (true, (std::is_same&, decltype(++i1)>::value)); EXPECT_EQ (true, (std::is_same::value)); // more practical EXPECT_EQ (true, i1 == i2); EXPECT_EQ (true, i1 != i3); EXPECT_EQ (0, *i1); EXPECT_EQ (0, it->m); EXPECT_EQ (true, (++i1 == i3)); EXPECT_EQ (1, *i1++); EXPECT_EQ (2, *i1); } // Legacy input iterator TEST(Tring_iterator, LegacyOutputIterator) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (true, (std::is_assignable::value)); EXPECT_EQ (true, (std::is_assignable::value)); // more practical *it = 42; EXPECT_EQ (42, A[0]); *it++ = 7; EXPECT_EQ (7, A[0]); EXPECT_EQ (&A[1], it.iter()); } // Legacy forward iterator TEST(Tring_iterator, LegacyForwardIterator) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (0, *it++); EXPECT_EQ (1, *it); } // Legacy bidirectional iterator TEST(Tring_iterator, LegacyBidirectionalIterator) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (true, (std::is_same&, decltype(--it)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it--)>::value)); EXPECT_EQ (true, (std::is_same::value)); // more practical ring_iterator i1(A), i2(A, 9); EXPECT_EQ (9, *i2--); // check loop also EXPECT_EQ (8, *i2); EXPECT_EQ (0, *i1--); // check loop also EXPECT_EQ (9, *i1); } // Legacy random access iterator TEST(Tring_iterator, LegacyRandomAccessIterator) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it1(A), it2(A, 7); EXPECT_EQ (true, (std::is_same&, decltype(it1 += 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it1 + 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(7 + it1)>::value)); EXPECT_EQ (true, (std::is_same&, decltype(it1 -= 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it1 - 7)>::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same it2)>::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same= it2)>::value)); // more practical ring_iterator i1(A), i2(A); i1 += 7; EXPECT_EQ (7, *i1); i1 -= 7; EXPECT_EQ (0, *i1); i1 += 11; EXPECT_EQ (1, *i1); i1 -= 2; EXPECT_EQ (9, *i1); EXPECT_EQ (7, *(i2+7)); EXPECT_EQ (7, *(7+i2)); EXPECT_EQ (1, *(i2+11)); EXPECT_EQ (1, *(11+i2)); EXPECT_EQ (7, *(i1-2)); EXPECT_EQ (8, *(i2-2)); EXPECT_EQ (9, (i1 - i2)); EXPECT_EQ (1, (i2 - i1)); // loop } // Test construction atomic TEST(Tring_iterator, construct_atomic) { int A[10]; //default constructor ring_iterator i1; EXPECT_EQ(nullptr, i1.base()); EXPECT_EQ(nullptr, i1.iter()); EXPECT_EQ(10UL, i1.size()); // implementation specific (you can remove it freely) EXPECT_EQ(2*sizeof(int*), sizeof(i1)); // basic ring_iterator i2(A); EXPECT_EQ(A, i2.base()); EXPECT_EQ(A, i2.iter()); EXPECT_EQ(10UL, i2.size()); // basic from assignment ring_iterator i3 = A; EXPECT_EQ(A, i3.base()); EXPECT_EQ(A, i3.iter()); EXPECT_EQ(10UL, i3.size()); // basic with offset ring_iterator i4(A, 5); EXPECT_EQ(A, i4.base()); EXPECT_EQ(&A[5], i4.iter()); EXPECT_EQ(10UL, i4.size()); // copy (Legacy iterator) auto i5 = i2; EXPECT_EQ(A, i5.base()); EXPECT_EQ(A, i5.iter()); EXPECT_EQ(10UL, i5.size()); // arbitrary type struct TT { int a,b,c; }; std::array t; ring_iterator it(t.data(), 2); EXPECT_EQ(t.begin(), it.base()); EXPECT_EQ(&t[2], it.iter()); EXPECT_EQ(10UL, it.size()); } // Legacy iterator atomic TEST(Tring_iterator, LegacyIterator_atomic) { EXPECT_EQ(true, (std::is_same::value_type>::value)); EXPECT_EQ(true, (std::is_same::difference_type>::value)); EXPECT_EQ(true, (std::is_same::reference>::value)); EXPECT_EQ(true, (std::is_same::pointer>::value)); EXPECT_EQ(true, (std::is_same::iterator_category>::value)); int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator i1(A); // copy constructible/assignable auto i2 = i1; EXPECT_EQ(A, i2.base()); EXPECT_EQ(A, i2.iter()); EXPECT_EQ(10UL, i2.size()); // dereferenceable - incrementable ring_iterator i3(A); EXPECT_EQ(true, (std::is_reference::value)); EXPECT_EQ(true, (std::is_same&, decltype(++i3)>::value)); EXPECT_EQ(true, (std::is_reference::value)); // more practical ring_iterator i4(A); ring_iterator i5(A, 9); EXPECT_EQ(A[0], *i4); EXPECT_EQ(&A[1], (++i4).iter()); // check loop EXPECT_EQ(A[9], *i5); EXPECT_EQ(&A[0], (++i5).iter()); } // Legacy input iterator atomic TEST(Tring_iterator, LegacyInputIterator_atomic) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator i1(A), i2(A), i3(A, 1); struct T { int m; }; T B[5] { {0}, {1}, {2}, {3}, {4}}; ring_iterator it(B); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_samem)>::value)); EXPECT_EQ (true, (std::is_same&, decltype(++i1)>::value)); EXPECT_EQ (true, (std::is_same::value)); // more practical EXPECT_EQ (true, i1 == i2); EXPECT_EQ (true, i1 != i3); EXPECT_EQ (0, *i1); EXPECT_EQ (0, it->m); EXPECT_EQ (true, (++i1 == i3)); EXPECT_EQ (1, *i1++); EXPECT_EQ (2, *i1); } // Legacy input iterator atomic TEST(Tring_iterator, LegacyOutputIterator_atomic) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (true, (std::is_assignable::value)); EXPECT_EQ (true, (std::is_assignable::value)); // more practical *it = 42; EXPECT_EQ (42, A[0]); *it++ = 7; EXPECT_EQ (7, A[0]); EXPECT_EQ (&A[1], it.iter()); } // Legacy forward iterator atomic TEST(Tring_iterator, LegacyForwardIterator_atomic) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (0, *it++); EXPECT_EQ (1, *it); } // Legacy bidirectional iterator atomic TEST(Tring_iterator, LegacyBidirectionalIterator_atomic) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it(A); EXPECT_EQ (true, (std::is_same&, decltype(--it)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it--)>::value)); EXPECT_EQ (true, (std::is_same::value)); // more practical ring_iterator i1(A), i2(A, 9); EXPECT_EQ (9, *i2--); // check loop also EXPECT_EQ (8, *i2); EXPECT_EQ (0, *i1--); // check loop also EXPECT_EQ (9, *i1); } // Legacy random access iterator atomic TEST(Tring_iterator, LegacyRandomAccessIterator_atomic) { int A[10] {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9}; ring_iterator it1(A), it2(A, 7); EXPECT_EQ (true, (std::is_same&, decltype(it1 += 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it1 + 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(7 + it1)>::value)); EXPECT_EQ (true, (std::is_same&, decltype(it1 -= 7)>::value)); EXPECT_EQ (true, (std::is_same, decltype(it1 - 7)>::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same it2)>::value)); EXPECT_EQ (true, (std::is_same::value)); EXPECT_EQ (true, (std::is_same= it2)>::value)); // more practical ring_iterator i1(A), i2(A); i1 += 7; EXPECT_EQ (7, *i1); i1 -= 7; EXPECT_EQ (0, *i1); i1 += 11; EXPECT_EQ (1, *i1); i1 -= 2; EXPECT_EQ (9, *i1); EXPECT_EQ (7, *(i2+7)); EXPECT_EQ (7, *(7+i2)); EXPECT_EQ (1, *(i2+11)); EXPECT_EQ (1, *(11+i2)); EXPECT_EQ (7, *(i1-2)); EXPECT_EQ (8, *(i2-2)); EXPECT_EQ (9, (i1 - i2)); EXPECT_EQ (1, (i2 - i1)); // loop } }