⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 numerics.hpp

📁 著名的Parser库Spirit在VC6上的Port
💻 HPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
// predefined unsigned integer parsers
const uint_parser_gen<2>    ubin_p = uint_parser_gen<2>();
const uint_parser_gen<8>    uoct_p = uint_parser_gen<8>();
const uint_parser_gen<10>   uint_p = uint_parser_gen<10>();
const uint_parser_gen<16>   uhex_p = uint_parser_gen<16>();

///////////////////////////////////////////////////////////////////////////////
//
//  int_parser class
//
//      Parses signed integers. An int_parser is never directly
//      instantiated. An instance of the int_parser_gen, int_p,
//      generates an int_parser through its [] operator:
//
//          int_p[f]
//
//      where f is a semantic action which may be a function or a
//      functor. A function should be compatible with the interface:
//
//          void f(NumT num);
//
//      A functor should have a member operator() with a compatible
//      signature as above. The matching number is passed into the
//      function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename T = int, const int Radix = 10>
struct int_parser : public parser<int_parser<T, Radix> > {

    typedef typename impl::IF<is_reference_wrapper<T>::value,
              typename unwrap_reference_wrapper<T>::type&,
	      T>::RET actual_type;

    int_parser(actual_type n_)
    :   n(n_) {}

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
    { 
       n = 0;
       if (first == last)
           return match();
   
       typedef typename impl::strip_scanner<IteratorT>
           ::iterator_type plain_iter;
       plain_iter  i1 = impl::strip_scanner<IteratorT>::get(first);
       plain_iter  i2 = impl::strip_scanner<IteratorT>::get(last);
   
       unsigned    count;
       bool        neg = impl::extract_sign(i1, count);
   
       bool matched = impl::extract<Radix>::sint(i1, i2, n, count, neg);
       match hit = match(count);
   
       if (matched && hit)
       {
           if (neg) n = -n;
           first = i1;
           return match(hit.length() + count);
       }
       return match();
    }

   mutable actual_type n;
 };


///////////////////////////////////////////////////////////////////////////////
template <const int Radix>
struct int_parser_gen : public int_parser<int, Radix> {

    int_parser_gen()
    :   int_parser<int, Radix>(0) {}

    template <typename T>
    typename int_numeric_action_traits<T, void (*)(T), Radix>::int_action
    operator [] (void (*actor)(T)) const
    {
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename int_numeric_action_traits<T, void(*)(T), Radix>::int_action 
            action_t;
        return action_t(actor);
    }

    template <typename T>
    typename int_numeric_action_traits<typename unwrap_reference_wrapper<T>::type,
              T, Radix>::int_action
    operator [] (T const& actor) const
    {
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename int_numeric_action_traits<unwrap_reference_wrapper<T>::type,
	                T, Radix>::int_action  action_t;
        return action_t(actor);
    }
};

///////////////////////////////////////////////////////////////////////////////
// predefined signed integer parsers
const int_parser_gen<2>     bin_p = int_parser_gen<2>();
const int_parser_gen<8>     oct_p = int_parser_gen<8>();
const int_parser_gen<10>    int_p = int_parser_gen<10>();
const int_parser_gen<16>    hex_p = int_parser_gen<16>();

