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-2020.
9 // Modifications copyright (c) 2015-2020, 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 #include <boost/variant/apply_visitor.hpp>
26 #include <boost/variant/static_visitor.hpp>
27 #include <boost/variant/variant_fwd.hpp>
28 
29 #include <boost/geometry/core/coordinate_system.hpp>
30 #include <boost/geometry/core/tag.hpp>
31 #include <boost/geometry/core/tags.hpp>
32 
33 #include <boost/geometry/geometries/concepts/check.hpp>
34 
35 #include <boost/geometry/algorithms/dispatch/expand.hpp>
36 
37 #include <boost/geometry/strategies/default_strategy.hpp>
38 #include <boost/geometry/strategies/detail.hpp>
39 #include <boost/geometry/strategies/expand/services.hpp>
40 #include <boost/geometry/strategy/expand.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_variant
102 {
103 
104 template <typename Geometry>
105 struct expand
106 {
107     template <typename Box, typename Strategy>
applyboost::geometry::resolve_variant::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 <BOOST_VARIANT_ENUM_PARAMS(typename T)>
121 struct expand<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
122 {
123     template <typename Box, typename Strategy>
124     struct visitor: boost::static_visitor<void>
125     {
126         Box& m_box;
127         Strategy const& m_strategy;
128 
visitorboost::geometry::resolve_variant::expand::visitor129         visitor(Box& box, Strategy const& strategy)
130             : m_box(box)
131             , m_strategy(strategy)
132         {}
133 
134         template <typename Geometry>
operator ()boost::geometry::resolve_variant::expand::visitor135         void operator()(Geometry const& geometry) const
136         {
137             return expand<Geometry>::apply(m_box, geometry, m_strategy);
138         }
139     };
140 
141     template <class Box, typename Strategy>
142     static inline void
applyboost::geometry::resolve_variant::expand143     apply(Box& box,
144           boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
145           Strategy const& strategy)
146     {
147         return boost::apply_visitor(visitor<Box, Strategy>(box, strategy),
148                                     geometry);
149     }
150 };
151 
152 } // namespace resolve_variant
153 
154 
155 /***
156 *!
157 \brief Expands a box using the extend (envelope) of another geometry (box, point)
158 \ingroup expand
159 \tparam Box type of the box
160 \tparam Geometry of second geometry, to be expanded with the box
161 \param box box to expand another geometry with, might be changed
162 \param geometry other geometry
163 \param strategy_less
164 \param strategy_greater
165 \note Strategy is currently ignored
166  *
167 template
168 <
169     typename Box, typename Geometry,
170     typename StrategyLess, typename StrategyGreater
171 >
172 inline void expand(Box& box, Geometry const& geometry,
173             StrategyLess const& strategy_less,
174             StrategyGreater const& strategy_greater)
175 {
176     concepts::check_concepts_and_equal_dimensions<Box, Geometry const>();
177 
178     dispatch::expand<Box, Geometry>::apply(box, geometry);
179 }
180 ***/
181 
182 /*!
183 \brief Expands (with strategy)
184 \ingroup expand
185 \tparam Box type of the box
186 \tparam Geometry \tparam_geometry
187 \tparam Strategy \tparam_strategy{expand}
188 \param box box to be expanded using another geometry, mutable
189 \param geometry \param_geometry geometry which envelope (bounding box)
190 \param strategy \param_strategy{expand}
191 will be added to the box
192 
193 \qbk{distinguish,with strategy}
194 \qbk{[include reference/algorithms/expand.qbk]}
195  */
196 template <typename Box, typename Geometry, typename Strategy>
expand(Box & box,Geometry const & geometry,Strategy const & strategy)197 inline void expand(Box& box, Geometry const& geometry, Strategy const& strategy)
198 {
199     resolve_variant::expand<Geometry>::apply(box, geometry, strategy);
200 }
201 
202 /*!
203 \brief Expands a box using the bounding box (envelope) of another geometry
204 (box, point)
205 \ingroup expand
206 \tparam Box type of the box
207 \tparam Geometry \tparam_geometry
208 \param box box to be expanded using another geometry, mutable
209 \param geometry \param_geometry geometry which envelope (bounding box) will be
210 added to the box
211 
212 \qbk{[include reference/algorithms/expand.qbk]}
213  */
214 template <typename Box, typename Geometry>
expand(Box & box,Geometry const & geometry)215 inline void expand(Box& box, Geometry const& geometry)
216 {
217     resolve_variant::expand<Geometry>::apply(box, geometry, default_strategy());
218 }
219 
220 }} // namespace boost::geometry
221 
222 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
223