Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:46

0001 //  (c) Copyright Fernando Luis Cacciola Carballal 2000-2004
0002 //  Use, modification, and distribution is subject to the Boost Software
0003 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See library home page at http://www.boost.org/libs/numeric/conversion
0007 //
0008 // Contact the author at: fernando_cacciola@hotmail.com
0009 // 
0010 #ifndef BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
0011 #define BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
0012 
0013 #include "boost/config.hpp"
0014 #include "boost/limits.hpp"
0015 
0016 #include "boost/mpl/int.hpp"
0017 #include "boost/mpl/multiplies.hpp"
0018 #include "boost/mpl/less.hpp"
0019 #include "boost/mpl/equal_to.hpp"
0020 
0021 #include "boost/type_traits/is_same.hpp"
0022 
0023 #include "boost/numeric/conversion/detail/meta.hpp"
0024 #include "boost/numeric/conversion/detail/int_float_mixture.hpp"
0025 #include "boost/numeric/conversion/detail/sign_mixture.hpp"
0026 #include "boost/numeric/conversion/detail/udt_builtin_mixture.hpp"
0027 
0028 namespace boost { namespace numeric { namespace convdetail
0029 {
0030   //---------------------------------------------------------------
0031   // Implementations of the compile time predicate "T is subranged"
0032   //---------------------------------------------------------------
0033 
0034     // for integral to integral conversions
0035     template<class T,class S>
0036     struct subranged_Sig2Unsig
0037     {
0038       // Signed to unsigned conversions are 'subranged' because of possible loose
0039       // of negative values.
0040       typedef mpl::true_ type ;
0041     } ;
0042 
0043     // for unsigned integral to signed integral conversions
0044     template<class T,class S>
0045     struct subranged_Unsig2Sig
0046     {
0047        // IMPORTANT NOTE:
0048        //
0049        // This code assumes that signed/unsigned integral values are represented
0050        // such that:
0051        //
0052        //  numeric_limits<signed T>::digits + 1 == numeric_limits<unsigned T>::digits
0053        //
0054        // The '+1' is required since numeric_limits<>::digits gives 1 bit less for signed integral types.
0055        //
0056        // This fact is used by the following logic:
0057        //
0058        //  if ( (numeric_limits<T>::digits+1) < (2*numeric_limits<S>::digits) )
0059        //    then the conversion is subranged.
0060        //
0061 
0062        typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
0063        typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
0064 
0065        // T is signed, so take digits+1
0066        typedef typename T_digits::next u_T_digits ;
0067 
0068        typedef mpl::int_<2> Two ;
0069 
0070        typedef typename mpl::multiplies<S_digits,Two>::type S_digits_times_2 ;
0071 
0072        typedef typename mpl::less<u_T_digits,S_digits_times_2>::type type ;
0073     } ;
0074 
0075     // for integral to integral conversions of the same sign.
0076     template<class T,class S>
0077     struct subranged_SameSign
0078     {
0079        // An integral conversion of the same sign is subranged if digits(T) < digits(S).
0080 
0081        typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
0082        typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
0083 
0084        typedef typename mpl::less<T_digits,S_digits>::type type ;
0085     } ;
0086 
0087     // for integral to float conversions
0088     template<class T,class S>
0089     struct subranged_Int2Float
0090     {
0091       typedef mpl::false_ type ;
0092     } ;
0093 
0094     // for float to integral conversions
0095     template<class T,class S>
0096     struct subranged_Float2Int
0097     {
0098       typedef mpl::true_ type ;
0099     } ;
0100 
0101     // for float to float conversions
0102     template<class T,class S>
0103     struct subranged_Float2Float
0104     {
0105       // If both T and S are floats,
0106       // compare exponent bits and if they match, mantisa bits.
0107 
0108       typedef mpl::int_< ::std::numeric_limits<S>::digits > S_mantisa ;
0109       typedef mpl::int_< ::std::numeric_limits<T>::digits > T_mantisa ;
0110 
0111       typedef mpl::int_< ::std::numeric_limits<S>::max_exponent > S_exponent ;
0112       typedef mpl::int_< ::std::numeric_limits<T>::max_exponent > T_exponent ;
0113 
0114       typedef typename mpl::less<T_exponent,S_exponent>::type T_smaller_exponent ;
0115 
0116       typedef typename mpl::equal_to<T_exponent,S_exponent>::type equal_exponents ;
0117 
0118       typedef mpl::less<T_mantisa,S_mantisa> T_smaller_mantisa ;
0119 
0120       typedef mpl::eval_if<equal_exponents,T_smaller_mantisa,mpl::false_> not_bigger_exponent_case ;
0121 
0122       typedef typename
0123         mpl::eval_if<T_smaller_exponent,mpl::true_,not_bigger_exponent_case>::type
0124           type ;
0125     } ;
0126 
0127     // for Udt to built-in conversions
0128     template<class T,class S>
0129     struct subranged_Udt2BuiltIn
0130     {
0131       typedef mpl::true_ type ;
0132     } ;
0133 
0134     // for built-in to Udt conversions
0135     template<class T,class S>
0136     struct subranged_BuiltIn2Udt
0137     {
0138       typedef mpl::false_ type ;
0139     } ;
0140 
0141     // for Udt to Udt conversions
0142     template<class T,class S>
0143     struct subranged_Udt2Udt
0144     {
0145       typedef mpl::false_ type ;
0146     } ;
0147 
0148   //-------------------------------------------------------------------
0149   // Selectors for the implementations of the subranged predicate
0150   //-------------------------------------------------------------------
0151 
0152     template<class T,class S>
0153     struct get_subranged_Int2Int
0154     {
0155       typedef subranged_SameSign<T,S>  Sig2Sig     ;
0156       typedef subranged_Sig2Unsig<T,S> Sig2Unsig   ;
0157       typedef subranged_Unsig2Sig<T,S> Unsig2Sig   ;
0158       typedef Sig2Sig                  Unsig2Unsig ;
0159 
0160       typedef typename get_sign_mixture<T,S>::type sign_mixture ;
0161 
0162       typedef typename
0163         for_sign_mixture<sign_mixture, Sig2Sig, Sig2Unsig, Unsig2Sig, Unsig2Unsig>::type
0164            type ;
0165     } ;
0166 
0167     template<class T,class S>
0168     struct get_subranged_BuiltIn2BuiltIn
0169     {
0170       typedef get_subranged_Int2Int<T,S> Int2IntQ ;
0171 
0172       typedef subranged_Int2Float  <T,S> Int2Float   ;
0173       typedef subranged_Float2Int  <T,S> Float2Int   ;
0174       typedef subranged_Float2Float<T,S> Float2Float ;
0175 
0176       typedef mpl::identity<Int2Float  > Int2FloatQ   ;
0177       typedef mpl::identity<Float2Int  > Float2IntQ   ;
0178       typedef mpl::identity<Float2Float> Float2FloatQ ;
0179 
0180       typedef typename get_int_float_mixture<T,S>::type int_float_mixture ;
0181 
0182       typedef for_int_float_mixture<int_float_mixture, Int2IntQ, Int2FloatQ, Float2IntQ, Float2FloatQ> for_ ;
0183 
0184       typedef typename for_::type selected ;
0185 
0186       typedef typename selected::type type ;
0187     } ;
0188 
0189     template<class T,class S>
0190     struct get_subranged
0191     {
0192       typedef get_subranged_BuiltIn2BuiltIn<T,S> BuiltIn2BuiltInQ ;
0193 
0194       typedef subranged_BuiltIn2Udt<T,S> BuiltIn2Udt ;
0195       typedef subranged_Udt2BuiltIn<T,S> Udt2BuiltIn ;
0196       typedef subranged_Udt2Udt<T,S>     Udt2Udt ;
0197 
0198       typedef mpl::identity<BuiltIn2Udt> BuiltIn2UdtQ ;
0199       typedef mpl::identity<Udt2BuiltIn> Udt2BuiltInQ ;
0200       typedef mpl::identity<Udt2Udt    > Udt2UdtQ     ;
0201 
0202       typedef typename get_udt_builtin_mixture<T,S>::type udt_builtin_mixture ;
0203       
0204       typedef typename
0205         for_udt_builtin_mixture<udt_builtin_mixture, BuiltIn2BuiltInQ, BuiltIn2UdtQ, Udt2BuiltInQ, Udt2UdtQ>::type
0206           selected ;
0207 
0208       typedef typename selected::type selected2 ;
0209  
0210       typedef typename selected2::type type ;
0211     } ;
0212 
0213 
0214   //-------------------------------------------------------------------
0215   // Top level implementation selector.
0216   //-------------------------------------------------------------------
0217   template<class T, class S>
0218   struct get_is_subranged
0219   {
0220     typedef get_subranged<T,S>         non_trivial_case ;
0221     typedef mpl::identity<mpl::false_> trivial_case ;
0222 
0223     typedef is_same<T,S> is_trivial ;
0224    
0225     typedef typename mpl::if_<is_trivial,trivial_case,non_trivial_case>::type selected ;
0226     
0227     typedef typename selected::type type ;
0228   } ;
0229 
0230 } } } // namespace boost::numeric::convdetail
0231 
0232 #endif
0233 
0234