123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #ifndef BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
- #define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
- #include <type_traits>
- namespace boost { namespace geometry
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace select_most_precise
- {
- template <typename T>
- struct type_priority
- : std::conditional_t
- <
- std::is_void<T>::value,
- std::integral_constant<int, 0>,
- std::conditional_t
- <
- std::is_fundamental<T>::value,
- std::conditional_t
- <
- std::is_floating_point<T>::value,
- std::integral_constant<int, 2>,
- std::integral_constant<int, 1>
- >,
- std::integral_constant<int, 3>
- >
- >
- {};
- template <typename T>
- struct type_size
- : std::integral_constant<std::size_t, sizeof(T)>
- {};
- template <>
- struct type_size<void>
- : std::integral_constant<std::size_t, 0>
- {};
- }}
- #endif
- template <typename ...Types>
- struct select_most_precise
- {
- typedef void type;
- };
- template <typename T>
- struct select_most_precise<T>
- {
- typedef T type;
- };
- template <typename T1, typename T2>
- struct select_most_precise<T1, T2>
- {
- static const int priority1 = detail::select_most_precise::type_priority<T1>::value;
- static const int priority2 = detail::select_most_precise::type_priority<T2>::value;
- static const std::size_t size1 = detail::select_most_precise::type_size<T1>::value;
- static const std::size_t size2 = detail::select_most_precise::type_size<T2>::value;
- typedef std::conditional_t
- <
- (priority1 > priority2),
- T1,
- std::conditional_t
- <
- (priority2 > priority1),
- T2,
- std::conditional_t
- <
- (priority1 == 0 || priority1 == 3),
- T1,
- std::conditional_t
- <
- (size2 > size1),
- T2,
- T1
- >
- >
- >
- > type;
- };
- template <typename T1, typename T2, typename ...Types>
- struct select_most_precise<T1, T2, Types...>
- {
- typedef typename select_most_precise
- <
- typename select_most_precise<T1, T2>::type,
- typename select_most_precise<Types...>::type
- >::type type;
- };
- }}
- #endif
|