///////////////////////////////////////////////////////////////////////////////
//
//  ureal_parser class
//
//      Parses unsigned reals. A ureal_parser is never directly
//      instantiated. An instance of the ureal_parser_gen, ureal_p,
//      generates a ureal_parser through its [] operator:
//
//          ureal_p[f]
//
//      where f is a semantic action which may be a function or a
//      functor. A function should be compatible with the interface:
//
//          void f(NumT num);
//
//      A functor should have a member operator() with a compatible
//      signature as above. The matching number is passed into the
//      function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename FloatT = double, typename TraitsT = numeric_parser_traits<> >
struct ureal_parser :
    public parser<
            ureal_parser< FloatT, TraitsT >
	    > 
{
    typedef typename impl::IF<is_reference_wrapper<FloatT>::value,
              typename unwrap_reference_wrapper<FloatT>::type&,
	      FloatT>::RET actual_type;

    ureal_parser(actual_type n_)
    :   n(n_) {}

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
    {
       n = 0;
       if (first == last)
          return match();
   
       typedef typename impl::strip_scanner<IteratorT>
           ::iterator_type plain_iter;
       plain_iter  i1 = impl::strip_scanner<IteratorT>::get(first);
       plain_iter  i2 = impl::strip_scanner<IteratorT>::get(last);
       plain_iter    ittemp = i1;
       unsigned    counttemp = 0;
   
       if (!(isdigit(*ittemp) || 
                   impl::traits_cmp<TraitsT>::is_ds(ittemp, i2, counttemp)))
           return match();
   
       unsigned    count = 0;
       unsigned    frac = 0;
   
       ittemp = i1;
       if (!impl::traits_cmp<TraitsT>::is_ds(ittemp, i2, count))
       {
           assert(0 == count);
           assert(ittemp == i1);
   
           //  Extract the digits before the decimal point: nnn.
           if (!impl::extract<10, TraitsT>::uint(ittemp, i2, n, count))
               return match();        // overflow, return non-match
           if (i1 == i2)
           {
               first = i1;
               return match(count);
           }
           i1 = ittemp;            // advance start position
       } 
       else
           count = 0;
   
       if (impl::traits_cmp<TraitsT>::is_ds(i1, i2, count))
       {
           //  Extract the digits after the decimal point .nnn
           if (!impl::extract<10>::uint(i1, i2, n, frac))
               return match();        // overflow, return non-match
           count += frac;
       }
       // Extract the exponent
       match   hit(count);
       int     exp = 0;
   
       if (impl::traits_cmp<TraitsT>::is_exp(i1, i2, count)) {
           hit = match(count);
           if (match mexp = int_p[ref(exp)].parse(i1, i2))
               hit += mexp;
       }


       typedef typename boost::remove_reference<FloatT>::type ref_type;
       typedef typename unwrap_reference_wrapper<ref_type>::type non_ref_type;
       typedef typename remove_wrap<non_ref_type>::type arg_type;
       //typedef typename remove_wrap<ref_type>::type arg_type;
   
       n *= impl::real_traits<arg_type>::pow(10, exp - int(frac));
       first = i1;
       return hit;
   }


    mutable actual_type n;
     
};

///////////////////////////////////////////////////////////////////////////////
//
template <typename TraitsT = numeric_parser_traits<> >
struct ureal_parser_gen :
    public ureal_parser<double, TraitsT>
{
    ureal_parser_gen()
    :   ureal_parser<double, TraitsT>(0) {}

    template <typename T>
    typename real_numeric_action_traits<T, void (*)(T), TraitsT>::ureal_action
    operator [] (void (*actor)(T)) const
    {
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename real_numeric_action_traits<T, void(*)(T), TraitsT>::ureal_action 
            action_t;
        return action_t(actor);
    }

    template <typename T>
    typename real_numeric_action_traits< typename unwrap_reference_wrapper<T>::type,
              T, TraitsT>::ureal_action
    operator [] (T const& actor) const
    {
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename real_numeric_action_traits<
	        unwrap_reference_wrapper<T>::type,T, TraitsT
		>::ureal_action  action_t ;
        return action_t(actor);
    }

// Helper function for specifying a numeric_parser_traits type when using
// the predefined parser ureal_p. Now we could write ureal_p(mytraits())[...],
// where 'mytraits' is a class, which defines the same names as the
// 'numeric_parser_traits' template.
    template <typename NewTraitsT>
    ureal_parser_gen<NewTraitsT>
    operator ()(NewTraitsT) const
    {
        return ureal_parser_gen<NewTraitsT>();
    }
};

