epoc32/include/stdapis/boost/numeric/conversion/detail/is_subranged.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 //  © Copyright Fernando Luis Cacciola Carballal 2000-2004
     2 //  Use, modification, and distribution is subject to the Boost Software
     3 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     4 //  http://www.boost.org/LICENSE_1_0.txt)
     5 
     6 //  See library home page at http://www.boost.org/libs/numeric/conversion
     7 //
     8 // Contact the author at: fernando_cacciola@hotmail.com
     9 // 
    10 #ifndef BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
    11 #define BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
    12 
    13 #include "boost/config.hpp"
    14 #include "boost/limits.hpp"
    15 
    16 #include "boost/mpl/int.hpp"
    17 #include "boost/mpl/multiplies.hpp"
    18 #include "boost/mpl/less.hpp"
    19 #include "boost/mpl/equal_to.hpp"
    20 
    21 #include "boost/type_traits/is_same.hpp"
    22 
    23 #include "boost/numeric/conversion/detail/meta.hpp"
    24 #include "boost/numeric/conversion/detail/int_float_mixture.hpp"
    25 #include "boost/numeric/conversion/detail/sign_mixture.hpp"
    26 #include "boost/numeric/conversion/detail/udt_builtin_mixture.hpp"
    27 
    28 namespace boost { namespace numeric { namespace convdetail
    29 {
    30   //---------------------------------------------------------------
    31   // Implementations of the compile time predicate "T is subranged"
    32   //---------------------------------------------------------------
    33 
    34     // for integral to integral conversions
    35     template<class T,class S>
    36     struct subranged_Sig2Unsig
    37     {
    38       // Signed to unsigned conversions are 'subranged' because of possible loose
    39       // of negative values.
    40       typedef mpl::true_ type ;
    41     } ;
    42 
    43     // for unsigned integral to signed integral conversions
    44     template<class T,class S>
    45     struct subranged_Unsig2Sig
    46     {
    47        // IMPORTANT NOTE:
    48        //
    49        // This code assumes that signed/unsigned integral values are represented
    50        // such that:
    51        //
    52        //  numeric_limits<signed T>::digits + 1 == numeric_limits<unsigned T>::digits
    53        //
    54        // The '+1' is required since numeric_limits<>::digits gives 1 bit less for signed integral types.
    55        //
    56        // This fact is used by the following logic:
    57        //
    58        //  if ( (numeric_limits<T>::digits+1) < (2*numeric_limits<S>::digits) )
    59        //    then the conversion is subranged.
    60        //
    61 
    62        typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
    63        typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
    64 
    65        // T is signed, so take digits+1
    66        typedef typename T_digits::next u_T_digits ;
    67 
    68        typedef mpl::int_<2> Two ;
    69 
    70        typedef typename mpl::multiplies<S_digits,Two>::type S_digits_times_2 ;
    71 
    72        typedef typename mpl::less<u_T_digits,S_digits_times_2>::type type ;
    73     } ;
    74 
    75     // for integral to integral conversions of the same sign.
    76     template<class T,class S>
    77     struct subranged_SameSign
    78     {
    79        // An integral conversion of the same sign is subranged if digits(T) < digits(S).
    80 
    81        typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
    82        typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
    83 
    84        typedef typename mpl::less<T_digits,S_digits>::type type ;
    85     } ;
    86 
    87     // for integral to float conversions
    88     template<class T,class S>
    89     struct subranged_Int2Float
    90     {
    91       typedef mpl::false_ type ;
    92     } ;
    93 
    94     // for float to integral conversions
    95     template<class T,class S>
    96     struct subranged_Float2Int
    97     {
    98       typedef mpl::true_ type ;
    99     } ;
   100 
   101     // for float to float conversions
   102     template<class T,class S>
   103     struct subranged_Float2Float
   104     {
   105       // If both T and S are floats,
   106       // compare exponent bits and if they match, mantisa bits.
   107 
   108       typedef mpl::int_< ::std::numeric_limits<S>::digits > S_mantisa ;
   109       typedef mpl::int_< ::std::numeric_limits<T>::digits > T_mantisa ;
   110 
   111       typedef mpl::int_< ::std::numeric_limits<S>::max_exponent > S_exponent ;
   112       typedef mpl::int_< ::std::numeric_limits<T>::max_exponent > T_exponent ;
   113 
   114       typedef typename mpl::less<T_exponent,S_exponent>::type T_smaller_exponent ;
   115 
   116       typedef typename mpl::equal_to<T_exponent,S_exponent>::type equal_exponents ;
   117 
   118       typedef mpl::less<T_mantisa,S_mantisa> T_smaller_mantisa ;
   119 
   120       typedef mpl::eval_if<equal_exponents,T_smaller_mantisa,mpl::false_> not_bigger_exponent_case ;
   121 
   122       typedef typename
   123         mpl::eval_if<T_smaller_exponent,mpl::true_,not_bigger_exponent_case>::type
   124           type ;
   125     } ;
   126 
   127     // for Udt to built-in conversions
   128     template<class T,class S>
   129     struct subranged_Udt2BuiltIn
   130     {
   131       typedef mpl::true_ type ;
   132     } ;
   133 
   134     // for built-in to Udt conversions
   135     template<class T,class S>
   136     struct subranged_BuiltIn2Udt
   137     {
   138       typedef mpl::false_ type ;
   139     } ;
   140 
   141     // for Udt to Udt conversions
   142     template<class T,class S>
   143     struct subranged_Udt2Udt
   144     {
   145       typedef mpl::false_ type ;
   146     } ;
   147 
   148   //-------------------------------------------------------------------
   149   // Selectors for the implementations of the subranged predicate
   150   //-------------------------------------------------------------------
   151 
   152     template<class T,class S>
   153     struct get_subranged_Int2Int
   154     {
   155       typedef subranged_SameSign<T,S>  Sig2Sig     ;
   156       typedef subranged_Sig2Unsig<T,S> Sig2Unsig   ;
   157       typedef subranged_Unsig2Sig<T,S> Unsig2Sig   ;
   158       typedef Sig2Sig                  Unsig2Unsig ;
   159 
   160       typedef typename get_sign_mixture<T,S>::type sign_mixture ;
   161 
   162       typedef typename
   163         for_sign_mixture<sign_mixture, Sig2Sig, Sig2Unsig, Unsig2Sig, Unsig2Unsig>::type
   164            type ;
   165     } ;
   166 
   167     template<class T,class S>
   168     struct get_subranged_BuiltIn2BuiltIn
   169     {
   170       typedef get_subranged_Int2Int<T,S> Int2IntQ ;
   171 
   172       typedef subranged_Int2Float  <T,S> Int2Float   ;
   173       typedef subranged_Float2Int  <T,S> Float2Int   ;
   174       typedef subranged_Float2Float<T,S> Float2Float ;
   175 
   176       typedef mpl::identity<Int2Float  > Int2FloatQ   ;
   177       typedef mpl::identity<Float2Int  > Float2IntQ   ;
   178       typedef mpl::identity<Float2Float> Float2FloatQ ;
   179 
   180       typedef typename get_int_float_mixture<T,S>::type int_float_mixture ;
   181 
   182       typedef for_int_float_mixture<int_float_mixture, Int2IntQ, Int2FloatQ, Float2IntQ, Float2FloatQ> for_ ;
   183 
   184       typedef typename for_::type selected ;
   185 
   186       typedef typename selected::type type ;
   187     } ;
   188 
   189     template<class T,class S>
   190     struct get_subranged
   191     {
   192       typedef get_subranged_BuiltIn2BuiltIn<T,S> BuiltIn2BuiltInQ ;
   193 
   194       typedef subranged_BuiltIn2Udt<T,S> BuiltIn2Udt ;
   195       typedef subranged_Udt2BuiltIn<T,S> Udt2BuiltIn ;
   196       typedef subranged_Udt2Udt<T,S>     Udt2Udt ;
   197 
   198       typedef mpl::identity<BuiltIn2Udt> BuiltIn2UdtQ ;
   199       typedef mpl::identity<Udt2BuiltIn> Udt2BuiltInQ ;
   200       typedef mpl::identity<Udt2Udt    > Udt2UdtQ     ;
   201 
   202       typedef typename get_udt_builtin_mixture<T,S>::type udt_builtin_mixture ;
   203       
   204       typedef typename
   205         for_udt_builtin_mixture<udt_builtin_mixture, BuiltIn2BuiltInQ, BuiltIn2UdtQ, Udt2BuiltInQ, Udt2UdtQ>::type
   206           selected ;
   207 
   208       typedef typename selected::type selected2 ;
   209  
   210       typedef typename selected2::type type ;
   211     } ;
   212 
   213 
   214   //-------------------------------------------------------------------
   215   // Top level implementation selector.
   216   //-------------------------------------------------------------------
   217   template<class T, class S>
   218   struct get_is_subranged
   219   {
   220     typedef get_subranged<T,S>         non_trivial_case ;
   221     typedef mpl::identity<mpl::false_> trivial_case ;
   222 
   223     typedef is_same<T,S> is_trivial ;
   224    
   225     typedef typename mpl::if_<is_trivial,trivial_case,non_trivial_case>::type selected ;
   226     
   227     typedef typename selected::type type ;
   228   } ;
   229 
   230 } } } // namespace boost::numeric::convdetail
   231 
   232 #endif
   233 
   234