diff --git a/include/boost/geometry/algorithms/make.hpp b/include/boost/geometry/algorithms/make.hpp index 899d5489b..b3a3034bf 100644 --- a/include/boost/geometry/algorithms/make.hpp +++ b/include/boost/geometry/algorithms/make.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2020, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, 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. @@ -14,8 +17,12 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP #define BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP +#include + #include +#include + #include namespace boost { namespace geometry @@ -32,12 +39,10 @@ namespace detail { namespace make \tparam Range \tparam_range_point \param range \param_range_point \return The constructed geometry, here: a linestring or a ring - \qbk{distinguish, with a range} \qbk{ [heading Example] [make_with_range] [make_with_range_output] - [heading See also] \* [link geometry.reference.algorithms.assign.assign_points assign] } @@ -75,7 +80,12 @@ inline Geometry make_points(Range const& range) \* [link geometry.reference.algorithms.assign.assign_values_3_2_coordinate_values assign] } */ -template +template +< + typename Geometry, + typename Type, + std::enable_if_t::is_specialized, int> = 0 +> inline Geometry make(Type const& c1, Type const& c2) { concepts::check(); @@ -90,6 +100,23 @@ inline Geometry make(Type const& c1, Type const& c2) return geometry; } + +template +< + typename Geometry, + typename Type, + std::enable_if_t::is_specialized, int> = 0 +> +constexpr inline Geometry make(Type const& c1, Type const& c2) +{ + concepts::check(); + + // NOTE: This is not fully equivalent to the above because assign uses + // numeric_cast which can't be used here since it's not constexpr. + return traits::make::apply(c1, c2); +} + + /*! \brief Construct a geometry \ingroup make @@ -109,7 +136,12 @@ inline Geometry make(Type const& c1, Type const& c2) \* [link geometry.reference.algorithms.assign.assign_values_4_3_coordinate_values assign] } */ -template +template +< + typename Geometry, + typename Type, + std::enable_if_t::is_specialized, int> = 0 +> inline Geometry make(Type const& c1, Type const& c2, Type const& c3) { concepts::check(); @@ -124,6 +156,22 @@ inline Geometry make(Type const& c1, Type const& c2, Type const& c3) return geometry; } +template +< + typename Geometry, + typename Type, + std::enable_if_t::is_specialized, int> = 0 +> +constexpr inline Geometry make(Type const& c1, Type const& c2, Type const& c3) +{ + concepts::check(); + + // NOTE: This is not fully equivalent to the above because assign uses + // numeric_cast which can't be used here since it's not constexpr. + return traits::make::apply(c1, c2, c3); +} + + template inline Geometry make(Type const& c1, Type const& c2, Type const& c3, Type const& c4) { diff --git a/include/boost/geometry/arithmetic/cross_product.hpp b/include/boost/geometry/arithmetic/cross_product.hpp index bcf23b7eb..4859568bf 100644 --- a/include/boost/geometry/arithmetic/cross_product.hpp +++ b/include/boost/geometry/arithmetic/cross_product.hpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -85,9 +86,10 @@ struct cross_product<3> assert_dimension(); assert_dimension(); - return ResultP(get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2), - get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2), - get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2)); + return traits::make::apply( + get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2), + get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2), + get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2)); } }; @@ -111,13 +113,7 @@ template std::enable_if_t < dimension::value != 3 - || ! std::is_constructible - < - ResultP, - typename coordinate_type::type const&, - typename coordinate_type::type const&, - typename coordinate_type::type const& - >::value, + || ! traits::make::is_specialized, int > = 0 > @@ -138,13 +134,7 @@ template std::enable_if_t < dimension::value == 3 - && std::is_constructible - < - ResultP, - typename coordinate_type::type const&, - typename coordinate_type::type const&, - typename coordinate_type::type const& - >::value, + && traits::make::is_specialized, int > = 0 > @@ -174,13 +164,7 @@ template std::enable_if_t < dimension

::value != 3 - || ! std::is_constructible - < - P, - typename coordinate_type

::type const&, - typename coordinate_type

::type const&, - typename coordinate_type

::type const& - >::value, + || ! traits::make

::is_specialized, int > = 0 > @@ -201,13 +185,7 @@ template std::enable_if_t < dimension

::value == 3 - && std::is_constructible - < - P, - typename coordinate_type

::type const&, - typename coordinate_type

::type const&, - typename coordinate_type

::type const& - >::value, + && traits::make

