• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry Index
2 //
3 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
4 //
5 // This file was modified by Oracle on 2019, 2020.
6 // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 //
9 // Use, modification and distribution is subject to the Boost Software License,
10 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 
13 #ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP
14 #define BOOST_GEOMETRY_UTIL_TUPLES_HPP
15 
16 #include <boost/geometry/core/config.hpp>
17 
18 #include <boost/mpl/if.hpp>
19 #include <boost/mpl/not.hpp>
20 #include <boost/tuple/tuple.hpp>
21 #include <boost/type_traits/integral_constant.hpp>
22 #include <boost/type_traits/is_same.hpp>
23 
24 #include <utility>
25 
26 #ifdef BOOST_GEOMETRY_CXX11_TUPLE
27 
28 #include <tuple>
29 
30 #endif // BOOST_GEOMETRY_CXX11_TUPLE
31 
32 namespace boost { namespace geometry { namespace tuples {
33 
34 
35 using boost::tuples::null_type;
36 
37 
38 template <int I, typename Tuple>
39 struct element
40     : boost::tuples::element<I, Tuple>
41 {};
42 
43 template <typename Tuple>
44 struct size
45     : boost::tuples::length<Tuple>
46 {};
47 
48 template <int I, typename HT, typename TT>
49 inline typename boost::tuples::access_traits
50     <
51         typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
52     >::non_const_type
get(boost::tuples::cons<HT,TT> & tup)53 get(boost::tuples::cons<HT, TT> & tup)
54 {
55     return boost::tuples::get<I>(tup);
56 }
57 
58 template <int I, typename HT, typename TT>
59 inline typename boost::tuples::access_traits
60     <
61         typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
62     >::const_type
get(boost::tuples::cons<HT,TT> const & tup)63 get(boost::tuples::cons<HT, TT> const& tup)
64 {
65     return boost::tuples::get<I>(tup);
66 }
67 
68 
69 template <int I, typename F, typename S>
70 struct element<I, std::pair<F, S> >
71 {};
72 
73 template <typename F, typename S>
74 struct element<0, std::pair<F, S> >
75 {
76     typedef F type;
77 };
78 
79 template <typename F, typename S>
80 struct element<1, std::pair<F, S> >
81 {
82     typedef S type;
83 };
84 
85 template <typename F, typename S>
86 struct size<std::pair<F, S> >
87     : boost::integral_constant<int, 2>
88 {};
89 
90 template <int I, typename Pair>
91 struct get_pair;
92 
93 template <typename F, typename S>
94 struct get_pair<0, std::pair<F, S> >
95 {
96     typedef F type;
97 
applyboost::geometry::tuples::get_pair98     static inline F& apply(std::pair<F, S> & p)
99     {
100         return p.first;
101     }
102 
applyboost::geometry::tuples::get_pair103     static inline F const& apply(std::pair<F, S> const& p)
104     {
105         return p.first;
106     }
107 };
108 
109 template <typename F, typename S>
110 struct get_pair<1, std::pair<F, S> >
111 {
112     typedef S type;
113 
applyboost::geometry::tuples::get_pair114     static inline S& apply(std::pair<F, S> & p)
115     {
116         return p.second;
117     }
118 
applyboost::geometry::tuples::get_pair119     static inline S const& apply(std::pair<F, S> const& p)
120     {
121         return p.second;
122     }
123 };
124 
125 template <int I, typename F, typename S>
126 inline typename get_pair<I, std::pair<F, S> >::type&
get(std::pair<F,S> & p)127 get(std::pair<F, S> & p)
128 {
129     return get_pair<I, std::pair<F, S> >::apply(p);
130 }
131 
132 template <int I, typename F, typename S>
133 inline typename get_pair<I, std::pair<F, S> >::type const&
get(std::pair<F,S> const & p)134 get(std::pair<F, S> const& p)
135 {
136     return get_pair<I, std::pair<F, S> >::apply(p);
137 }
138 
139 #ifdef BOOST_GEOMETRY_CXX11_TUPLE
140 
141 template <int I, typename ...Ts>
142 struct element<I, std::tuple<Ts...> >
143     : std::tuple_element<I, std::tuple<Ts...> >
144 {};
145 
146 template <typename ...Ts>
147 struct size<std::tuple<Ts...> >
148     : std::tuple_size<std::tuple<Ts...> >
149 {};
150 
151 template <int I, typename ...Ts>
152 inline typename std::tuple_element<I, std::tuple<Ts...> >::type&
get(std::tuple<Ts...> & tup)153 get(std::tuple<Ts...> & tup)
154 {
155     return std::get<I>(tup);
156 }
157 
158 template <int I, typename ...Ts>
159 inline typename std::tuple_element<I, std::tuple<Ts...> >::type const&
get(std::tuple<Ts...> const & tup)160 get(std::tuple<Ts...> const& tup)
161 {
162     return std::get<I>(tup);
163 }
164 
165 #endif // BOOST_GEOMETRY_CXX11_TUPLE
166 
167 
168 // find_index_if
169 // Searches for the index of an element for which UnaryPredicate returns true
170 // If such element is not found the result is N
171 
172 template
173 <
174     typename Tuple,
175     template <typename> class UnaryPred,
176     int I = 0,
177     int N = size<Tuple>::value
178 >
179 struct find_index_if
180     : boost::mpl::if_c
181         <
182             UnaryPred<typename element<I, Tuple>::type>::value,
183             boost::integral_constant<int, I>,
184             typename find_index_if<Tuple, UnaryPred, I+1, N>::type
185         >::type
186 {};
187 
188 template
189 <
190     typename Tuple,
191     template <typename> class UnaryPred,
192     int N
193 >
194 struct find_index_if<Tuple, UnaryPred, N, N>
195     : boost::integral_constant<int, N>
196 {};
197 
198 
199 // find_if
200 // Searches for an element for which UnaryPredicate returns true
201 // If such element is not found the result is boost::tuples::null_type
202 
203 template
204 <
205     typename Tuple,
206     template <typename> class UnaryPred,
207     int I = 0,
208     int N = size<Tuple>::value
209 >
210 struct find_if
211     : boost::mpl::if_c
212         <
213             UnaryPred<typename element<I, Tuple>::type>::value,
214             element<I, Tuple>,
215             find_if<Tuple, UnaryPred, I+1, N>
216         >::type
217 {};
218 
219 template
220 <
221     typename Tuple,
222     template <typename> class UnaryPred,
223     int N
224 >
225 struct find_if<Tuple, UnaryPred, N, N>
226 {
227     typedef boost::tuples::null_type type;
228 };
229 
230 
231 // is_found
232 // Returns true if a type T (the result of find_if) was found.
233 
234 template <typename T>
235 struct is_found
236     : boost::mpl::not_<boost::is_same<T, boost::tuples::null_type> >
237 {};
238 
239 
240 // is_not_found
241 // Returns true if a type T (the result of find_if) was not found.
242 
243 template <typename T>
244 struct is_not_found
245     : boost::is_same<T, boost::tuples::null_type>
246 {};
247 
248 
249 // exists_if
250 // Returns true if search for element meeting UnaryPred can be found.
251 
252 template <typename Tuple, template <typename> class UnaryPred>
253 struct exists_if
254     : is_found<typename find_if<Tuple, UnaryPred>::type>
255 {};
256 
257 
258 // push_back
259 // A utility used to create a type/object of a Tuple containing
260 //   all types/objects stored in another Tuple plus additional one.
261 
262 template <typename Tuple,
263           typename T,
264           size_t I = 0,
265           size_t N = size<Tuple>::value>
266 struct push_back_bt
267 {
268     typedef
269     boost::tuples::cons<
270         typename element<I, Tuple>::type,
271         typename push_back_bt<Tuple, T, I+1, N>::type
272     > type;
273 
applyboost::geometry::tuples::push_back_bt274     static type apply(Tuple const& tup, T const& t)
275     {
276         return
277         type(
278             geometry::tuples::get<I>(tup),
279             push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
280         );
281     }
282 };
283 
284 template <typename Tuple, typename T, size_t N>
285 struct push_back_bt<Tuple, T, N, N>
286 {
287     typedef boost::tuples::cons<T, boost::tuples::null_type> type;
288 
applyboost::geometry::tuples::push_back_bt289     static type apply(Tuple const&, T const& t)
290     {
291         return type(t, boost::tuples::null_type());
292     }
293 };
294 
295 template <typename Tuple, typename T>
296 struct push_back
297     : push_back_bt<Tuple, T>
298 {};
299 
300 template <typename F, typename S, typename T>
301 struct push_back<std::pair<F, S>, T>
302 {
303 #ifdef BOOST_GEOMETRY_CXX11_TUPLE
304     typedef std::tuple<F, S, T> type;
305 #else
306     typedef boost::tuple<F, S, T> type;
307 #endif // BOOST_GEOMETRY_CXX11_TUPLE
308 
applyboost::geometry::tuples::push_back309     static type apply(std::pair<F, S> const& p, T const& t)
310     {
311         return type(p.first, p.second, t);
312     }
313 
314 #ifdef BOOST_GEOMETRY_CXX11_TUPLE
315 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
316 
applyboost::geometry::tuples::push_back317     static type apply(std::pair<F, S> && p, T const& t)
318     {
319         return type(std::move(p.first), std::move(p.second), t);
320     }
321 
applyboost::geometry::tuples::push_back322     static type apply(std::pair<F, S> && p, T && t)
323     {
324         return type(std::move(p.first), std::move(p.second), std::move(t));
325     }
326 
327 #endif
328 #endif // BOOST_GEOMETRY_CXX11_TUPLE
329 
330 };
331 
332 #ifdef BOOST_GEOMETRY_CXX11_TUPLE
333 
334 // NOTE: In C++14 std::integer_sequence and std::make_integer_sequence could be used
335 
336 template <int... Is>
337 struct int_sequence {};
338 
339 template <int N, int ...Is>
340 struct make_int_sequence
341 {
342     typedef typename make_int_sequence<N - 1, N - 1, Is...>::type type;
343 };
344 
345 template <int ...Is>
346 struct make_int_sequence<0, Is...>
347 {
348     typedef int_sequence<Is...> type;
349 };
350 
351 template <typename Is, typename Tuple, typename T>
352 struct push_back_st;
353 
354 template <int ...Is, typename ...Ts, typename T>
355 struct push_back_st<int_sequence<Is...>, std::tuple<Ts...>, T>
356 {
357     typedef std::tuple<Ts..., T> type;
358 
applyboost::geometry::tuples::push_back_st359     static type apply(std::tuple<Ts...> const& tup, T const& t)
360     {
361         return type(std::get<Is>(tup)..., t);
362     }
363 
364 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
365 
applyboost::geometry::tuples::push_back_st366     static type apply(std::tuple<Ts...> && tup, T const& t)
367     {
368         return type(std::move(std::get<Is>(tup))..., t);
369     }
370 
applyboost::geometry::tuples::push_back_st371     static type apply(std::tuple<Ts...> && tup, T && t)
372     {
373         return type(std::move(std::get<Is>(tup))..., std::move(t));
374     }
375 
376 #endif
377 };
378 
379 template <typename ...Ts, typename T>
380 struct push_back<std::tuple<Ts...>, T>
381     : push_back_st
382         <
383             typename make_int_sequence<sizeof...(Ts)>::type,
384             std::tuple<Ts...>,
385             T
386         >
387 {};
388 
389 #endif // BOOST_GEOMETRY_CXX11_TUPLE
390 
391 
392 }}} // namespace boost::geometry::tuples
393 
394 #endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP
395