// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2007-2024 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // This file was modified by Oracle on 2025. // Modifications copyright (c) 2025 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include #include #include void test_coordinate_cast(std::string const& s, int expected_nom, int expected_denom) { boost::rational const a = bg::detail::coordinate_cast >::apply(s); BOOST_CHECK_EQUAL(a.numerator(), expected_nom); BOOST_CHECK_EQUAL(a.denominator(), expected_denom); } void test_numeric_cast() { boost::rational const r1(3, 4); BOOST_CHECK_CLOSE(bg::util::numeric_cast(r1), 0.75, 0.00001); boost::rational const r2(10, 4); BOOST_CHECK_CLOSE(bg::util::numeric_cast(r2), 2.5, 0.00001); BOOST_CHECK_EQUAL(bg::util::numeric_cast(r2), 2); } template void test_bounds() { using coordinate_t = boost::rational; auto const lowest = bg::util::bounds::lowest(); auto const highest = bg::util::bounds::highest(); BOOST_CHECK_MESSAGE(lowest < highest, "Lowest should be smaller than highest, lowest: " << lowest << " highest: " << highest); } // Tests box-related functionality, which depends on geometry::util::bounds // specialization for Boost.Rational template void test_box() { using coordinate_t = boost::rational; using point_t = bg::model::point; using box_t = bg::model::box; box_t box; bg::assign_inverse(box); point_t south_west, north_east; bg::detail::assign_point_from_index<0>(box, south_west); bg::detail::assign_point_from_index<1>(box, north_east); BOOST_CHECK_MESSAGE(bg::get<0>(south_west) > bg::get<0>(north_east), "Bounding box should be inversed. Now x-min: " << bg::get<0>(south_west) << " x-max: " << bg::get<0>(north_east) << " " << bg::wkt(box)); BOOST_CHECK_MESSAGE(bg::get<1>(south_west) > bg::get<1>(north_east), "Bounding box should be inversed. Now y-min: " << bg::get<1>(south_west) << " y-max: " << bg::get<1>(north_east) << " " << bg::wkt(box)); // Test specifically for points larger than 0, because without specialization Boost.Rational // will return (0,1) (== 0) by default and code will compile but give wrong results. bg::expand(box, bg::make(4, 4)); bg::expand(box, bg::make(8, 8)); // Test within (without specialization, both points are within the box) auto const point1 = bg::make(6, 6); auto const point2 = bg::make(2, 2); BOOST_CHECK_MESSAGE(bg::within(point1, box), "Point " << bg::wkt(point1) << " is not within the box " << bg::wkt(box)); BOOST_CHECK_MESSAGE(! bg::within(point2, box), "Point " << bg::wkt(point2) << " is within the box " << bg::wkt(box)); // Test area (without specialization, it will be 64) auto const area = bg::util::numeric_cast(bg::area(box)); T const expected_area = 16; BOOST_CHECK_EQUAL(expected_area, area); } void test_select_most_precise() { using rational1_t = boost::rational; using rational2_t = boost::rational; using t1 = bg::select_most_precise::type; using t2 = bg::select_most_precise::type; using t12 = bg::select_most_precise::type; BOOST_CHECK((std::is_same::value)); BOOST_CHECK((std::is_same::value)); BOOST_CHECK((std::is_same::value)); } void test_wkt(std::string const& wkt, std::string const expected_wkt) { bg::model::point, 2, bg::cs::cartesian> p; bg::read_wkt(wkt, p); std::ostringstream out; out << bg::wkt(p); BOOST_CHECK_EQUAL(out.str(), expected_wkt); } int test_main(int, char* []) { test_coordinate_cast("0", 0, 1); test_coordinate_cast("1", 1, 1); test_coordinate_cast("-1", -1, 1); test_coordinate_cast("-0.5", -1, 2); test_coordinate_cast("-1.5", -3, 2); test_coordinate_cast("0.5", 1, 2); test_coordinate_cast("1.5", 3, 2); test_coordinate_cast("2.12345", 42469, 20000); test_coordinate_cast("1.", 1, 1); test_coordinate_cast("3/2", 3, 2); test_coordinate_cast("-3/2", -3, 2); test_numeric_cast(); test_bounds(); test_bounds(); test_bounds(); test_box(); test_select_most_precise(); test_wkt("POINT(1.5 2.75)", "POINT(3/2 11/4)"); test_wkt("POINT(3/2 11/4)", "POINT(3/2 11/4)"); test_wkt("POINT(-1.5 2.75)", "POINT(-3/2 11/4)"); test_wkt("POINT(-3/2 11/4)", "POINT(-3/2 11/4)"); return 0; }