]> AND Public Git Repository - simgrid.git/blobdiff - src/xbt/utils/iter/subsets_tests.cpp
Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'operation-plugin' into 'master'
[simgrid.git] / src / xbt / utils / iter / subsets_tests.cpp
index 2415a16657cb5606171dbad03a7d001770d94a12..41bdf419ee9a533bc1419e4ee4c0a8c675d849d3 100644 (file)
@@ -73,11 +73,118 @@ TEST_CASE("simgrid::xbt::powerset_iterator: Iteration General Properties")
 
 TEST_CASE("simgrid::xbt::variable_for_loop: Edge Cases")
 {
+  // Note the extra `{}` in the tests. This constructs a
+  // `std::reference_wrapper` to the specified collection
+  std::vector<int> outer_loop1{0, 1, 2, 3, 4};
+  std::vector<int> outer_loop2{0, 1, 6, 7};
+  std::vector<int> outer_loop3{1, 2};
+  std::vector<int> empty_set;
 
   SECTION("Iterations without effect")
   {
-    SECTION("Iteration over no collections") {}
+    SECTION("Iteration over no collections")
+    {
+      variable_for_loop<std::vector<int>> first;
+      variable_for_loop<std::vector<int>> last;
+      REQUIRE(first == last);
+    }
+
+    SECTION("Iteration with an empty collection")
+    {
+      variable_for_loop<std::vector<int>> last;
+      REQUIRE(variable_for_loop<std::vector<int>>{{empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop1}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop1}, {outer_loop2}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop1}, {outer_loop2}, {outer_loop3}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop3}, {empty_set}} == last);
+    }
+
+    SECTION("Iteration with multiple empty collections")
+    {
+      variable_for_loop<std::vector<int>> last;
+      REQUIRE(variable_for_loop<std::vector<int>>{{empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{empty_set}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop1}, {outer_loop2}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{{outer_loop1}, {outer_loop2}, {empty_set}, {empty_set}} == last);
+      REQUIRE(variable_for_loop<std::vector<int>>{
+                  {outer_loop1}, {outer_loop2}, {outer_loop3}, {empty_set}, {empty_set}} == last);
+    }
+  }
+
+  SECTION("Iteration with effects")
+  {
+    SECTION("Iteration over a single collection yields the collection")
+    {
+      variable_for_loop<std::vector<int>> first{{outer_loop1}};
+      variable_for_loop<std::vector<int>> last;
 
-    SECTION("Iteration with an empty collection") {}
+      std::vector<int> elements_seen;
+
+      for (; first != last; ++first) {
+        const auto& elements = *first;
+        REQUIRE(elements.size() == 1);
+        elements_seen.push_back(*elements[0]);
+      }
+
+      REQUIRE(elements_seen == outer_loop1);
+    }
+
+    SECTION("Iteration over two collections yields all pairs")
+    {
+      variable_for_loop<std::vector<int>> first{{outer_loop1, outer_loop2}};
+      variable_for_loop<std::vector<int>> last;
+
+      std::vector<std::pair<int, int>> pairs_seen;
+      for (; first != last; ++first) {
+        const auto& elements = *first;
+        REQUIRE(elements.size() == 2);
+        pairs_seen.push_back(std::make_pair(*elements[0], *elements[1]));
+      }
+
+      std::vector<std::pair<int, int>> expected_pairs{{0, 0}, {0, 1}, {0, 6}, {0, 7}, {1, 0}, {1, 1}, {1, 6},
+                                                      {1, 7}, {2, 0}, {2, 1}, {2, 6}, {2, 7}, {3, 0}, {3, 1},
+                                                      {3, 6}, {3, 7}, {4, 0}, {4, 1}, {4, 6}, {4, 7}};
+      REQUIRE(pairs_seen == expected_pairs);
+    }
+
+    SECTION("Iteration over three collections yields all triples")
+    {
+      variable_for_loop<std::vector<int>> first{{outer_loop3, outer_loop1, outer_loop2}};
+      variable_for_loop<std::vector<int>> last;
+
+      std::vector<std::tuple<int, int, int>> triples_seen;
+      for (; first != last; ++first) {
+        const auto& elements = *first;
+        REQUIRE(elements.size() == 3);
+        triples_seen.push_back(std::make_tuple(*elements[0], *elements[1], *elements[2]));
+      }
+
+      std::vector<std::tuple<int, int, int>> expected_triples{
+          {1, 0, 0}, {1, 0, 1}, {1, 0, 6}, {1, 0, 7}, {1, 1, 0}, {1, 1, 1}, {1, 1, 6}, {1, 1, 7}, {1, 2, 0}, {1, 2, 1},
+          {1, 2, 6}, {1, 2, 7}, {1, 3, 0}, {1, 3, 1}, {1, 3, 6}, {1, 3, 7}, {1, 4, 0}, {1, 4, 1}, {1, 4, 6}, {1, 4, 7},
+
+          {2, 0, 0}, {2, 0, 1}, {2, 0, 6}, {2, 0, 7}, {2, 1, 0}, {2, 1, 1}, {2, 1, 6}, {2, 1, 7}, {2, 2, 0}, {2, 2, 1},
+          {2, 2, 6}, {2, 2, 7}, {2, 3, 0}, {2, 3, 1}, {2, 3, 6}, {2, 3, 7}, {2, 4, 0}, {2, 4, 1}, {2, 4, 6}, {2, 4, 7}};
+
+      REQUIRE(triples_seen == expected_triples);
+    }
+
+    SECTION("Iteration over all collections yields all combinations")
+    {
+      std::vector<int> outer_loop4{1, 5};
+      std::vector<int> outer_loop5{1, 8};
+
+      variable_for_loop<std::vector<int>> first{
+          {outer_loop1}, {outer_loop2}, {outer_loop3}, {outer_loop4}, {outer_loop5}};
+      variable_for_loop<std::vector<int>> last;
+
+      size_t total_iterations = 0;
+      for (; first != last; ++first, ++total_iterations) {
+        const auto& elements = *first;
+        REQUIRE(elements.size() == 5);
+      }
+      REQUIRE(total_iterations ==
+              (outer_loop1.size() * outer_loop2.size() * outer_loop3.size() * outer_loop4.size() * outer_loop5.size()));
+    }
   }
 }
\ No newline at end of file