Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:53

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 
0007 // This file was modified by Oracle on 2014-2020.
0008 // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
0009 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0010 
0011 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0012 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0013 
0014 // Use, modification and distribution is subject to the Boost Software License,
0015 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0016 // http://www.boost.org/LICENSE_1_0.txt)
0017 
0018 #ifndef BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
0019 #define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP
0020 
0021 
0022 #include <type_traits>
0023 
0024 
0025 namespace boost { namespace geometry
0026 {
0027 
0028 #ifndef DOXYGEN_NO_DETAIL
0029 
0030 namespace detail { namespace select_most_precise
0031 {
0032 
0033 
0034 // 0 - void
0035 // 1 - integral
0036 // 2 - floating point
0037 // 3 - non-fundamental
0038 template <typename T>
0039 struct type_priority
0040     : std::conditional_t
0041         <
0042             std::is_void<T>::value,
0043             std::integral_constant<int, 0>,
0044             std::conditional_t
0045                 <
0046                     std::is_fundamental<T>::value,
0047                     std::conditional_t
0048                         <
0049                             std::is_floating_point<T>::value,
0050                             std::integral_constant<int, 2>,
0051                             std::integral_constant<int, 1>
0052                         >,
0053                     std::integral_constant<int, 3>
0054                 >
0055         >
0056 {};
0057 
0058 
0059 template <typename T>
0060 struct type_size
0061     : std::integral_constant<std::size_t, sizeof(T)>
0062 {};
0063 
0064 template <>
0065 struct type_size<void>
0066     : std::integral_constant<std::size_t, 0>
0067 {};
0068 
0069 
0070 }} // namespace detail::select_most_precise
0071 #endif // DOXYGEN_NO_DETAIL
0072 
0073 
0074 /*!
0075     \brief Meta-function to select the most accurate type for
0076         calculations
0077     \ingroup utility
0078     \details select_most_precise classes, compares types on compile time.
0079     For example, if an addition must be done with a double and an integer, the
0080         result must be a double.
0081     If both types are integer, the result can be an integer.
0082     \note It is different from the "promote" class, already in boost. That
0083         class promotes e.g. a (one) float to a double. This class selects a
0084         type from two types. It takes the most accurate, but does not promote
0085         afterwards.
0086     \note If the input is a non-fundamental type, it might be a calculation
0087         type such as a GMP-value or another high precision value. Therefore,
0088         if one is non-fundamental, that one is chosen.
0089     \note If both types are non-fundamental, the result is indeterminate and
0090         currently the first one is chosen.
0091 */
0092 template <typename ...Types>
0093 struct select_most_precise
0094 {
0095     typedef void type;
0096 };
0097 
0098 template <typename T>
0099 struct select_most_precise<T>
0100 {
0101     typedef T type;
0102 };
0103 
0104 template <typename T1, typename T2>
0105 struct select_most_precise<T1, T2>
0106 {
0107     static const int priority1 = detail::select_most_precise::type_priority<T1>::value;
0108     static const int priority2 = detail::select_most_precise::type_priority<T2>::value;
0109     static const std::size_t size1 = detail::select_most_precise::type_size<T1>::value;
0110     static const std::size_t size2 = detail::select_most_precise::type_size<T2>::value;
0111 
0112     typedef std::conditional_t
0113         <
0114             (priority1 > priority2),
0115             T1,
0116             std::conditional_t
0117                 <
0118                     (priority2 > priority1),
0119                     T2,
0120                     std::conditional_t // priority1 == priority2
0121                         <
0122                             (priority1 == 0 || priority1 == 3), // both void or non-fundamental
0123                             T1,
0124                             std::conditional_t // both fundamental
0125                                 <
0126                                     (size2 > size1),
0127                                     T2,
0128                                     T1
0129                                 >
0130                         >
0131                 >
0132         > type;
0133 };
0134 
0135 template <typename T1, typename T2, typename ...Types>
0136 struct select_most_precise<T1, T2, Types...>
0137 {
0138     typedef typename select_most_precise
0139         <
0140             typename select_most_precise<T1, T2>::type,
0141             typename select_most_precise<Types...>::type
0142         >::type type;
0143 };
0144 
0145 
0146 }} // namespace boost::geometry
0147 
0148 #endif // BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP