#include "iterator/indexed_iterator.hpp" #include #include #include #include "iterator/end_aware_iterator.hpp" using idx_iterator = iterator::indexed_iterator::iterator>; // TODO: This ought to be implemented as a compiles-test TEST(IndexedIteratorTest, CanCastCompatibleIterators) { std::vector v{1, 2, 3, 4, 5}; idx_iterator eai(v.begin()); ::iterator::indexed_iterator::const_iterator>{eai}; } TEST(IndexedIteratorTest, CanLieAboutIndex) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator it(vec.begin(), 3); EXPECT_THAT(it->first, 3); } TEST(IndexedIteratorTest, FakeIndexDoesntEffectEqualityCheck) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; EXPECT_THAT(idx_iterator(vec.begin()), idx_iterator(vec.begin(), 3)); EXPECT_THAT(idx_iterator(vec.begin()) + 3, testing::Ne(idx_iterator(vec.begin(), 3))); } TEST(IndexedIteratorTest, IffBaseIteratorEmptyIsEndThenEmptyIsEnd) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; EXPECT_THAT(idx_iterator(), testing::Ne(idx_iterator(vec.end()))); iterator::end_aware_iterator end(vec.end()); EXPECT_THAT(iterator::indexed_iterator(), iterator::indexed_iterator(end)); } TEST(IndexedIteratorTest, CanCompareIteratorOrder) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator const begin(vec.begin()); idx_iterator const it = begin + 3; EXPECT_THAT(begin, testing::Lt(it)); EXPECT_THAT(begin, testing::Le(it)); EXPECT_THAT(it, testing::Le(it)); EXPECT_THAT(it, testing::Gt(begin)); EXPECT_THAT(it, testing::Ge(begin)); EXPECT_THAT(it, testing::Ge(it)); } TEST(IndexedIteratorTest, PreIncrementAdvancesIterator) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator it(vec.begin() + 1); EXPECT_THAT(it->second, 3); EXPECT_THAT((++it)->second, 2); EXPECT_THAT(it->second, 2); } TEST(IndexedIteratorTest, PostIncrementReturnsCopyOfPrev) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator it(vec.begin() + 1); EXPECT_THAT(it->second, 3); EXPECT_THAT((it++)->second, 3); EXPECT_THAT(it->second, 2); } TEST(IndexedIteratorTest, PreDecrementAdvancesIterator) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator it(vec.begin() + 1); EXPECT_THAT(it->second, 3); EXPECT_THAT((--it)->second, 5); EXPECT_THAT(it->second, 5); } TEST(IndexedIteratorTest, PostDecrementReturnsCopyOfPrev) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator it(vec.begin() + 1); EXPECT_THAT(it->second, 3); EXPECT_THAT((it--)->second, 3); EXPECT_THAT(it->second, 5); } TEST(IndexedIteratorTest, CanWalkNStepsForward) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator const begin(vec.begin()); idx_iterator it = begin; it += 4; EXPECT_THAT(std::distance(begin, it), 4); } TEST(IndexedIteratorTest, CanWalkNStepsBackwards) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator const end(vec.end()); idx_iterator it = end; it -= 4; EXPECT_THAT(std::distance(it, end), 4); } TEST(IndexedIteratorTest, RandomAccessIsPassthrough) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; EXPECT_THAT(idx_iterator(vec.begin()) + 4, idx_iterator(vec.begin() + 4)); EXPECT_THAT(idx_iterator(vec.end()) - 4, idx_iterator(vec.end() - 4)); } TEST(IndexedIteratorTest, TreatsVectorIteratorAsPairIdxValue) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; std::vector> const expected{ {0, 5}, {1, 3}, {2, 2}, {3, 8}, {4, 9}, {5, 11}, {6, 2}, {7, 4}}; std::vector> const result(idx_iterator(vec.begin()), idx_iterator(vec.end())); EXPECT_THAT(result, expected); } TEST(IndexedIteratorTest, TreatsVectorIteratorAsMapIdxToValue) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; std::map const expected{{0, 5}, {1, 3}, {2, 2}, {3, 8}, {4, 9}, {5, 11}, {6, 2}, {7, 4}}; std::map const result(idx_iterator(vec.begin()), idx_iterator(vec.end())); EXPECT_THAT(result, expected); } TEST(IndexedIteratorTest, CanMutatePointedToData) { std::vector vec{5, 3, 2, 8, 9, 11, 2, 4}; idx_iterator(vec.begin() + 4, 4)->second = -1; EXPECT_THAT(vec[4], -1); }