Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:50

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2014-2021, Oracle and/or its affiliates.
0004 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0005 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
0011 #define BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP
0012 
0013 
0014 #include <boost/geometry/algorithms/detail/select_geometry_type.hpp>
0015 #include <boost/geometry/core/point_type.hpp>
0016 #include <boost/geometry/core/reverse_dispatch.hpp>
0017 #include <boost/geometry/strategies/default_strategy.hpp>
0018 #include <boost/geometry/strategies/detail.hpp>
0019 #include <boost/geometry/strategies/distance.hpp>
0020 #include <boost/geometry/strategies/distance/services.hpp>
0021 #include <boost/geometry/util/select_most_precise.hpp>
0022 #include <boost/geometry/util/sequence.hpp>
0023 #include <boost/geometry/util/type_traits.hpp>
0024 
0025 
0026 namespace boost { namespace geometry
0027 {
0028 
0029 namespace resolve_strategy
0030 {
0031 
0032 
0033 // TODO: This utility could be entirely implemented as:
0034 //       decltype(geometry::comparable_distance(std::declval<Geometry1>(), std::declval<Geometry2>(), std::declval<Strategy>()))
0035 //       however then the algorithm would have to be compiled.
0036 
0037 
0038 template
0039 <
0040     typename Geometry1, typename Geometry2, typename Strategy,
0041     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0042 >
0043 struct comparable_distance_strategy2_type
0044 {
0045     typedef decltype(std::declval<Strategy>().distance(
0046         std::declval<Geometry1>(), std::declval<Geometry2>())) type;
0047 };
0048 
0049 template <typename Geometry1, typename Geometry2, typename Strategy>
0050 struct comparable_distance_strategy2_type<Geometry1, Geometry2, Strategy, false>
0051 {
0052     typedef Strategy type;
0053 };
0054 
0055 template
0056 <
0057     typename Geometry1, typename Geometry2, typename Strategy,
0058     bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
0059 >
0060 struct comparable_distance_strategy_type
0061     : strategy::distance::services::comparable_type
0062         <
0063             typename comparable_distance_strategy2_type
0064                 <
0065                     Geometry1, Geometry2, Strategy
0066                 >::type
0067         >
0068 {};
0069 
0070 template <typename Geometry1, typename Geometry2, typename Strategy>
0071 struct comparable_distance_strategy_type<Geometry1, Geometry2, Strategy, true>
0072     : comparable_distance_strategy_type<Geometry2, Geometry1, Strategy, false>
0073 {};
0074 
0075 
0076 template <typename Geometry1, typename Geometry2, typename Strategy>
0077 struct comparable_distance_result
0078     : strategy::distance::services::return_type
0079         <
0080             typename comparable_distance_strategy_type<Geometry1, Geometry2, Strategy>::type,
0081             typename point_type<Geometry1>::type,
0082             typename point_type<Geometry2>::type
0083         >
0084 {};
0085 
0086 template <typename Geometry1, typename Geometry2>
0087 struct comparable_distance_result<Geometry1, Geometry2, default_strategy>
0088     : comparable_distance_result
0089         <
0090             Geometry1,
0091             Geometry2,
0092             typename strategies::distance::services::default_strategy
0093                 <
0094                     Geometry1, Geometry2
0095                 >::type
0096         >
0097 {};
0098 
0099 
0100 } // namespace resolve_strategy
0101 
0102 
0103 #ifndef DOXYGEN_NO_DETAIL
0104 namespace detail { namespace distance
0105 {
0106 
0107 template <typename Strategy = geometry::default_strategy>
0108 struct more_precise_comparable_distance_result
0109 {
0110     template <typename Curr, typename Next>
0111     struct predicate
0112         : std::is_same
0113             <
0114                 typename resolve_strategy::comparable_distance_result
0115                     <
0116                         typename util::sequence_element<0, Curr>::type,
0117                         typename util::sequence_element<1, Curr>::type,
0118                         Strategy
0119                     >::type,
0120                 typename geometry::select_most_precise
0121                     <
0122                         typename resolve_strategy::comparable_distance_result
0123                             <
0124                                 typename util::sequence_element<0, Curr>::type,
0125                                 typename util::sequence_element<1, Curr>::type,
0126                                 Strategy
0127                             >::type,
0128                         typename resolve_strategy::comparable_distance_result
0129                             <
0130                                 typename util::sequence_element<0, Next>::type,
0131                                 typename util::sequence_element<1, Next>::type,
0132                                 Strategy
0133                             >::type
0134                     >::type
0135             >
0136     {};
0137 };
0138 
0139 }} // namespace detail::distance
0140 #endif //DOXYGEN_NO_DETAIL
0141 
0142 
0143 namespace resolve_dynamic
0144 {
0145 
0146 template
0147 <
0148     typename Geometry1, typename Geometry2, typename Strategy,
0149     bool IsDynamicOrCollection = util::is_dynamic_geometry<Geometry1>::value
0150                               || util::is_dynamic_geometry<Geometry2>::value
0151                               || util::is_geometry_collection<Geometry1>::value
0152                               || util::is_geometry_collection<Geometry2>::value
0153 >
0154 struct comparable_distance_result
0155     : resolve_strategy::comparable_distance_result
0156         <
0157             Geometry1,
0158             Geometry2,
0159             Strategy
0160         >
0161 {};
0162 
0163 template <typename Geometry1, typename Geometry2, typename Strategy>
0164 struct comparable_distance_result<Geometry1, Geometry2, Strategy, true>
0165 {
0166     // Select the most precise distance strategy result type
0167     //   for all variant type combinations.
0168     // TODO: We should ignore the combinations that are not valid
0169     //   but is_implemented is not ready for prime time.
0170     using selected_types = typename detail::select_geometry_types
0171         <
0172             Geometry1, Geometry2,
0173             detail::distance::more_precise_comparable_distance_result<Strategy>::template predicate
0174         >::type;
0175 
0176     using type = typename resolve_strategy::comparable_distance_result
0177         <
0178             typename util::sequence_element<0, selected_types>::type,
0179             typename util::sequence_element<1, selected_types>::type,
0180             Strategy
0181         >::type;
0182 };
0183 
0184 
0185 } // namespace resolve_dynamic
0186 
0187 
0188 /*!
0189 \brief Meta-function defining return type of comparable_distance function
0190 \ingroup distance
0191 */
0192 template
0193 <
0194     typename Geometry1,
0195     typename Geometry2 = Geometry1,
0196     typename Strategy = void
0197 >
0198 struct comparable_distance_result
0199     : resolve_dynamic::comparable_distance_result
0200         <
0201             Geometry1, Geometry2, Strategy
0202         >
0203 {};
0204 
0205 template <typename Geometry1, typename Geometry2>
0206 struct comparable_distance_result<Geometry1, Geometry2, void>
0207     : comparable_distance_result<Geometry1, Geometry2, default_strategy>
0208 {};
0209 
0210 
0211 }} // namespace boost::geometry
0212 
0213 
0214 #endif // BOOST_GEOMETRY_STRATEGIES_COMPARABLE_DISTANCE_RESULT_HPP