1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright (c) 2001-2011 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_SPIRIT_KARMA_DELIMIT_MAR_02_2007_0217PM)
#define BOOST_SPIRIT_KARMA_DELIMIT_MAR_02_2007_0217PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/detail/unused_delimiter.hpp>
#include <boost/spirit/home/karma/delimit_out.hpp>
#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_directive<karma::domain, tag::delimit> // enables delimit[]
: mpl::true_ {};
// enables delimit(d)[g], where d is a generator
template <typename T>
struct use_directive<karma::domain
, terminal_ex<tag::delimit, fusion::vector1<T> > >
: boost::spirit::traits::matches<karma::domain, T> {};
// enables *lazy* delimit(d)[g]
template <>
struct use_lazy_directive<karma::domain, tag::delimit, 1>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace karma
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::delimit;
#endif
using spirit::delimit_type;
///////////////////////////////////////////////////////////////////////////
// The redelimit_generator generator is used for delimit[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct redelimit_generator : unary_generator<redelimit_generator<Subject> >
{
typedef Subject subject_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
redelimit_generator(Subject const& subject)
: subject(subject) {}
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// The delimit_space generator simply dispatches to the embedded
// generator while supplying either the delimiter which has been
// used before a surrounding verbatim[] directive or a single
// space as the new delimiter to use (if no surrounding verbatim[]
// was specified).
return subject.generate(sink, ctx
, detail::get_delimiter(d, compile<karma::domain>(' ')), attr);
}
template <typename Context>
info what(Context& context) const
{
return info("delimit", subject.what(context));
}
Subject subject;
};
///////////////////////////////////////////////////////////////////////////
// The delimit_generator is used for delimit(d)[...] directives.
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Delimiter>
struct delimit_generator
: unary_generator<delimit_generator<Subject, Delimiter> >
{
typedef Subject subject_type;
typedef Delimiter delimiter_type;
typedef typename subject_type::properties properties;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
delimit_generator(Subject const& subject, Delimiter const& delimiter)
: subject(subject), delimiter(delimiter) {}
template <typename OutputIterator, typename Context
, typename Delimiter_, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter_ const&
, Attribute const& attr) const
{
// the delimit generator simply dispatches to the embedded
// generator while supplying it's argument as the new delimiter
// to use
return subject.generate(sink, ctx, delimiter, attr);
}
template <typename Context>
info what(Context& context) const
{
return info("delimit", subject.what(context));
}
Subject subject;
Delimiter delimiter;
};
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<tag::delimit, Subject, Modifiers>
{
typedef redelimit_generator<Subject> result_type;
result_type operator()(unused_type, Subject const& subject
, unused_type) const
{
return result_type(subject);
}
};
template <typename Delimiter, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<tag::delimit, fusion::vector1<Delimiter> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Delimiter, Modifiers>::type
delimiter_type;
typedef delimit_generator<Subject, delimiter_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, unused_type) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args)));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<karma::redelimit_generator<Subject> >
: unary_has_semantic_action<Subject> {};
template <typename Subject, typename Delimiter>
struct has_semantic_action<karma::delimit_generator<Subject, Delimiter> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::redelimit_generator<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
template <typename Subject, typename Delimiter, typename Attribute
, typename Context, typename Iterator>
struct handles_container<karma::delimit_generator<Subject, Delimiter>
, Attribute, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}}
#endif