| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #include "iterator/recursive_iterator.hpp"
- #include <map>
- #include <vector>
- #include <gmock/gmock.h>
- // TODO: std::string should not be unwrapped
- TEST(RecursiveIteratorTest, CanArrowMultiVector) {
- std::vector<std::vector<int>> obj{{{0, 1}}, {{2, 3}}};
- auto rit = make_recursive_iterator(obj);
- testing::StaticAssertTypeEq<decltype(rit.operator->()), int *>();
- EXPECT_THAT(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);
- testing::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);
- auto inner = iterator::end_aware_iterator<decltype(obj)::iterator>(rit);
- EXPECT_THAT(&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);
- auto inner = iterator::end_aware_iterator<std::vector<int>::iterator>(rit);
- EXPECT_THAT(&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);
- testing::StaticAssertTypeEq<
- decltype(std::get<0>(rit)),
- iterator::end_aware_iterator<decltype(obj)::iterator>>();
- testing::StaticAssertTypeEq<decltype(std::get<1>(rit)),
- iterator::end_aware_iterator<
- std::vector<std::map<int, int>>::iterator>>();
- testing::StaticAssertTypeEq<
- decltype(std::get<2>(rit)),
- iterator::end_aware_iterator<std::map<int, int>::iterator>>();
- testing::StaticAssertTypeEq<decltype(*rit),
- std::tuple<int const &, int const &, int &>>();
- }
- 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_THAT(std::get<0>(rit), make_end_aware_iterator(obj));
- EXPECT_THAT(std::get<1>(rit), make_end_aware_iterator(obj[1]));
- EXPECT_THAT(std::get<2>(rit), make_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_THAT(rit, testing::Ne(decltype(rit)()));
- EXPECT_THAT(std::distance(rit, decltype(rit)()), 4);
- std::advance(rit, 4);
- EXPECT_THAT(rit, decltype(rit)());
- }
- 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);
- testing::StaticAssertTypeEq<
- decltype(std::get<0>(rit)),
- iterator::end_aware_iterator<decltype(obj)::iterator>>();
- testing::StaticAssertTypeEq<decltype(std::get<1>(rit)),
- iterator::end_aware_iterator<
- std::vector<std::map<int, int>>::iterator>>();
- testing::StaticAssertTypeEq<decltype(*rit),
- std::tuple<int const &, std::map<int, int> &>>();
- }
- 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_THAT(std::get<0>(rit), make_end_aware_iterator(obj));
- EXPECT_THAT(std::get<1>(rit), make_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<2>(obj);
- EXPECT_THAT(rit, testing::Ne(decltype(rit)()));
- EXPECT_THAT(std::distance(rit, decltype(rit)()), 3);
- std::advance(rit, 3);
- EXPECT_THAT(rit, decltype(rit)());
- }
- 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_THAT(*rit, obj[0][0]);
- }
- // TEST(RecursiveIteratorTest, CanConstructInPlaceFromIterators) {
- // std::map<int, std::vector<std::map<int, int>>> const obj{
- // {1, {{{1, 1}}, {{2, 2}}}}, {2, {{{3, 3}, {4, 4}}}}};
- // auto const it = make_end_aware_iterator(obj.begin(), obj.end());
- // auto const it_1 = ++make_end_aware_iterator(it->second);
- // auto const it_2 = make_end_aware_iterator(*it_1);
- // // Note that this carries the weakness of non bounds-checking that our
- // // iterators are all sitting on the same hierarchy...
- // EXPECT_NO_THROW(make_recursive_iterator(it, it_1, it_2));
- //}
- //
- // TEST(RecursiveIteratorTest, InternalIteratorsFromStdGetMatchCtorArgs) {
- // std::map<int, std::vector<std::map<int, int>>> const obj{
- // {1, {{{1, 1}}, {{2, 2}}}}, {2, {{{3, 3}, {4, 4}}}}};
- // auto const it = make_end_aware_iterator(obj.begin(), obj.end());
- // auto const it_1 = ++make_end_aware_iterator(it->second);
- // auto const it_2 = make_end_aware_iterator(*it_1);
- // iterator::recursive_iterator<decltype(obj.cbegin())> rit{iterator::in_place,
- // it, it_1, it_2};
- // EXPECT_THAT(std::get<0>(rit), it);
- // EXPECT_THAT(std::get<1>(rit), it_1);
- // EXPECT_THAT(std::get<2>(rit), it_2);
- //}
|