• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(BOOST_SPIRIT_KARMA_PADDING_MAY_06_2008_0436PM)
7 #define BOOST_SPIRIT_KARMA_PADDING_MAY_06_2008_0436PM
8 
9 #if defined(_MSC_VER)
10 #pragma once
11 #endif
12 
13 #include <boost/spirit/home/support/common_terminals.hpp>
14 #include <boost/spirit/home/support/info.hpp>
15 
16 #include <boost/spirit/home/karma/domain.hpp>
17 #include <boost/spirit/home/karma/meta_compiler.hpp>
18 #include <boost/spirit/home/karma/delimit_out.hpp>
19 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
20 #include <boost/spirit/home/karma/detail/generate_to.hpp>
21 #include <boost/spirit/home/support/unused.hpp>
22 #include <boost/fusion/include/at.hpp>
23 #include <boost/fusion/include/vector.hpp>
24 
25 ///////////////////////////////////////////////////////////////////////////////
26 namespace boost { namespace spirit
27 {
28     ///////////////////////////////////////////////////////////////////////////
29     // Enablers
30     ///////////////////////////////////////////////////////////////////////////
31 
32     // enables pad(...)
33     template <typename A0>
34     struct use_terminal<karma::domain
35         , terminal_ex<tag::pad, fusion::vector1<A0> > >
36       : mpl::true_ {};
37 
38     // enables lazy pad(...)
39     template <>
40     struct use_lazy_terminal<karma::domain, tag::pad, 1>
41       : mpl::true_ {};
42 
43 }}
44 
45 ///////////////////////////////////////////////////////////////////////////////
46 namespace boost { namespace spirit { namespace karma
47 {
48 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
49     using boost::spirit::pad;
50 #endif
51     using boost::spirit::pad_type;
52 
53     struct binary_padding_generator
54       : primitive_generator<binary_padding_generator>
55     {
56         typedef mpl::int_<generator_properties::tracking> properties;
57 
58         template <typename Context, typename Unused>
59         struct attribute
60         {
61             typedef unused_type type;
62         };
63 
binary_padding_generatorboost::spirit::karma::binary_padding_generator64         binary_padding_generator(int numpadbytes)
65           : numpadbytes_(numpadbytes)
66         {}
67 
68         template <
69             typename OutputIterator, typename Context, typename Delimiter
70           , typename Attribute>
generateboost::spirit::karma::binary_padding_generator71         bool generate(OutputIterator& sink, Context&, Delimiter const& d
72           , Attribute const& /*attr*/) const
73         {
74             std::size_t count = sink.get_out_count() % numpadbytes_;
75             if (count)
76                 count = numpadbytes_ - count;
77 
78             bool result = true;
79             while (result && count-- != 0)
80                 result = detail::generate_to(sink, '\0');
81 
82             if (result)
83                 result = karma::delimit_out(sink, d);  // always do post-delimiting
84             return result;
85         }
86 
87         template <typename Context>
whatboost::spirit::karma::binary_padding_generator88         static info what(Context const&)
89         {
90             return info("pad");
91         }
92 
93         int numpadbytes_;
94     };
95 
96     ///////////////////////////////////////////////////////////////////////////
97     // Generator generators: make_xxx function (objects)
98     ///////////////////////////////////////////////////////////////////////////
99     template <typename Modifiers, typename A0>
100     struct make_primitive<
101         terminal_ex<tag::pad, fusion::vector1<A0> >
102       , Modifiers>
103     {
104         typedef binary_padding_generator result_type;
105 
106         template <typename Terminal>
operator ()boost::spirit::karma::make_primitive107         result_type operator()(Terminal const& term, unused_type) const
108         {
109             return result_type(fusion::at_c<0>(term.args));
110         }
111     };
112 
113 }}}
114 
115 #endif
116