::is_specialized, int > = 0 > diff --git a/include/boost/geometry/core/coordinate_dimension.hpp b/include/boost/geometry/core/coordinate_dimension.hpp index 12146f97e..8d9638e4c 100644 --- a/include/boost/geometry/core/coordinate_dimension.hpp +++ b/include/boost/geometry/core/coordinate_dimension.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2020, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, 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. diff --git a/include/boost/geometry/core/make.hpp b/include/boost/geometry/core/make.hpp new file mode 100644 index 000000000..b1f2b5e69 --- /dev/null +++ b/include/boost/geometry/core/make.hpp @@ -0,0 +1,46 @@ +// Boost.Geometry + +// Copyright (c) 2020, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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) + +#ifndef BOOST_GEOMETRY_CORE_MAKE_HPP +#define BOOST_GEOMETRY_CORE_MAKE_HPP + +namespace boost { namespace geometry +{ + +namespace traits +{ + +/*! +\brief Traits class to create an object of Geometry type. +\details This trait is optional and allows to define efficient way of creating Geometries. +\ingroup traits +\par Geometries: + - points + - boxes + - segments +\par Specializations should provide: + - static const bool is_specialized = true; + - static member function apply() taking: + - N coordinates (points) + - 2 points, min and max (boxes) + - 2 points, first and second (segments) +\tparam Geometry geometry +*/ +template +struct make +{ + static const bool is_specialized = false; +}; + +} // namespace traits + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_CORE_MAKE_HPP diff --git a/include/boost/geometry/geometries/box.hpp b/include/boost/geometry/geometries/box.hpp index 9213f3318..d773129af 100644 --- a/include/boost/geometry/geometries/box.hpp +++ b/include/boost/geometry/geometries/box.hpp @@ -24,6 +24,13 @@ #include #include + +#include +#include +#include +#include +#include + #include #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) @@ -84,18 +91,14 @@ public: */ template < - typename P1 = Point, - typename P2 = Point, + typename P = Point, std::enable_if_t < - ! std::is_copy_constructible::value - || ! std::is_copy_constructible::value - || ! std::is_convertible::value - || ! std::is_convertible::value, + ! std::is_copy_constructible

