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 + -
显示快捷键?