~ubuntu-branches/ubuntu/wily/bombono-dvd/wily

« back to all changes in this revision

Viewing changes to libs/boost-lib/boost/numeric/conversion/detail/is_subranged.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2010-11-04 11:46:25 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20101104114625-8xfdhvhpsm51i0nu
Tags: upstream-0.8.0
ImportĀ upstreamĀ versionĀ 0.8.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  (c) 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