diff options
-rw-r--r-- | src/hole.cpp | 62 | ||||
-rw-r--r-- | test/hole.cpp | 55 |
2 files changed, 66 insertions, 51 deletions
diff --git a/src/hole.cpp b/src/hole.cpp index 5551b780..396d6d44 100644 --- a/src/hole.cpp +++ b/src/hole.cpp @@ -13,6 +13,7 @@ namespace floormat { namespace { using bbox = cut_rectangle_result::bbox; +using rect = cut_rectangle_result::rect; enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, }; enum class location : uint8_t { R0, R1, H0, H1, }; @@ -33,6 +34,8 @@ struct element constexpr element make_element(uint8_t s) { + // ReSharper disable CppIdenticalOperandsInBinaryExpression + // NOLINTBEGIN(*-simplify) switch (s) { using enum location; @@ -110,11 +113,38 @@ constexpr element make_element(uint8_t s) {R0, H0, H0, H1}, }}}; } - fm_assert(false); + // NOLINTEND(*-simplify) + // ReSharper restore CppIdenticalOperandsInBinaryExpression + std::unreachable(); } constexpr auto elements = map(make_element, iota_array<uint8_t, 16>); +constexpr auto get_value_from_coord(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, coords c) +{ + const auto xs = std::array{ r0.x(), r1.x(), h0.x(), h1.x(), }; + const auto ys = std::array{ r0.y(), r1.y(), h0.y(), h1.y(), }; + const auto x0 = xs[(uint8_t)c.x0]; + const auto x1 = xs[(uint8_t)c.x1]; + const auto y0 = ys[(uint8_t)c.y0]; + const auto y1 = ys[(uint8_t)c.y1]; + return rect{ Vector2i{x0, y0}, Vector2i{x1, y1} }; +} + +[[nodiscard]] +constexpr bool +check_empty(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, Vector2ub input_bb, Vector2ub hole_bb) +{ + bool iempty = Vector2ui{input_bb}.product() == 0; + bool hempty = Vector2ui{hole_bb}.product() == 0; + bool empty_before_x = h1.x() <= r0.x(); + bool empty_after_x = h0.x() >= r1.x(); + bool empty_before_y = h1.y() <= r0.y(); + bool empty_after_y = h0.y() >= r1.y(); + + return iempty | hempty | empty_before_x | empty_after_x | empty_before_y | empty_after_y; +} + constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole) { auto ihalf = Vector2i{input.bbox_size/2}; @@ -125,17 +155,8 @@ constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole) auto h0 = hole.position - hhalf; auto h1 = hole.position + Vector2i{hole.bbox_size} - hhalf; - { - bool iempty = Vector2ui{input.bbox_size}.product() == 0; - bool hempty = Vector2ui{hole.bbox_size}.product() == 0; - bool empty_before_x = h1.x() <= r0.x(); - bool empty_after_x = h0.x() >= r1.x(); - bool empty_before_y = h1.y() <= r0.y(); - bool empty_after_y = h0.y() >= r1.y(); - - if (iempty | hempty | empty_before_x | empty_after_x | empty_before_y | empty_after_y) [[unlikely]] - return { 0, {} }; - } + if (check_empty(r0, r1, h0, h1, input.bbox_size, hole.bbox_size)) + return {0, {}}; const bool sx = h0.x() <= r0.x(); const bool ex = h1.x() >= r1.x(); @@ -150,20 +171,11 @@ constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole) .array = {}, }; - const Int xs[4] = { r0.x(), r1.x(), h0.x(), h1.x(), }; - const Int ys[4] = { r0.y(), r1.y(), h0.y(), h1.y(), }; - - for (auto i = 0uz; i < elt.size; i++) - { - const auto e = elt.array[i]; - - const auto x0 = xs[(uint8_t)e.x0]; - const auto x1 = xs[(uint8_t)e.x1]; - const auto y0 = ys[(uint8_t)e.y0]; - const auto y1 = ys[(uint8_t)e.y1]; + const auto sz = elt.size; + CORRADE_ASSUME(sz <= 8); - res.array[i] = { {x0, y0}, {x1, y1}, }; - } + for (auto i = 0u; i < sz; i++) + res.array[i] = get_value_from_coord(r0, r1, h0, h1, elt.array[i]); return res; } diff --git a/test/hole.cpp b/test/hole.cpp index 6cc39af1..2e2acc32 100644 --- a/test/hole.cpp +++ b/test/hole.cpp @@ -6,40 +6,38 @@ namespace { using bbox = cut_rectangle_result::bbox; -template<Int x, Int y> -void test1() +void test1(Vector2i offset) { - static constexpr auto vec = Vector2i{x, y}; - static constexpr auto rect = bbox{{}, {50, 50}}; + constexpr auto rect = bbox{{}, {50, 50}}; - constexpr auto cutʹ = [](bbox rect, bbox hole) { - auto rectʹ = bbox { rect.position + vec, rect.bbox_size }; - auto holeʹ = bbox { hole.position + vec, hole.bbox_size }; + constexpr auto cutʹ = [](bbox rect, bbox hole, Vector2i offset) { + auto rectʹ = bbox { rect.position + offset, rect.bbox_size }; + auto holeʹ = bbox { hole.position + offset, hole.bbox_size }; return cut_rectangle(rectʹ, holeʹ).size; }; #if 1 - fm_assert_not_equal(0, cutʹ(rect, {{ 49, 0}, {50, 50}})); - fm_assert_not_equal(0, cutʹ(rect, {{ 0, 49}, {50, 50}})); - fm_assert_not_equal(0, cutʹ(rect, {{ 49, 49}, {50, 50}})); + fm_assert_not_equal(0, cutʹ(rect, {{ 49, 0}, {50, 50}}, offset)); + fm_assert_not_equal(0, cutʹ(rect, {{ 0, 49}, {50, 50}}, offset)); + fm_assert_not_equal(0, cutʹ(rect, {{ 49, 49}, {50, 50}}, offset)); #endif #if 1 - fm_assert_not_equal(0, cutʹ(rect, {{-49, 0}, {50, 50}})); - fm_assert_not_equal(0, cutʹ(rect, {{ 0, -49}, {50, 50}})); - fm_assert_not_equal(0, cutʹ(rect, {{ 49, -49}, {50, 50}})); + fm_assert_not_equal(0, cutʹ(rect, {{-49, 0}, {50, 50}}, offset)); + fm_assert_not_equal(0, cutʹ(rect, {{ 0, -49}, {50, 50}}, offset)); + fm_assert_not_equal(0, cutʹ(rect, {{ 49, -49}, {50, 50}}, offset)); #endif #if 1 - fm_assert_equal(0, cutʹ(rect, {{50, 0}, {50, 50}})); - fm_assert_equal(0, cutʹ(rect, {{ 0, 50}, {50, 50}})); - fm_assert_equal(0, cutʹ(rect, {{50, 50}, {50, 50}})); + fm_assert_equal(0, cutʹ(rect, {{50, 0}, {50, 50}}, offset)); + fm_assert_equal(0, cutʹ(rect, {{ 0, 50}, {50, 50}}, offset)); + fm_assert_equal(0, cutʹ(rect, {{50, 50}, {50, 50}}, offset)); #endif #if 1 - fm_assert_equal(1, cutʹ(rect, {{ 9, 9}, {70, 70}})); - fm_assert_equal(1, cutʹ(rect, {{10, 10}, {70, 70}})); + fm_assert_equal(1, cutʹ(rect, {{ 9, 9}, {70, 70}}, offset)); + fm_assert_equal(1, cutʹ(rect, {{10, 10}, {70, 70}}, offset)); #endif #if 1 - fm_assert_equal(1, cutʹ(rect, {{1, 0}, {50, 50}})); - fm_assert_equal(1, cutʹ(rect, {{0, 1}, {50, 50}})); - fm_assert_equal(2, cutʹ(rect, {{1, 1}, {50, 50}})); + fm_assert_equal(1, cutʹ(rect, {{1, 0}, {50, 50}}, offset)); + fm_assert_equal(1, cutʹ(rect, {{0, 1}, {50, 50}}, offset)); + fm_assert_equal(2, cutʹ(rect, {{1, 1}, {50, 50}}, offset)); #endif #if 1 // todo! coverage @@ -50,11 +48,16 @@ void test1() void Test::test_hole() { - test1< 0, 0 >(); - test1< 110, 105 >(); - test1< 15, 110 >(); - test1< - 15, -110 >(); - test1< -110, -15 >(); + constexpr Vector2i offsets[] = { + { 0, 0}, + { 110, 105}, + { 15, 110}, + {- 15, -110}, + {-110, -15}, + }; + + for (auto offset : offsets) + test1(offset); } } // namespace floormat |