1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/numeric/conversion/detail/converter.hpp Wed Mar 31 12:33:34 2010 +0100
1.3 @@ -0,0 +1,602 @@
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_CONVERTER_FLC_12NOV2002_HPP
1.14 +#define BOOST_NUMERIC_CONVERSION_DETAIL_CONVERTER_FLC_12NOV2002_HPP
1.15 +
1.16 +#include <functional>
1.17 +
1.18 +#include "boost/numeric/conversion/detail/meta.hpp"
1.19 +#include "boost/numeric/conversion/detail/conversion_traits.hpp"
1.20 +#include "boost/numeric/conversion/bounds.hpp"
1.21 +
1.22 +#include "boost/type_traits/is_same.hpp"
1.23 +
1.24 +#include "boost/mpl/integral_c.hpp"
1.25 +
1.26 +namespace boost { namespace numeric { namespace convdetail
1.27 +{
1.28 + // Integral Constants representing rounding modes
1.29 + typedef mpl::integral_c<std::float_round_style, std::round_toward_zero> round2zero_c ;
1.30 + typedef mpl::integral_c<std::float_round_style, std::round_to_nearest> round2nearest_c ;
1.31 + typedef mpl::integral_c<std::float_round_style, std::round_toward_infinity> round2inf_c ;
1.32 + typedef mpl::integral_c<std::float_round_style, std::round_toward_neg_infinity> round2neg_inf_c ;
1.33 +
1.34 + // Metafunction:
1.35 + //
1.36 + // for_round_style<RoundStyle,RoundToZero,RoundToNearest,RoundToInf,RoundToNegInf>::type
1.37 + //
1.38 + // {RoundStyle} Integral Constant specifying a round style as declared above.
1.39 + // {RoundToZero,RoundToNearest,RoundToInf,RoundToNegInf} arbitrary types.
1.40 + //
1.41 + // Selects one of the 4 types according to the value of RoundStyle.
1.42 + //
1.43 + template<class RoundStyle,class RoundToZero,class RoundToNearest,class RoundToInf,class RoundToNegInf>
1.44 + struct for_round_style
1.45 + {
1.46 + typedef ct_switch4<RoundStyle
1.47 + , round2zero_c, round2nearest_c, round2inf_c // round2neg_inf_c
1.48 + , RoundToZero , RoundToNearest , RoundToInf , RoundToNegInf
1.49 + > selector ;
1.50 +
1.51 + typedef typename selector::type type ;
1.52 + } ;
1.53 +
1.54 +
1.55 +
1.56 +
1.57 +
1.58 +
1.59 +
1.60 +
1.61 +
1.62 +
1.63 +
1.64 +
1.65 +
1.66 +
1.67 +
1.68 +
1.69 +
1.70 +
1.71 +//--------------------------------------------------------------------------
1.72 +// Range Checking Logic.
1.73 +//
1.74 +// The range checking logic is built up by combining 1 or 2 predicates.
1.75 +// Each predicate is encapsulated in a template class and exposes
1.76 +// the static member function 'apply'.
1.77 +//
1.78 +//--------------------------------------------------------------------------
1.79 +
1.80 +
1.81 + // Because a particular logic can combine either 1 or two predicates, the following
1.82 + // tags are used to allow the predicate applier to receive 2 preds, but optimize away
1.83 + // one of them if it is 'non-applicable'
1.84 + struct non_applicable { typedef mpl::false_ do_apply ; } ;
1.85 + struct applicable { typedef mpl::true_ do_apply ; } ;
1.86 +
1.87 +
1.88 + //--------------------------------------------------------------------------
1.89 + //
1.90 + // Range Checking Logic implementations.
1.91 + //
1.92 + // The following classes, collectivelly named 'Predicates', are instantiated within
1.93 + // the corresponding range checkers.
1.94 + // Their static member function 'apply' is called to perform the actual range checking logic.
1.95 + //--------------------------------------------------------------------------
1.96 +
1.97 + // s < Lowest(T) ? cNegOverflow : cInRange
1.98 + //
1.99 + template<class Traits>
1.100 + struct LT_LoT : applicable
1.101 + {
1.102 + typedef typename Traits::target_type T ;
1.103 + typedef typename Traits::source_type S ;
1.104 + typedef typename Traits::argument_type argument_type ;
1.105 +
1.106 + static range_check_result apply ( argument_type s )
1.107 + {
1.108 + return s < static_cast<S>(bounds<T>::lowest()) ? cNegOverflow : cInRange ;
1.109 + }
1.110 + } ;
1.111 +
1.112 + // s < 0 ? cNegOverflow : cInRange
1.113 + //
1.114 + template<class Traits>
1.115 + struct LT_Zero : applicable
1.116 + {
1.117 + typedef typename Traits::source_type S ;
1.118 + typedef typename Traits::argument_type argument_type ;
1.119 +
1.120 + static range_check_result apply ( argument_type s )
1.121 + {
1.122 + return s < static_cast<S>(0) ? cNegOverflow : cInRange ;
1.123 + }
1.124 + } ;
1.125 +
1.126 + // s <= Lowest(T)-1 ? cNegOverflow : cInRange
1.127 + //
1.128 + template<class Traits>
1.129 + struct LE_PrevLoT : applicable
1.130 + {
1.131 + typedef typename Traits::target_type T ;
1.132 + typedef typename Traits::source_type S ;
1.133 + typedef typename Traits::argument_type argument_type ;
1.134 +
1.135 + static range_check_result apply ( argument_type s )
1.136 + {
1.137 + return s <= static_cast<S>(bounds<T>::lowest()) - static_cast<S>(1.0)
1.138 + ? cNegOverflow : cInRange ;
1.139 + }
1.140 + } ;
1.141 +
1.142 + // s < Lowest(T)-0.5 ? cNegOverflow : cInRange
1.143 + //
1.144 + template<class Traits>
1.145 + struct LT_HalfPrevLoT : applicable
1.146 + {
1.147 + typedef typename Traits::target_type T ;
1.148 + typedef typename Traits::source_type S ;
1.149 + typedef typename Traits::argument_type argument_type ;
1.150 +
1.151 + static range_check_result apply ( argument_type s )
1.152 + {
1.153 + return s < static_cast<S>(bounds<T>::lowest()) - static_cast<S>(0.5)
1.154 + ? cNegOverflow : cInRange ;
1.155 + }
1.156 + } ;
1.157 +
1.158 + // s > Highest(T) ? cPosOverflow : cInRange
1.159 + //
1.160 + template<class Traits>
1.161 + struct GT_HiT : applicable
1.162 + {
1.163 + typedef typename Traits::target_type T ;
1.164 + typedef typename Traits::source_type S ;
1.165 + typedef typename Traits::argument_type argument_type ;
1.166 +
1.167 + static range_check_result apply ( argument_type s )
1.168 + {
1.169 + return s > static_cast<S>(bounds<T>::highest())
1.170 + ? cPosOverflow : cInRange ;
1.171 + }
1.172 + } ;
1.173 +
1.174 + // s >= Lowest(T) + 1 ? cPosOverflow : cInRange
1.175 + //
1.176 + template<class Traits>
1.177 + struct GE_SuccHiT : applicable
1.178 + {
1.179 + typedef typename Traits::target_type T ;
1.180 + typedef typename Traits::source_type S ;
1.181 + typedef typename Traits::argument_type argument_type ;
1.182 +
1.183 + static range_check_result apply ( argument_type s )
1.184 + {
1.185 + return s >= static_cast<S>(bounds<T>::highest()) + static_cast<S>(1.0)
1.186 + ? cPosOverflow : cInRange ;
1.187 + }
1.188 + } ;
1.189 +
1.190 + // s >= Lowest(T) + 0.5 ? cPosgOverflow : cInRange
1.191 + //
1.192 + template<class Traits>
1.193 + struct GT_HalfSuccHiT : applicable
1.194 + {
1.195 + typedef typename Traits::target_type T ;
1.196 + typedef typename Traits::source_type S ;
1.197 + typedef typename Traits::argument_type argument_type ;
1.198 +
1.199 + static range_check_result apply ( argument_type s )
1.200 + {
1.201 + return s >= static_cast<S>(bounds<T>::highest()) + static_cast<S>(0.5)
1.202 + ? cPosOverflow : cInRange ;
1.203 + }
1.204 + } ;
1.205 +
1.206 +
1.207 + //--------------------------------------------------------------------------
1.208 + //
1.209 + // Predicate Combiner.
1.210 + //
1.211 + // This helper classes are used to possibly combine the range checking logic
1.212 + // individually performed by the predicates
1.213 + //
1.214 + //--------------------------------------------------------------------------
1.215 +
1.216 +
1.217 + // Applies both predicates: first 'PredA', and if it equals 'cInRange', 'PredB'
1.218 + template<class PredA, class PredB>
1.219 + struct applyBoth
1.220 + {
1.221 + typedef typename PredA::argument_type argument_type ;
1.222 +
1.223 + static range_check_result apply ( argument_type s )
1.224 + {
1.225 + range_check_result r = PredA::apply(s) ;
1.226 + if ( r == cInRange )
1.227 + r = PredB::apply(s);
1.228 + return r ;
1.229 + }
1.230 + } ;
1.231 +
1.232 + template<class PredA, class PredB>
1.233 + struct combine
1.234 + {
1.235 + typedef applyBoth<PredA,PredB> Both ;
1.236 + typedef void NNone ; // 'None' is defined as a macro in (/usr/X11R6/include/X11/X.h)
1.237 +
1.238 + typedef typename PredA::do_apply do_applyA ;
1.239 + typedef typename PredB::do_apply do_applyB ;
1.240 +
1.241 + typedef typename for_both<do_applyA, do_applyB, Both, PredA, PredB, NNone>::type type ;
1.242 + } ;
1.243 +
1.244 +
1.245 +
1.246 +
1.247 +
1.248 +
1.249 +
1.250 +
1.251 +
1.252 +
1.253 +
1.254 +
1.255 +//--------------------------------------------------------------------------
1.256 +// Range Checker classes.
1.257 +//
1.258 +// The following classes are VISIBLE base classes of the user-level converter<> class.
1.259 +// They supply the optimized 'out_of_range()' and 'validate_range()' static member functions
1.260 +// visible in the user interface.
1.261 +//
1.262 +//--------------------------------------------------------------------------
1.263 +
1.264 + // Dummy range checker.
1.265 + template<class Traits>
1.266 + struct dummy_range_checker
1.267 + {
1.268 + typedef typename Traits::argument_type argument_type ;
1.269 +
1.270 + static range_check_result out_of_range ( argument_type ) { return cInRange ; }
1.271 + static void validate_range ( argument_type ) {}
1.272 + } ;
1.273 +
1.274 + // Generic range checker.
1.275 + //
1.276 + // All the range checking logic for all possible combinations of source and target
1.277 + // can be arranged in terms of one or two predicates, which test overflow on both neg/pos 'sides'
1.278 + // of the ranges.
1.279 + //
1.280 + // These predicates are given here as IsNegOverflow and IsPosOverflow.
1.281 + //
1.282 + template<class Traits, class IsNegOverflow, class IsPosOverflow, class OverflowHandler>
1.283 + struct generic_range_checker
1.284 + {
1.285 + typedef OverflowHandler overflow_handler ;
1.286 +
1.287 + typedef typename Traits::argument_type argument_type ;
1.288 +
1.289 + static range_check_result out_of_range ( argument_type s )
1.290 + {
1.291 + typedef typename combine<IsNegOverflow,IsPosOverflow>::type Predicate ;
1.292 +
1.293 + return Predicate::apply(s);
1.294 + }
1.295 +
1.296 + static void validate_range ( argument_type s )
1.297 + { OverflowHandler()( out_of_range(s) ) ; }
1.298 + } ;
1.299 +
1.300 +
1.301 +
1.302 +//--------------------------------------------------------------------------
1.303 +//
1.304 +// Selectors for the optimized Range Checker class.
1.305 +//
1.306 +//--------------------------------------------------------------------------
1.307 +
1.308 + template<class Traits,class OverflowHandler>
1.309 + struct GetRC_Sig2Sig_or_Unsig2Unsig
1.310 + {
1.311 + typedef dummy_range_checker<Traits> Dummy ;
1.312 +
1.313 + typedef LT_LoT<Traits> Pred1 ;
1.314 + typedef GT_HiT<Traits> Pred2 ;
1.315 +
1.316 + typedef generic_range_checker<Traits,Pred1,Pred2,OverflowHandler> Normal ;
1.317 +
1.318 + typedef typename Traits::subranged subranged ;
1.319 +
1.320 + typedef typename mpl::if_<subranged,Normal,Dummy>::type type ;
1.321 + } ;
1.322 +
1.323 + template<class Traits, class OverflowHandler>
1.324 + struct GetRC_Sig2Unsig
1.325 + {
1.326 + typedef LT_Zero<Traits> Pred1 ;
1.327 + typedef GT_HiT <Traits> Pred2 ;
1.328 +
1.329 + typedef generic_range_checker<Traits,Pred1,Pred2,OverflowHandler> ChoiceA ;
1.330 +
1.331 + typedef generic_range_checker<Traits,Pred1,non_applicable,OverflowHandler> ChoiceB ;
1.332 +
1.333 + typedef typename Traits::target_type T ;
1.334 + typedef typename Traits::source_type S ;
1.335 +
1.336 + typedef typename subranged_Unsig2Sig<S,T>::type oposite_subranged ;
1.337 +
1.338 + typedef typename mpl::not_<oposite_subranged>::type positively_subranged ;
1.339 +
1.340 + typedef typename mpl::if_<positively_subranged,ChoiceA,ChoiceB>::type type ;
1.341 + } ;
1.342 +
1.343 + template<class Traits, class OverflowHandler>
1.344 + struct GetRC_Unsig2Sig
1.345 + {
1.346 + typedef GT_HiT<Traits> Pred1 ;
1.347 +
1.348 + typedef generic_range_checker<Traits,non_applicable,Pred1,OverflowHandler> type ;
1.349 + } ;
1.350 +
1.351 + template<class Traits,class OverflowHandler>
1.352 + struct GetRC_Int2Int
1.353 + {
1.354 + typedef GetRC_Sig2Sig_or_Unsig2Unsig<Traits,OverflowHandler> Sig2SigQ ;
1.355 + typedef GetRC_Sig2Unsig <Traits,OverflowHandler> Sig2UnsigQ ;
1.356 + typedef GetRC_Unsig2Sig <Traits,OverflowHandler> Unsig2SigQ ;
1.357 + typedef Sig2SigQ Unsig2UnsigQ ;
1.358 +
1.359 + typedef typename Traits::sign_mixture sign_mixture ;
1.360 +
1.361 + typedef typename
1.362 + for_sign_mixture<sign_mixture,Sig2SigQ,Sig2UnsigQ,Unsig2SigQ,Unsig2UnsigQ>::type
1.363 + selector ;
1.364 +
1.365 + typedef typename selector::type type ;
1.366 + } ;
1.367 +
1.368 + template<class Traits>
1.369 + struct GetRC_Int2Float
1.370 + {
1.371 + typedef dummy_range_checker<Traits> type ;
1.372 + } ;
1.373 +
1.374 + template<class Traits, class OverflowHandler, class Float2IntRounder>
1.375 + struct GetRC_Float2Int
1.376 + {
1.377 + typedef LE_PrevLoT <Traits> Pred1 ;
1.378 + typedef GE_SuccHiT <Traits> Pred2 ;
1.379 + typedef LT_HalfPrevLoT<Traits> Pred3 ;
1.380 + typedef GT_HalfSuccHiT<Traits> Pred4 ;
1.381 + typedef GT_HiT <Traits> Pred5 ;
1.382 + typedef LT_LoT <Traits> Pred6 ;
1.383 +
1.384 + typedef generic_range_checker<Traits,Pred1,Pred2,OverflowHandler> ToZero ;
1.385 + typedef generic_range_checker<Traits,Pred3,Pred4,OverflowHandler> ToNearest ;
1.386 + typedef generic_range_checker<Traits,Pred1,Pred5,OverflowHandler> ToInf ;
1.387 + typedef generic_range_checker<Traits,Pred6,Pred2,OverflowHandler> ToNegInf ;
1.388 +
1.389 + typedef typename Float2IntRounder::round_style round_style ;
1.390 +
1.391 + typedef typename for_round_style<round_style,ToZero,ToNearest,ToInf,ToNegInf>::type type ;
1.392 + } ;
1.393 +
1.394 + template<class Traits, class OverflowHandler>
1.395 + struct GetRC_Float2Float
1.396 + {
1.397 + typedef dummy_range_checker<Traits> Dummy ;
1.398 +
1.399 + typedef LT_LoT<Traits> Pred1 ;
1.400 + typedef GT_HiT<Traits> Pred2 ;
1.401 +
1.402 + typedef generic_range_checker<Traits,Pred1,Pred2,OverflowHandler> Normal ;
1.403 +
1.404 + typedef typename Traits::subranged subranged ;
1.405 +
1.406 + typedef typename mpl::if_<subranged,Normal,Dummy>::type type ;
1.407 + } ;
1.408 +
1.409 + template<class Traits, class OverflowHandler, class Float2IntRounder>
1.410 + struct GetRC_BuiltIn2BuiltIn
1.411 + {
1.412 + typedef GetRC_Int2Int<Traits,OverflowHandler> Int2IntQ ;
1.413 + typedef GetRC_Int2Float<Traits> Int2FloatQ ;
1.414 + typedef GetRC_Float2Int<Traits,OverflowHandler,Float2IntRounder> Float2IntQ ;
1.415 + typedef GetRC_Float2Float<Traits,OverflowHandler> Float2FloatQ ;
1.416 +
1.417 + typedef typename Traits::int_float_mixture int_float_mixture ;
1.418 +
1.419 + typedef typename for_int_float_mixture<int_float_mixture, Int2IntQ, Int2FloatQ, Float2IntQ, Float2FloatQ>::type selector ;
1.420 +
1.421 + typedef typename selector::type type ;
1.422 + } ;
1.423 +
1.424 + template<class Traits, class OverflowHandler, class Float2IntRounder>
1.425 + struct GetRC
1.426 + {
1.427 + typedef GetRC_BuiltIn2BuiltIn<Traits,OverflowHandler,Float2IntRounder> BuiltIn2BuiltInQ ;
1.428 +
1.429 + typedef dummy_range_checker<Traits> Dummy ;
1.430 +
1.431 + typedef mpl::identity<Dummy> DummyQ ;
1.432 +
1.433 + typedef typename Traits::udt_builtin_mixture udt_builtin_mixture ;
1.434 +
1.435 + typedef typename for_udt_builtin_mixture<udt_builtin_mixture,BuiltIn2BuiltInQ,DummyQ,DummyQ,DummyQ>::type selector ;
1.436 +
1.437 + typedef typename selector::type type ;
1.438 + } ;
1.439 +
1.440 +
1.441 +
1.442 +
1.443 +//--------------------------------------------------------------------------
1.444 +// Converter classes.
1.445 +//
1.446 +// The following classes are VISIBLE base classes of the user-level converter<> class.
1.447 +// They supply the optimized 'nearbyint()' and 'convert()' static member functions
1.448 +// visible in the user interface.
1.449 +//
1.450 +//--------------------------------------------------------------------------
1.451 +
1.452 + //
1.453 + // Trivial Converter : used when (cv-unqualified) T == (cv-unqualified) S
1.454 + //
1.455 + template<class Traits>
1.456 + struct trivial_converter_impl : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
1.457 + ,BOOST_DEDUCED_TYPENAME Traits::result_type
1.458 + >
1.459 + ,public dummy_range_checker<Traits>
1.460 + {
1.461 + typedef Traits traits ;
1.462 +
1.463 + typedef typename Traits::source_type source_type ;
1.464 + typedef typename Traits::argument_type argument_type ;
1.465 + typedef typename Traits::result_type result_type ;
1.466 +
1.467 + static result_type low_level_convert ( argument_type s ) { return s ; }
1.468 + static source_type nearbyint ( argument_type s ) { return s ; }
1.469 + static result_type convert ( argument_type s ) { return s ; }
1.470 + } ;
1.471 +
1.472 +
1.473 + //
1.474 + // Rounding Converter : used for float to integral conversions.
1.475 + //
1.476 + template<class Traits,class RangeChecker,class RawConverter,class Float2IntRounder>
1.477 + struct rounding_converter : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
1.478 + ,BOOST_DEDUCED_TYPENAME Traits::result_type
1.479 + >
1.480 + ,public RangeChecker
1.481 + ,public Float2IntRounder
1.482 + ,public RawConverter
1.483 + {
1.484 + typedef RangeChecker RangeCheckerBase ;
1.485 + typedef Float2IntRounder Float2IntRounderBase ;
1.486 + typedef RawConverter RawConverterBase ;
1.487 +
1.488 + typedef Traits traits ;
1.489 +
1.490 + typedef typename Traits::source_type source_type ;
1.491 + typedef typename Traits::argument_type argument_type ;
1.492 + typedef typename Traits::result_type result_type ;
1.493 +
1.494 + static result_type convert ( argument_type s )
1.495 + {
1.496 + RangeCheckerBase::validate_range(s);
1.497 + source_type s1 = Float2IntRounderBase::nearbyint(s);
1.498 + return RawConverterBase::low_level_convert(s1);
1.499 + }
1.500 + } ;
1.501 +
1.502 +
1.503 + //
1.504 + // Non-Rounding Converter : used for all other conversions.
1.505 + //
1.506 + template<class Traits,class RangeChecker,class RawConverter>
1.507 + struct non_rounding_converter : public std::unary_function< BOOST_DEDUCED_TYPENAME Traits::argument_type
1.508 + ,BOOST_DEDUCED_TYPENAME Traits::result_type
1.509 + >
1.510 + ,public RangeChecker
1.511 + ,public RawConverter
1.512 + {
1.513 + typedef RangeChecker RangeCheckerBase ;
1.514 + typedef RawConverter RawConverterBase ;
1.515 +
1.516 + typedef Traits traits ;
1.517 +
1.518 + typedef typename Traits::source_type source_type ;
1.519 + typedef typename Traits::argument_type argument_type ;
1.520 + typedef typename Traits::result_type result_type ;
1.521 +
1.522 + static source_type nearbyint ( argument_type s ) { return s ; }
1.523 +
1.524 + static result_type convert ( argument_type s )
1.525 + {
1.526 + RangeCheckerBase::validate_range(s);
1.527 + return RawConverterBase::low_level_convert(s);
1.528 + }
1.529 + } ;
1.530 +
1.531 +
1.532 +
1.533 +
1.534 +//--------------------------------------------------------------------------
1.535 +//
1.536 +// Selectors for the optimized Converter class.
1.537 +//
1.538 +//--------------------------------------------------------------------------
1.539 +
1.540 + template<class Traits,class OverflowHandler,class Float2IntRounder,class RawConverter, class UserRangeChecker>
1.541 + struct get_non_trivial_converter
1.542 + {
1.543 + typedef GetRC<Traits,OverflowHandler,Float2IntRounder> InternalRangeCheckerQ ;
1.544 +
1.545 + typedef is_same<UserRangeChecker,UseInternalRangeChecker> use_internal_RC ;
1.546 +
1.547 + typedef mpl::identity<UserRangeChecker> UserRangeCheckerQ ;
1.548 +
1.549 + typedef typename
1.550 + mpl::eval_if<use_internal_RC,InternalRangeCheckerQ,UserRangeCheckerQ>::type
1.551 + RangeChecker ;
1.552 +
1.553 + typedef non_rounding_converter<Traits,RangeChecker,RawConverter> NonRounding ;
1.554 + typedef rounding_converter<Traits,RangeChecker,RawConverter,Float2IntRounder> Rounding ;
1.555 +
1.556 + typedef mpl::identity<NonRounding> NonRoundingQ ;
1.557 + typedef mpl::identity<Rounding> RoundingQ ;
1.558 +
1.559 + typedef typename Traits::int_float_mixture int_float_mixture ;
1.560 +
1.561 + typedef typename
1.562 + for_int_float_mixture<int_float_mixture, NonRoundingQ, NonRoundingQ, RoundingQ, NonRoundingQ>::type
1.563 + selector ;
1.564 +
1.565 + typedef typename selector::type type ;
1.566 + } ;
1.567 +
1.568 + template< class Traits
1.569 + ,class OverflowHandler
1.570 + ,class Float2IntRounder
1.571 + ,class RawConverter
1.572 + ,class UserRangeChecker
1.573 + >
1.574 + struct get_converter_impl
1.575 + {
1.576 +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT( 0x0561 ) )
1.577 + // bcc55 prefers sometimes template parameters to be explicit local types.
1.578 + // (notice that is is illegal to reuse the names like this)
1.579 + typedef Traits Traits ;
1.580 + typedef OverflowHandler OverflowHandler ;
1.581 + typedef Float2IntRounder Float2IntRounder ;
1.582 + typedef RawConverter RawConverter ;
1.583 + typedef UserRangeChecker UserRangeChecker ;
1.584 +#endif
1.585 +
1.586 + typedef trivial_converter_impl<Traits> Trivial ;
1.587 + typedef mpl::identity <Trivial> TrivialQ ;
1.588 +
1.589 + typedef get_non_trivial_converter< Traits
1.590 + ,OverflowHandler
1.591 + ,Float2IntRounder
1.592 + ,RawConverter
1.593 + ,UserRangeChecker
1.594 + > NonTrivialQ ;
1.595 +
1.596 + typedef typename Traits::trivial trivial ;
1.597 +
1.598 + typedef typename mpl::eval_if<trivial,TrivialQ,NonTrivialQ>::type type ;
1.599 + } ;
1.600 +
1.601 +} } } // namespace boost::numeric::convdetail
1.602 +
1.603 +#endif
1.604 +
1.605 +