// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // This file was modified by Oracle on 2014. // Modifications copyright (c) 2014 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP #define BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace select_most_precise { // At least one of the types is non-fundamental. Take that one. // if both are non-fundamental, the type-to-be-selected // is unknown, it should be defined by explicit specialization. template struct select_non_fundamental { typedef T1 type; }; template struct select_non_fundamental { typedef T2 type; }; template struct select_non_fundamental { typedef T1 type; }; // Selection of largest type (e.g. int of // It defaults takes the first one, if second is larger, take the second one template struct select_largest { typedef T1 type; }; template struct select_largest { typedef T2 type; }; // Selection of floating point and specializations: // both FP or both !FP does never occur... template struct select_floating_point { typedef char type; }; // ... so if ONE but not both of these types is floating point, take that one template struct select_floating_point { typedef T1 type; }; template struct select_floating_point { typedef T2 type; }; }} // namespace detail::select_most_precise #endif // DOXYGEN_NO_DETAIL /*! \brief Meta-function to select, of two types, the most accurate type for calculations \ingroup utility \details select_most_precise classes, compares two types on compile time. For example, if an addition must be done with a double and an integer, the result must be a double. If both types are integer, the result can be an integer. \note It is different from the "promote" class, already in boost. That class promotes e.g. a (one) float to a double. This class selects a type from two types. It takes the most accurate, but does not promote afterwards. \note This traits class is completely independant from GGL and might be a separate addition to Boost \note If the input is a non-fundamental type, it might be a calculation type such as a GMP-value or another high precision value. Therefore, if one is non-fundamental, that one is chosen. \note If both types are non-fundamental, the result is indeterminate and currently the first one is chosen. */ template struct select_most_precise { typedef typename select_most_precise < typename select_most_precise::type, T3 >::type type; }; template struct select_most_precise { static const bool second_larger = sizeof(T2) > sizeof(T1); static const bool one_not_fundamental = ! (boost::is_fundamental::type::value && boost::is_fundamental::type::value); static const bool both_same = boost::is_floating_point::type::value == boost::is_floating_point::type::value; typedef typename boost::mpl::if_c < one_not_fundamental, typename detail::select_most_precise::select_non_fundamental < boost::is_fundamental::type::value, boost::is_fundamental::type::value, T1, T2 >::type, typename boost::mpl::if_c < both_same, typename detail::select_most_precise::select_largest < second_larger, T1, T2 >::type, typename detail::select_most_precise::select_floating_point < boost::is_floating_point::type::value, boost::is_floating_point::type::value, T1, T2 >::type >::type >::type type; }; template struct select_most_precise { typedef T1 type; }; }} // namespace boost::geometry #endif // BOOST_GEOMETRY_UTIL_SELECT_MOST_PRECISE_HPP