::value, int > = 0 > - box(P1 const& min_corner, P2 const& max_corner) + box(Point const& min_corner, Point const& max_corner) { geometry::convert(min_corner, m_min_corner); geometry::convert(max_corner, m_max_corner); @@ -110,21 +113,17 @@ public: */ template < - typename P1 = Point, - typename P2 = Point, + typename P = Point, std::enable_if_t < - std::is_copy_constructible::value - && std::is_copy_constructible::value - && std::is_convertible::value - && std::is_convertible::value, + std::is_copy_constructible

::value, int > = 0 > #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) constexpr #endif - box(P1 const& min_corner, P2 const& max_corner) + box(Point const& min_corner, Point const& max_corner) : m_min_corner(min_corner) , m_max_corner(max_corner) { @@ -234,6 +233,20 @@ struct indexed_access, max_corner, Dimension> } }; +template +struct make > +{ + typedef model::box box_type; + + static const bool is_specialized = true; + + static constexpr box_type apply(Point const& min_corner, Point const& max_corner) + { + return box_type(min_corner, max_corner); + } +}; + + } // namespace traits #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS diff --git a/include/boost/geometry/geometries/concepts/check.hpp b/include/boost/geometry/geometries/concepts/check.hpp index 8888481d8..f7616a27d 100644 --- a/include/boost/geometry/geometries/concepts/check.hpp +++ b/include/boost/geometry/geometries/concepts/check.hpp @@ -4,6 +4,9 @@ // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2020, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, 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. @@ -214,7 +217,7 @@ struct checker const> \ingroup concepts */ template -inline void check() +constexpr inline void check() { detail::checker c; boost::ignore_unused(c); @@ -227,7 +230,7 @@ inline void check() \ingroup concepts */ template -inline void check_concepts_and_equal_dimensions() +constexpr inline void check_concepts_and_equal_dimensions() { check(); check(); diff --git a/include/boost/geometry/geometries/geometries.hpp b/include/boost/geometry/geometries/geometries.hpp index de9e2b1fd..a116b20cb 100644 --- a/include/boost/geometry/geometries/geometries.hpp +++ b/include/boost/geometry/geometries/geometries.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2020. +// Modifications copyright (c) 2020, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, 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. @@ -14,15 +18,15 @@ #ifndef BOOST_GEOMETRY_GEOMETRIES_HPP #define BOOST_GEOMETRY_GEOMETRIES_HPP -#include -#include -#include - -#include -#include -#include - #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include diff --git a/include/boost/geometry/geometries/point.hpp b/include/boost/geometry/geometries/point.hpp index 2153c1b33..244ee6e4b 100644 --- a/include/boost/geometry/geometries/point.hpp +++ b/include/boost/geometry/geometries/point.hpp @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) #include @@ -47,6 +50,23 @@ namespace boost { namespace geometry #pragma warning(disable : 4127) #endif +namespace detail +{ + +template +struct is_coordinates_number_leq +{ + static const bool value = (N <= DimensionCount); +}; + +template +struct is_coordinates_number_eq +{ + static const bool value = (N == DimensionCount); +}; + +} // namespace detail + namespace model { @@ -109,6 +129,11 @@ public: #endif /// @brief Constructor to set one value + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) constexpr #endif @@ -117,11 +142,16 @@ public: { #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) m_created = 1; - std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1); + std::fill_n(m_values_initialized, DimensionCount, 1); #endif } /// @brief Constructor to set two values + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) constexpr #endif @@ -130,21 +160,25 @@ public: { #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) m_created = 1; - std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1); + std::fill_n(m_values_initialized, DimensionCount, 1); #endif } /// @brief Constructor to set three values + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > #if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) constexpr #endif - point(CoordinateType const& v0, CoordinateType const& v1, - CoordinateType const& v2) + point(CoordinateType const& v0, CoordinateType const& v1, CoordinateType const& v2) : m_values{ v0, v1, v2 } { #if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING) m_created = 1; - std::fill_n(m_values_initialized, (std::min)(std::size_t(3), DimensionCount), 1); + std::fill_n(m_values_initialized, DimensionCount, 1); #endif } @@ -262,6 +296,53 @@ struct access, Di } }; +template +< + typename CoordinateType, + std::size_t DimensionCount, + typename CoordinateSystem +> +struct make > +{ + typedef model::point point_type; + + static const bool is_specialized = true; + + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > + static constexpr point_type apply(CoordinateType const& v0) + { + return point_type(v0); + } + + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > + static constexpr point_type apply(CoordinateType const& v0, + CoordinateType const& v1) + { + return point_type(v0, v1); + } + + template + < + typename C = CoordinateType, + std::enable_if_t::value, int> = 0 + > + static constexpr point_type apply(CoordinateType const& v0, + CoordinateType const& v1, + CoordinateType const& v2) + { + return point_type(v0, v1, v2); + } +}; + + } // namespace traits #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS diff --git a/include/boost/geometry/geometries/point_xy.hpp b/include/boost/geometry/geometries/point_xy.hpp index 9041ecbbe..8a6c60a8c 100644 --- a/include/boost/geometry/geometries/point_xy.hpp +++ b/include/boost/geometry/geometries/point_xy.hpp @@ -121,6 +121,21 @@ struct access, Dimension > } }; +template +struct make > +{ + typedef model::d2::point_xy point_type; + + static const bool is_specialized = true; + + static constexpr point_type apply(CoordinateType const& x, + CoordinateType const& y) + { + return point_type(x, y); + } +}; + + } // namespace traits #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS diff --git a/include/boost/geometry/geometries/point_xyz.hpp b/include/boost/geometry/geometries/point_xyz.hpp index 861141cca..7d2b44749 100644 --- a/include/boost/geometry/geometries/point_xyz.hpp +++ b/include/boost/geometry/geometries/point_xyz.hpp @@ -124,6 +124,22 @@ struct access, Dimension> } }; +template +struct make > +{ + typedef model::d3::point_xyz point_type; + + static const bool is_specialized = true; + + static constexpr point_type apply(CoordinateType const& x, + CoordinateType const& y, + CoordinateType const& z) + { + return point_type(x, y, z); + } +}; + + } // namespace traits #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS diff --git a/include/boost/geometry/geometries/segment.hpp b/include/boost/geometry/geometries/segment.hpp index 53bddd2c9..b27937279 100644 --- a/include/boost/geometry/geometries/segment.hpp +++ b/include/boost/geometry/geometries/segment.hpp @@ -25,6 +25,12 @@ #include #include +#include +#include +#include +#include +#include + #include namespace boost { namespace geometry @@ -164,6 +170,21 @@ struct indexed_access, 1, Dimension> }; +template +struct make > +{ + typedef model::segment segment_type; + + static const bool is_specialized = true; + + static constexpr segment_type apply(Point const& p1, Point const& p2) + { + return segment_type(p1, p2); + } +}; + + + template struct tag > {