recursive_iterator_accessors_test.cxx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "iterator/recursive_iterator.hpp"
  2. #include <map>
  3. #include <vector>
  4. #include <gmock/gmock.h>
  5. // TODO: std::string should not be unwrapped
  6. TEST(RecursiveIteratorTest, CanArrowMultiVector) {
  7. std::vector<std::vector<int>> obj{{{0, 1}}, {{2, 3}}};
  8. auto rit = make_recursive_iterator(obj);
  9. testing::StaticAssertTypeEq<decltype(rit.operator->()), int *>();
  10. EXPECT_THAT(rit.operator->(), &obj[0][0]);
  11. }
  12. TEST(RecursiveIteratorTest, CannotArrowMap) {
  13. std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
  14. auto rit = make_recursive_iterator(obj);
  15. testing::StaticAssertTypeEq<decltype(rit.operator->()), void>();
  16. }
  17. TEST(RecursiveIteratorTest, CanAccessOuterterator) {
  18. std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
  19. auto rit = make_recursive_iterator(obj);
  20. auto inner = iterator::end_aware_iterator<decltype(obj)::iterator>(rit);
  21. EXPECT_THAT(&std::get<0>(*rit), &(inner->first));
  22. }
  23. TEST(RecursiveIteratorTest, CanAccessInnerIterator) {
  24. std::map<int, std::vector<int>> obj{{1, {{0, 1}}}, {2, {{2, 3}}}};
  25. auto rit = make_recursive_iterator(obj);
  26. auto inner = iterator::end_aware_iterator<std::vector<int>::iterator>(rit);
  27. EXPECT_THAT(&std::get<1>(*rit), &*inner);
  28. }
  29. TEST(RecursiveIteratorTest, CanStdGetToAllLayersOfInternalIteration) {
  30. std::map<int, std::vector<std::map<int, int>>> obj{
  31. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  32. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  33. };
  34. auto rit = make_recursive_iterator(obj);
  35. testing::StaticAssertTypeEq<
  36. decltype(std::get<0>(rit)),
  37. iterator::end_aware_iterator<decltype(obj)::iterator>>();
  38. testing::StaticAssertTypeEq<decltype(std::get<1>(rit)),
  39. iterator::end_aware_iterator<
  40. std::vector<std::map<int, int>>::iterator>>();
  41. testing::StaticAssertTypeEq<
  42. decltype(std::get<2>(rit)),
  43. iterator::end_aware_iterator<std::map<int, int>::iterator>>();
  44. testing::StaticAssertTypeEq<decltype(*rit),
  45. std::tuple<int const &, int const &, int &>>();
  46. }
  47. TEST(RecursiveIteratorTest, CanAccessInternalIteratorsWithGet) {
  48. std::map<int, std::vector<std::map<int, int>>> obj{
  49. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  50. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  51. };
  52. auto rit = make_recursive_iterator(obj);
  53. EXPECT_THAT(std::get<0>(rit), make_end_aware_iterator(obj));
  54. EXPECT_THAT(std::get<1>(rit), make_end_aware_iterator(obj[1]));
  55. EXPECT_THAT(std::get<2>(rit), make_end_aware_iterator(obj[1][0]));
  56. }
  57. // TODO: This ought to be implemented as a compiles-test
  58. TEST(RecursiveIteratorTest, CanCastCompatibleIterators) {
  59. std::map<int, std::vector<std::map<int, int>>> obj{
  60. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  61. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  62. };
  63. auto rit = make_recursive_iterator(obj);
  64. iterator::recursive_iterator<decltype(obj)::const_iterator> cit(rit);
  65. }
  66. TEST(RecursiveIteratorTest, EmptyCtorIsEnd) {
  67. std::map<int, std::vector<std::map<int, int>>> obj{
  68. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  69. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  70. };
  71. auto rit = make_recursive_iterator(obj);
  72. EXPECT_THAT(rit, testing::Ne(decltype(rit)()));
  73. EXPECT_THAT(std::distance(rit, decltype(rit)()), 4);
  74. std::advance(rit, 4);
  75. EXPECT_THAT(rit, decltype(rit)());
  76. }
  77. TEST(BoundedRecursiveIteratorTest, CanStdGetToNLayersOfInternalIteration) {
  78. std::map<int, std::vector<std::map<int, int>>> obj{
  79. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  80. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  81. };
  82. auto rit = make_recursive_iterator<2>(obj);
  83. testing::StaticAssertTypeEq<
  84. decltype(std::get<0>(rit)),
  85. iterator::end_aware_iterator<decltype(obj)::iterator>>();
  86. testing::StaticAssertTypeEq<decltype(std::get<1>(rit)),
  87. iterator::end_aware_iterator<
  88. std::vector<std::map<int, int>>::iterator>>();
  89. testing::StaticAssertTypeEq<decltype(*rit),
  90. std::tuple<int const &, std::map<int, int> &>>();
  91. }
  92. TEST(BoundedRecursiveIteratorTest, CanAccessInternalIteratorsWithGet) {
  93. std::map<int, std::vector<std::map<int, int>>> obj{
  94. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  95. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  96. };
  97. auto rit = make_recursive_iterator<2>(obj);
  98. EXPECT_THAT(std::get<0>(rit), make_end_aware_iterator(obj));
  99. EXPECT_THAT(std::get<1>(rit), make_end_aware_iterator(obj[1]));
  100. }
  101. // TODO: This ought to be implemented as a compiles-test
  102. TEST(BoundedRecursiveIteratorTest, CanCastCompatibleIterators) {
  103. std::map<int, std::vector<std::map<int, int>>> obj{
  104. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  105. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  106. };
  107. auto rit = make_recursive_iterator<2>(obj);
  108. iterator::recursive_iterator_n<decltype(obj)::const_iterator, 2> cit(rit);
  109. }
  110. TEST(BoundedRecursiveIteratorTest, EmptyCtorIsEnd) {
  111. std::map<int, std::vector<std::map<int, int>>> obj{
  112. {1, {{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  113. {2, {{{3, 3}, {4, 4}}}} // 1 2-element map
  114. };
  115. auto rit = make_recursive_iterator<2>(obj);
  116. EXPECT_THAT(rit, testing::Ne(decltype(rit)()));
  117. EXPECT_THAT(std::distance(rit, decltype(rit)()), 3);
  118. std::advance(rit, 3);
  119. EXPECT_THAT(rit, decltype(rit)());
  120. }
  121. TEST(BoundedRecursiveIteratorTest, CanFetchInnerCollections) {
  122. std::vector<std::vector<std::map<int, int>>> obj{
  123. {{{{1, 1}}, {{2, 2}}}}, // 2 1-element maps
  124. {{{{3, 3}, {4, 4}}}} // 1 2-element map
  125. };
  126. auto rit = make_recursive_iterator<2>(obj);
  127. EXPECT_THAT(*rit, obj[0][0]);
  128. }
  129. // TEST(RecursiveIteratorTest, CanConstructInPlaceFromIterators) {
  130. // std::map<int, std::vector<std::map<int, int>>> const obj{
  131. // {1, {{{1, 1}}, {{2, 2}}}}, {2, {{{3, 3}, {4, 4}}}}};
  132. // auto const it = make_end_aware_iterator(obj.begin(), obj.end());
  133. // auto const it_1 = ++make_end_aware_iterator(it->second);
  134. // auto const it_2 = make_end_aware_iterator(*it_1);
  135. // // Note that this carries the weakness of non bounds-checking that our
  136. // // iterators are all sitting on the same hierarchy...
  137. // EXPECT_NO_THROW(make_recursive_iterator(it, it_1, it_2));
  138. //}
  139. //
  140. // TEST(RecursiveIteratorTest, InternalIteratorsFromStdGetMatchCtorArgs) {
  141. // std::map<int, std::vector<std::map<int, int>>> const obj{
  142. // {1, {{{1, 1}}, {{2, 2}}}}, {2, {{{3, 3}, {4, 4}}}}};
  143. // auto const it = make_end_aware_iterator(obj.begin(), obj.end());
  144. // auto const it_1 = ++make_end_aware_iterator(it->second);
  145. // auto const it_2 = make_end_aware_iterator(*it_1);
  146. // iterator::recursive_iterator<decltype(obj.cbegin())> rit{iterator::in_place,
  147. // it, it_1, it_2};
  148. // EXPECT_THAT(std::get<0>(rit), it);
  149. // EXPECT_THAT(std::get<1>(rit), it_1);
  150. // EXPECT_THAT(std::get<2>(rit), it_2);
  151. //}