1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
6 // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
7 
8 // This file was modified by Oracle on 2015-2021.
9 // Modifications copyright (c) 2015-2021, Oracle and/or its affiliates.
10 
11 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
13 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
14 
15 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
16 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
17 
18 // Distributed under the Boost Software License, Version 1.0.
19 // (See accompanying file LICENSE_1_0.txt or copy at
20 // http://www.boost.org/LICENSE_1_0.txt)
21 
22 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
23 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
24 
25 
26 #include <boost/geometry/algorithms/dispatch/expand.hpp>
27 
28 #include <boost/geometry/core/coordinate_system.hpp>
29 #include <boost/geometry/core/tag.hpp>
30 #include <boost/geometry/core/tags.hpp>
31 #include <boost/geometry/core/visit.hpp>
32 
33 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
34 #include <boost/geometry/geometries/concepts/check.hpp>
35 
36 #include <boost/geometry/strategies/default_strategy.hpp>
37 #include <boost/geometry/strategies/detail.hpp>
38 #include <boost/geometry/strategies/expand/services.hpp>
39 
40 #include <boost/geometry/util/type_traits_std.hpp>
41 
42 
43 namespace boost { namespace geometry
44 {
45 
46 namespace resolve_strategy
47 {
48 
49 template
50 <
51     typename Strategy,
52     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
53 >
54 struct expand
55 {
56     template <typename Box, typename Geometry>
applyboost::geometry::resolve_strategy::expand57     static inline void apply(Box& box,
58                              Geometry const& geometry,
59                              Strategy const& strategy)
60     {
61         dispatch::expand<Box, Geometry>::apply(box, geometry, strategy);
62     }
63 };
64 
65 template <typename Strategy>
66 struct expand<Strategy, false>
67 {
68     template <typename Box, typename Geometry>
applyboost::geometry::resolve_strategy::expand69     static inline void apply(Box& box,
70                              Geometry const& geometry,
71                              Strategy const& strategy)
72     {
73         using strategies::expand::services::strategy_converter;
74         dispatch::expand
75             <
76                 Box, Geometry
77             >::apply(box, geometry, strategy_converter<Strategy>::get(strategy));
78     }
79 };
80 
81 template <>
82 struct expand<default_strategy, false>
83 {
84     template <typename Box, typename Geometry>
applyboost::geometry::resolve_strategy::expand85     static inline void apply(Box& box,
86                              Geometry const& geometry,
87                              default_strategy)
88     {
89         typedef typename strategies::expand::services::default_strategy
90             <
91                 Box, Geometry
92             >::type strategy_type;
93 
94         dispatch::expand<Box, Geometry>::apply(box, geometry, strategy_type());
95     }
96 };
97 
98 } //namespace resolve_strategy
99 
100 
101 namespace resolve_dynamic
102 {
103 
104 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
105 struct expand
106 {
107     template <typename Box, typename Strategy>
applyboost::geometry::resolve_dynamic::expand108     static inline void apply(Box& box,
109                              Geometry const& geometry,
110                              Strategy const& strategy)
111     {
112         concepts::check<Box>();
113         concepts::check<Geometry const>();
114         concepts::check_concepts_and_equal_dimensions<Box, Geometry const>();
115 
116         resolve_strategy::expand<Strategy>::apply(box, geometry, strategy);
117     }
118 };
119 
120 template <typename Geometry>
121 struct expand<Geometry, dynamic_geometry_tag>
122 {
123     template <class Box, typename Strategy>
applyboost::geometry::resolve_dynamic::expand124     static inline void apply(Box& box,
125                              Geometry const& geometry,
126                              Strategy const& strategy)
127     {
128         traits::visit<Geometry>::apply([&](auto const& g)
129         {
130             expand<util::remove_cref_t<decltype(g)>>::apply(box, g, strategy);
131         }, geometry);
132     }
133 };
134 
135 } // namespace resolve_dynamic
136 
137 
138 /*!
139 \brief Expands (with strategy)
140 \ingroup expand
141 \tparam Box type of the box
142 \tparam Geometry \tparam_geometry
143 \tparam Strategy \tparam_strategy{expand}
144 \param box box to be expanded using another geometry, mutable
145 \param geometry \param_geometry geometry which envelope (bounding box)
146 \param strategy \param_strategy{expand}
147 will be added to the box
148 
149 \qbk{distinguish,with strategy}
150 \qbk{[include reference/algorithms/expand.qbk]}
151  */
152 template <typename Box, typename Geometry, typename Strategy>
expand(Box & box,Geometry const & geometry,Strategy const & strategy)153 inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy)
154 {
155     resolve_dynamic::expand<Geometry>::apply(box, geometry, strategy);
156 }
157 
158 /*!
159 \brief Expands a box using the bounding box (envelope) of another geometry
160 (box, point)
161 \ingroup expand
162 \tparam Box type of the box
163 \tparam Geometry \tparam_geometry
164 \param box box to be expanded using another geometry, mutable
165 \param geometry \param_geometry geometry which envelope (bounding box) will be
166 added to the box
167 
168 \qbk{[include reference/algorithms/expand.qbk]}
169  */
170 template <typename Box, typename Geometry>
expand(Box & box,Geometry const & geometry)171 inline void expand(Box& box, Geometry const& geometry)
172 {
173     resolve_dynamic::expand<Geometry>::apply(box, geometry, default_strategy());
174 }
175 
176 }} // namespace boost::geometry
177 
178 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
179