Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file regex_actions.hpp
|
Chris@16
|
3 /// Defines the syntax elements of xpressive's action expressions.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
|
Chris@16
|
10 #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
|
Chris@16
|
11
|
Chris@16
|
12 // MS compatible compilers support #pragma once
|
Chris@101
|
13 #if defined(_MSC_VER)
|
Chris@16
|
14 # pragma once
|
Chris@16
|
15 #endif
|
Chris@16
|
16
|
Chris@16
|
17 #include <boost/config.hpp>
|
Chris@16
|
18 #include <boost/preprocessor/punctuation/comma_if.hpp>
|
Chris@16
|
19 #include <boost/ref.hpp>
|
Chris@16
|
20 #include <boost/mpl/if.hpp>
|
Chris@16
|
21 #include <boost/mpl/or.hpp>
|
Chris@16
|
22 #include <boost/mpl/int.hpp>
|
Chris@16
|
23 #include <boost/mpl/assert.hpp>
|
Chris@16
|
24 #include <boost/noncopyable.hpp>
|
Chris@16
|
25 #include <boost/lexical_cast.hpp>
|
Chris@16
|
26 #include <boost/throw_exception.hpp>
|
Chris@16
|
27 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
28 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
29 #include <boost/type_traits/is_const.hpp>
|
Chris@16
|
30 #include <boost/type_traits/is_integral.hpp>
|
Chris@16
|
31 #include <boost/type_traits/decay.hpp>
|
Chris@16
|
32 #include <boost/type_traits/remove_cv.hpp>
|
Chris@16
|
33 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
34 #include <boost/range/iterator_range.hpp>
|
Chris@16
|
35 #include <boost/xpressive/detail/detail_fwd.hpp>
|
Chris@16
|
36 #include <boost/xpressive/detail/core/state.hpp>
|
Chris@16
|
37 #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp>
|
Chris@16
|
38 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
|
Chris@16
|
39 #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp>
|
Chris@16
|
40 #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp>
|
Chris@16
|
41 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
Chris@16
|
42 #include <boost/xpressive/detail/static/type_traits.hpp>
|
Chris@16
|
43
|
Chris@16
|
44 // These are very often needed by client code.
|
Chris@16
|
45 #include <boost/typeof/std/map.hpp>
|
Chris@16
|
46 #include <boost/typeof/std/string.hpp>
|
Chris@16
|
47
|
Chris@16
|
48 // Doxygen can't handle proto :-(
|
Chris@16
|
49 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
|
Chris@16
|
50 # include <boost/proto/core.hpp>
|
Chris@16
|
51 # include <boost/proto/transform.hpp>
|
Chris@16
|
52 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
|
Chris@16
|
53 #endif
|
Chris@16
|
54
|
Chris@16
|
55 #if BOOST_MSVC
|
Chris@16
|
56 #pragma warning(push)
|
Chris@16
|
57 #pragma warning(disable : 4510) // default constructor could not be generated
|
Chris@16
|
58 #pragma warning(disable : 4512) // assignment operator could not be generated
|
Chris@16
|
59 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
|
Chris@16
|
60 #endif
|
Chris@16
|
61
|
Chris@16
|
62 namespace boost { namespace xpressive
|
Chris@16
|
63 {
|
Chris@16
|
64
|
Chris@16
|
65 namespace detail
|
Chris@16
|
66 {
|
Chris@16
|
67 template<typename T, typename U>
|
Chris@16
|
68 struct action_arg
|
Chris@16
|
69 {
|
Chris@16
|
70 typedef T type;
|
Chris@16
|
71 typedef typename add_reference<T>::type reference;
|
Chris@16
|
72
|
Chris@16
|
73 reference cast(void *pv) const
|
Chris@16
|
74 {
|
Chris@16
|
75 return *static_cast<typename remove_reference<T>::type *>(pv);
|
Chris@16
|
76 }
|
Chris@16
|
77 };
|
Chris@16
|
78
|
Chris@16
|
79 template<typename T>
|
Chris@16
|
80 struct value_wrapper
|
Chris@16
|
81 : private noncopyable
|
Chris@16
|
82 {
|
Chris@16
|
83 value_wrapper()
|
Chris@16
|
84 : value()
|
Chris@16
|
85 {}
|
Chris@16
|
86
|
Chris@16
|
87 value_wrapper(T const &t)
|
Chris@16
|
88 : value(t)
|
Chris@16
|
89 {}
|
Chris@16
|
90
|
Chris@16
|
91 T value;
|
Chris@16
|
92 };
|
Chris@16
|
93
|
Chris@16
|
94 struct check_tag
|
Chris@16
|
95 {};
|
Chris@16
|
96
|
Chris@16
|
97 struct BindArg
|
Chris@16
|
98 {
|
Chris@16
|
99 BOOST_PROTO_CALLABLE()
|
Chris@16
|
100 template<typename Sig>
|
Chris@16
|
101 struct result {};
|
Chris@16
|
102
|
Chris@16
|
103 template<typename This, typename MatchResults, typename Expr>
|
Chris@16
|
104 struct result<This(MatchResults, Expr)>
|
Chris@16
|
105 {
|
Chris@16
|
106 typedef Expr type;
|
Chris@16
|
107 };
|
Chris@16
|
108
|
Chris@16
|
109 template<typename MatchResults, typename Expr>
|
Chris@16
|
110 Expr const & operator ()(MatchResults &what, Expr const &expr) const
|
Chris@16
|
111 {
|
Chris@16
|
112 what.let(expr);
|
Chris@16
|
113 return expr;
|
Chris@16
|
114 }
|
Chris@16
|
115 };
|
Chris@16
|
116
|
Chris@16
|
117 struct let_tag
|
Chris@16
|
118 {};
|
Chris@16
|
119
|
Chris@16
|
120 // let(_a = b, _c = d)
|
Chris@16
|
121 struct BindArgs
|
Chris@16
|
122 : proto::function<
|
Chris@16
|
123 proto::terminal<let_tag>
|
Chris@16
|
124 , proto::vararg<
|
Chris@16
|
125 proto::when<
|
Chris@16
|
126 proto::assign<proto::_, proto::_>
|
Chris@16
|
127 , proto::call<BindArg(proto::_data, proto::_)>
|
Chris@16
|
128 >
|
Chris@16
|
129 >
|
Chris@16
|
130 >
|
Chris@16
|
131 {};
|
Chris@16
|
132
|
Chris@16
|
133 struct let_domain
|
Chris@16
|
134 : boost::proto::domain<boost::proto::pod_generator<let_> >
|
Chris@16
|
135 {};
|
Chris@16
|
136
|
Chris@16
|
137 template<typename Expr>
|
Chris@16
|
138 struct let_
|
Chris@16
|
139 {
|
Chris@16
|
140 BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain)
|
Chris@16
|
141 BOOST_PROTO_EXTENDS_FUNCTION()
|
Chris@16
|
142 };
|
Chris@16
|
143
|
Chris@16
|
144 template<typename Args, typename BidiIter>
|
Chris@16
|
145 void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
|
Chris@16
|
146 {
|
Chris@16
|
147 BindArgs()(args, 0, what);
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 typedef boost::proto::functional::make_expr<proto::tag::function, proto::default_domain> make_function;
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 namespace op
|
Chris@16
|
154 {
|
Chris@16
|
155 /// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence
|
Chris@16
|
156 struct at
|
Chris@16
|
157 {
|
Chris@16
|
158 BOOST_PROTO_CALLABLE()
|
Chris@16
|
159 template<typename Sig>
|
Chris@16
|
160 struct result {};
|
Chris@16
|
161
|
Chris@16
|
162 template<typename This, typename Cont, typename Idx>
|
Chris@16
|
163 struct result<This(Cont &, Idx)>
|
Chris@16
|
164 {
|
Chris@16
|
165 typedef typename Cont::reference type;
|
Chris@16
|
166 };
|
Chris@16
|
167
|
Chris@16
|
168 template<typename This, typename Cont, typename Idx>
|
Chris@16
|
169 struct result<This(Cont const &, Idx)>
|
Chris@16
|
170 {
|
Chris@16
|
171 typedef typename Cont::const_reference type;
|
Chris@16
|
172 };
|
Chris@16
|
173
|
Chris@16
|
174 template<typename This, typename Cont, typename Idx>
|
Chris@16
|
175 struct result<This(Cont, Idx)>
|
Chris@16
|
176 {
|
Chris@16
|
177 typedef typename Cont::const_reference type;
|
Chris@16
|
178 };
|
Chris@16
|
179
|
Chris@16
|
180 /// \pre \c Cont is a model of RandomAccessSequence
|
Chris@16
|
181 /// \param c The RandomAccessSequence to index into
|
Chris@16
|
182 /// \param idx The index
|
Chris@16
|
183 /// \return <tt>c[idx]</tt>
|
Chris@16
|
184 template<typename Cont, typename Idx>
|
Chris@16
|
185 typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const
|
Chris@16
|
186 {
|
Chris@16
|
187 return c[idx];
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 /// \overload
|
Chris@16
|
191 ///
|
Chris@16
|
192 template<typename Cont, typename Idx>
|
Chris@16
|
193 typename Cont::const_reference operator()(Cont const &c, Idx idx) const
|
Chris@16
|
194 {
|
Chris@16
|
195 return c[idx];
|
Chris@16
|
196 }
|
Chris@16
|
197 };
|
Chris@16
|
198
|
Chris@16
|
199 /// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container.
|
Chris@16
|
200 struct push
|
Chris@16
|
201 {
|
Chris@16
|
202 BOOST_PROTO_CALLABLE()
|
Chris@16
|
203 typedef void result_type;
|
Chris@16
|
204
|
Chris@16
|
205 /// \param seq The sequence into which the value should be pushed.
|
Chris@16
|
206 /// \param val The value to push into the sequence.
|
Chris@16
|
207 /// \brief Equivalent to <tt>seq.push(val)</tt>.
|
Chris@16
|
208 /// \return \c void
|
Chris@16
|
209 template<typename Sequence, typename Value>
|
Chris@16
|
210 void operator()(Sequence &seq, Value const &val) const
|
Chris@16
|
211 {
|
Chris@16
|
212 seq.push(val);
|
Chris@16
|
213 }
|
Chris@16
|
214 };
|
Chris@16
|
215
|
Chris@16
|
216 /// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container.
|
Chris@16
|
217 struct push_back
|
Chris@16
|
218 {
|
Chris@16
|
219 BOOST_PROTO_CALLABLE()
|
Chris@16
|
220 typedef void result_type;
|
Chris@16
|
221
|
Chris@16
|
222 /// \param seq The sequence into which the value should be pushed.
|
Chris@16
|
223 /// \param val The value to push into the sequence.
|
Chris@16
|
224 /// \brief Equivalent to <tt>seq.push_back(val)</tt>.
|
Chris@16
|
225 /// \return \c void
|
Chris@16
|
226 template<typename Sequence, typename Value>
|
Chris@16
|
227 void operator()(Sequence &seq, Value const &val) const
|
Chris@16
|
228 {
|
Chris@16
|
229 seq.push_back(val);
|
Chris@16
|
230 }
|
Chris@16
|
231 };
|
Chris@16
|
232
|
Chris@16
|
233 /// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container.
|
Chris@16
|
234 struct push_front
|
Chris@16
|
235 {
|
Chris@16
|
236 BOOST_PROTO_CALLABLE()
|
Chris@16
|
237 typedef void result_type;
|
Chris@16
|
238
|
Chris@16
|
239 /// \param seq The sequence into which the value should be pushed.
|
Chris@16
|
240 /// \param val The value to push into the sequence.
|
Chris@16
|
241 /// \brief Equivalent to <tt>seq.push_front(val)</tt>.
|
Chris@16
|
242 /// \return \c void
|
Chris@16
|
243 template<typename Sequence, typename Value>
|
Chris@16
|
244 void operator()(Sequence &seq, Value const &val) const
|
Chris@16
|
245 {
|
Chris@16
|
246 seq.push_front(val);
|
Chris@16
|
247 }
|
Chris@16
|
248 };
|
Chris@16
|
249
|
Chris@16
|
250 /// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container.
|
Chris@16
|
251 struct pop
|
Chris@16
|
252 {
|
Chris@16
|
253 BOOST_PROTO_CALLABLE()
|
Chris@16
|
254 typedef void result_type;
|
Chris@16
|
255
|
Chris@16
|
256 /// \param seq The sequence from which to pop.
|
Chris@16
|
257 /// \brief Equivalent to <tt>seq.pop()</tt>.
|
Chris@16
|
258 /// \return \c void
|
Chris@16
|
259 template<typename Sequence>
|
Chris@16
|
260 void operator()(Sequence &seq) const
|
Chris@16
|
261 {
|
Chris@16
|
262 seq.pop();
|
Chris@16
|
263 }
|
Chris@16
|
264 };
|
Chris@16
|
265
|
Chris@16
|
266 /// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container.
|
Chris@16
|
267 struct pop_back
|
Chris@16
|
268 {
|
Chris@16
|
269 BOOST_PROTO_CALLABLE()
|
Chris@16
|
270 typedef void result_type;
|
Chris@16
|
271
|
Chris@16
|
272 /// \param seq The sequence from which to pop.
|
Chris@16
|
273 /// \brief Equivalent to <tt>seq.pop_back()</tt>.
|
Chris@16
|
274 /// \return \c void
|
Chris@16
|
275 template<typename Sequence>
|
Chris@16
|
276 void operator()(Sequence &seq) const
|
Chris@16
|
277 {
|
Chris@16
|
278 seq.pop_back();
|
Chris@16
|
279 }
|
Chris@16
|
280 };
|
Chris@16
|
281
|
Chris@16
|
282 /// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container.
|
Chris@16
|
283 struct pop_front
|
Chris@16
|
284 {
|
Chris@16
|
285 BOOST_PROTO_CALLABLE()
|
Chris@16
|
286 typedef void result_type;
|
Chris@16
|
287
|
Chris@16
|
288 /// \param seq The sequence from which to pop.
|
Chris@16
|
289 /// \brief Equivalent to <tt>seq.pop_front()</tt>.
|
Chris@16
|
290 /// \return \c void
|
Chris@16
|
291 template<typename Sequence>
|
Chris@16
|
292 void operator()(Sequence &seq) const
|
Chris@16
|
293 {
|
Chris@16
|
294 seq.pop_front();
|
Chris@16
|
295 }
|
Chris@16
|
296 };
|
Chris@16
|
297
|
Chris@16
|
298 /// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container.
|
Chris@16
|
299 struct front
|
Chris@16
|
300 {
|
Chris@16
|
301 BOOST_PROTO_CALLABLE()
|
Chris@16
|
302 template<typename Sig>
|
Chris@16
|
303 struct result {};
|
Chris@16
|
304
|
Chris@16
|
305 template<typename This, typename Sequence>
|
Chris@16
|
306 struct result<This(Sequence)>
|
Chris@16
|
307 {
|
Chris@16
|
308 typedef typename remove_reference<Sequence>::type sequence_type;
|
Chris@16
|
309 typedef
|
Chris@16
|
310 typename mpl::if_c<
|
Chris@16
|
311 is_const<sequence_type>::value
|
Chris@16
|
312 , typename sequence_type::const_reference
|
Chris@16
|
313 , typename sequence_type::reference
|
Chris@16
|
314 >::type
|
Chris@16
|
315 type;
|
Chris@16
|
316 };
|
Chris@16
|
317
|
Chris@16
|
318 /// \param seq The sequence from which to fetch the front.
|
Chris@16
|
319 /// \return <tt>seq.front()</tt>
|
Chris@16
|
320 template<typename Sequence>
|
Chris@16
|
321 typename result<front(Sequence &)>::type operator()(Sequence &seq) const
|
Chris@16
|
322 {
|
Chris@16
|
323 return seq.front();
|
Chris@16
|
324 }
|
Chris@16
|
325 };
|
Chris@16
|
326
|
Chris@16
|
327 /// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container.
|
Chris@16
|
328 struct back
|
Chris@16
|
329 {
|
Chris@16
|
330 BOOST_PROTO_CALLABLE()
|
Chris@16
|
331 template<typename Sig>
|
Chris@16
|
332 struct result {};
|
Chris@16
|
333
|
Chris@16
|
334 template<typename This, typename Sequence>
|
Chris@16
|
335 struct result<This(Sequence)>
|
Chris@16
|
336 {
|
Chris@16
|
337 typedef typename remove_reference<Sequence>::type sequence_type;
|
Chris@16
|
338 typedef
|
Chris@16
|
339 typename mpl::if_c<
|
Chris@16
|
340 is_const<sequence_type>::value
|
Chris@16
|
341 , typename sequence_type::const_reference
|
Chris@16
|
342 , typename sequence_type::reference
|
Chris@16
|
343 >::type
|
Chris@16
|
344 type;
|
Chris@16
|
345 };
|
Chris@16
|
346
|
Chris@16
|
347 /// \param seq The sequence from which to fetch the back.
|
Chris@16
|
348 /// \return <tt>seq.back()</tt>
|
Chris@16
|
349 template<typename Sequence>
|
Chris@16
|
350 typename result<back(Sequence &)>::type operator()(Sequence &seq) const
|
Chris@16
|
351 {
|
Chris@16
|
352 return seq.back();
|
Chris@16
|
353 }
|
Chris@16
|
354 };
|
Chris@16
|
355
|
Chris@16
|
356 /// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack.
|
Chris@16
|
357 struct top
|
Chris@16
|
358 {
|
Chris@16
|
359 BOOST_PROTO_CALLABLE()
|
Chris@16
|
360 template<typename Sig>
|
Chris@16
|
361 struct result {};
|
Chris@16
|
362
|
Chris@16
|
363 template<typename This, typename Sequence>
|
Chris@16
|
364 struct result<This(Sequence)>
|
Chris@16
|
365 {
|
Chris@16
|
366 typedef typename remove_reference<Sequence>::type sequence_type;
|
Chris@16
|
367 typedef
|
Chris@16
|
368 typename mpl::if_c<
|
Chris@16
|
369 is_const<sequence_type>::value
|
Chris@16
|
370 , typename sequence_type::value_type const &
|
Chris@16
|
371 , typename sequence_type::value_type &
|
Chris@16
|
372 >::type
|
Chris@16
|
373 type;
|
Chris@16
|
374 };
|
Chris@16
|
375
|
Chris@16
|
376 /// \param seq The sequence from which to fetch the top.
|
Chris@16
|
377 /// \return <tt>seq.top()</tt>
|
Chris@16
|
378 template<typename Sequence>
|
Chris@16
|
379 typename result<top(Sequence &)>::type operator()(Sequence &seq) const
|
Chris@16
|
380 {
|
Chris@16
|
381 return seq.top();
|
Chris@16
|
382 }
|
Chris@16
|
383 };
|
Chris@16
|
384
|
Chris@16
|
385 /// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair.
|
Chris@16
|
386 struct first
|
Chris@16
|
387 {
|
Chris@16
|
388 BOOST_PROTO_CALLABLE()
|
Chris@16
|
389 template<typename Sig>
|
Chris@16
|
390 struct result {};
|
Chris@16
|
391
|
Chris@16
|
392 template<typename This, typename Pair>
|
Chris@16
|
393 struct result<This(Pair)>
|
Chris@16
|
394 {
|
Chris@16
|
395 typedef typename remove_reference<Pair>::type::first_type type;
|
Chris@16
|
396 };
|
Chris@16
|
397
|
Chris@16
|
398 /// \param p The pair from which to fetch the first element.
|
Chris@16
|
399 /// \return <tt>p.first</tt>
|
Chris@16
|
400 template<typename Pair>
|
Chris@16
|
401 typename Pair::first_type operator()(Pair const &p) const
|
Chris@16
|
402 {
|
Chris@16
|
403 return p.first;
|
Chris@16
|
404 }
|
Chris@16
|
405 };
|
Chris@16
|
406
|
Chris@16
|
407 /// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair.
|
Chris@16
|
408 struct second
|
Chris@16
|
409 {
|
Chris@16
|
410 BOOST_PROTO_CALLABLE()
|
Chris@16
|
411 template<typename Sig>
|
Chris@16
|
412 struct result {};
|
Chris@16
|
413
|
Chris@16
|
414 template<typename This, typename Pair>
|
Chris@16
|
415 struct result<This(Pair)>
|
Chris@16
|
416 {
|
Chris@16
|
417 typedef typename remove_reference<Pair>::type::second_type type;
|
Chris@16
|
418 };
|
Chris@16
|
419
|
Chris@16
|
420 /// \param p The pair from which to fetch the second element.
|
Chris@16
|
421 /// \return <tt>p.second</tt>
|
Chris@16
|
422 template<typename Pair>
|
Chris@16
|
423 typename Pair::second_type operator()(Pair const &p) const
|
Chris@16
|
424 {
|
Chris@16
|
425 return p.second;
|
Chris@16
|
426 }
|
Chris@16
|
427 };
|
Chris@16
|
428
|
Chris@16
|
429 /// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object
|
Chris@16
|
430 /// matched or not.
|
Chris@16
|
431 struct matched
|
Chris@16
|
432 {
|
Chris@16
|
433 BOOST_PROTO_CALLABLE()
|
Chris@16
|
434 typedef bool result_type;
|
Chris@16
|
435
|
Chris@16
|
436 /// \param sub The \c sub_match object.
|
Chris@16
|
437 /// \return <tt>sub.matched</tt>
|
Chris@16
|
438 template<typename Sub>
|
Chris@16
|
439 bool operator()(Sub const &sub) const
|
Chris@16
|
440 {
|
Chris@16
|
441 return sub.matched;
|
Chris@16
|
442 }
|
Chris@16
|
443 };
|
Chris@16
|
444
|
Chris@16
|
445 /// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match.
|
Chris@16
|
446 struct length
|
Chris@16
|
447 {
|
Chris@16
|
448 BOOST_PROTO_CALLABLE()
|
Chris@16
|
449 template<typename Sig>
|
Chris@16
|
450 struct result {};
|
Chris@16
|
451
|
Chris@16
|
452 template<typename This, typename Sub>
|
Chris@16
|
453 struct result<This(Sub)>
|
Chris@16
|
454 {
|
Chris@16
|
455 typedef typename remove_reference<Sub>::type::difference_type type;
|
Chris@16
|
456 };
|
Chris@16
|
457
|
Chris@16
|
458 /// \param sub The \c sub_match object.
|
Chris@16
|
459 /// \return <tt>sub.length()</tt>
|
Chris@16
|
460 template<typename Sub>
|
Chris@16
|
461 typename Sub::difference_type operator()(Sub const &sub) const
|
Chris@16
|
462 {
|
Chris@16
|
463 return sub.length();
|
Chris@16
|
464 }
|
Chris@16
|
465 };
|
Chris@16
|
466
|
Chris@16
|
467 /// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an
|
Chris@16
|
468 /// equivalent \c std::string.
|
Chris@16
|
469 struct str
|
Chris@16
|
470 {
|
Chris@16
|
471 BOOST_PROTO_CALLABLE()
|
Chris@16
|
472 template<typename Sig>
|
Chris@16
|
473 struct result {};
|
Chris@16
|
474
|
Chris@16
|
475 template<typename This, typename Sub>
|
Chris@16
|
476 struct result<This(Sub)>
|
Chris@16
|
477 {
|
Chris@16
|
478 typedef typename remove_reference<Sub>::type::string_type type;
|
Chris@16
|
479 };
|
Chris@16
|
480
|
Chris@16
|
481 /// \param sub The \c sub_match object.
|
Chris@16
|
482 /// \return <tt>sub.str()</tt>
|
Chris@16
|
483 template<typename Sub>
|
Chris@16
|
484 typename Sub::string_type operator()(Sub const &sub) const
|
Chris@16
|
485 {
|
Chris@16
|
486 return sub.str();
|
Chris@16
|
487 }
|
Chris@16
|
488 };
|
Chris@16
|
489
|
Chris@16
|
490 // This codifies the return types of the various insert member
|
Chris@16
|
491 // functions found in sequence containers, the 2 flavors of
|
Chris@16
|
492 // associative containers, and strings.
|
Chris@16
|
493 //
|
Chris@16
|
494 /// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a
|
Chris@16
|
495 /// sequence of values into a sequence container, an associative
|
Chris@16
|
496 /// container, or a string.
|
Chris@16
|
497 struct insert
|
Chris@16
|
498 {
|
Chris@16
|
499 BOOST_PROTO_CALLABLE()
|
Chris@16
|
500
|
Chris@16
|
501 /// INTERNAL ONLY
|
Chris@16
|
502 ///
|
Chris@16
|
503 struct detail
|
Chris@16
|
504 {
|
Chris@16
|
505 template<typename Sig, typename EnableIf = void>
|
Chris@16
|
506 struct result_detail
|
Chris@16
|
507 {};
|
Chris@16
|
508
|
Chris@16
|
509 // assoc containers
|
Chris@16
|
510 template<typename This, typename Cont, typename Value>
|
Chris@16
|
511 struct result_detail<This(Cont, Value), void>
|
Chris@16
|
512 {
|
Chris@16
|
513 typedef typename remove_reference<Cont>::type cont_type;
|
Chris@16
|
514 typedef typename remove_reference<Value>::type value_type;
|
Chris@16
|
515 static cont_type &scont_;
|
Chris@16
|
516 static value_type &svalue_;
|
Chris@16
|
517 typedef char yes_type;
|
Chris@16
|
518 typedef char (&no_type)[2];
|
Chris@16
|
519 static yes_type check_insert_return(typename cont_type::iterator);
|
Chris@16
|
520 static no_type check_insert_return(std::pair<typename cont_type::iterator, bool>);
|
Chris@16
|
521 BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_)))));
|
Chris@16
|
522 typedef
|
Chris@16
|
523 typename mpl::if_c<
|
Chris@16
|
524 is_iterator
|
Chris@16
|
525 , typename cont_type::iterator
|
Chris@16
|
526 , std::pair<typename cont_type::iterator, bool>
|
Chris@16
|
527 >::type
|
Chris@16
|
528 type;
|
Chris@16
|
529 };
|
Chris@16
|
530
|
Chris@16
|
531 // sequence containers, assoc containers, strings
|
Chris@16
|
532 template<typename This, typename Cont, typename It, typename Value>
|
Chris@16
|
533 struct result_detail<This(Cont, It, Value),
|
Chris@16
|
534 typename disable_if<
|
Chris@16
|
535 mpl::or_<
|
Chris@16
|
536 is_integral<typename remove_cv<typename remove_reference<It>::type>::type>
|
Chris@16
|
537 , is_same<
|
Chris@16
|
538 typename remove_cv<typename remove_reference<It>::type>::type
|
Chris@16
|
539 , typename remove_cv<typename remove_reference<Value>::type>::type
|
Chris@16
|
540 >
|
Chris@16
|
541 >
|
Chris@16
|
542 >::type
|
Chris@16
|
543 >
|
Chris@16
|
544 {
|
Chris@16
|
545 typedef typename remove_reference<Cont>::type::iterator type;
|
Chris@16
|
546 };
|
Chris@16
|
547
|
Chris@16
|
548 // strings
|
Chris@16
|
549 template<typename This, typename Cont, typename Size, typename T>
|
Chris@16
|
550 struct result_detail<This(Cont, Size, T),
|
Chris@16
|
551 typename enable_if<
|
Chris@16
|
552 is_integral<typename remove_cv<typename remove_reference<Size>::type>::type>
|
Chris@16
|
553 >::type
|
Chris@16
|
554 >
|
Chris@16
|
555 {
|
Chris@16
|
556 typedef typename remove_reference<Cont>::type &type;
|
Chris@16
|
557 };
|
Chris@16
|
558
|
Chris@16
|
559 // assoc containers
|
Chris@16
|
560 template<typename This, typename Cont, typename It>
|
Chris@16
|
561 struct result_detail<This(Cont, It, It), void>
|
Chris@16
|
562 {
|
Chris@16
|
563 typedef void type;
|
Chris@16
|
564 };
|
Chris@16
|
565
|
Chris@16
|
566 // sequence containers, strings
|
Chris@16
|
567 template<typename This, typename Cont, typename It, typename Size, typename Value>
|
Chris@16
|
568 struct result_detail<This(Cont, It, Size, Value),
|
Chris@16
|
569 typename disable_if<
|
Chris@16
|
570 is_integral<typename remove_cv<typename remove_reference<It>::type>::type>
|
Chris@16
|
571 >::type
|
Chris@16
|
572 >
|
Chris@16
|
573 {
|
Chris@16
|
574 typedef void type;
|
Chris@16
|
575 };
|
Chris@16
|
576
|
Chris@16
|
577 // strings
|
Chris@16
|
578 template<typename This, typename Cont, typename Size, typename A0, typename A1>
|
Chris@16
|
579 struct result_detail<This(Cont, Size, A0, A1),
|
Chris@16
|
580 typename enable_if<
|
Chris@16
|
581 is_integral<typename remove_cv<typename remove_reference<Size>::type>::type>
|
Chris@16
|
582 >::type
|
Chris@16
|
583 >
|
Chris@16
|
584 {
|
Chris@16
|
585 typedef typename remove_reference<Cont>::type &type;
|
Chris@16
|
586 };
|
Chris@16
|
587
|
Chris@16
|
588 // strings
|
Chris@16
|
589 template<typename This, typename Cont, typename Pos0, typename String, typename Pos1, typename Length>
|
Chris@16
|
590 struct result_detail<This(Cont, Pos0, String, Pos1, Length)>
|
Chris@16
|
591 {
|
Chris@16
|
592 typedef typename remove_reference<Cont>::type &type;
|
Chris@16
|
593 };
|
Chris@16
|
594 };
|
Chris@16
|
595
|
Chris@16
|
596 template<typename Sig>
|
Chris@16
|
597 struct result
|
Chris@16
|
598 {
|
Chris@16
|
599 typedef typename detail::result_detail<Sig>::type type;
|
Chris@16
|
600 };
|
Chris@16
|
601
|
Chris@16
|
602 /// \overload
|
Chris@16
|
603 ///
|
Chris@16
|
604 template<typename Cont, typename A0>
|
Chris@16
|
605 typename result<insert(Cont &, A0 const &)>::type
|
Chris@16
|
606 operator()(Cont &cont, A0 const &a0) const
|
Chris@16
|
607 {
|
Chris@16
|
608 return cont.insert(a0);
|
Chris@16
|
609 }
|
Chris@16
|
610
|
Chris@16
|
611 /// \overload
|
Chris@16
|
612 ///
|
Chris@16
|
613 template<typename Cont, typename A0, typename A1>
|
Chris@16
|
614 typename result<insert(Cont &, A0 const &, A1 const &)>::type
|
Chris@16
|
615 operator()(Cont &cont, A0 const &a0, A1 const &a1) const
|
Chris@16
|
616 {
|
Chris@16
|
617 return cont.insert(a0, a1);
|
Chris@16
|
618 }
|
Chris@16
|
619
|
Chris@16
|
620 /// \overload
|
Chris@16
|
621 ///
|
Chris@16
|
622 template<typename Cont, typename A0, typename A1, typename A2>
|
Chris@16
|
623 typename result<insert(Cont &, A0 const &, A1 const &, A2 const &)>::type
|
Chris@16
|
624 operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const
|
Chris@16
|
625 {
|
Chris@16
|
626 return cont.insert(a0, a1, a2);
|
Chris@16
|
627 }
|
Chris@16
|
628
|
Chris@16
|
629 /// \param cont The container into which to insert the element(s)
|
Chris@16
|
630 /// \param a0 A value, iterator, or count
|
Chris@16
|
631 /// \param a1 A value, iterator, string, count, or character
|
Chris@16
|
632 /// \param a2 A value, iterator, or count
|
Chris@16
|
633 /// \param a3 A count
|
Chris@16
|
634 /// \return \li For the form <tt>insert()(cont, a0)</tt>, return <tt>cont.insert(a0)</tt>.
|
Chris@16
|
635 /// \li For the form <tt>insert()(cont, a0, a1)</tt>, return <tt>cont.insert(a0, a1)</tt>.
|
Chris@16
|
636 /// \li For the form <tt>insert()(cont, a0, a1, a2)</tt>, return <tt>cont.insert(a0, a1, a2)</tt>.
|
Chris@16
|
637 /// \li For the form <tt>insert()(cont, a0, a1, a2, a3)</tt>, return <tt>cont.insert(a0, a1, a2, a3)</tt>.
|
Chris@16
|
638 template<typename Cont, typename A0, typename A1, typename A2, typename A3>
|
Chris@16
|
639 typename result<insert(Cont &, A0 const &, A1 const &, A2 const &, A3 const &)>::type
|
Chris@16
|
640 operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const
|
Chris@16
|
641 {
|
Chris@16
|
642 return cont.insert(a0, a1, a2, a3);
|
Chris@16
|
643 }
|
Chris@16
|
644 };
|
Chris@16
|
645
|
Chris@16
|
646 /// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters
|
Chris@16
|
647 struct make_pair
|
Chris@16
|
648 {
|
Chris@16
|
649 BOOST_PROTO_CALLABLE()
|
Chris@16
|
650 template<typename Sig>
|
Chris@16
|
651 struct result {};
|
Chris@16
|
652
|
Chris@16
|
653 template<typename This, typename First, typename Second>
|
Chris@16
|
654 struct result<This(First, Second)>
|
Chris@16
|
655 {
|
Chris@16
|
656 /// \brief For exposition only
|
Chris@16
|
657 typedef typename decay<First>::type first_type;
|
Chris@16
|
658 /// \brief For exposition only
|
Chris@16
|
659 typedef typename decay<Second>::type second_type;
|
Chris@16
|
660 typedef std::pair<first_type, second_type> type;
|
Chris@16
|
661 };
|
Chris@16
|
662
|
Chris@16
|
663 /// \param first The first element of the pair
|
Chris@16
|
664 /// \param second The second element of the pair
|
Chris@16
|
665 /// \return <tt>std::make_pair(first, second)</tt>
|
Chris@16
|
666 template<typename First, typename Second>
|
Chris@16
|
667 std::pair<First, Second> operator()(First const &first, Second const &second) const
|
Chris@16
|
668 {
|
Chris@16
|
669 return std::make_pair(first, second);
|
Chris@16
|
670 }
|
Chris@16
|
671 };
|
Chris@16
|
672
|
Chris@16
|
673 /// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type.
|
Chris@16
|
674 /// \tparam T The type to which to lexically cast the parameter.
|
Chris@16
|
675 template<typename T>
|
Chris@16
|
676 struct as
|
Chris@16
|
677 {
|
Chris@16
|
678 BOOST_PROTO_CALLABLE()
|
Chris@16
|
679 typedef T result_type;
|
Chris@16
|
680
|
Chris@16
|
681 /// \param val The value to lexically cast.
|
Chris@16
|
682 /// \return <tt>boost::lexical_cast\<T\>(val)</tt>
|
Chris@16
|
683 template<typename Value>
|
Chris@16
|
684 T operator()(Value const &val) const
|
Chris@16
|
685 {
|
Chris@16
|
686 return boost::lexical_cast<T>(val);
|
Chris@16
|
687 }
|
Chris@16
|
688
|
Chris@16
|
689 // Hack around some limitations in boost::lexical_cast
|
Chris@16
|
690 /// INTERNAL ONLY
|
Chris@16
|
691 T operator()(csub_match const &val) const
|
Chris@16
|
692 {
|
Chris@16
|
693 return val.matched
|
Chris@16
|
694 ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second))
|
Chris@16
|
695 : boost::lexical_cast<T>("");
|
Chris@16
|
696 }
|
Chris@16
|
697
|
Chris@16
|
698 #ifndef BOOST_XPRESSIVE_NO_WREGEX
|
Chris@16
|
699 /// INTERNAL ONLY
|
Chris@16
|
700 T operator()(wcsub_match const &val) const
|
Chris@16
|
701 {
|
Chris@16
|
702 return val.matched
|
Chris@16
|
703 ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second))
|
Chris@16
|
704 : boost::lexical_cast<T>("");
|
Chris@16
|
705 }
|
Chris@16
|
706 #endif
|
Chris@16
|
707
|
Chris@16
|
708 /// INTERNAL ONLY
|
Chris@16
|
709 template<typename BidiIter>
|
Chris@16
|
710 T operator()(sub_match<BidiIter> const &val) const
|
Chris@16
|
711 {
|
Chris@16
|
712 // If this assert fires, you're trying to coerce a sequences of non-characters
|
Chris@16
|
713 // to some other type. Xpressive doesn't know how to do that.
|
Chris@16
|
714 typedef typename iterator_value<BidiIter>::type char_type;
|
Chris@16
|
715 BOOST_MPL_ASSERT_MSG(
|
Chris@16
|
716 (xpressive::detail::is_char<char_type>::value)
|
Chris@16
|
717 , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES
|
Chris@16
|
718 , (char_type)
|
Chris@16
|
719 );
|
Chris@16
|
720 return this->impl(val, xpressive::detail::is_string_iterator<BidiIter>());
|
Chris@16
|
721 }
|
Chris@16
|
722
|
Chris@16
|
723 private:
|
Chris@16
|
724 /// INTERNAL ONLY
|
Chris@16
|
725 template<typename RandIter>
|
Chris@16
|
726 T impl(sub_match<RandIter> const &val, mpl::true_) const
|
Chris@16
|
727 {
|
Chris@16
|
728 return val.matched
|
Chris@16
|
729 ? boost::lexical_cast<T>(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first)))
|
Chris@16
|
730 : boost::lexical_cast<T>("");
|
Chris@16
|
731 }
|
Chris@16
|
732
|
Chris@16
|
733 /// INTERNAL ONLY
|
Chris@16
|
734 template<typename BidiIter>
|
Chris@16
|
735 T impl(sub_match<BidiIter> const &val, mpl::false_) const
|
Chris@16
|
736 {
|
Chris@16
|
737 return boost::lexical_cast<T>(val.str());
|
Chris@16
|
738 }
|
Chris@16
|
739 };
|
Chris@16
|
740
|
Chris@16
|
741 /// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type.
|
Chris@16
|
742 /// \tparam T The type to which to statically cast the parameter.
|
Chris@16
|
743 template<typename T>
|
Chris@16
|
744 struct static_cast_
|
Chris@16
|
745 {
|
Chris@16
|
746 BOOST_PROTO_CALLABLE()
|
Chris@16
|
747 typedef T result_type;
|
Chris@16
|
748
|
Chris@16
|
749 /// \param val The value to statically cast.
|
Chris@16
|
750 /// \return <tt>static_cast\<T\>(val)</tt>
|
Chris@16
|
751 template<typename Value>
|
Chris@16
|
752 T operator()(Value const &val) const
|
Chris@16
|
753 {
|
Chris@16
|
754 return static_cast<T>(val);
|
Chris@16
|
755 }
|
Chris@16
|
756 };
|
Chris@16
|
757
|
Chris@16
|
758 /// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type.
|
Chris@16
|
759 /// \tparam T The type to which to dynamically cast the parameter.
|
Chris@16
|
760 template<typename T>
|
Chris@16
|
761 struct dynamic_cast_
|
Chris@16
|
762 {
|
Chris@16
|
763 BOOST_PROTO_CALLABLE()
|
Chris@16
|
764 typedef T result_type;
|
Chris@16
|
765
|
Chris@16
|
766 /// \param val The value to dynamically cast.
|
Chris@16
|
767 /// \return <tt>dynamic_cast\<T\>(val)</tt>
|
Chris@16
|
768 template<typename Value>
|
Chris@16
|
769 T operator()(Value const &val) const
|
Chris@16
|
770 {
|
Chris@16
|
771 return dynamic_cast<T>(val);
|
Chris@16
|
772 }
|
Chris@16
|
773 };
|
Chris@16
|
774
|
Chris@16
|
775 /// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification.
|
Chris@16
|
776 /// \tparam T The type to which to const-cast the parameter.
|
Chris@16
|
777 template<typename T>
|
Chris@16
|
778 struct const_cast_
|
Chris@16
|
779 {
|
Chris@16
|
780 BOOST_PROTO_CALLABLE()
|
Chris@16
|
781 typedef T result_type;
|
Chris@16
|
782
|
Chris@16
|
783 /// \param val The value to const-cast.
|
Chris@16
|
784 /// \pre Types \c T and \c Value differ only in cv-qualification.
|
Chris@16
|
785 /// \return <tt>const_cast\<T\>(val)</tt>
|
Chris@16
|
786 template<typename Value>
|
Chris@16
|
787 T operator()(Value const &val) const
|
Chris@16
|
788 {
|
Chris@16
|
789 return const_cast<T>(val);
|
Chris@16
|
790 }
|
Chris@16
|
791 };
|
Chris@16
|
792
|
Chris@16
|
793 /// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object.
|
Chris@16
|
794 /// \tparam T The type of the object to construct.
|
Chris@16
|
795 template<typename T>
|
Chris@16
|
796 struct construct
|
Chris@16
|
797 {
|
Chris@16
|
798 BOOST_PROTO_CALLABLE()
|
Chris@16
|
799 typedef T result_type;
|
Chris@16
|
800
|
Chris@16
|
801 /// \overload
|
Chris@16
|
802 T operator()() const
|
Chris@16
|
803 {
|
Chris@16
|
804 return T();
|
Chris@16
|
805 }
|
Chris@16
|
806
|
Chris@16
|
807 /// \overload
|
Chris@16
|
808 template<typename A0>
|
Chris@16
|
809 T operator()(A0 const &a0) const
|
Chris@16
|
810 {
|
Chris@16
|
811 return T(a0);
|
Chris@16
|
812 }
|
Chris@16
|
813
|
Chris@16
|
814 /// \overload
|
Chris@16
|
815 template<typename A0, typename A1>
|
Chris@16
|
816 T operator()(A0 const &a0, A1 const &a1) const
|
Chris@16
|
817 {
|
Chris@16
|
818 return T(a0, a1);
|
Chris@16
|
819 }
|
Chris@16
|
820
|
Chris@16
|
821 /// \param a0 The first argument to the constructor
|
Chris@16
|
822 /// \param a1 The second argument to the constructor
|
Chris@16
|
823 /// \param a2 The third argument to the constructor
|
Chris@16
|
824 /// \return <tt>T(a0,a1,...)</tt>
|
Chris@16
|
825 template<typename A0, typename A1, typename A2>
|
Chris@16
|
826 T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
|
Chris@16
|
827 {
|
Chris@16
|
828 return T(a0, a1, a2);
|
Chris@16
|
829 }
|
Chris@16
|
830 };
|
Chris@16
|
831
|
Chris@16
|
832 /// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception.
|
Chris@16
|
833 /// \tparam Except The type of the object to throw.
|
Chris@16
|
834 template<typename Except>
|
Chris@16
|
835 struct throw_
|
Chris@16
|
836 {
|
Chris@16
|
837 BOOST_PROTO_CALLABLE()
|
Chris@16
|
838 typedef void result_type;
|
Chris@16
|
839
|
Chris@16
|
840 /// \overload
|
Chris@16
|
841 void operator()() const
|
Chris@16
|
842 {
|
Chris@16
|
843 BOOST_THROW_EXCEPTION(Except());
|
Chris@16
|
844 }
|
Chris@16
|
845
|
Chris@16
|
846 /// \overload
|
Chris@16
|
847 template<typename A0>
|
Chris@16
|
848 void operator()(A0 const &a0) const
|
Chris@16
|
849 {
|
Chris@16
|
850 BOOST_THROW_EXCEPTION(Except(a0));
|
Chris@16
|
851 }
|
Chris@16
|
852
|
Chris@16
|
853 /// \overload
|
Chris@16
|
854 template<typename A0, typename A1>
|
Chris@16
|
855 void operator()(A0 const &a0, A1 const &a1) const
|
Chris@16
|
856 {
|
Chris@16
|
857 BOOST_THROW_EXCEPTION(Except(a0, a1));
|
Chris@16
|
858 }
|
Chris@16
|
859
|
Chris@16
|
860 /// \param a0 The first argument to the constructor
|
Chris@16
|
861 /// \param a1 The second argument to the constructor
|
Chris@16
|
862 /// \param a2 The third argument to the constructor
|
Chris@16
|
863 /// \throw <tt>Except(a0,a1,...)</tt>
|
Chris@16
|
864 /// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro
|
Chris@16
|
865 /// to actually throw the exception. See the documentation for the
|
Chris@16
|
866 /// Boost.Exception library.
|
Chris@16
|
867 template<typename A0, typename A1, typename A2>
|
Chris@16
|
868 void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
|
Chris@16
|
869 {
|
Chris@16
|
870 BOOST_THROW_EXCEPTION(Except(a0, a1, a2));
|
Chris@16
|
871 }
|
Chris@16
|
872 };
|
Chris@16
|
873
|
Chris@16
|
874 /// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a <tt>boost::reference_wrapper\<\></tt>.
|
Chris@16
|
875 struct unwrap_reference
|
Chris@16
|
876 {
|
Chris@16
|
877 BOOST_PROTO_CALLABLE()
|
Chris@16
|
878 template<typename Sig>
|
Chris@16
|
879 struct result {};
|
Chris@16
|
880
|
Chris@16
|
881 template<typename This, typename Ref>
|
Chris@16
|
882 struct result<This(Ref)>
|
Chris@16
|
883 {
|
Chris@16
|
884 typedef typename boost::unwrap_reference<Ref>::type &type;
|
Chris@16
|
885 };
|
Chris@16
|
886
|
Chris@16
|
887 template<typename This, typename Ref>
|
Chris@16
|
888 struct result<This(Ref &)>
|
Chris@16
|
889 {
|
Chris@16
|
890 typedef typename boost::unwrap_reference<Ref>::type &type;
|
Chris@16
|
891 };
|
Chris@16
|
892
|
Chris@16
|
893 /// \param r The <tt>boost::reference_wrapper\<T\></tt> to unwrap.
|
Chris@16
|
894 /// \return <tt>static_cast\<T &\>(r)</tt>
|
Chris@16
|
895 template<typename T>
|
Chris@16
|
896 T &operator()(boost::reference_wrapper<T> r) const
|
Chris@16
|
897 {
|
Chris@16
|
898 return static_cast<T &>(r);
|
Chris@16
|
899 }
|
Chris@16
|
900 };
|
Chris@16
|
901 }
|
Chris@16
|
902
|
Chris@16
|
903 /// \brief A unary metafunction that turns an ordinary function object type into the type of
|
Chris@16
|
904 /// a deferred function object for use in xpressive semantic actions.
|
Chris@16
|
905 ///
|
Chris@16
|
906 /// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type
|
Chris@16
|
907 /// into a type that can be used to declare an object for use in xpressive semantic actions.
|
Chris@16
|
908 ///
|
Chris@16
|
909 /// For example, the global object \c xpressive::push_back can be used to create deferred actions
|
Chris@16
|
910 /// that have the effect of pushing a value into a container. It is defined with
|
Chris@16
|
911 /// \c xpressive::function\<\> as follows:
|
Chris@16
|
912 ///
|
Chris@16
|
913 /** \code
|
Chris@16
|
914 xpressive::function<xpressive::op::push_back>::type const push_back = {};
|
Chris@16
|
915 \endcode
|
Chris@16
|
916 */
|
Chris@16
|
917 ///
|
Chris@16
|
918 /// where \c op::push_back is an ordinary function object that pushes its second argument into
|
Chris@16
|
919 /// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows:
|
Chris@16
|
920 ///
|
Chris@16
|
921 /** \code
|
Chris@16
|
922 namespace xp = boost::xpressive;
|
Chris@16
|
923 using xp::_;
|
Chris@16
|
924 std::list<int> result;
|
Chris@16
|
925 std::string str("1 23 456 7890");
|
Chris@16
|
926 xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ]
|
Chris@16
|
927 >> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ) ]);
|
Chris@16
|
928 \endcode
|
Chris@16
|
929 */
|
Chris@16
|
930 template<typename PolymorphicFunctionObject>
|
Chris@16
|
931 struct function
|
Chris@16
|
932 {
|
Chris@16
|
933 typedef typename proto::terminal<PolymorphicFunctionObject>::type type;
|
Chris@16
|
934 };
|
Chris@16
|
935
|
Chris@16
|
936 /// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an
|
Chris@16
|
937 /// xpressive semantic action.
|
Chris@16
|
938 function<op::at>::type const at = {{}};
|
Chris@16
|
939
|
Chris@16
|
940 /// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an
|
Chris@16
|
941 /// xpressive semantic action.
|
Chris@16
|
942 function<op::push>::type const push = {{}};
|
Chris@16
|
943
|
Chris@16
|
944 /// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an
|
Chris@16
|
945 /// xpressive semantic action.
|
Chris@16
|
946 function<op::push_back>::type const push_back = {{}};
|
Chris@16
|
947
|
Chris@16
|
948 /// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an
|
Chris@16
|
949 /// xpressive semantic action.
|
Chris@16
|
950 function<op::push_front>::type const push_front = {{}};
|
Chris@16
|
951
|
Chris@16
|
952 /// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an
|
Chris@16
|
953 /// xpressive semantic action.
|
Chris@16
|
954 function<op::pop>::type const pop = {{}};
|
Chris@16
|
955
|
Chris@16
|
956 /// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an
|
Chris@16
|
957 /// xpressive semantic action.
|
Chris@16
|
958 function<op::pop_back>::type const pop_back = {{}};
|
Chris@16
|
959
|
Chris@16
|
960 /// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an
|
Chris@16
|
961 /// xpressive semantic action.
|
Chris@16
|
962 function<op::pop_front>::type const pop_front = {{}};
|
Chris@16
|
963
|
Chris@16
|
964 /// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an
|
Chris@16
|
965 /// xpressive semantic action.
|
Chris@16
|
966 function<op::top>::type const top = {{}};
|
Chris@16
|
967
|
Chris@16
|
968 /// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an
|
Chris@16
|
969 /// xpressive semantic action.
|
Chris@16
|
970 function<op::back>::type const back = {{}};
|
Chris@16
|
971
|
Chris@16
|
972 /// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an
|
Chris@16
|
973 /// xpressive semantic action.
|
Chris@16
|
974 function<op::front>::type const front = {{}};
|
Chris@16
|
975
|
Chris@16
|
976 /// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an
|
Chris@16
|
977 /// xpressive semantic action.
|
Chris@16
|
978 function<op::first>::type const first = {{}};
|
Chris@16
|
979
|
Chris@16
|
980 /// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an
|
Chris@16
|
981 /// xpressive semantic action.
|
Chris@16
|
982 function<op::second>::type const second = {{}};
|
Chris@16
|
983
|
Chris@16
|
984 /// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an
|
Chris@16
|
985 /// xpressive semantic action.
|
Chris@16
|
986 function<op::matched>::type const matched = {{}};
|
Chris@16
|
987
|
Chris@16
|
988 /// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an
|
Chris@16
|
989 /// xpressive semantic action.
|
Chris@16
|
990 function<op::length>::type const length = {{}};
|
Chris@16
|
991
|
Chris@16
|
992 /// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an
|
Chris@16
|
993 /// xpressive semantic action.
|
Chris@16
|
994 function<op::str>::type const str = {{}};
|
Chris@16
|
995
|
Chris@16
|
996 /// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an
|
Chris@16
|
997 /// xpressive semantic action.
|
Chris@16
|
998 function<op::insert>::type const insert = {{}};
|
Chris@16
|
999
|
Chris@16
|
1000 /// \brief \c make_pair is a lazy PolymorphicFunctionObject for making a \c std::pair\<\> in an
|
Chris@16
|
1001 /// xpressive semantic action.
|
Chris@16
|
1002 function<op::make_pair>::type const make_pair = {{}};
|
Chris@16
|
1003
|
Chris@16
|
1004 /// \brief \c unwrap_reference is a lazy PolymorphicFunctionObject for unwrapping a \c boost::reference_wrapper\<\> in an
|
Chris@16
|
1005 /// xpressive semantic action.
|
Chris@16
|
1006 function<op::unwrap_reference>::type const unwrap_reference = {{}};
|
Chris@16
|
1007
|
Chris@16
|
1008 /// \brief \c value\<\> is a lazy wrapper for a value that can be used in xpressive semantic actions.
|
Chris@16
|
1009 /// \tparam T The type of the value to store.
|
Chris@16
|
1010 ///
|
Chris@16
|
1011 /// Below is an example that shows where \c <tt>value\<\></tt> is useful.
|
Chris@16
|
1012 ///
|
Chris@16
|
1013 /** \code
|
Chris@16
|
1014 sregex good_voodoo(boost::shared_ptr<int> pi)
|
Chris@16
|
1015 {
|
Chris@16
|
1016 using namespace boost::xpressive;
|
Chris@16
|
1017 // Use val() to hold the shared_ptr by value:
|
Chris@16
|
1018 sregex rex = +( _d [ ++*val(pi) ] >> '!' );
|
Chris@16
|
1019 // OK, rex holds a reference count to the integer.
|
Chris@16
|
1020 return rex;
|
Chris@16
|
1021 }
|
Chris@16
|
1022 \endcode
|
Chris@16
|
1023 */
|
Chris@16
|
1024 ///
|
Chris@16
|
1025 /// In the above code, \c xpressive::val() is a function that returns a \c value\<\> object. Had
|
Chris@16
|
1026 /// \c val() not been used here, the operation <tt>++*pi</tt> would have been evaluated eagerly
|
Chris@16
|
1027 /// once, instead of lazily when the regex match happens.
|
Chris@16
|
1028 template<typename T>
|
Chris@16
|
1029 struct value
|
Chris@16
|
1030 : proto::extends<typename proto::terminal<T>::type, value<T> >
|
Chris@16
|
1031 {
|
Chris@16
|
1032 /// INTERNAL ONLY
|
Chris@16
|
1033 typedef proto::extends<typename proto::terminal<T>::type, value<T> > base_type;
|
Chris@16
|
1034
|
Chris@16
|
1035 /// \brief Store a default-constructed \c T
|
Chris@16
|
1036 value()
|
Chris@16
|
1037 : base_type()
|
Chris@16
|
1038 {}
|
Chris@16
|
1039
|
Chris@16
|
1040 /// \param t The initial value.
|
Chris@16
|
1041 /// \brief Store a copy of \c t.
|
Chris@16
|
1042 explicit value(T const &t)
|
Chris@16
|
1043 : base_type(base_type::proto_base_expr::make(t))
|
Chris@16
|
1044 {}
|
Chris@16
|
1045
|
Chris@16
|
1046 using base_type::operator=;
|
Chris@16
|
1047
|
Chris@16
|
1048 /// \overload
|
Chris@16
|
1049 T &get()
|
Chris@16
|
1050 {
|
Chris@16
|
1051 return proto::value(*this);
|
Chris@16
|
1052 }
|
Chris@16
|
1053
|
Chris@16
|
1054 /// \brief Fetch the stored value
|
Chris@16
|
1055 T const &get() const
|
Chris@16
|
1056 {
|
Chris@16
|
1057 return proto::value(*this);
|
Chris@16
|
1058 }
|
Chris@16
|
1059 };
|
Chris@16
|
1060
|
Chris@16
|
1061 /// \brief \c reference\<\> is a lazy wrapper for a reference that can be used in
|
Chris@16
|
1062 /// xpressive semantic actions.
|
Chris@16
|
1063 ///
|
Chris@16
|
1064 /// \tparam T The type of the referent.
|
Chris@16
|
1065 ///
|
Chris@16
|
1066 /// Here is an example of how to use \c reference\<\> to create a lazy reference to
|
Chris@16
|
1067 /// an existing object so it can be read and written in an xpressive semantic action.
|
Chris@16
|
1068 ///
|
Chris@16
|
1069 /** \code
|
Chris@16
|
1070 using namespace boost::xpressive;
|
Chris@16
|
1071 std::map<std::string, int> result;
|
Chris@16
|
1072 reference<std::map<std::string, int> > result_ref(result);
|
Chris@16
|
1073
|
Chris@16
|
1074 // Match a word and an integer, separated by =>,
|
Chris@16
|
1075 // and then stuff the result into a std::map<>
|
Chris@16
|
1076 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
|
Chris@16
|
1077 [ result_ref[s1] = as<int>(s2) ];
|
Chris@16
|
1078 \endcode
|
Chris@16
|
1079 */
|
Chris@16
|
1080 template<typename T>
|
Chris@16
|
1081 struct reference
|
Chris@16
|
1082 : proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> >
|
Chris@16
|
1083 {
|
Chris@16
|
1084 /// INTERNAL ONLY
|
Chris@16
|
1085 typedef proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > base_type;
|
Chris@16
|
1086
|
Chris@16
|
1087 /// \param t Reference to object
|
Chris@16
|
1088 /// \brief Store a reference to \c t
|
Chris@16
|
1089 explicit reference(T &t)
|
Chris@16
|
1090 : base_type(base_type::proto_base_expr::make(boost::ref(t)))
|
Chris@16
|
1091 {}
|
Chris@16
|
1092
|
Chris@16
|
1093 using base_type::operator=;
|
Chris@16
|
1094
|
Chris@16
|
1095 /// \brief Fetch the stored value
|
Chris@16
|
1096 T &get() const
|
Chris@16
|
1097 {
|
Chris@16
|
1098 return proto::value(*this).get();
|
Chris@16
|
1099 }
|
Chris@16
|
1100 };
|
Chris@16
|
1101
|
Chris@16
|
1102 /// \brief \c local\<\> is a lazy wrapper for a reference to a value that is stored within the local itself.
|
Chris@16
|
1103 /// It is for use within xpressive semantic actions.
|
Chris@16
|
1104 ///
|
Chris@16
|
1105 /// \tparam T The type of the local variable.
|
Chris@16
|
1106 ///
|
Chris@16
|
1107 /// Below is an example of how to use \c local\<\> in semantic actions.
|
Chris@16
|
1108 ///
|
Chris@16
|
1109 /** \code
|
Chris@16
|
1110 using namespace boost::xpressive;
|
Chris@16
|
1111 local<int> i(0);
|
Chris@16
|
1112 std::string str("1!2!3?");
|
Chris@16
|
1113 // count the exciting digits, but not the
|
Chris@16
|
1114 // questionable ones.
|
Chris@16
|
1115 sregex rex = +( _d [ ++i ] >> '!' );
|
Chris@16
|
1116 regex_search(str, rex);
|
Chris@16
|
1117 assert( i.get() == 2 );
|
Chris@16
|
1118 \endcode
|
Chris@16
|
1119 */
|
Chris@16
|
1120 ///
|
Chris@16
|
1121 /// \note As the name "local" suggests, \c local\<\> objects and the regexes
|
Chris@16
|
1122 /// that refer to them should never leave the local scope. The value stored
|
Chris@16
|
1123 /// within the local object will be destroyed at the end of the \c local\<\>'s
|
Chris@16
|
1124 /// lifetime, and any regex objects still holding the \c local\<\> will be
|
Chris@16
|
1125 /// left with a dangling reference.
|
Chris@16
|
1126 template<typename T>
|
Chris@16
|
1127 struct local
|
Chris@16
|
1128 : detail::value_wrapper<T>
|
Chris@16
|
1129 , proto::terminal<reference_wrapper<T> >::type
|
Chris@16
|
1130 {
|
Chris@16
|
1131 /// INTERNAL ONLY
|
Chris@16
|
1132 typedef typename proto::terminal<reference_wrapper<T> >::type base_type;
|
Chris@16
|
1133
|
Chris@16
|
1134 /// \brief Store a default-constructed value of type \c T
|
Chris@16
|
1135 local()
|
Chris@16
|
1136 : detail::value_wrapper<T>()
|
Chris@16
|
1137 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
|
Chris@16
|
1138 {}
|
Chris@16
|
1139
|
Chris@16
|
1140 /// \param t The initial value.
|
Chris@16
|
1141 /// \brief Store a default-constructed value of type \c T
|
Chris@16
|
1142 explicit local(T const &t)
|
Chris@16
|
1143 : detail::value_wrapper<T>(t)
|
Chris@16
|
1144 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
|
Chris@16
|
1145 {}
|
Chris@16
|
1146
|
Chris@16
|
1147 using base_type::operator=;
|
Chris@16
|
1148
|
Chris@16
|
1149 /// Fetch the wrapped value.
|
Chris@16
|
1150 T &get()
|
Chris@16
|
1151 {
|
Chris@16
|
1152 return proto::value(*this);
|
Chris@16
|
1153 }
|
Chris@16
|
1154
|
Chris@16
|
1155 /// \overload
|
Chris@16
|
1156 T const &get() const
|
Chris@16
|
1157 {
|
Chris@16
|
1158 return proto::value(*this);
|
Chris@16
|
1159 }
|
Chris@16
|
1160 };
|
Chris@16
|
1161
|
Chris@16
|
1162 /// \brief \c as() is a lazy funtion for lexically casting a parameter to a different type.
|
Chris@16
|
1163 /// \tparam T The type to which to lexically cast the parameter.
|
Chris@16
|
1164 /// \param a The lazy value to lexically cast.
|
Chris@16
|
1165 /// \return A lazy object that, when evaluated, lexically casts its argument to the desired type.
|
Chris@16
|
1166 template<typename T, typename A>
|
Chris@16
|
1167 typename detail::make_function::impl<op::as<T> const, A const &>::result_type const
|
Chris@16
|
1168 as(A const &a)
|
Chris@16
|
1169 {
|
Chris@16
|
1170 return detail::make_function::impl<op::as<T> const, A const &>()((op::as<T>()), a);
|
Chris@16
|
1171 }
|
Chris@16
|
1172
|
Chris@16
|
1173 /// \brief \c static_cast_ is a lazy funtion for statically casting a parameter to a different type.
|
Chris@16
|
1174 /// \tparam T The type to which to statically cast the parameter.
|
Chris@16
|
1175 /// \param a The lazy value to statically cast.
|
Chris@16
|
1176 /// \return A lazy object that, when evaluated, statically casts its argument to the desired type.
|
Chris@16
|
1177 template<typename T, typename A>
|
Chris@16
|
1178 typename detail::make_function::impl<op::static_cast_<T> const, A const &>::result_type const
|
Chris@16
|
1179 static_cast_(A const &a)
|
Chris@16
|
1180 {
|
Chris@16
|
1181 return detail::make_function::impl<op::static_cast_<T> const, A const &>()((op::static_cast_<T>()), a);
|
Chris@16
|
1182 }
|
Chris@16
|
1183
|
Chris@16
|
1184 /// \brief \c dynamic_cast_ is a lazy funtion for dynamically casting a parameter to a different type.
|
Chris@16
|
1185 /// \tparam T The type to which to dynamically cast the parameter.
|
Chris@16
|
1186 /// \param a The lazy value to dynamically cast.
|
Chris@16
|
1187 /// \return A lazy object that, when evaluated, dynamically casts its argument to the desired type.
|
Chris@16
|
1188 template<typename T, typename A>
|
Chris@16
|
1189 typename detail::make_function::impl<op::dynamic_cast_<T> const, A const &>::result_type const
|
Chris@16
|
1190 dynamic_cast_(A const &a)
|
Chris@16
|
1191 {
|
Chris@16
|
1192 return detail::make_function::impl<op::dynamic_cast_<T> const, A const &>()((op::dynamic_cast_<T>()), a);
|
Chris@16
|
1193 }
|
Chris@16
|
1194
|
Chris@16
|
1195 /// \brief \c dynamic_cast_ is a lazy funtion for const-casting a parameter to a different type.
|
Chris@16
|
1196 /// \tparam T The type to which to const-cast the parameter.
|
Chris@16
|
1197 /// \param a The lazy value to const-cast.
|
Chris@16
|
1198 /// \return A lazy object that, when evaluated, const-casts its argument to the desired type.
|
Chris@16
|
1199 template<typename T, typename A>
|
Chris@16
|
1200 typename detail::make_function::impl<op::const_cast_<T> const, A const &>::result_type const
|
Chris@16
|
1201 const_cast_(A const &a)
|
Chris@16
|
1202 {
|
Chris@16
|
1203 return detail::make_function::impl<op::const_cast_<T> const, A const &>()((op::const_cast_<T>()), a);
|
Chris@16
|
1204 }
|
Chris@16
|
1205
|
Chris@16
|
1206 /// \brief Helper for constructing \c value\<\> objects.
|
Chris@16
|
1207 /// \return <tt>value\<T\>(t)</tt>
|
Chris@16
|
1208 template<typename T>
|
Chris@16
|
1209 value<T> const val(T const &t)
|
Chris@16
|
1210 {
|
Chris@16
|
1211 return value<T>(t);
|
Chris@16
|
1212 }
|
Chris@16
|
1213
|
Chris@16
|
1214 /// \brief Helper for constructing \c reference\<\> objects.
|
Chris@16
|
1215 /// \return <tt>reference\<T\>(t)</tt>
|
Chris@16
|
1216 template<typename T>
|
Chris@16
|
1217 reference<T> const ref(T &t)
|
Chris@16
|
1218 {
|
Chris@16
|
1219 return reference<T>(t);
|
Chris@16
|
1220 }
|
Chris@16
|
1221
|
Chris@16
|
1222 /// \brief Helper for constructing \c reference\<\> objects that
|
Chris@16
|
1223 /// store a reference to const.
|
Chris@16
|
1224 /// \return <tt>reference\<T const\>(t)</tt>
|
Chris@16
|
1225 template<typename T>
|
Chris@16
|
1226 reference<T const> const cref(T const &t)
|
Chris@16
|
1227 {
|
Chris@16
|
1228 return reference<T const>(t);
|
Chris@16
|
1229 }
|
Chris@16
|
1230
|
Chris@16
|
1231 /// \brief For adding user-defined assertions to your regular expressions.
|
Chris@16
|
1232 ///
|
Chris@16
|
1233 /// \param t The UnaryPredicate object or Boolean semantic action.
|
Chris@16
|
1234 ///
|
Chris@16
|
1235 /// A \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.user_defined_assertions,user-defined assertion}
|
Chris@16
|
1236 /// is a kind of semantic action that evaluates
|
Chris@16
|
1237 /// a Boolean lambda and, if it evaluates to false, causes the match to
|
Chris@16
|
1238 /// fail at that location in the string. This will cause backtracking,
|
Chris@16
|
1239 /// so the match may ultimately succeed.
|
Chris@16
|
1240 ///
|
Chris@16
|
1241 /// To use \c check() to specify a user-defined assertion in a regex, use the
|
Chris@16
|
1242 /// following syntax:
|
Chris@16
|
1243 ///
|
Chris@16
|
1244 /** \code
|
Chris@16
|
1245 sregex s = (_d >> _d)[check( XXX )]; // XXX is a custom assertion
|
Chris@16
|
1246 \endcode
|
Chris@16
|
1247 */
|
Chris@16
|
1248 ///
|
Chris@16
|
1249 /// The assertion is evaluated with a \c sub_match\<\> object that delineates
|
Chris@16
|
1250 /// what part of the string matched the sub-expression to which the assertion
|
Chris@16
|
1251 /// was attached.
|
Chris@16
|
1252 ///
|
Chris@16
|
1253 /// \c check() can be used with an ordinary predicate that takes a
|
Chris@16
|
1254 /// \c sub_match\<\> object as follows:
|
Chris@16
|
1255 ///
|
Chris@16
|
1256 /** \code
|
Chris@16
|
1257 // A predicate that is true IFF a sub-match is
|
Chris@16
|
1258 // either 3 or 6 characters long.
|
Chris@16
|
1259 struct three_or_six
|
Chris@16
|
1260 {
|
Chris@16
|
1261 bool operator()(ssub_match const &sub) const
|
Chris@16
|
1262 {
|
Chris@16
|
1263 return sub.length() == 3 || sub.length() == 6;
|
Chris@16
|
1264 }
|
Chris@16
|
1265 };
|
Chris@16
|
1266
|
Chris@16
|
1267 // match words of 3 characters or 6 characters.
|
Chris@16
|
1268 sregex rx = (bow >> +_w >> eow)[ check(three_or_six()) ] ;
|
Chris@16
|
1269 \endcode
|
Chris@16
|
1270 */
|
Chris@16
|
1271 ///
|
Chris@16
|
1272 /// Alternately, \c check() can be used to define inline custom
|
Chris@16
|
1273 /// assertions with the same syntax as is used to define semantic
|
Chris@16
|
1274 /// actions. The following code is equivalent to above:
|
Chris@16
|
1275 ///
|
Chris@16
|
1276 /** \code
|
Chris@16
|
1277 // match words of 3 characters or 6 characters.
|
Chris@16
|
1278 sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ;
|
Chris@16
|
1279 \endcode
|
Chris@16
|
1280 */
|
Chris@16
|
1281 ///
|
Chris@16
|
1282 /// Within a custom assertion, \c _ is a placeholder for the \c sub_match\<\>
|
Chris@16
|
1283 /// That delineates the part of the string matched by the sub-expression to
|
Chris@16
|
1284 /// which the custom assertion was attached.
|
Chris@16
|
1285 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful.
|
Chris@16
|
1286 template<typename T>
|
Chris@16
|
1287 detail::unspecified check(T const &t);
|
Chris@16
|
1288 #else
|
Chris@16
|
1289 proto::terminal<detail::check_tag>::type const check = {{}};
|
Chris@16
|
1290 #endif
|
Chris@16
|
1291
|
Chris@16
|
1292 /// \brief For binding local variables to placeholders in semantic actions when
|
Chris@16
|
1293 /// constructing a \c regex_iterator or a \c regex_token_iterator.
|
Chris@16
|
1294 ///
|
Chris@16
|
1295 /// \param args A set of argument bindings, where each argument binding is an assignment
|
Chris@16
|
1296 /// expression, the left hand side of which must be an instance of \c placeholder\<X\>
|
Chris@16
|
1297 /// for some \c X, and the right hand side is an lvalue of type \c X.
|
Chris@16
|
1298 ///
|
Chris@16
|
1299 /// \c xpressive::let() serves the same purpose as <tt>match_results::let()</tt>;
|
Chris@16
|
1300 /// that is, it binds a placeholder to a local value. The purpose is to allow a
|
Chris@16
|
1301 /// regex with semantic actions to be defined that refers to objects that do not yet exist.
|
Chris@16
|
1302 /// Rather than referring directly to an object, a semantic action can refer to a placeholder,
|
Chris@16
|
1303 /// and the value of the placeholder can be specified later with a <em>let expression</em>.
|
Chris@16
|
1304 /// The <em>let expression</em> created with \c let() is passed to the constructor of either
|
Chris@16
|
1305 /// \c regex_iterator or \c regex_token_iterator.
|
Chris@16
|
1306 ///
|
Chris@16
|
1307 /// See the section \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"}
|
Chris@16
|
1308 /// in the Users' Guide for more discussion.
|
Chris@16
|
1309 ///
|
Chris@16
|
1310 /// \em Example:
|
Chris@16
|
1311 ///
|
Chris@16
|
1312 /**
|
Chris@16
|
1313 \code
|
Chris@16
|
1314 // Define a placeholder for a map object:
|
Chris@16
|
1315 placeholder<std::map<std::string, int> > _map;
|
Chris@16
|
1316
|
Chris@16
|
1317 // Match a word and an integer, separated by =>,
|
Chris@16
|
1318 // and then stuff the result into a std::map<>
|
Chris@16
|
1319 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
|
Chris@16
|
1320 [ _map[s1] = as<int>(s2) ];
|
Chris@16
|
1321
|
Chris@16
|
1322 // The string to parse
|
Chris@16
|
1323 std::string str("aaa=>1 bbb=>23 ccc=>456");
|
Chris@16
|
1324
|
Chris@16
|
1325 // Here is the actual map to fill in:
|
Chris@16
|
1326 std::map<std::string, int> result;
|
Chris@16
|
1327
|
Chris@16
|
1328 // Create a regex_iterator to find all the matches
|
Chris@16
|
1329 sregex_iterator it(str.begin(), str.end(), pair, let(_map=result));
|
Chris@16
|
1330 sregex_iterator end;
|
Chris@16
|
1331
|
Chris@16
|
1332 // step through all the matches, and fill in
|
Chris@16
|
1333 // the result map
|
Chris@16
|
1334 while(it != end)
|
Chris@16
|
1335 ++it;
|
Chris@16
|
1336
|
Chris@16
|
1337 std::cout << result["aaa"] << '\n';
|
Chris@16
|
1338 std::cout << result["bbb"] << '\n';
|
Chris@16
|
1339 std::cout << result["ccc"] << '\n';
|
Chris@16
|
1340 \endcode
|
Chris@16
|
1341 */
|
Chris@16
|
1342 ///
|
Chris@16
|
1343 /// The above code displays:
|
Chris@16
|
1344 ///
|
Chris@16
|
1345 /** \code{.txt}
|
Chris@16
|
1346 1
|
Chris@16
|
1347 23
|
Chris@16
|
1348 456
|
Chris@16
|
1349 \endcode
|
Chris@16
|
1350 */
|
Chris@16
|
1351 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful.
|
Chris@16
|
1352 template<typename...ArgBindings>
|
Chris@16
|
1353 detail::unspecified let(ArgBindings const &...args);
|
Chris@16
|
1354 #else
|
Chris@16
|
1355 detail::let_<proto::terminal<detail::let_tag>::type> const let = {{{}}};
|
Chris@16
|
1356 #endif
|
Chris@16
|
1357
|
Chris@16
|
1358 /// \brief For defining a placeholder to stand in for a variable a semantic action.
|
Chris@16
|
1359 ///
|
Chris@16
|
1360 /// Use \c placeholder\<\> to define a placeholder for use in semantic actions to stand
|
Chris@16
|
1361 /// in for real objects. The use of placeholders allows regular expressions with actions
|
Chris@16
|
1362 /// to be defined once and reused in many contexts to read and write from objects which
|
Chris@16
|
1363 /// were not available when the regex was defined.
|
Chris@16
|
1364 ///
|
Chris@16
|
1365 /// \tparam T The type of the object for which this placeholder stands in.
|
Chris@16
|
1366 /// \tparam I An optional identifier that can be used to distinguish this placeholder
|
Chris@16
|
1367 /// from others that may be used in the same semantic action that happen
|
Chris@16
|
1368 /// to have the same type.
|
Chris@16
|
1369 ///
|
Chris@16
|
1370 /// You can use \c placeholder\<\> by creating an object of type \c placeholder\<T\>
|
Chris@16
|
1371 /// and using that object in a semantic action exactly as you intend an object of
|
Chris@16
|
1372 /// type \c T to be used.
|
Chris@16
|
1373 ///
|
Chris@16
|
1374 /**
|
Chris@16
|
1375 \code
|
Chris@16
|
1376 placeholder<int> _i;
|
Chris@16
|
1377 placeholder<double> _d;
|
Chris@16
|
1378
|
Chris@16
|
1379 sregex rex = ( some >> regex >> here )
|
Chris@16
|
1380 [ ++_i, _d *= _d ];
|
Chris@16
|
1381 \endcode
|
Chris@16
|
1382 */
|
Chris@16
|
1383 ///
|
Chris@16
|
1384 /// Then, when doing a pattern match with either \c regex_search(),
|
Chris@16
|
1385 /// \c regex_match() or \c regex_replace(), pass a \c match_results\<\> object that
|
Chris@16
|
1386 /// contains bindings for the placeholders used in the regex object's semantic actions.
|
Chris@16
|
1387 /// You can create the bindings by calling \c match_results::let as follows:
|
Chris@16
|
1388 ///
|
Chris@16
|
1389 /**
|
Chris@16
|
1390 \code
|
Chris@16
|
1391 int i = 0;
|
Chris@16
|
1392 double d = 3.14;
|
Chris@16
|
1393
|
Chris@16
|
1394 smatch what;
|
Chris@16
|
1395 what.let(_i = i)
|
Chris@16
|
1396 .let(_d = d);
|
Chris@16
|
1397
|
Chris@16
|
1398 if(regex_match("some string", rex, what))
|
Chris@16
|
1399 // i and d mutated here
|
Chris@16
|
1400 \endcode
|
Chris@16
|
1401 */
|
Chris@16
|
1402 ///
|
Chris@16
|
1403 /// If a semantic action executes that contains an unbound placeholder, a exception of
|
Chris@16
|
1404 /// type \c regex_error is thrown.
|
Chris@16
|
1405 ///
|
Chris@16
|
1406 /// See the discussion for \c xpressive::let() and the
|
Chris@16
|
1407 /// \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"}
|
Chris@16
|
1408 /// section in the Users' Guide for more information.
|
Chris@16
|
1409 ///
|
Chris@16
|
1410 /// <em>Example:</em>
|
Chris@16
|
1411 ///
|
Chris@16
|
1412 /**
|
Chris@16
|
1413 \code
|
Chris@16
|
1414 // Define a placeholder for a map object:
|
Chris@16
|
1415 placeholder<std::map<std::string, int> > _map;
|
Chris@16
|
1416
|
Chris@16
|
1417 // Match a word and an integer, separated by =>,
|
Chris@16
|
1418 // and then stuff the result into a std::map<>
|
Chris@16
|
1419 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
|
Chris@16
|
1420 [ _map[s1] = as<int>(s2) ];
|
Chris@16
|
1421
|
Chris@16
|
1422 // Match one or more word/integer pairs, separated
|
Chris@16
|
1423 // by whitespace.
|
Chris@16
|
1424 sregex rx = pair >> *(+_s >> pair);
|
Chris@16
|
1425
|
Chris@16
|
1426 // The string to parse
|
Chris@16
|
1427 std::string str("aaa=>1 bbb=>23 ccc=>456");
|
Chris@16
|
1428
|
Chris@16
|
1429 // Here is the actual map to fill in:
|
Chris@16
|
1430 std::map<std::string, int> result;
|
Chris@16
|
1431
|
Chris@16
|
1432 // Bind the _map placeholder to the actual map
|
Chris@16
|
1433 smatch what;
|
Chris@16
|
1434 what.let( _map = result );
|
Chris@16
|
1435
|
Chris@16
|
1436 // Execute the match and fill in result map
|
Chris@16
|
1437 if(regex_match(str, what, rx))
|
Chris@16
|
1438 {
|
Chris@16
|
1439 std::cout << result["aaa"] << '\n';
|
Chris@16
|
1440 std::cout << result["bbb"] << '\n';
|
Chris@16
|
1441 std::cout << result["ccc"] << '\n';
|
Chris@16
|
1442 }
|
Chris@16
|
1443 \endcode
|
Chris@16
|
1444 */
|
Chris@16
|
1445 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful.
|
Chris@16
|
1446 template<typename T, int I = 0>
|
Chris@16
|
1447 struct placeholder
|
Chris@16
|
1448 {
|
Chris@16
|
1449 /// \param t The object to associate with this placeholder
|
Chris@16
|
1450 /// \return An object of unspecified type that records the association of \c t
|
Chris@16
|
1451 /// with \c *this.
|
Chris@16
|
1452 detail::unspecified operator=(T &t) const;
|
Chris@16
|
1453 /// \overload
|
Chris@16
|
1454 detail::unspecified operator=(T const &t) const;
|
Chris@16
|
1455 };
|
Chris@16
|
1456 #else
|
Chris@16
|
1457 template<typename T, int I, typename Dummy>
|
Chris@16
|
1458 struct placeholder
|
Chris@16
|
1459 {
|
Chris@16
|
1460 typedef placeholder<T, I, Dummy> this_type;
|
Chris@16
|
1461 typedef
|
Chris@16
|
1462 typename proto::terminal<detail::action_arg<T, mpl::int_<I> > >::type
|
Chris@16
|
1463 action_arg_type;
|
Chris@16
|
1464
|
Chris@16
|
1465 BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain)
|
Chris@16
|
1466 };
|
Chris@16
|
1467 #endif
|
Chris@16
|
1468
|
Chris@16
|
1469 /// \brief A lazy funtion for constructing objects objects of the specified type.
|
Chris@16
|
1470 /// \tparam T The type of object to construct.
|
Chris@16
|
1471 /// \param args The arguments to the constructor.
|
Chris@16
|
1472 /// \return A lazy object that, when evaluated, returns <tt>T(xs...)</tt>, where
|
Chris@16
|
1473 /// <tt>xs...</tt> is the result of evaluating the lazy arguments
|
Chris@16
|
1474 /// <tt>args...</tt>.
|
Chris@16
|
1475 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful.
|
Chris@16
|
1476 template<typename T, typename ...Args>
|
Chris@16
|
1477 detail::unspecified construct(Args const &...args);
|
Chris@16
|
1478 #else
|
Chris@16
|
1479 /// INTERNAL ONLY
|
Chris@16
|
1480 #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a) \
|
Chris@16
|
1481 template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \
|
Chris@16
|
1482 typename detail::make_function::impl< \
|
Chris@16
|
1483 op::construct<X2_0> const \
|
Chris@16
|
1484 BOOST_PP_COMMA_IF(N) A_const_ref(N) \
|
Chris@16
|
1485 >::result_type const \
|
Chris@16
|
1486 construct(A_const_ref_a(N)) \
|
Chris@16
|
1487 { \
|
Chris@16
|
1488 return detail::make_function::impl< \
|
Chris@16
|
1489 op::construct<X2_0> const \
|
Chris@16
|
1490 BOOST_PP_COMMA_IF(N) A_const_ref(N) \
|
Chris@16
|
1491 >()((op::construct<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \
|
Chris@16
|
1492 } \
|
Chris@16
|
1493 \
|
Chris@16
|
1494 template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \
|
Chris@16
|
1495 typename detail::make_function::impl< \
|
Chris@16
|
1496 op::throw_<X2_0> const \
|
Chris@16
|
1497 BOOST_PP_COMMA_IF(N) A_const_ref(N) \
|
Chris@16
|
1498 >::result_type const \
|
Chris@16
|
1499 throw_(A_const_ref_a(N)) \
|
Chris@16
|
1500 { \
|
Chris@16
|
1501 return detail::make_function::impl< \
|
Chris@16
|
1502 op::throw_<X2_0> const \
|
Chris@16
|
1503 BOOST_PP_COMMA_IF(N) A_const_ref(N) \
|
Chris@16
|
1504 >()((op::throw_<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \
|
Chris@16
|
1505 } \
|
Chris@16
|
1506 /**/
|
Chris@16
|
1507
|
Chris@16
|
1508 #define BOOST_PROTO_LOCAL_a BOOST_PROTO_a ///< INTERNAL ONLY
|
Chris@16
|
1509 #define BOOST_PROTO_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)) ///< INTERNAL ONLY
|
Chris@16
|
1510 #include BOOST_PROTO_LOCAL_ITERATE()
|
Chris@16
|
1511 #endif
|
Chris@16
|
1512
|
Chris@16
|
1513 namespace detail
|
Chris@16
|
1514 {
|
Chris@16
|
1515 inline void ignore_unused_regex_actions()
|
Chris@16
|
1516 {
|
Chris@16
|
1517 detail::ignore_unused(xpressive::at);
|
Chris@16
|
1518 detail::ignore_unused(xpressive::push);
|
Chris@16
|
1519 detail::ignore_unused(xpressive::push_back);
|
Chris@16
|
1520 detail::ignore_unused(xpressive::push_front);
|
Chris@16
|
1521 detail::ignore_unused(xpressive::pop);
|
Chris@16
|
1522 detail::ignore_unused(xpressive::pop_back);
|
Chris@16
|
1523 detail::ignore_unused(xpressive::pop_front);
|
Chris@16
|
1524 detail::ignore_unused(xpressive::top);
|
Chris@16
|
1525 detail::ignore_unused(xpressive::back);
|
Chris@16
|
1526 detail::ignore_unused(xpressive::front);
|
Chris@16
|
1527 detail::ignore_unused(xpressive::first);
|
Chris@16
|
1528 detail::ignore_unused(xpressive::second);
|
Chris@16
|
1529 detail::ignore_unused(xpressive::matched);
|
Chris@16
|
1530 detail::ignore_unused(xpressive::length);
|
Chris@16
|
1531 detail::ignore_unused(xpressive::str);
|
Chris@16
|
1532 detail::ignore_unused(xpressive::insert);
|
Chris@16
|
1533 detail::ignore_unused(xpressive::make_pair);
|
Chris@16
|
1534 detail::ignore_unused(xpressive::unwrap_reference);
|
Chris@16
|
1535 detail::ignore_unused(xpressive::check);
|
Chris@16
|
1536 detail::ignore_unused(xpressive::let);
|
Chris@16
|
1537 }
|
Chris@16
|
1538
|
Chris@16
|
1539 struct mark_nbr
|
Chris@16
|
1540 {
|
Chris@16
|
1541 BOOST_PROTO_CALLABLE()
|
Chris@16
|
1542 typedef int result_type;
|
Chris@16
|
1543
|
Chris@16
|
1544 int operator()(mark_placeholder m) const
|
Chris@16
|
1545 {
|
Chris@16
|
1546 return m.mark_number_;
|
Chris@16
|
1547 }
|
Chris@16
|
1548 };
|
Chris@16
|
1549
|
Chris@16
|
1550 struct ReplaceAlgo
|
Chris@16
|
1551 : proto::or_<
|
Chris@16
|
1552 proto::when<
|
Chris@16
|
1553 proto::terminal<mark_placeholder>
|
Chris@16
|
1554 , op::at(proto::_data, proto::call<mark_nbr(proto::_value)>)
|
Chris@16
|
1555 >
|
Chris@16
|
1556 , proto::when<
|
Chris@16
|
1557 proto::terminal<any_matcher>
|
Chris@16
|
1558 , op::at(proto::_data, proto::size_t<0>)
|
Chris@16
|
1559 >
|
Chris@16
|
1560 , proto::when<
|
Chris@16
|
1561 proto::terminal<reference_wrapper<proto::_> >
|
Chris@16
|
1562 , op::unwrap_reference(proto::_value)
|
Chris@16
|
1563 >
|
Chris@16
|
1564 , proto::_default<ReplaceAlgo>
|
Chris@16
|
1565 >
|
Chris@16
|
1566 {};
|
Chris@16
|
1567 }
|
Chris@16
|
1568 }}
|
Chris@16
|
1569
|
Chris@16
|
1570 #if BOOST_MSVC
|
Chris@16
|
1571 #pragma warning(pop)
|
Chris@16
|
1572 #endif
|
Chris@16
|
1573
|
Chris@16
|
1574 #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
|