| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include "iterator/recursive_iterator.h"
- #include <map>
- #include <string>
- #include <tuple>
- #include <vector>
- #include "ranges.h"
- #include "xcode_gtest_helper.h"
- using iterator::end_aware_iterator;
- using testing::StaticAssertTypeEq;
- TEST(RecursiveIteratorTest, DoesNotUnwrapString) {
- std::vector<std::string> obj{"A", "B", "C", "D"};
- auto rit = make_recursive_iterator(obj);
- StaticAssertTypeEq<decltype(rit.operator->()), std::string *>();
- }
- TEST(RecursiveIteratorTest, CanArrowMultiVector) {
- std::vector<std::vector<int>> obj{{{0, 1}}, {{2, 3}}};
- auto rit = make_recursive_iterator(obj);
- StaticAssertTypeEq<decltype(rit.operator->()), int *>();
- EXPECT_EQ(rit.operator->(), &obj[0][0]);
- }
- // TEST(RecursiveIteratorTest, CannotArrowMap) {
- // std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
- // auto rit = make_recursive_iterator(obj);
- // StaticAssertTypeEq<decltype(rit.operator->()), void>();
- //}
- TEST(RecursiveIteratorTest, CanAccessOuterterator) {
- std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
- auto rit = make_recursive_iterator(obj);
- end_aware_iterator<decltype(obj)::iterator> inner = rit;
- EXPECT_EQ(&std::get<0>(*rit), &(inner->first));
- }
- TEST(RecursiveIteratorTest, CanAccessInnerIterator) {
- std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
- auto rit = make_recursive_iterator(obj);
- end_aware_iterator<std::vector<int>::iterator> inner = rit;
- EXPECT_EQ(&std::get<1>(*rit), &*inner);
- }
- TEST(RecursiveIteratorTest, CanStdGetToAllLayersOfInternalIteration) {
- std::map<int, std::vector<std::map<int, int>>> 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<int, std::vector<std::map<int, int>>>::iterator;
- StaticAssertTypeEq<decltype(std::get<0>(rit)),
- end_aware_iterator<mvm_iterator>>();
- using vm_iterator = std::vector<std::map<int, int>>::iterator;
- StaticAssertTypeEq<decltype(std::get<1>(rit)),
- end_aware_iterator<vm_iterator>>();
- using m_iterator = std::map<int, int>::iterator;
- StaticAssertTypeEq<decltype(std::get<2>(rit)),
- end_aware_iterator<m_iterator>>();
- using tup_i_i_i = std::tuple<int const &, int const &, int &>;
- StaticAssertTypeEq<decltype(*rit), tup_i_i_i>();
- }
- TEST(RecursiveIteratorTest, CanAccessInternalIteratorsWithGet) {
- std::map<int, std::vector<std::map<int, int>>> 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<int, std::vector<std::map<int, int>>> 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<decltype(obj)::const_iterator> cit(rit);
- }
- TEST(RecursiveIteratorTest, EmptyCtorIsEnd) {
- std::map<int, std::vector<std::map<int, int>>> 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<int, std::vector<std::map<int, int>>> 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<int, std::vector<std::map<int, int>>>::iterator;
- StaticAssertTypeEq<decltype(std::get<0>(rit)),
- end_aware_iterator<mvm_iterator>>();
- using vm_iterator = std::vector<std::map<int, int>>::iterator;
- StaticAssertTypeEq<decltype(std::get<1>(rit)),
- end_aware_iterator<vm_iterator>>();
- using tup_i_mii = std::tuple<int const &, std::map<int, int> &>;
- StaticAssertTypeEq<decltype(*rit), tup_i_mii>();
- }
- TEST(BoundedRecursiveIteratorTest, CanAccessInternalIteratorsWithGet) {
- std::map<int, std::vector<std::map<int, int>>> 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<int, std::vector<std::map<int, int>>> 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<decltype(obj)::const_iterator, 2> cit(rit);
- }
- TEST(BoundedRecursiveIteratorTest, EmptyCtorIsEnd) {
- std::map<int, std::vector<std::map<int, int>>> 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<std::vector<std::map<int, int>>> 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]);
- }
|