#include "iterator/recursive_iterator.h" #include #include #include #include #include "ranges.h" #include "xcode_gtest_helper.h" using iterator::end_aware_iterator; using testing::StaticAssertTypeEq; TEST(RecursiveIteratorTest, DoesNotUnwrapString) { std::vector obj{"A", "B", "C", "D"}; auto rit = make_recursive_iterator(obj); StaticAssertTypeEq()), std::string *>(); } TEST(RecursiveIteratorTest, CanArrowMultiVector) { std::vector> obj{{{0, 1}}, {{2, 3}}}; auto rit = make_recursive_iterator(obj); StaticAssertTypeEq()), int *>(); EXPECT_EQ(rit.operator->(), &obj[0][0]); } // TEST(RecursiveIteratorTest, CannotArrowMap) { // std::map> obj{{1, {{0, 1}}}, {2, {{2, 3}}}}; // auto rit = make_recursive_iterator(obj); // StaticAssertTypeEq()), void>(); //} TEST(RecursiveIteratorTest, CanAccessOuterterator) { std::map> obj{{1, {{0, 1}}}, {2, {{2, 3}}}}; auto rit = make_recursive_iterator(obj); end_aware_iterator inner = rit; EXPECT_EQ(&std::get<0>(*rit), &(inner->first)); } TEST(RecursiveIteratorTest, CanAccessInnerIterator) { std::map> obj{{1, {{0, 1}}}, {2, {{2, 3}}}}; auto rit = make_recursive_iterator(obj); end_aware_iterator::iterator> inner = rit; EXPECT_EQ(&std::get<1>(*rit), &*inner); } TEST(RecursiveIteratorTest, CanStdGetToAllLayersOfInternalIteration) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator(obj); using mvm_iterator = std::map>>::iterator; StaticAssertTypeEq(rit)), end_aware_iterator>(); using vm_iterator = std::vector>::iterator; StaticAssertTypeEq(rit)), end_aware_iterator>(); using m_iterator = std::map::iterator; StaticAssertTypeEq(rit)), end_aware_iterator>(); using tup_i_i_i = std::tuple; StaticAssertTypeEq(); } TEST(RecursiveIteratorTest, CanAccessInternalIteratorsWithGet) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator(obj); EXPECT_EQ(std::get<0>(rit), end_aware_iterator(obj)); EXPECT_EQ(std::get<1>(rit), end_aware_iterator(obj[1])); EXPECT_EQ(std::get<2>(rit), end_aware_iterator(obj[1][0])); } // TODO: This ought to be implemented as a compiles-test TEST(RecursiveIteratorTest, CanCastCompatibleIterators) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator(obj); iterator::recursive_iterator cit(rit); } TEST(RecursiveIteratorTest, EmptyCtorIsEnd) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator(obj); EXPECT_NE(rit, iterator::sentinel); EXPECT_EQ(ranges::distance(rit, iterator::sentinel), 4); std::advance(rit, 4); EXPECT_EQ(rit, iterator::sentinel); } TEST(BoundedRecursiveIteratorTest, CanStdGetToNLayersOfInternalIteration) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator<2>(obj); using mvm_iterator = std::map>>::iterator; StaticAssertTypeEq(rit)), end_aware_iterator>(); using vm_iterator = std::vector>::iterator; StaticAssertTypeEq(rit)), end_aware_iterator>(); using tup_i_mii = std::tuple &>; StaticAssertTypeEq(); } TEST(BoundedRecursiveIteratorTest, CanAccessInternalIteratorsWithGet) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator<2>(obj); EXPECT_EQ(std::get<0>(rit), end_aware_iterator(obj)); EXPECT_EQ(std::get<1>(rit), end_aware_iterator(obj[1])); } // TODO: This ought to be implemented as a compiles-test TEST(BoundedRecursiveIteratorTest, CanCastCompatibleIterators) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator<2>(obj); iterator::recursive_iterator_n cit(rit); } TEST(BoundedRecursiveIteratorTest, EmptyCtorIsEnd) { std::map>> obj{ {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {2, {{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator<3>(obj); EXPECT_NE(rit, iterator::sentinel); EXPECT_EQ(ranges::distance(rit, iterator::sentinel), 4); std::advance(rit, 4); EXPECT_EQ(rit, iterator::sentinel); } TEST(BoundedRecursiveIteratorTest, CanFetchInnerCollections) { std::vector>> obj{ {{{{1, 1}}, {{2, 2}}}}, // 2 1-element maps {{{{3, 3}, {4, 4}}}} // 1 2-element map }; auto rit = make_recursive_iterator<2>(obj); EXPECT_EQ(*rit, obj[0][0]); }