From 13c0c4b272169e5eb10c985853c986503b85a2b5 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 8 Feb 2023 17:08:02 +0100 Subject: [PATCH 1/2] :white_check_mark: Added tests for STL utils --- include/fiction/utils/stl_utils.hpp | 12 ++++- test/utils/stl_utils.cpp | 78 +++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 test/utils/stl_utils.cpp diff --git a/include/fiction/utils/stl_utils.hpp b/include/fiction/utils/stl_utils.hpp index 1a4317bee..0d5988886 100644 --- a/include/fiction/utils/stl_utils.hpp +++ b/include/fiction/utils/stl_utils.hpp @@ -6,7 +6,9 @@ #define FICTION_STL_UTILS_HPP #include +#include #include +#include #include namespace fiction @@ -29,11 +31,19 @@ namespace fiction * @param last End of the range to examine. * @param s_first Begin of the range to search for. * @param s_last End of the range to search for. - * @return Iterator to the first position of the first shared 2-element sub-sequence shared between the two ranges. + * @return Iterator in the range `[first, last)` to the first position of the first 2-element sub-sequence shared + * between the two ranges, or `last` if no such shared sub-sequence exists. */ template InputIt find_first_two_of(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last) noexcept { + static_assert( + std::is_base_of::iterator_category>::value, + "InputIt must meet the requirements of LegacyInputIterator"); + static_assert( + std::is_base_of::iterator_category>::value, + "ForwardIt must meet the requirements of LegacyForwardIterator"); + for (; first != last - 1; ++first) { for (ForwardIt it = s_first; it != s_last - 1; ++it) diff --git a/test/utils/stl_utils.cpp b/test/utils/stl_utils.cpp new file mode 100644 index 000000000..d6ee6cdf5 --- /dev/null +++ b/test/utils/stl_utils.cpp @@ -0,0 +1,78 @@ +// +// Created by marcel on 07.02.23. +// + +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Test find_first_two_of with vector input", "[find_first_two_of]") +{ + static const std::vector v1{0, 1, 1, 2, 3, 3}; + static const std::vector v2{1, 2, 3, 3}; + + auto it = find_first_two_of(v1.begin(), v1.end(), v2.begin(), v2.end()); + CHECK(*it == 1); + CHECK(*(it + 1) == 2); + + static const std::vector v3{1, 2, 4, 3}; + it = find_first_two_of(v1.begin(), v1.end(), v3.begin(), v3.end()); + CHECK(it == std::next(v1.begin(), 2)); +} + +TEST_CASE("Test find_first_two_of with array input", "[find_first_two_of]") +{ + static constexpr const std::array a1{0, 1, 1, 2, 3, 3}; + static constexpr const std::array a2{1, 2, 3, 3}; + + const auto* it = find_first_two_of(std::begin(a1), std::end(a1), std::begin(a2), std::end(a2)); + CHECK(*it == 1); + CHECK(*(std::next(it, 1)) == 2); + + static constexpr const std::array a3{1, 2, 4, 3}; + it = find_first_two_of(std::begin(a1), std::end(a1), std::begin(a3), std::end(a3)); + CHECK(it == std::next(std::begin(a1), 2)); +} + +TEST_CASE("Test find_first_two_of with different iterator types", "[find_first_two_of]") +{ + static const std::vector v1{0, 1, 1, 2, 3, 3}; + static constexpr const std::array a2{1, 2, 3, 3}; + + auto it = find_first_two_of(v1.begin(), v1.end(), std::begin(a2), std::end(a2)); + CHECK(*it == 1); + CHECK(*(it + 1) == 2); + + static constexpr const std::array a3{1, 2, 4, 3}; + it = find_first_two_of(v1.begin(), v1.end(), std::begin(a3), std::end(a3)); + CHECK(it == std::next(v1.begin(), 2)); +} + +TEST_CASE("Test find_first_two_of with layout_coordinate_paths", "[first_first_two_of]") +{ + static const layout_coordinate_path p1{{1, 1}, {2, 1}}; + static const layout_coordinate_path p2{{0, 1}, {1, 1}, {2, 1}}; + + // regular iterators + const auto it1 = find_first_two_of(p1.begin(), p1.end(), p2.begin(), p2.end()); + const auto it2 = find_first_two_of(p2.begin(), p2.end(), p1.begin(), p1.end()); + + CHECK(it1 == p1.begin()); + CHECK(it2 == std::next(p2.begin(), 1)); + + // const iterators via std::cbegin and std::cend + const auto it3 = find_first_two_of(std::cbegin(p1), std::cend(p1), std::cbegin(p2), std::cend(p2)); + const auto it4 = find_first_two_of(std::cbegin(p2), std::cend(p2), std::cbegin(p1), std::cend(p1)); + + CHECK(it3 == p1.begin()); + CHECK(it4 == std::next(p2.begin(), 1)); +} From 0e46f38dd8ed1420de93b0ca6a457f47001be915 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 9 Feb 2023 09:47:18 +0100 Subject: [PATCH 2/2] :green_heart: Fixed test for STL utils under MSVC --- test/utils/stl_utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/stl_utils.cpp b/test/utils/stl_utils.cpp index d6ee6cdf5..079bef1ba 100644 --- a/test/utils/stl_utils.cpp +++ b/test/utils/stl_utils.cpp @@ -34,7 +34,7 @@ TEST_CASE("Test find_first_two_of with array input", "[find_first_two_of]") static constexpr const std::array a1{0, 1, 1, 2, 3, 3}; static constexpr const std::array a2{1, 2, 3, 3}; - const auto* it = find_first_two_of(std::begin(a1), std::end(a1), std::begin(a2), std::end(a2)); + auto it = find_first_two_of(std::begin(a1), std::end(a1), std::begin(a2), std::end(a2)); CHECK(*it == 1); CHECK(*(std::next(it, 1)) == 2);