Chris@16: // (c) Copyright Fernando Luis Cacciola Carballal 2000-2004 Chris@16: // Use, modification, and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See library home page at http://www.boost.org/libs/numeric/conversion Chris@16: // Chris@16: // Contact the author at: fernando_cacciola@hotmail.com Chris@16: // Chris@16: #ifndef BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP Chris@16: #define BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP Chris@16: Chris@16: #include "boost/config.hpp" Chris@16: #include "boost/limits.hpp" Chris@16: Chris@16: #include "boost/mpl/int.hpp" Chris@16: #include "boost/mpl/multiplies.hpp" Chris@16: #include "boost/mpl/less.hpp" Chris@16: #include "boost/mpl/equal_to.hpp" Chris@16: Chris@16: #include "boost/type_traits/is_same.hpp" Chris@16: Chris@16: #include "boost/numeric/conversion/detail/meta.hpp" Chris@16: #include "boost/numeric/conversion/detail/int_float_mixture.hpp" Chris@16: #include "boost/numeric/conversion/detail/sign_mixture.hpp" Chris@16: #include "boost/numeric/conversion/detail/udt_builtin_mixture.hpp" Chris@16: Chris@16: namespace boost { namespace numeric { namespace convdetail Chris@16: { Chris@16: //--------------------------------------------------------------- Chris@16: // Implementations of the compile time predicate "T is subranged" Chris@16: //--------------------------------------------------------------- Chris@16: Chris@16: // for integral to integral conversions Chris@16: template Chris@16: struct subranged_Sig2Unsig Chris@16: { Chris@16: // Signed to unsigned conversions are 'subranged' because of possible loose Chris@16: // of negative values. Chris@16: typedef mpl::true_ type ; Chris@16: } ; Chris@16: Chris@16: // for unsigned integral to signed integral conversions Chris@16: template Chris@16: struct subranged_Unsig2Sig Chris@16: { Chris@16: // IMPORTANT NOTE: Chris@16: // Chris@16: // This code assumes that signed/unsigned integral values are represented Chris@16: // such that: Chris@16: // Chris@16: // numeric_limits::digits + 1 == numeric_limits::digits Chris@16: // Chris@16: // The '+1' is required since numeric_limits<>::digits gives 1 bit less for signed integral types. Chris@16: // Chris@16: // This fact is used by the following logic: Chris@16: // Chris@16: // if ( (numeric_limits::digits+1) < (2*numeric_limits::digits) ) Chris@16: // then the conversion is subranged. Chris@16: // Chris@16: Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > S_digits ; Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > T_digits ; Chris@16: Chris@16: // T is signed, so take digits+1 Chris@16: typedef typename T_digits::next u_T_digits ; Chris@16: Chris@16: typedef mpl::int_<2> Two ; Chris@16: Chris@16: typedef typename mpl::multiplies::type S_digits_times_2 ; Chris@16: Chris@16: typedef typename mpl::less::type type ; Chris@16: } ; Chris@16: Chris@16: // for integral to integral conversions of the same sign. Chris@16: template Chris@16: struct subranged_SameSign Chris@16: { Chris@16: // An integral conversion of the same sign is subranged if digits(T) < digits(S). Chris@16: Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > S_digits ; Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > T_digits ; Chris@16: Chris@16: typedef typename mpl::less::type type ; Chris@16: } ; Chris@16: Chris@16: // for integral to float conversions Chris@16: template Chris@16: struct subranged_Int2Float Chris@16: { Chris@16: typedef mpl::false_ type ; Chris@16: } ; Chris@16: Chris@16: // for float to integral conversions Chris@16: template Chris@16: struct subranged_Float2Int Chris@16: { Chris@16: typedef mpl::true_ type ; Chris@16: } ; Chris@16: Chris@16: // for float to float conversions Chris@16: template Chris@16: struct subranged_Float2Float Chris@16: { Chris@16: // If both T and S are floats, Chris@16: // compare exponent bits and if they match, mantisa bits. Chris@16: Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > S_mantisa ; Chris@16: typedef mpl::int_< ::std::numeric_limits::digits > T_mantisa ; Chris@16: Chris@16: typedef mpl::int_< ::std::numeric_limits::max_exponent > S_exponent ; Chris@16: typedef mpl::int_< ::std::numeric_limits::max_exponent > T_exponent ; Chris@16: Chris@16: typedef typename mpl::less::type T_smaller_exponent ; Chris@16: Chris@16: typedef typename mpl::equal_to::type equal_exponents ; Chris@16: Chris@16: typedef mpl::less T_smaller_mantisa ; Chris@16: Chris@16: typedef mpl::eval_if not_bigger_exponent_case ; Chris@16: Chris@16: typedef typename Chris@16: mpl::eval_if::type Chris@16: type ; Chris@16: } ; Chris@16: Chris@16: // for Udt to built-in conversions Chris@16: template Chris@16: struct subranged_Udt2BuiltIn Chris@16: { Chris@16: typedef mpl::true_ type ; Chris@16: } ; Chris@16: Chris@16: // for built-in to Udt conversions Chris@16: template Chris@16: struct subranged_BuiltIn2Udt Chris@16: { Chris@16: typedef mpl::false_ type ; Chris@16: } ; Chris@16: Chris@16: // for Udt to Udt conversions Chris@16: template Chris@16: struct subranged_Udt2Udt Chris@16: { Chris@16: typedef mpl::false_ type ; Chris@16: } ; Chris@16: Chris@16: //------------------------------------------------------------------- Chris@16: // Selectors for the implementations of the subranged predicate Chris@16: //------------------------------------------------------------------- Chris@16: Chris@16: template Chris@16: struct get_subranged_Int2Int Chris@16: { Chris@16: typedef subranged_SameSign Sig2Sig ; Chris@16: typedef subranged_Sig2Unsig Sig2Unsig ; Chris@16: typedef subranged_Unsig2Sig Unsig2Sig ; Chris@16: typedef Sig2Sig Unsig2Unsig ; Chris@16: Chris@16: typedef typename get_sign_mixture::type sign_mixture ; Chris@16: Chris@16: typedef typename Chris@16: for_sign_mixture::type Chris@16: type ; Chris@16: } ; Chris@16: Chris@16: template Chris@16: struct get_subranged_BuiltIn2BuiltIn Chris@16: { Chris@16: typedef get_subranged_Int2Int Int2IntQ ; Chris@16: Chris@16: typedef subranged_Int2Float Int2Float ; Chris@16: typedef subranged_Float2Int Float2Int ; Chris@16: typedef subranged_Float2Float Float2Float ; Chris@16: Chris@16: typedef mpl::identity Int2FloatQ ; Chris@16: typedef mpl::identity Float2IntQ ; Chris@16: typedef mpl::identity Float2FloatQ ; Chris@16: Chris@16: typedef typename get_int_float_mixture::type int_float_mixture ; Chris@16: Chris@16: typedef for_int_float_mixture for_ ; Chris@16: Chris@16: typedef typename for_::type selected ; Chris@16: Chris@16: typedef typename selected::type type ; Chris@16: } ; Chris@16: Chris@16: template Chris@16: struct get_subranged Chris@16: { Chris@16: typedef get_subranged_BuiltIn2BuiltIn BuiltIn2BuiltInQ ; Chris@16: Chris@16: typedef subranged_BuiltIn2Udt BuiltIn2Udt ; Chris@16: typedef subranged_Udt2BuiltIn Udt2BuiltIn ; Chris@16: typedef subranged_Udt2Udt Udt2Udt ; Chris@16: Chris@16: typedef mpl::identity BuiltIn2UdtQ ; Chris@16: typedef mpl::identity Udt2BuiltInQ ; Chris@16: typedef mpl::identity Udt2UdtQ ; Chris@16: Chris@16: typedef typename get_udt_builtin_mixture::type udt_builtin_mixture ; Chris@16: Chris@16: typedef typename Chris@16: for_udt_builtin_mixture::type Chris@16: selected ; Chris@16: Chris@16: typedef typename selected::type selected2 ; Chris@16: Chris@16: typedef typename selected2::type type ; Chris@16: } ; Chris@16: Chris@16: Chris@16: //------------------------------------------------------------------- Chris@16: // Top level implementation selector. Chris@16: //------------------------------------------------------------------- Chris@16: template Chris@16: struct get_is_subranged Chris@16: { Chris@16: typedef get_subranged non_trivial_case ; Chris@16: typedef mpl::identity trivial_case ; Chris@16: Chris@16: typedef is_same is_trivial ; Chris@16: Chris@16: typedef typename mpl::if_::type selected ; Chris@16: Chris@16: typedef typename selected::type type ; Chris@16: } ; Chris@16: Chris@16: } } } // namespace boost::numeric::convdetail Chris@16: Chris@16: #endif Chris@16: Chris@16: