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