Back to home page

EIC code displayed by LXR

 
 

    


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

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_LEFT_ALIGNMENT_FEB_27_2007_1216PM)
0007 #define BOOST_SPIRIT_KARMA_LEFT_ALIGNMENT_FEB_27_2007_1216PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/spirit/home/karma/meta_compiler.hpp>
0014 #include <boost/spirit/home/karma/generator.hpp>
0015 #include <boost/spirit/home/karma/domain.hpp>
0016 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
0017 #include <boost/spirit/home/karma/detail/default_width.hpp>
0018 #include <boost/spirit/home/karma/delimit_out.hpp>
0019 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
0020 #include <boost/spirit/home/karma/char/char.hpp>
0021 #include <boost/spirit/home/support/unused.hpp>
0022 #include <boost/spirit/home/support/common_terminals.hpp>
0023 #include <boost/spirit/home/karma/detail/attributes.hpp>
0024 #include <boost/spirit/home/support/info.hpp>
0025 #include <boost/spirit/home/support/unused.hpp>
0026 #include <boost/spirit/home/support/has_semantic_action.hpp>
0027 #include <boost/spirit/home/support/handles_container.hpp>
0028 #include <boost/fusion/include/at.hpp>
0029 #include <boost/fusion/include/vector.hpp>
0030 #include <boost/integer_traits.hpp>
0031 #include <boost/mpl/bool.hpp>
0032 #include <boost/utility/enable_if.hpp>
0033 #include <boost/detail/workaround.hpp>
0034 
0035 ///////////////////////////////////////////////////////////////////////////////
0036 namespace boost { namespace spirit
0037 {
0038     ///////////////////////////////////////////////////////////////////////////
0039     // Enablers
0040     ///////////////////////////////////////////////////////////////////////////
0041 
0042     // enables left_align[]
0043     template <>
0044     struct use_directive<karma::domain, tag::left_align>
0045       : mpl::true_ {};
0046 
0047     // enables left_align(d)[g] and left_align(w)[g], where d is a generator
0048     // and w is a maximum width
0049     template <typename T>
0050     struct use_directive<karma::domain
0051           , terminal_ex<tag::left_align, fusion::vector1<T> > >
0052       : mpl::true_ {};
0053 
0054     // enables *lazy* left_align(d)[g], where d provides a generator
0055     template <>
0056     struct use_lazy_directive<karma::domain, tag::left_align, 1> 
0057       : mpl::true_ {};
0058 
0059     // enables left_align(w, d)[g], where d is a generator and w is a maximum 
0060     // width
0061     template <typename Width, typename Padding>
0062     struct use_directive<karma::domain
0063           , terminal_ex<tag::left_align, fusion::vector2<Width, Padding> > >
0064       : spirit::traits::matches<karma::domain, Padding> {};
0065 
0066     // enables *lazy* left_align(w, d)[g], where d provides a generator and w 
0067     // is a maximum width
0068     template <>
0069     struct use_lazy_directive<karma::domain, tag::left_align, 2> 
0070       : mpl::true_ {};
0071 
0072 }}
0073 
0074 ///////////////////////////////////////////////////////////////////////////////
0075 namespace boost { namespace spirit { namespace karma
0076 {
0077 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
0078     using spirit::left_align;
0079 #endif
0080     using spirit::left_align_type;
0081 
0082     namespace detail
0083     {
0084         ///////////////////////////////////////////////////////////////////////
0085         //  The left_align_generate template function is used for all the 
0086         //  different flavors of the left_align[] directive. 
0087         ///////////////////////////////////////////////////////////////////////
0088         template <typename OutputIterator, typename Context, typename Delimiter, 
0089             typename Attribute, typename Embedded, typename Padding>
0090         inline static bool 
0091         left_align_generate(OutputIterator& sink, Context& ctx, 
0092             Delimiter const& d, Attribute const& attr, Embedded const& e, 
0093             unsigned int const width, Padding const& p) 
0094         {
0095 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
0096             (void)e; // suppresses warning: C4100: 'e' : unreferenced formal parameter
0097 #endif
0098             // wrap the given output iterator to allow counting
0099             detail::enable_counting<OutputIterator> counting(sink);
0100 
0101             // first generate the underlying output 
0102             bool r = e.generate(sink, ctx, d, attr);
0103 
0104             // pad the output until the max width is reached
0105             while(r && counting.count() < width) 
0106                 r = p.generate(sink, ctx, unused, unused);
0107 
0108             return r;
0109         }
0110     }
0111 
0112     ///////////////////////////////////////////////////////////////////////////
0113     //  The simple left alignment directive is used for left_align[...]
0114     //  generators. It uses default values for the generated width (defined via
0115     //  the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant) and for the padding
0116     //  generator (always spaces).
0117     ///////////////////////////////////////////////////////////////////////////
0118     template <typename Subject, typename Width = detail::default_width>
0119     struct simple_left_alignment 
0120       : unary_generator<simple_left_alignment<Subject, Width> >
0121     {
0122         typedef Subject subject_type;
0123 
0124         typedef mpl::int_<
0125             generator_properties::counting | subject_type::properties::value
0126         > properties;
0127 
0128         template <typename Context, typename Iterator>
0129         struct attribute
0130           : traits::attribute_of<subject_type, Context, Iterator>
0131         {};
0132 
0133         simple_left_alignment(Subject const& subject, Width width = Width())
0134           : subject(subject), width(width) {}
0135 
0136         template <typename OutputIterator, typename Context, typename Delimiter
0137           , typename Attribute>
0138         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0139           , Attribute const& attr) const
0140         {
0141             return detail::left_align_generate(sink, ctx, d, attr,
0142                 subject, width, compile<karma::domain>(' '));
0143         }
0144 
0145         template <typename Context>
0146         info what(Context& context) const
0147         {
0148             return info("left_align", subject.what(context));
0149         }
0150 
0151         Subject subject;
0152         Width width;
0153     };
0154 
0155     ///////////////////////////////////////////////////////////////////////////
0156     //  The left alignment directive with padding, is used for generators like
0157     //  left_align(padding)[...], where padding is a arbitrary generator
0158     //  expression. It uses a default value for the generated width (defined
0159     //  via the BOOST_KARMA_DEFAULT_FIELD_LENGTH constant).
0160     ///////////////////////////////////////////////////////////////////////////
0161     template <typename Subject, typename Padding
0162       , typename Width = detail::default_width>
0163     struct padding_left_alignment 
0164       : unary_generator<padding_left_alignment<Subject, Padding, Width> >
0165     {
0166         typedef Subject subject_type;
0167         typedef Padding padding_type;
0168 
0169         typedef mpl::int_<
0170             generator_properties::counting | 
0171             subject_type::properties::value | padding_type::properties::value 
0172         > properties;
0173 
0174         template <typename Context, typename Iterator>
0175         struct attribute
0176           : traits::attribute_of<subject_type, Context, Iterator>
0177         {};
0178 
0179         padding_left_alignment(Subject const& subject, Padding const& padding
0180               , Width width = Width())
0181           : subject(subject), padding(padding), width(width) {}
0182 
0183         template <typename OutputIterator, typename Context, typename Delimiter
0184           , typename Attribute>
0185         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
0186           , Attribute const& attr) const
0187         {
0188             return detail::left_align_generate(sink, ctx, d, attr,
0189                 subject, width, padding);
0190         }
0191 
0192         template <typename Context>
0193         info what(Context& context) const
0194         {
0195             return info("left_align", subject.what(context));
0196         }
0197 
0198         Subject subject;
0199         Padding padding;
0200         Width width;
0201     };
0202 
0203     ///////////////////////////////////////////////////////////////////////////
0204     // Generator generators: make_xxx function (objects)
0205     ///////////////////////////////////////////////////////////////////////////
0206 
0207     // creates left_align[] directive generator
0208     template <typename Subject, typename Modifiers>
0209     struct make_directive<tag::left_align, Subject, Modifiers>
0210     {
0211         typedef simple_left_alignment<Subject> result_type;
0212         result_type operator()(unused_type, Subject const& subject
0213           , unused_type) const
0214         {
0215             return result_type(subject);
0216         }
0217     };
0218 
0219     // creates left_align(width)[] directive generator
0220     template <typename Width, typename Subject, typename Modifiers>
0221     struct make_directive<
0222         terminal_ex<tag::left_align, fusion::vector1<Width> >
0223       , Subject, Modifiers
0224       , typename enable_if_c< integer_traits<Width>::is_integral >::type>
0225     {
0226         typedef simple_left_alignment<Subject, Width> result_type;
0227 
0228         template <typename Terminal>
0229         result_type operator()(Terminal const& term, Subject const& subject
0230           , unused_type) const
0231         {
0232             return result_type(subject, fusion::at_c<0>(term.args));
0233         }
0234     };
0235 
0236     // creates left_align(pad)[] directive generator
0237     template <typename Padding, typename Subject, typename Modifiers>
0238     struct make_directive<
0239         terminal_ex<tag::left_align, fusion::vector1<Padding> >
0240       , Subject, Modifiers
0241       , typename enable_if<
0242             mpl::and_<
0243                 spirit::traits::matches<karma::domain, Padding>,
0244                 mpl::not_<mpl::bool_<integer_traits<Padding>::is_integral> >
0245             >
0246         >::type>
0247     {
0248         typedef typename
0249             result_of::compile<karma::domain, Padding, Modifiers>::type
0250         padding_type;
0251 
0252         typedef padding_left_alignment<Subject, padding_type> result_type;
0253 
0254         template <typename Terminal>
0255         result_type operator()(Terminal const& term, Subject const& subject
0256           , Modifiers const& modifiers) const
0257         {
0258             return result_type(subject
0259               , compile<karma::domain>(fusion::at_c<0>(term.args), modifiers));
0260         }
0261     };
0262 
0263     // creates left_align(width, pad)[] directive generator
0264     template <typename Width, typename Padding, typename Subject
0265       , typename Modifiers>
0266     struct make_directive<
0267         terminal_ex<tag::left_align, fusion::vector2<Width, Padding> >
0268       , Subject, Modifiers>
0269     {
0270         typedef typename
0271             result_of::compile<karma::domain, Padding, Modifiers>::type
0272         padding_type;
0273 
0274         typedef padding_left_alignment<Subject, padding_type, Width> result_type;
0275 
0276         template <typename Terminal>
0277         result_type operator()(Terminal const& term, Subject const& subject
0278           , Modifiers const& modifiers) const
0279         {
0280             return result_type(subject
0281               , compile<karma::domain>(fusion::at_c<1>(term.args), modifiers)
0282               , fusion::at_c<0>(term.args));
0283         }
0284     };
0285 
0286 }}} // namespace boost::spirit::karma
0287 
0288 namespace boost { namespace spirit { namespace traits
0289 {
0290     ///////////////////////////////////////////////////////////////////////////
0291     template <typename Subject, typename Width>
0292     struct has_semantic_action<karma::simple_left_alignment<Subject, Width> >
0293       : unary_has_semantic_action<Subject> {};
0294 
0295     template <typename Subject, typename Padding, typename Width>
0296     struct has_semantic_action<
0297             karma::padding_left_alignment<Subject, Padding, Width> >
0298       : unary_has_semantic_action<Subject> {};
0299 
0300     ///////////////////////////////////////////////////////////////////////////
0301     template <typename Subject, typename Width, typename Attribute
0302       , typename Context, typename Iterator>
0303     struct handles_container<
0304             karma::simple_left_alignment<Subject, Width>, Attribute
0305           , Context, Iterator>
0306       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0307 
0308     template <typename Subject, typename Padding, typename Width
0309       , typename Attribute, typename Context, typename Iterator>
0310     struct handles_container<
0311             karma::padding_left_alignment<Subject, Padding, Width>
0312           , Attribute, Context, Iterator>
0313       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
0314 }}}
0315 
0316 #endif
0317 
0318