annotate DEPENDENCIES/generic/include/boost/numeric/conversion/detail/is_subranged.hpp @ 133:4acb5d8d80b6 tip

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