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