1 // Boost.Geometry
2 
3 // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
4 
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_GEOMETRY_UTIL_SELECT_SEQUENCE_ELEMENT
10 #define BOOST_GEOMETRY_UTIL_SELECT_SEQUENCE_ELEMENT
11 
12 
13 #include <boost/mpl/if.hpp>
14 #include <boost/mpl/int.hpp>
15 #include <boost/mpl/at.hpp>
16 #include <boost/mpl/size.hpp>
17 
18 #include <boost/type_traits/is_same.hpp>
19 
20 #include <boost/geometry/core/coordinate_type.hpp>
21 #include <boost/geometry/util/select_most_precise.hpp>
22 
23 
24 namespace boost { namespace geometry
25 {
26 
27 namespace util
28 {
29 
30 template <typename Curr, typename Next>
31 struct pred_more_precise_coordinate_type
32 {
33     typedef typename geometry::coordinate_type<Curr>::type curr_coord_t;
34     typedef typename geometry::coordinate_type<Next>::type next_coord_t;
35 
36     typedef typename boost::mpl::if_c
37         <
38             boost::is_same
39                 <
40                     curr_coord_t,
41                     typename select_most_precise
42                         <
43                             curr_coord_t,
44                             next_coord_t
45                         >::type
46                 >::value,
47             Curr,
48             Next
49         >::type type;
50 };
51 
52 template
53 <
54     typename Seq,
55     template<typename, typename> class Pred = pred_more_precise_coordinate_type,
56     int I = 0,
57     int N = boost::mpl::size<Seq>::value
58 >
59 struct select_sequence_element
60 {
61     typedef typename boost::mpl::at<Seq, boost::mpl::int_<I> >::type curr_t;
62     typedef typename select_sequence_element<Seq, Pred, I+1, N>::type next_t;
63 
64     typedef typename Pred<curr_t, next_t>::type type;
65 };
66 
67 template <typename Seq, template<typename, typename> class Pred, int N>
68 struct select_sequence_element<Seq, Pred, N, N>
69 {
70     typedef typename boost::mpl::at<Seq, boost::mpl::int_<N-1> >::type type;
71 };
72 
73 } // namespace util
74 
75 }} // namespace boost::geometry
76 
77 
78 #endif // BOOST_GEOMETRY_UTIL_SELECT_SEQUENCE_ELEMENT
79