]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/example/karma/simple_columns_directive.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / example / karma / simple_columns_directive.hpp
1 // Copyright (c) 2001-2010 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(COLUMNS_DEC_05_2009_0716PM)
7 #define COLUMNS_DEC_05_2009_0716PM
8
9 #include <boost/spirit/include/karma_generate.hpp>
10
11 ///////////////////////////////////////////////////////////////////////////////
12 // definition the place holder
13 namespace custom_generator
14 {
15 BOOST_SPIRIT_TERMINAL(columns);
16 }
17
18 ///////////////////////////////////////////////////////////////////////////////
19 // implementation the enabler
20 namespace boost { namespace spirit
21 {
22 // We want custom_generator::columns to be usable as a directive only,
23 // and only for generator expressions (karma::domain).
24 template <>
25 struct use_directive<karma::domain, custom_generator::tag::columns>
26 : mpl::true_ {};
27 }}
28
29 ///////////////////////////////////////////////////////////////////////////////
30 // implementation of the generator
31 namespace custom_generator
32 {
33 // special delimiter wrapping the original one while additionally emitting
34 // the column delimiter after each 5th invocation
35 template <typename Delimiter>
36 struct columns_delimiter
37 {
38 columns_delimiter(Delimiter const& delim)
39 : delimiter(delim), count(0) {}
40
41 // This function is called during the actual delimiter output
42 template <typename OutputIterator, typename Context
43 , typename Delimiter_, typename Attribute>
44 bool generate(OutputIterator& sink, Context&, Delimiter_ const&
45 , Attribute const&) const
46 {
47 // first invoke the wrapped delimiter
48 if (!karma::delimit_out(sink, delimiter))
49 return false;
50
51 // now we count the number of invocations and emit the column
52 // delimiter after each 5th column
53 if ((++count % 5) == 0)
54 *sink++ = '\n';
55 return true;
56 }
57
58 // Generate a final column delimiter if the last invocation didn't
59 // emit one
60 template <typename OutputIterator>
61 bool final_delimit_out(OutputIterator& sink) const
62 {
63 if (count % 5)
64 *sink++ = '\n';
65 return true;
66 }
67
68 Delimiter const& delimiter; // wrapped delimiter
69 mutable unsigned int count; // invocation counter
70 };
71
72 // That's the actual columns generator
73 template <typename Subject>
74 struct simple_columns_generator
75 : boost::spirit::karma::unary_generator<
76 simple_columns_generator<Subject> >
77 {
78 // Define required output iterator properties
79 typedef typename Subject::properties properties;
80
81 // Define the attribute type exposed by this parser component
82 template <typename Context, typename Iterator>
83 struct attribute
84 : boost::spirit::traits::attribute_of<Subject, Context, Iterator>
85 {};
86
87 simple_columns_generator(Subject const& s)
88 : subject(s)
89 {}
90
91 // This function is called during the actual output generation process.
92 // It dispatches to the embedded generator while supplying a new
93 // delimiter to use, wrapping the outer delimiter.
94 template <typename OutputIterator, typename Context
95 , typename Delimiter, typename Attribute>
96 bool generate(OutputIterator& sink, Context& ctx
97 , Delimiter const& delimiter, Attribute const& attr) const
98 {
99 columns_delimiter<Delimiter> d(delimiter);
100 return subject.generate(sink, ctx, d, attr) && d.final_delimit_out(sink);
101 }
102
103 // This function is called during error handling to create
104 // a human readable string for the error context.
105 template <typename Context>
106 boost::spirit::info what(Context& ctx) const
107 {
108 return boost::spirit::info("columns", subject.what(ctx));
109 }
110
111 Subject subject;
112 };
113 }
114
115 ///////////////////////////////////////////////////////////////////////////////
116 // instantiation of the generator
117 namespace boost { namespace spirit { namespace karma
118 {
119 // This is the factory function object invoked in order to create
120 // an instance of our simple_columns_generator.
121 template <typename Subject, typename Modifiers>
122 struct make_directive<custom_generator::tag::columns, Subject, Modifiers>
123 {
124 typedef custom_generator::simple_columns_generator<Subject> result_type;
125
126 result_type operator()(unused_type, Subject const& s, unused_type) const
127 {
128 return result_type(s);
129 }
130 };
131 }}}
132
133 #endif