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