// An iterator that shuffles over a vector. #define CATCH_CONFIG_MAIN #include #include #include #include #include #include using string_view = std::experimental::string_view; // Should work over any SequenceContainer. template std::string join(const Container& vect, string_view sep = " ") { auto i = 0; std::stringstream out; for (const auto& item : vect) { if (i != 0) { out << sep; } out << item; i++; } return out.str(); } template Container shuffle_1(const Container& src) { using pair = std::pair; std::vector indexes; int i = 0; for (size_t i = 0; i < src.size(); i++) { indexes.emplace_back(pair{i, std::rand()}); } std::cout << join(indexes | ranges::view::keys) << "\n"; std::sort(indexes.begin(), indexes.end(), [](auto lhs, auto rhs) { return lhs.second < rhs.second; }); Container out; for (auto key : indexes | ranges::view::keys) { out.emplace_back(src[key]); } return out; } template Container shuffle(const Container& src) { Container dup{src}; for (size_t i = 0; i < src.size(); i++) { std::swap(dup[i], dup[std::rand() % src.size()]); } return dup; } TEST_CASE("cx_shuffle", "shuffle") { std::vector items{1, 2, 3, 4, 5, 6}; CHECK(join(items) == "1 2 3 4 5 6"); CHECK(join(shuffle(items)) == "2 1 4 5 6 3"); }