epoc32/include/stdapis/boost/numeric/conversion/detail/is_subranged.hpp
branchSymbian2
changeset 2 2fe1408b6811
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/epoc32/include/stdapis/boost/numeric/conversion/detail/is_subranged.hpp	Tue Mar 16 16:12:26 2010 +0000
     1.3 @@ -0,0 +1,234 @@
     1.4 +//  © Copyright Fernando Luis Cacciola Carballal 2000-2004
     1.5 +//  Use, modification, and distribution is subject to the Boost Software
     1.6 +//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     1.7 +//  http://www.boost.org/LICENSE_1_0.txt)
     1.8 +
     1.9 +//  See library home page at http://www.boost.org/libs/numeric/conversion
    1.10 +//
    1.11 +// Contact the author at: fernando_cacciola@hotmail.com
    1.12 +// 
    1.13 +#ifndef BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
    1.14 +#define BOOST_NUMERIC_CONVERSION_DETAIL_IS_SUBRANGED_FLC_12NOV2002_HPP
    1.15 +
    1.16 +#include "boost/config.hpp"
    1.17 +#include "boost/limits.hpp"
    1.18 +
    1.19 +#include "boost/mpl/int.hpp"
    1.20 +#include "boost/mpl/multiplies.hpp"
    1.21 +#include "boost/mpl/less.hpp"
    1.22 +#include "boost/mpl/equal_to.hpp"
    1.23 +
    1.24 +#include "boost/type_traits/is_same.hpp"
    1.25 +
    1.26 +#include "boost/numeric/conversion/detail/meta.hpp"
    1.27 +#include "boost/numeric/conversion/detail/int_float_mixture.hpp"
    1.28 +#include "boost/numeric/conversion/detail/sign_mixture.hpp"
    1.29 +#include "boost/numeric/conversion/detail/udt_builtin_mixture.hpp"
    1.30 +
    1.31 +namespace boost { namespace numeric { namespace convdetail
    1.32 +{
    1.33 +  //---------------------------------------------------------------
    1.34 +  // Implementations of the compile time predicate "T is subranged"
    1.35 +  //---------------------------------------------------------------
    1.36 +
    1.37 +    // for integral to integral conversions
    1.38 +    template<class T,class S>
    1.39 +    struct subranged_Sig2Unsig
    1.40 +    {
    1.41 +      // Signed to unsigned conversions are 'subranged' because of possible loose
    1.42 +      // of negative values.
    1.43 +      typedef mpl::true_ type ;
    1.44 +    } ;
    1.45 +
    1.46 +    // for unsigned integral to signed integral conversions
    1.47 +    template<class T,class S>
    1.48 +    struct subranged_Unsig2Sig
    1.49 +    {
    1.50 +       // IMPORTANT NOTE:
    1.51 +       //
    1.52 +       // This code assumes that signed/unsigned integral values are represented
    1.53 +       // such that:
    1.54 +       //
    1.55 +       //  numeric_limits<signed T>::digits + 1 == numeric_limits<unsigned T>::digits
    1.56 +       //
    1.57 +       // The '+1' is required since numeric_limits<>::digits gives 1 bit less for signed integral types.
    1.58 +       //
    1.59 +       // This fact is used by the following logic:
    1.60 +       //
    1.61 +       //  if ( (numeric_limits<T>::digits+1) < (2*numeric_limits<S>::digits) )
    1.62 +       //    then the conversion is subranged.
    1.63 +       //
    1.64 +
    1.65 +       typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
    1.66 +       typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
    1.67 +
    1.68 +       // T is signed, so take digits+1
    1.69 +       typedef typename T_digits::next u_T_digits ;
    1.70 +
    1.71 +       typedef mpl::int_<2> Two ;
    1.72 +
    1.73 +       typedef typename mpl::multiplies<S_digits,Two>::type S_digits_times_2 ;
    1.74 +
    1.75 +       typedef typename mpl::less<u_T_digits,S_digits_times_2>::type type ;
    1.76 +    } ;
    1.77 +
    1.78 +    // for integral to integral conversions of the same sign.
    1.79 +    template<class T,class S>
    1.80 +    struct subranged_SameSign
    1.81 +    {
    1.82 +       // An integral conversion of the same sign is subranged if digits(T) < digits(S).
    1.83 +
    1.84 +       typedef mpl::int_< ::std::numeric_limits<S>::digits > S_digits ;
    1.85 +       typedef mpl::int_< ::std::numeric_limits<T>::digits > T_digits ;
    1.86 +
    1.87 +       typedef typename mpl::less<T_digits,S_digits>::type type ;
    1.88 +    } ;
    1.89 +
    1.90 +    // for integral to float conversions
    1.91 +    template<class T,class S>
    1.92 +    struct subranged_Int2Float
    1.93 +    {
    1.94 +      typedef mpl::false_ type ;
    1.95 +    } ;
    1.96 +
    1.97 +    // for float to integral conversions
    1.98 +    template<class T,class S>
    1.99 +    struct subranged_Float2Int
   1.100 +    {
   1.101 +      typedef mpl::true_ type ;
   1.102 +    } ;
   1.103 +
   1.104 +    // for float to float conversions
   1.105 +    template<class T,class S>
   1.106 +    struct subranged_Float2Float
   1.107 +    {
   1.108 +      // If both T and S are floats,
   1.109 +      // compare exponent bits and if they match, mantisa bits.
   1.110 +
   1.111 +      typedef mpl::int_< ::std::numeric_limits<S>::digits > S_mantisa ;
   1.112 +      typedef mpl::int_< ::std::numeric_limits<T>::digits > T_mantisa ;
   1.113 +
   1.114 +      typedef mpl::int_< ::std::numeric_limits<S>::max_exponent > S_exponent ;
   1.115 +      typedef mpl::int_< ::std::numeric_limits<T>::max_exponent > T_exponent ;
   1.116 +
   1.117 +      typedef typename mpl::less<T_exponent,S_exponent>::type T_smaller_exponent ;
   1.118 +
   1.119 +      typedef typename mpl::equal_to<T_exponent,S_exponent>::type equal_exponents ;
   1.120 +
   1.121 +      typedef mpl::less<T_mantisa,S_mantisa> T_smaller_mantisa ;
   1.122 +
   1.123 +      typedef mpl::eval_if<equal_exponents,T_smaller_mantisa,mpl::false_> not_bigger_exponent_case ;
   1.124 +
   1.125 +      typedef typename
   1.126 +        mpl::eval_if<T_smaller_exponent,mpl::true_,not_bigger_exponent_case>::type
   1.127 +          type ;
   1.128 +    } ;
   1.129 +
   1.130 +    // for Udt to built-in conversions
   1.131 +    template<class T,class S>
   1.132 +    struct subranged_Udt2BuiltIn
   1.133 +    {
   1.134 +      typedef mpl::true_ type ;
   1.135 +    } ;
   1.136 +
   1.137 +    // for built-in to Udt conversions
   1.138 +    template<class T,class S>
   1.139 +    struct subranged_BuiltIn2Udt
   1.140 +    {
   1.141 +      typedef mpl::false_ type ;
   1.142 +    } ;
   1.143 +
   1.144 +    // for Udt to Udt conversions
   1.145 +    template<class T,class S>
   1.146 +    struct subranged_Udt2Udt
   1.147 +    {
   1.148 +      typedef mpl::false_ type ;
   1.149 +    } ;
   1.150 +
   1.151 +  //-------------------------------------------------------------------
   1.152 +  // Selectors for the implementations of the subranged predicate
   1.153 +  //-------------------------------------------------------------------
   1.154 +
   1.155 +    template<class T,class S>
   1.156 +    struct get_subranged_Int2Int
   1.157 +    {
   1.158 +      typedef subranged_SameSign<T,S>  Sig2Sig     ;
   1.159 +      typedef subranged_Sig2Unsig<T,S> Sig2Unsig   ;
   1.160 +      typedef subranged_Unsig2Sig<T,S> Unsig2Sig   ;
   1.161 +      typedef Sig2Sig                  Unsig2Unsig ;
   1.162 +
   1.163 +      typedef typename get_sign_mixture<T,S>::type sign_mixture ;
   1.164 +
   1.165 +      typedef typename
   1.166 +        for_sign_mixture<sign_mixture, Sig2Sig, Sig2Unsig, Unsig2Sig, Unsig2Unsig>::type
   1.167 +           type ;
   1.168 +    } ;
   1.169 +
   1.170 +    template<class T,class S>
   1.171 +    struct get_subranged_BuiltIn2BuiltIn
   1.172 +    {
   1.173 +      typedef get_subranged_Int2Int<T,S> Int2IntQ ;
   1.174 +
   1.175 +      typedef subranged_Int2Float  <T,S> Int2Float   ;
   1.176 +      typedef subranged_Float2Int  <T,S> Float2Int   ;
   1.177 +      typedef subranged_Float2Float<T,S> Float2Float ;
   1.178 +
   1.179 +      typedef mpl::identity<Int2Float  > Int2FloatQ   ;
   1.180 +      typedef mpl::identity<Float2Int  > Float2IntQ   ;
   1.181 +      typedef mpl::identity<Float2Float> Float2FloatQ ;
   1.182 +
   1.183 +      typedef typename get_int_float_mixture<T,S>::type int_float_mixture ;
   1.184 +
   1.185 +      typedef for_int_float_mixture<int_float_mixture, Int2IntQ, Int2FloatQ, Float2IntQ, Float2FloatQ> for_ ;
   1.186 +
   1.187 +      typedef typename for_::type selected ;
   1.188 +
   1.189 +      typedef typename selected::type type ;
   1.190 +    } ;
   1.191 +
   1.192 +    template<class T,class S>
   1.193 +    struct get_subranged
   1.194 +    {
   1.195 +      typedef get_subranged_BuiltIn2BuiltIn<T,S> BuiltIn2BuiltInQ ;
   1.196 +
   1.197 +      typedef subranged_BuiltIn2Udt<T,S> BuiltIn2Udt ;
   1.198 +      typedef subranged_Udt2BuiltIn<T,S> Udt2BuiltIn ;
   1.199 +      typedef subranged_Udt2Udt<T,S>     Udt2Udt ;
   1.200 +
   1.201 +      typedef mpl::identity<BuiltIn2Udt> BuiltIn2UdtQ ;
   1.202 +      typedef mpl::identity<Udt2BuiltIn> Udt2BuiltInQ ;
   1.203 +      typedef mpl::identity<Udt2Udt    > Udt2UdtQ     ;
   1.204 +
   1.205 +      typedef typename get_udt_builtin_mixture<T,S>::type udt_builtin_mixture ;
   1.206 +      
   1.207 +      typedef typename
   1.208 +        for_udt_builtin_mixture<udt_builtin_mixture, BuiltIn2BuiltInQ, BuiltIn2UdtQ, Udt2BuiltInQ, Udt2UdtQ>::type
   1.209 +          selected ;
   1.210 +
   1.211 +      typedef typename selected::type selected2 ;
   1.212 + 
   1.213 +      typedef typename selected2::type type ;
   1.214 +    } ;
   1.215 +
   1.216 +
   1.217 +  //-------------------------------------------------------------------
   1.218 +  // Top level implementation selector.
   1.219 +  //-------------------------------------------------------------------
   1.220 +  template<class T, class S>
   1.221 +  struct get_is_subranged
   1.222 +  {
   1.223 +    typedef get_subranged<T,S>         non_trivial_case ;
   1.224 +    typedef mpl::identity<mpl::false_> trivial_case ;
   1.225 +
   1.226 +    typedef is_same<T,S> is_trivial ;
   1.227 +   
   1.228 +    typedef typename mpl::if_<is_trivial,trivial_case,non_trivial_case>::type selected ;
   1.229 +    
   1.230 +    typedef typename selected::type type ;
   1.231 +  } ;
   1.232 +
   1.233 +} } } // namespace boost::numeric::convdetail
   1.234 +
   1.235 +#endif
   1.236 +
   1.237 +