Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:38

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM)
0007 #define BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/config/no_tr1/cmath.hpp>
0014 #include <boost/config.hpp>
0015 #include <boost/mpl/bool.hpp>
0016 #include <boost/utility/enable_if.hpp>
0017 #include <boost/spirit/home/support/common_terminals.hpp>
0018 #include <boost/spirit/home/support/string_traits.hpp>
0019 #include <boost/spirit/home/support/numeric_traits.hpp>
0020 #include <boost/spirit/home/support/info.hpp>
0021 #include <boost/spirit/home/support/char_class.hpp>
0022 #include <boost/spirit/home/support/container.hpp>
0023 #include <boost/spirit/home/support/detail/get_encoding.hpp>
0024 #include <boost/spirit/home/karma/meta_compiler.hpp>
0025 #include <boost/spirit/home/karma/char.hpp>
0026 #include <boost/spirit/home/karma/delimit_out.hpp>
0027 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0028 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
0029 #include <boost/spirit/home/karma/detail/extract_from.hpp>
0030 #include <boost/spirit/home/karma/detail/enable_lit.hpp>
0031 #include <boost/spirit/home/karma/domain.hpp>
0032 #include <boost/spirit/home/karma/numeric/real_policies.hpp>
0033 #include <boost/spirit/home/karma/numeric/detail/real_utils.hpp>
0034 #include <boost/fusion/include/at.hpp>
0035 #include <boost/fusion/include/value_at.hpp>
0036 #include <boost/fusion/include/vector.hpp>
0037 
0038 namespace boost { namespace spirit
0039 {
0040     namespace karma
0041     {
0042         ///////////////////////////////////////////////////////////////////////
0043         // forward declaration only
0044         template <typename T>
0045         struct real_policies;
0046 
0047         ///////////////////////////////////////////////////////////////////////
0048         // This is the class that the user can instantiate directly in
0049         // order to create a customized real generator
0050         template <typename T = double, typename Policies = real_policies<T> >
0051         struct real_generator
0052           : spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
0053         {
0054             typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
0055 
0056             real_generator() {}
0057             real_generator(Policies const& p)
0058               : spirit::terminal<tag_type>(p) {}
0059         };
0060     }
0061 
0062     ///////////////////////////////////////////////////////////////////////////
0063     // Enablers
0064     ///////////////////////////////////////////////////////////////////////////
0065     template <>
0066     struct use_terminal<karma::domain, tag::float_>       // enables float_
0067       : mpl::true_ {};
0068 
0069     template <>
0070     struct use_terminal<karma::domain, tag::double_>      // enables double_
0071       : mpl::true_ {};
0072 
0073     template <>
0074     struct use_terminal<karma::domain, tag::long_double>  // enables long_double
0075       : mpl::true_ {};
0076 
0077     ///////////////////////////////////////////////////////////////////////////
0078     template <>
0079     struct use_terminal<karma::domain, float>             // enables lit(1.0f)
0080       : mpl::true_ {};
0081 
0082     template <>
0083     struct use_terminal<karma::domain, double>            // enables lit(1.0)
0084       : mpl::true_ {};
0085 
0086     template <>
0087     struct use_terminal<karma::domain, long double>       // enables lit(1.0l)
0088       : mpl::true_ {};
0089 
0090     ///////////////////////////////////////////////////////////////////////////
0091     template <typename A0>
0092     struct use_terminal<karma::domain                   // enables float_(...)
0093       , terminal_ex<tag::float_, fusion::vector1<A0> >
0094     > : mpl::true_ {};
0095 
0096     template <typename A0>
0097     struct use_terminal<karma::domain                   // enables double_(...)
0098       , terminal_ex<tag::double_, fusion::vector1<A0> >
0099     > : mpl::true_ {};
0100 
0101     template <typename A0>
0102     struct use_terminal<karma::domain                   // enables long_double(...)
0103       , terminal_ex<tag::long_double, fusion::vector1<A0> >
0104     > : mpl::true_ {};
0105 
0106     // lazy float_(...), double_(...), long_double(...)
0107     template <>
0108     struct use_lazy_terminal<karma::domain, tag::float_, 1>
0109       : mpl::true_ {};
0110 
0111     template <>
0112     struct use_lazy_terminal<karma::domain, tag::double_, 1>
0113       : mpl::true_ {};
0114 
0115     template <>
0116     struct use_lazy_terminal<karma::domain, tag::long_double, 1>
0117       : mpl::true_ {};
0118 
0119     ///////////////////////////////////////////////////////////////////////////
0120     // enables custom real generator
0121     template <typename T, typename Policies>
0122     struct use_terminal<karma::domain
0123           , tag::stateful_tag<Policies, tag::double_, T> >
0124       : mpl::true_ {};
0125 
0126     template <typename T, typename Policies, typename A0>
0127     struct use_terminal<karma::domain
0128           , terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
0129           , fusion::vector1<A0> > >
0130       : mpl::true_ {};
0131 
0132     // enables *lazy* custom real generator
0133     template <typename T, typename Policies>
0134     struct use_lazy_terminal<
0135         karma::domain
0136       , tag::stateful_tag<Policies, tag::double_, T>
0137       , 1 // arity
0138     > : mpl::true_ {};
0139 
0140     // enables lit(double)
0141     template <typename A0>
0142     struct use_terminal<karma::domain
0143           , terminal_ex<tag::lit, fusion::vector1<A0> >
0144           , typename enable_if<traits::is_real<A0> >::type>
0145       : mpl::true_ {};
0146 }}
0147 
0148 ///////////////////////////////////////////////////////////////////////////////
0149 namespace boost { namespace spirit { namespace karma
0150 {
0151 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0152     using spirit::float_;
0153     using spirit::double_;
0154     using spirit::long_double;
0155 #endif
0156 
0157     using spirit::float_type;
0158     using spirit::double_type;
0159     using spirit::long_double_type;
0160 
0161     ///////////////////////////////////////////////////////////////////////////
0162     //  This specialization is used for real generators not having a direct
0163     //  initializer: float_, double_ etc. These generators must be used in
0164     //  conjunction with an attribute.
0165     ///////////////////////////////////////////////////////////////////////////
0166     template <
0167         typename T, typename Policies, typename CharEncoding, typename Tag>
0168     struct any_real_generator
0169       : primitive_generator<any_real_generator<T, Policies, CharEncoding, Tag> >
0170     {
0171         typedef typename Policies::properties properties;
0172 
0173         template <typename Context, typename Unused>
0174         struct attribute
0175         {
0176             typedef T type;
0177         };
0178 
0179         any_real_generator(Policies const& policies = Policies())
0180           : p_(policies) {}
0181 
0182         // double_/float_/etc. has an attached attribute
0183         template <typename OutputIterator, typename Context, typename Delimiter
0184           , typename Attribute>
0185         bool generate(OutputIterator& sink, Context& context
0186           , Delimiter const& d, Attribute const& attr) const
0187         {
0188             if (!traits::has_optional_value(attr))
0189                 return false;       // fail if it's an uninitialized optional
0190 
0191             typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
0192             return inserter_type::call(sink, traits::extract_from<T>(attr, context), p_) &&
0193                    karma::delimit_out(sink, d);    // always do post-delimiting
0194         }
0195 
0196         // this double_/float_/etc. has no attribute attached, it needs to have
0197         // been initialized from a direct literal
0198         template <typename OutputIterator, typename Context, typename Delimiter>
0199         static bool generate(OutputIterator&, Context&, Delimiter const&
0200           , unused_type)
0201         {
0202             // It is not possible (doesn't make sense) to use numeric generators
0203             // without providing any attribute, as the generator doesn't 'know'
0204             // what to output. The following assertion fires if this situation
0205             // is detected in your code.
0206             BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, real_not_usable_without_attribute, ());
0207             return false;
0208         }
0209 
0210         template <typename Context>
0211         static info what(Context const& /*context*/)
0212         {
0213             return info("real");
0214         }
0215 
0216         Policies p_;
0217     };
0218 
0219     ///////////////////////////////////////////////////////////////////////////
0220     //  This specialization is used for real generators having a direct
0221     //  initializer: float_(10.), double_(20.) etc.
0222     ///////////////////////////////////////////////////////////////////////////
0223     template <
0224         typename T, typename Policies, typename CharEncoding, typename Tag
0225       , bool no_attribute>
0226     struct literal_real_generator
0227       : primitive_generator<literal_real_generator<T, Policies, CharEncoding
0228           , Tag, no_attribute> >
0229     {
0230         typedef typename Policies::properties properties;
0231 
0232         template <typename Context, typename Unused = unused_type>
0233         struct attribute
0234           : mpl::if_c<no_attribute, unused_type, T>
0235         {};
0236 
0237         literal_real_generator(typename add_const<T>::type n
0238               , Policies const& policies = Policies())
0239           : n_(n), p_(policies) {}
0240 
0241         // A double_(1.0) which additionally has an associated attribute emits
0242         // its immediate literal only if it matches the attribute, otherwise
0243         // it fails.
0244         template <typename OutputIterator, typename Context, typename Delimiter
0245           , typename Attribute>
0246         bool generate(OutputIterator& sink, Context& context
0247           , Delimiter const& d, Attribute const& attr) const
0248         {
0249             typedef typename attribute<Context>::type attribute_type;
0250             if (!traits::has_optional_value(attr) ||
0251                 n_ != traits::extract_from<attribute_type>(attr, context))
0252             {
0253                 return false;
0254             }
0255 
0256             typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
0257             return inserter_type::call(sink, n_, p_) &&
0258                    karma::delimit_out(sink, d);    // always do post-delimiting
0259         }
0260 
0261         // A double_(1.0) without any associated attribute just emits its
0262         // immediate literal
0263         template <typename OutputIterator, typename Context, typename Delimiter>
0264         bool generate(OutputIterator& sink, Context&, Delimiter const& d
0265           , unused_type) const
0266         {
0267             typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
0268             return inserter_type::call(sink, n_, p_) &&
0269                    karma::delimit_out(sink, d);    // always do post-delimiting
0270         }
0271 
0272         template <typename Context>
0273         static info what(Context const& /*context*/)
0274         {
0275             return info("real");
0276         }
0277 
0278         T n_;
0279         Policies p_;
0280     };
0281 
0282     ///////////////////////////////////////////////////////////////////////////
0283     // Generator generators: make_xxx function (objects)
0284     ///////////////////////////////////////////////////////////////////////////
0285     namespace detail
0286     {
0287         template <typename T, typename Modifiers
0288           , typename Policies = real_policies<T> >
0289         struct make_real
0290         {
0291             static bool const lower =
0292                 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0293             static bool const upper =
0294                 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0295 
0296             typedef any_real_generator<
0297                 T, Policies
0298               , typename spirit::detail::get_encoding_with_case<
0299                     Modifiers, unused_type, lower || upper>::type
0300               , typename detail::get_casetag<Modifiers, lower || upper>::type
0301             > result_type;
0302 
0303             template <typename Terminal>
0304             result_type operator()(Terminal const& term, unused_type) const
0305             {
0306                 typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
0307                 using spirit::detail::get_stateful_data;
0308                 return result_type(get_stateful_data<tag_type>::call(term));
0309             }
0310         };
0311     }
0312 
0313     template <typename Modifiers>
0314     struct make_primitive<tag::float_, Modifiers>
0315       : detail::make_real<float, Modifiers> {};
0316 
0317     template <typename Modifiers>
0318     struct make_primitive<tag::double_, Modifiers>
0319       : detail::make_real<double, Modifiers> {};
0320 
0321     template <typename Modifiers>
0322     struct make_primitive<tag::long_double, Modifiers>
0323       : detail::make_real<long double, Modifiers> {};
0324 
0325     ///////////////////////////////////////////////////////////////////////////
0326     template <typename T, typename Policies, typename Modifiers>
0327     struct make_primitive<
0328             tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
0329       : detail::make_real<typename remove_const<T>::type
0330           , Modifiers, Policies> {};
0331 
0332     ///////////////////////////////////////////////////////////////////////////
0333     namespace detail
0334     {
0335         template <typename T, typename Modifiers
0336           , typename Policies = real_policies<T> >
0337         struct make_real_direct
0338         {
0339             static bool const lower =
0340                 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0341             static bool const upper =
0342                 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0343 
0344             typedef literal_real_generator<
0345                 T, Policies
0346               , typename spirit::detail::get_encoding_with_case<
0347                     Modifiers, unused_type, lower || upper>::type
0348               , typename detail::get_casetag<Modifiers, lower || upper>::type
0349               , false
0350             > result_type;
0351 
0352             template <typename Terminal>
0353             result_type operator()(Terminal const& term, unused_type) const
0354             {
0355                 typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
0356                 using spirit::detail::get_stateful_data;
0357                 return result_type(T(fusion::at_c<0>(term.args))
0358                   , get_stateful_data<tag_type>::call(term.term));
0359             }
0360         };
0361     }
0362 
0363     template <typename Modifiers, typename A0>
0364     struct make_primitive<
0365         terminal_ex<tag::float_, fusion::vector1<A0> >, Modifiers>
0366       : detail::make_real_direct<float, Modifiers> {};
0367 
0368     template <typename Modifiers, typename A0>
0369     struct make_primitive<
0370         terminal_ex<tag::double_, fusion::vector1<A0> >, Modifiers>
0371       : detail::make_real_direct<double, Modifiers> {};
0372 
0373     template <typename Modifiers, typename A0>
0374     struct make_primitive<
0375         terminal_ex<tag::long_double, fusion::vector1<A0> >, Modifiers>
0376       : detail::make_real_direct<long double, Modifiers> {};
0377 
0378     ///////////////////////////////////////////////////////////////////////////
0379     template <typename T, typename Policies, typename A0, typename Modifiers>
0380     struct make_primitive<
0381         terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
0382           , fusion::vector1<A0> >
0383           , Modifiers>
0384       : detail::make_real_direct<typename remove_const<T>::type
0385           , Modifiers, Policies> {};
0386 
0387     ///////////////////////////////////////////////////////////////////////////
0388     namespace detail
0389     {
0390         template <typename T, typename Modifiers>
0391         struct basic_real_literal
0392         {
0393             static bool const lower =
0394                 has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0395             static bool const upper =
0396                 has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0397 
0398             typedef literal_real_generator<
0399                 T, real_policies<T>
0400               , typename spirit::detail::get_encoding_with_case<
0401                     Modifiers, unused_type, lower || upper>::type
0402               , typename detail::get_casetag<Modifiers, lower || upper>::type
0403               , true
0404             > result_type;
0405 
0406             template <typename T_>
0407             result_type operator()(T_ i, unused_type) const
0408             {
0409                 return result_type(T(i));
0410             }
0411         };
0412     }
0413 
0414     template <typename Modifiers>
0415     struct make_primitive<float, Modifiers>
0416       : detail::basic_real_literal<float, Modifiers> {};
0417 
0418     template <typename Modifiers>
0419     struct make_primitive<double, Modifiers>
0420       : detail::basic_real_literal<double, Modifiers> {};
0421 
0422     template <typename Modifiers>
0423     struct make_primitive<long double, Modifiers>
0424       : detail::basic_real_literal<long double, Modifiers> {};
0425 
0426     // lit(double)
0427     template <typename Modifiers, typename A0>
0428     struct make_primitive<
0429             terminal_ex<tag::lit, fusion::vector1<A0> >
0430           , Modifiers
0431           , typename enable_if<traits::is_real<A0> >::type>
0432     {
0433         static bool const lower =
0434             has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
0435         static bool const upper =
0436             has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
0437 
0438         typedef literal_real_generator<
0439             typename remove_const<A0>::type, real_policies<A0>
0440           , typename spirit::detail::get_encoding_with_case<
0441                 Modifiers, unused_type, lower || upper>::type
0442           , typename detail::get_casetag<Modifiers, lower || upper>::type
0443           , true
0444         > result_type;
0445 
0446         template <typename Terminal>
0447         result_type operator()(Terminal const& term, unused_type) const
0448         {
0449             return result_type(fusion::at_c<0>(term.args));
0450         }
0451     };
0452 }}}
0453 
0454 #endif // defined(BOOST_SPIRIT_KARMA_REAL_FEB_26_2007_0512PM)