converter.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 603 行 · 第 1/2 页
HPP
603 行
// (c) Copyright Fernando Luis Cacciola Carballal 2000-2004// Use, modification, and distribution is subject to the Boost Software// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// See library home page at http://www.boost.org/libs/numeric/conversion//// Contact the author at: fernando_cacciola@hotmail.com//#ifndef BOOST_NUMERIC_CONVERSION_DETAIL_CONVERTER_FLC_12NOV2002_HPP#define BOOST_NUMERIC_CONVERSION_DETAIL_CONVERTER_FLC_12NOV2002_HPP#include <functional>#include "boost/numeric/conversion/detail/meta.hpp"#include "boost/numeric/conversion/detail/conversion_traits.hpp"#include "boost/numeric/conversion/bounds.hpp"#include "boost/type_traits/is_same.hpp"#include "boost/mpl/integral_c.hpp"namespace boost { namespace numeric { namespace convdetail{ // Integral Constants representing rounding modes typedef mpl::integral_c<std::float_round_style, std::round_toward_zero> round2zero_c ; typedef mpl::integral_c<std::float_round_style, std::round_to_nearest> round2nearest_c ; typedef mpl::integral_c<std::float_round_style, std::round_toward_infinity> round2inf_c ; typedef mpl::integral_c<std::float_round_style, std::round_toward_neg_infinity> round2neg_inf_c ; // Metafunction: // // for_round_style<RoundStyle,RoundToZero,RoundToNearest,RoundToInf,RoundToNegInf>::type // // {RoundStyle} Integral Constant specifying a round style as declared above. // {RoundToZero,RoundToNearest,RoundToInf,RoundToNegInf} arbitrary types. // // Selects one of the 4 types according to the value of RoundStyle. // template<class RoundStyle,class RoundToZero,class RoundToNearest,class RoundToInf,class RoundToNegInf> struct for_round_style { typedef ct_switch4<RoundStyle , round2zero_c, round2nearest_c, round2inf_c // round2neg_inf_c , RoundToZero , RoundToNearest , RoundToInf , RoundToNegInf > selector ; typedef typename selector::type type ; } ;//--------------------------------------------------------------------------// Range Checking Logic.//// The range checking logic is built up by combining 1 or 2 predicates.// Each predicate is encapsulated in a template class and exposes// the static member function 'apply'.////-------------------------------------------------------------------------- // Because a particular logic can combine either 1 or two predicates, the following // tags are used to allow the predicate applier to receive 2 preds, but optimize away // one of them if it is 'non-applicable' struct non_applicable { typedef mpl::false_ do_apply ; } ; struct applicable { typedef mpl::true_ do_apply ; } ; //-------------------------------------------------------------------------- // // Range Checking Logic implementations. // // The following classes, collectivelly named 'Predicates', are instantiated within // the corresponding range checkers. // Their static member function 'apply' is called to perform the actual range checking logic. //-------------------------------------------------------------------------- // s < Lowest(T) ? cNegOverflow : cInRange // template<class Traits> struct LT_LoT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s < static_cast<S>(bounds<T>::lowest()) ? cNegOverflow : cInRange ; } } ; // s < 0 ? cNegOverflow : cInRange // template<class Traits> struct LT_Zero : applicable { typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s < static_cast<S>(0) ? cNegOverflow : cInRange ; } } ; // s <= Lowest(T)-1 ? cNegOverflow : cInRange // template<class Traits> struct LE_PrevLoT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s <= static_cast<S>(bounds<T>::lowest()) - static_cast<S>(1.0) ? cNegOverflow : cInRange ; } } ; // s < Lowest(T)-0.5 ? cNegOverflow : cInRange // template<class Traits> struct LT_HalfPrevLoT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s < static_cast<S>(bounds<T>::lowest()) - static_cast<S>(0.5) ? cNegOverflow : cInRange ; } } ; // s > Highest(T) ? cPosOverflow : cInRange // template<class Traits> struct GT_HiT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s > static_cast<S>(bounds<T>::highest()) ? cPosOverflow : cInRange ; } } ; // s >= Lowest(T) + 1 ? cPosOverflow : cInRange // template<class Traits> struct GE_SuccHiT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s >= static_cast<S>(bounds<T>::highest()) + static_cast<S>(1.0) ? cPosOverflow : cInRange ; } } ; // s >= Lowest(T) + 0.5 ? cPosgOverflow : cInRange // template<class Traits> struct GT_HalfSuccHiT : applicable { typedef typename Traits::target_type T ; typedef typename Traits::source_type S ; typedef typename Traits::argument_type argument_type ; static range_check_result apply ( argument_type s ) { return s >= static_cast<S>(bounds<T>::highest()) + static_cast<S>(0.5) ? cPosOverflow : cInRange ; } } ; //-------------------------------------------------------------------------- // // Predicate Combiner. // // This helper classes are used to possibly combine the range checking logic // individually performed by the predicates // //-------------------------------------------------------------------------- // Applies both predicates: first 'PredA', and if it equals 'cInRange', 'PredB' template<class PredA, class PredB> struct applyBoth { typedef typename PredA::argument_type argument_type ; static range_check_result apply ( argument_type s ) { range_check_result r = PredA::apply(s) ; if ( r == cInRange ) r = PredB::apply(s); return r ; } } ; template<class PredA, class PredB> struct combine { typedef applyBoth<PredA,PredB> Both ; typedef void NNone ; // 'None' is defined as a macro in (/usr/X11R6/include/X11/X.h) typedef typename PredA::do_apply do_applyA ; typedef typename PredB::do_apply do_applyB ; typedef typename for_both<do_applyA, do_applyB, Both, PredA, PredB, NNone>::type type ; } ;//--------------------------------------------------------------------------// Range Checker classes.//// The following classes are VISIBLE base classes of the user-level converter<> class.// They supply the optimized 'out_of_range()' and 'validate_range()' static member functions// visible in the user interface.////-------------------------------------------------------------------------- // Dummy range checker. template<class Traits> struct dummy_range_checker { typedef typename Traits::argument_type argument_type ; static range_check_result out_of_range ( argument_type ) { return cInRange ; } static void validate_range ( argument_type ) {} } ; // Generic range checker. // // All the range checking logic for all possible combinations of source and target // can be arranged in terms of one or two predicates, which test overflow on both neg/pos 'sides' // of the ranges. // // These predicates are given here as IsNegOverflow and IsPosOverflow. // template<class Traits, class IsNegOverflow, class IsPosOverflow, class OverflowHandler> struct generic_range_checker { typedef OverflowHandler overflow_handler ; typedef typename Traits::argument_type argument_type ; static range_check_result out_of_range ( argument_type s ) { typedef typename combine<IsNegOverflow,IsPosOverflow>::type Predicate ; return Predicate::apply(s); } static void validate_range ( argument_type s ) { OverflowHandler()( out_of_range(s) ) ; } } ;//--------------------------------------------------------------------------//// Selectors for the optimized Range Checker class.//
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?