///////////////////////////////////////////////////////////////////////////////
// Predefined unsigned floating point parser
//
// The underlying base type (float, double etc.) is selected automatically at
// compile time through the type accociated with the attached semantic action.
// If no sematic action is used, double will be selected.
const ureal_parser_gen<> ureal_p = ureal_parser_gen<>();

///////////////////////////////////////////////////////////////////////////////
//
//  real_parser class
//
//      Parses signed reals. A real_parser is never directly
//      instantiated. An instance of the real_parser_gen, real_p,
//      generates a real_parser through its [] operator:
//
//          real_p[f]
//
//      where f is a semantic action which may be a function or a
//      functor. A function should be compatible with the interface:
//
//          void f(NumT num);
//
//      A functor should have a member operator() with a compatible
//      signature as above. The matching number is passed into the
//      function/functor (see numeric_action class above).
//
///////////////////////////////////////////////////////////////////////////////
template <typename FloatT = double , typename TraitsT = numeric_parser_traits<> >
struct real_parser :
    public parser<
            real_parser< FloatT, TraitsT>
            >
{
    typedef typename impl::IF<is_reference_wrapper<FloatT>::value,
              typename unwrap_reference_wrapper<FloatT>::type&,
	      FloatT>::RET actual_type;

    real_parser(actual_type n_)
    :   n(n_) {}

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
   {
       n = 0;
       if (first == last)
           return match();
   
       typedef typename impl::strip_scanner<IteratorT>
           ::iterator_type plain_iter;
       plain_iter  i1 = impl::strip_scanner<IteratorT>::get(first);
       plain_iter  i2 = impl::strip_scanner<IteratorT>::get(last);
   
       unsigned    count;
       bool        neg = impl::extract_sign(i1, count);
       ureal_parser_gen<TraitsT> parse_ureal;
   
       if (match hit = parse_ureal[ref(n)].parse(i1, i2))
       {
           if (neg) n = -n;
           first = i1;
           return match(hit.length() + count);
       }
       return match();
   }

    mutable actual_type n;
    //mutable FloatT n;
};

///////////////////////////////////////////////////////////////////////////////
template <typename TraitsT = numeric_parser_traits<> >
struct real_parser_gen :
    public real_parser<double, TraitsT>
{
    real_parser_gen()
    :   real_parser<double, TraitsT>(0) {}

    template <typename T>
    typename real_numeric_action_traits<T, void (*)(T), TraitsT>::real_action
    operator [] (void (*actor)(T)) const
    {
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename real_numeric_action_traits<T, void(*)(T) ,TraitsT>::real_action 
            action_t;
        return action_t(actor);
    }

    template <typename T>
    typename real_numeric_action_traits<typename unwrap_reference_wrapper<T>::type, 
             T, TraitsT>::real_action
    operator [] (T const& actor) const
    {
        //functors and reference_wrappers will fall through here  
        //  Borland 5.5 reports an internal compiler
        //  error if this is not defined here.
        typedef typename real_numeric_action_traits<
		unwrap_reference_wrapper<T>::type, T, TraitsT
		>::real_action  action_t ;
        return action_t(actor);
    }


// Helper function for specifying a numeric_parser_traits type when using
// the predefined parser real_p. Now we could write real_p(mytraits())[...],
// where 'mytraits' is a class, which defines the same names as the
// 'numeric_parser_traits' template.
    template <typename NewTraitsT>
    real_parser_gen<NewTraitsT>
    operator ()(NewTraitsT) const
    {
        return real_parser_gen<NewTraitsT>();
    }
};

///////////////////////////////////////////////////////////////////////////////
// Predefined signed floating point parser
//
// The underlying base type (float, double etc.) is selected automatically at
// compile time through the type associated with the attached semantic action.
// If no sematic action is used, double will be selected.
const real_parser_gen<> real_p = real_parser_gen<>();

///////////////////////////////////////////////////////////////////////////////
}   //  namespace Spirit

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -