1 | // Copyright Daniel Wallin, David Abrahams 2005. |
2 | // Copyright Cromwell D. Enage 2017. |
3 | // Distributed under the Boost Software License, Version 1.0. |
4 | // (See accompanying file LICENSE_1_0.txt or copy at |
5 | // http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | #ifndef BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP |
8 | #define BOOST_PARAMETER_TAGGED_ARGUMENT_050328_HPP |
9 | |
10 | namespace boost { namespace parameter { namespace aux { |
11 | |
12 | struct error_const_lvalue_bound_to_out_parameter; |
13 | struct error_lvalue_bound_to_consume_parameter; |
14 | struct error_rvalue_bound_to_out_parameter; |
15 | }}} // namespace boost::parameter::aux |
16 | |
17 | #include <boost/parameter/keyword_fwd.hpp> |
18 | #include <boost/parameter/config.hpp> |
19 | #include <boost/mpl/eval_if.hpp> |
20 | #include <boost/type_traits/is_same.hpp> |
21 | #include <boost/type_traits/remove_const.hpp> |
22 | |
23 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
24 | #include <boost/mp11/integral.hpp> |
25 | #include <boost/mp11/utility.hpp> |
26 | #include <type_traits> |
27 | #endif |
28 | |
29 | namespace boost { namespace parameter { namespace aux { |
30 | |
31 | template <typename Keyword, typename Arg> |
32 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
33 | using tagged_argument_type = ::boost::mp11::mp_if< |
34 | ::boost::mp11::mp_if< |
35 | ::std::is_scalar<Arg> |
36 | , ::boost::mp11::mp_false |
37 | , ::std::is_same< |
38 | typename Keyword::qualifier |
39 | , ::boost::parameter::consume_reference |
40 | > |
41 | > |
42 | , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter |
43 | , ::boost::mp11::mp_if< |
44 | ::std::is_const<Arg> |
45 | , ::boost::mp11::mp_if< |
46 | ::std::is_same< |
47 | typename Keyword::qualifier |
48 | , ::boost::parameter::out_reference |
49 | > |
50 | , ::boost::parameter::aux |
51 | ::error_const_lvalue_bound_to_out_parameter |
52 | , ::std::remove_const<Arg> |
53 | > |
54 | , ::boost::mp11::mp_identity<Arg> |
55 | > |
56 | >; |
57 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
58 | struct tagged_argument_type |
59 | : ::boost::mpl::eval_if< |
60 | ::boost::is_same< |
61 | typename Keyword::qualifier |
62 | , ::boost::parameter::out_reference |
63 | > |
64 | , ::boost::parameter::aux::error_const_lvalue_bound_to_out_parameter |
65 | , ::boost::remove_const<Arg> |
66 | > |
67 | { |
68 | }; |
69 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
70 | }}} // namespace boost::parameter::aux |
71 | |
72 | #include <boost/parameter/aux_/tagged_argument_fwd.hpp> |
73 | #include <boost/parameter/aux_/is_tagged_argument.hpp> |
74 | #include <boost/parameter/aux_/default.hpp> |
75 | #include <boost/parameter/aux_/void.hpp> |
76 | #include <boost/parameter/aux_/arg_list.hpp> |
77 | #include <boost/parameter/aux_/result_of0.hpp> |
78 | #include <boost/mpl/bool.hpp> |
79 | #include <boost/mpl/if.hpp> |
80 | #include <boost/mpl/identity.hpp> |
81 | #include <boost/mpl/apply_wrap.hpp> |
82 | #include <boost/type_traits/is_const.hpp> |
83 | #include <boost/type_traits/is_function.hpp> |
84 | #include <boost/type_traits/is_scalar.hpp> |
85 | #include <boost/type_traits/remove_reference.hpp> |
86 | |
87 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
88 | #include <boost/function.hpp> |
89 | #else |
90 | #include <functional> |
91 | #endif |
92 | |
93 | #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
94 | #include <boost/core/enable_if.hpp> |
95 | #include <utility> |
96 | |
97 | namespace boost { namespace parameter { namespace aux { |
98 | |
99 | // Holds an lvalue reference to an argument of type Arg associated with |
100 | // keyword Keyword |
101 | template <typename Keyword, typename Arg> |
102 | class tagged_argument |
103 | : public ::boost::parameter::aux::tagged_argument_base |
104 | { |
105 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
106 | using arg_type = typename ::boost::parameter::aux |
107 | ::tagged_argument_type<Keyword,Arg>::type; |
108 | #else |
109 | typedef typename ::boost::mpl::eval_if< |
110 | typename ::boost::mpl::eval_if< |
111 | ::boost::is_scalar<Arg> |
112 | , ::boost::mpl::false_ |
113 | , ::boost::is_same< |
114 | typename Keyword::qualifier |
115 | , ::boost::parameter::consume_reference |
116 | > |
117 | >::type |
118 | , ::boost::parameter::aux::error_lvalue_bound_to_consume_parameter |
119 | , ::boost::mpl::eval_if< |
120 | ::boost::is_const<Arg> |
121 | , ::boost::parameter::aux::tagged_argument_type<Keyword,Arg> |
122 | , ::boost::mpl::identity<Arg> |
123 | > |
124 | >::type arg_type; |
125 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
126 | |
127 | public: |
128 | typedef Keyword key_type; |
129 | |
130 | // Wrap plain (non-UDT) function objects in either |
131 | // a boost::function or a std::function. -- Cromwell D. Enage |
132 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
133 | using value_type = ::boost::mp11::mp_if< |
134 | ::std::is_function<arg_type> |
135 | , ::std::function<arg_type> |
136 | , Arg |
137 | >; |
138 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
139 | typedef typename ::boost::mpl::if_< |
140 | ::boost::is_function<arg_type> |
141 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
142 | , ::boost::function<arg_type> |
143 | #else |
144 | , ::std::function<arg_type> |
145 | #endif |
146 | , Arg |
147 | >::type value_type; |
148 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
149 | |
150 | // If Arg is void_, then this type will evaluate to void_&. If the |
151 | // supplied argument is a plain function, then this type will evaluate |
152 | // to a reference-to-const function wrapper type. If the supplied |
153 | // argument is an lvalue, then Arg will be deduced to the lvalue |
154 | // reference. -- Cromwell D. Enage |
155 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
156 | using reference = ::boost::mp11::mp_if< |
157 | ::std::is_function<arg_type> |
158 | , value_type const& |
159 | , Arg& |
160 | >; |
161 | #else |
162 | typedef typename ::boost::mpl::if_< |
163 | ::boost::is_function<arg_type> |
164 | , value_type const& |
165 | , Arg& |
166 | >::type reference; |
167 | #endif |
168 | |
169 | private: |
170 | // Store plain functions by value, everything else by reference. |
171 | // -- Cromwell D. Enage |
172 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
173 | ::boost::mp11::mp_if< |
174 | ::std::is_function<arg_type> |
175 | , value_type |
176 | , reference |
177 | > value; |
178 | #else |
179 | typename ::boost::mpl::if_< |
180 | ::boost::is_function<arg_type> |
181 | , value_type |
182 | , reference |
183 | >::type value; |
184 | #endif |
185 | |
186 | public: |
187 | inline explicit BOOST_CONSTEXPR tagged_argument(reference x) |
188 | : value(x) |
189 | { |
190 | } |
191 | |
192 | inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy) |
193 | : value(copy.value) |
194 | { |
195 | } |
196 | |
197 | // A metafunction class that, given a keyword and a default type, |
198 | // returns the appropriate result type for a keyword lookup given |
199 | // that default. |
200 | struct binding |
201 | { |
202 | template <typename KW, typename Default, typename Reference> |
203 | struct apply |
204 | : ::boost::mpl::eval_if< |
205 | ::boost::is_same<KW,key_type> |
206 | , ::boost::mpl::if_<Reference,reference,value_type> |
207 | , ::boost::mpl::identity<Default> |
208 | > |
209 | { |
210 | }; |
211 | |
212 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
213 | template <typename KW, typename Default, typename Reference> |
214 | using fn = ::boost::mp11::mp_if< |
215 | ::std::is_same<KW,key_type> |
216 | , ::boost::mp11::mp_if<Reference,reference,value_type> |
217 | , Default |
218 | >; |
219 | #endif |
220 | }; |
221 | |
222 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
223 | // Comma operator to compose argument list without using parameters<>. |
224 | // Useful for argument lists with undetermined length. |
225 | template <typename Keyword2, typename Arg2> |
226 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
227 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
228 | , ::boost::parameter::aux::arg_list< |
229 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
230 | > |
231 | > |
232 | operator,( |
233 | ::boost::parameter::aux |
234 | ::tagged_argument<Keyword2,Arg2> const& x |
235 | ) const |
236 | { |
237 | return ::boost::parameter::aux::arg_list< |
238 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
239 | , ::boost::parameter::aux::arg_list< |
240 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
241 | > |
242 | >( |
243 | *this |
244 | , ::boost::parameter::aux::arg_list< |
245 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
246 | >(x, ::boost::parameter::aux::empty_arg_list()) |
247 | ); |
248 | } |
249 | |
250 | template <typename Keyword2, typename Arg2> |
251 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
252 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
253 | , ::boost::parameter::aux::arg_list< |
254 | ::boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2> |
255 | > |
256 | > |
257 | operator,( |
258 | ::boost::parameter::aux |
259 | ::tagged_argument_rref<Keyword2,Arg2> const& x |
260 | ) const |
261 | { |
262 | return ::boost::parameter::aux::arg_list< |
263 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
264 | , boost::parameter::aux::arg_list< |
265 | boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2> |
266 | > |
267 | >( |
268 | *this |
269 | , ::boost::parameter::aux::arg_list< |
270 | ::boost::parameter::aux |
271 | ::tagged_argument_rref<Keyword2,Arg2> |
272 | >(x, ::boost::parameter::aux::empty_arg_list()) |
273 | ); |
274 | } |
275 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
276 | |
277 | // Accessor interface. |
278 | inline BOOST_CONSTEXPR reference get_value() const |
279 | { |
280 | return this->value; |
281 | } |
282 | |
283 | inline BOOST_CONSTEXPR reference |
284 | operator[](::boost::parameter::keyword<Keyword> const&) const |
285 | { |
286 | return this->get_value(); |
287 | } |
288 | |
289 | template <typename Default> |
290 | inline BOOST_CONSTEXPR reference |
291 | operator[]( |
292 | ::boost::parameter::aux::default_<key_type,Default> const& |
293 | ) const |
294 | { |
295 | return this->get_value(); |
296 | } |
297 | |
298 | template <typename Default> |
299 | inline BOOST_CONSTEXPR reference |
300 | operator[]( |
301 | ::boost::parameter::aux::default_r_<key_type,Default> const& |
302 | ) const |
303 | { |
304 | return this->get_value(); |
305 | } |
306 | |
307 | template <typename F> |
308 | inline BOOST_CONSTEXPR reference |
309 | operator[]( |
310 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
311 | ) const |
312 | { |
313 | return this->get_value(); |
314 | } |
315 | |
316 | template <typename KW, typename Default> |
317 | inline BOOST_CONSTEXPR Default& |
318 | operator[]( |
319 | ::boost::parameter::aux::default_<KW,Default> const& x |
320 | ) const |
321 | { |
322 | return x.value; |
323 | } |
324 | |
325 | template <typename KW, typename Default> |
326 | inline BOOST_CONSTEXPR Default&& |
327 | operator[]( |
328 | ::boost::parameter::aux::default_r_<KW,Default> const& x |
329 | ) const |
330 | { |
331 | return ::std::forward<Default>(x.value); |
332 | } |
333 | |
334 | template <typename KW, typename F> |
335 | inline BOOST_CONSTEXPR |
336 | typename ::boost::parameter::aux::result_of0<F>::type |
337 | operator[]( |
338 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
339 | ) const |
340 | { |
341 | return x.compute_default(); |
342 | } |
343 | |
344 | template <typename ParameterRequirements> |
345 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
346 | satisfies(ParameterRequirements*); |
347 | |
348 | template <typename HasDefault, typename Predicate> |
349 | static BOOST_CONSTEXPR |
350 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
351 | satisfies( |
352 | ::boost::parameter::aux::parameter_requirements< |
353 | key_type |
354 | , Predicate |
355 | , HasDefault |
356 | >* |
357 | ); |
358 | |
359 | // MPL sequence support |
360 | // Convenience for users |
361 | typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type; |
362 | // For the benefit of iterators |
363 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
364 | // For dispatching to sequence intrinsics |
365 | typedef ::boost::parameter::aux::arg_list_tag tag; |
366 | }; |
367 | |
368 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
369 | template <typename Keyword> |
370 | using tagged_argument_rref_key = ::boost::mp11::mp_if< |
371 | ::std::is_same< |
372 | typename Keyword::qualifier |
373 | , ::boost::parameter::out_reference |
374 | > |
375 | , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter |
376 | , ::boost::mp11::mp_identity<Keyword> |
377 | >; |
378 | #endif |
379 | |
380 | // Holds an rvalue reference to an argument of type Arg associated with |
381 | // keyword Keyword |
382 | template <typename Keyword, typename Arg> |
383 | struct tagged_argument_rref |
384 | : ::boost::parameter::aux::tagged_argument_base |
385 | { |
386 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
387 | using key_type = typename ::boost::parameter::aux |
388 | ::tagged_argument_rref_key<Keyword>::type; |
389 | #else |
390 | typedef typename ::boost::mpl::eval_if< |
391 | ::boost::is_same< |
392 | typename Keyword::qualifier |
393 | , ::boost::parameter::out_reference |
394 | > |
395 | , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter |
396 | , ::boost::mpl::identity<Keyword> |
397 | >::type key_type; |
398 | #endif |
399 | typedef Arg value_type; |
400 | typedef Arg&& reference; |
401 | |
402 | private: |
403 | reference value; |
404 | |
405 | public: |
406 | inline explicit BOOST_CONSTEXPR tagged_argument_rref(reference x) |
407 | : value(::std::forward<Arg>(x)) |
408 | { |
409 | } |
410 | |
411 | inline BOOST_CONSTEXPR tagged_argument_rref( |
412 | tagged_argument_rref const& copy |
413 | ) : value(::std::forward<Arg>(copy.value)) |
414 | { |
415 | } |
416 | |
417 | // A metafunction class that, given a keyword and a default type, |
418 | // returns the appropriate result type for a keyword lookup given |
419 | // that default. |
420 | struct binding |
421 | { |
422 | template <typename KW, typename Default, typename Reference> |
423 | struct apply |
424 | { |
425 | typedef typename ::boost::mpl::eval_if< |
426 | ::boost::is_same<KW,key_type> |
427 | , ::boost::mpl::if_<Reference,reference,value_type> |
428 | , ::boost::mpl::identity<Default> |
429 | >::type type; |
430 | }; |
431 | |
432 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
433 | template <typename KW, typename Default, typename Reference> |
434 | using fn = ::boost::mp11::mp_if< |
435 | ::std::is_same<KW,key_type> |
436 | , ::boost::mp11::mp_if<Reference,reference,value_type> |
437 | , Default |
438 | >; |
439 | #endif |
440 | }; |
441 | |
442 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
443 | // Comma operator to compose argument list without using parameters<>. |
444 | // Useful for argument lists with undetermined length. |
445 | template <typename Keyword2, typename Arg2> |
446 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
447 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
448 | , ::boost::parameter::aux::arg_list< |
449 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
450 | > |
451 | > |
452 | operator,( |
453 | ::boost::parameter::aux |
454 | ::tagged_argument<Keyword2,Arg2> const& x |
455 | ) const |
456 | { |
457 | return boost::parameter::aux::arg_list< |
458 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
459 | , ::boost::parameter::aux::arg_list< |
460 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
461 | > |
462 | >( |
463 | *this |
464 | , ::boost::parameter::aux::arg_list< |
465 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
466 | >(x, ::boost::parameter::aux::empty_arg_list()) |
467 | ); |
468 | } |
469 | |
470 | template <typename Keyword2, typename Arg2> |
471 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
472 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
473 | , ::boost::parameter::aux::arg_list< |
474 | ::boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2> |
475 | > |
476 | > |
477 | operator,( |
478 | ::boost::parameter::aux |
479 | ::tagged_argument_rref<Keyword2,Arg2> const& x |
480 | ) const |
481 | { |
482 | return ::boost::parameter::aux::arg_list< |
483 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
484 | , ::boost::parameter::aux::arg_list< |
485 | ::boost::parameter::aux |
486 | ::tagged_argument_rref<Keyword2,Arg2> |
487 | > |
488 | >( |
489 | *this |
490 | , ::boost::parameter::aux::arg_list< |
491 | ::boost::parameter::aux::tagged_argument_rref< |
492 | Keyword2 |
493 | , Arg2 |
494 | > |
495 | >(x, ::boost::parameter::aux::empty_arg_list()) |
496 | ); |
497 | } |
498 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
499 | |
500 | // Accessor interface. |
501 | inline BOOST_CONSTEXPR reference get_value() const |
502 | { |
503 | return ::std::forward<Arg>(this->value); |
504 | } |
505 | |
506 | inline BOOST_CONSTEXPR reference |
507 | operator[](::boost::parameter::keyword<Keyword> const&) const |
508 | { |
509 | return this->get_value(); |
510 | } |
511 | |
512 | template <typename Default> |
513 | inline BOOST_CONSTEXPR reference |
514 | operator[]( |
515 | ::boost::parameter::aux::default_<key_type,Default> const& |
516 | ) const |
517 | { |
518 | return this->get_value(); |
519 | } |
520 | |
521 | template <typename Default> |
522 | inline BOOST_CONSTEXPR reference |
523 | operator[]( |
524 | ::boost::parameter::aux::default_r_<key_type,Default> const& |
525 | ) const |
526 | { |
527 | return this->get_value(); |
528 | } |
529 | |
530 | template <typename F> |
531 | inline BOOST_CONSTEXPR reference |
532 | operator[]( |
533 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
534 | ) const |
535 | { |
536 | return this->get_value(); |
537 | } |
538 | |
539 | template <typename KW, typename Default> |
540 | inline BOOST_CONSTEXPR Default& |
541 | operator[]( |
542 | ::boost::parameter::aux::default_<KW,Default> const& x |
543 | ) const |
544 | { |
545 | return x.value; |
546 | } |
547 | |
548 | template <typename KW, typename Default> |
549 | inline BOOST_CONSTEXPR Default&& |
550 | operator[]( |
551 | ::boost::parameter::aux::default_r_<KW,Default> const& x |
552 | ) const |
553 | { |
554 | return ::std::forward<Default>(x.value); |
555 | } |
556 | |
557 | template <typename KW, typename F> |
558 | inline BOOST_CONSTEXPR |
559 | typename ::boost::parameter::aux::result_of0<F>::type |
560 | operator[]( |
561 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
562 | ) const |
563 | { |
564 | return x.compute_default(); |
565 | } |
566 | |
567 | template <typename ParameterRequirements> |
568 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
569 | satisfies(ParameterRequirements*); |
570 | |
571 | template <typename HasDefault, typename Predicate> |
572 | static BOOST_CONSTEXPR |
573 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
574 | satisfies( |
575 | ::boost::parameter::aux::parameter_requirements< |
576 | key_type |
577 | , Predicate |
578 | , HasDefault |
579 | >* |
580 | ); |
581 | |
582 | // MPL sequence support |
583 | // Convenience for users |
584 | typedef ::boost::parameter::aux |
585 | ::tagged_argument_rref<Keyword,Arg> type; |
586 | // For the benefit of iterators |
587 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
588 | // For dispatching to sequence intrinsics |
589 | typedef ::boost::parameter::aux::arg_list_tag tag; |
590 | }; |
591 | }}} // namespace boost::parameter::aux |
592 | |
593 | #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
594 | |
595 | namespace boost { namespace parameter { namespace aux { |
596 | |
597 | // Holds an lvalue reference to an argument of type Arg associated with |
598 | // keyword Keyword |
599 | template <typename Keyword, typename Arg> |
600 | class tagged_argument |
601 | : public ::boost::parameter::aux::tagged_argument_base |
602 | { |
603 | typedef typename ::boost::remove_const<Arg>::type arg_type; |
604 | |
605 | public: |
606 | typedef Keyword key_type; |
607 | |
608 | // Wrap plain (non-UDT) function objects in either |
609 | // a boost::function or a std::function. -- Cromwell D. Enage |
610 | typedef typename ::boost::mpl::if_< |
611 | ::boost::is_function<arg_type> |
612 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
613 | , ::boost::function<arg_type> |
614 | #else |
615 | , ::std::function<arg_type> |
616 | #endif |
617 | , Arg |
618 | >::type value_type; |
619 | |
620 | // If Arg is void_, then this type will evaluate to void_&. If the |
621 | // supplied argument is a plain function, then this type will evaluate |
622 | // to a reference-to-const function wrapper type. If the supplied |
623 | // argument is an lvalue, then Arg will be deduced to the lvalue |
624 | // reference. -- Cromwell D. Enage |
625 | typedef typename ::boost::mpl::if_< |
626 | ::boost::is_function<arg_type> |
627 | , value_type const& |
628 | , Arg& |
629 | >::type reference; |
630 | |
631 | private: |
632 | // Store plain functions by value, everything else by reference. |
633 | // -- Cromwell D. Enage |
634 | typename ::boost::mpl::if_< |
635 | ::boost::is_function<arg_type> |
636 | , value_type |
637 | , reference |
638 | >::type value; |
639 | |
640 | public: |
641 | inline explicit BOOST_CONSTEXPR tagged_argument(reference x) |
642 | : value(x) |
643 | { |
644 | } |
645 | |
646 | inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy) |
647 | : value(copy.value) |
648 | { |
649 | } |
650 | |
651 | // A metafunction class that, given a keyword and a default type, |
652 | // returns the appropriate result type for a keyword lookup given |
653 | // that default. |
654 | struct binding |
655 | { |
656 | template <typename KW, typename Default, typename Reference> |
657 | struct apply |
658 | { |
659 | typedef typename ::boost::mpl::eval_if< |
660 | ::boost::is_same<KW,key_type> |
661 | , ::boost::mpl::if_<Reference,reference,value_type> |
662 | , ::boost::mpl::identity<Default> |
663 | >::type type; |
664 | }; |
665 | }; |
666 | |
667 | // Comma operator to compose argument list without using parameters<>. |
668 | // Useful for argument lists with undetermined length. |
669 | template <typename Keyword2, typename Arg2> |
670 | inline ::boost::parameter::aux::arg_list< |
671 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
672 | , ::boost::parameter::aux::arg_list< |
673 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
674 | > |
675 | > |
676 | operator,( |
677 | ::boost::parameter::aux |
678 | ::tagged_argument<Keyword2,Arg2> const& x |
679 | ) const |
680 | { |
681 | return ::boost::parameter::aux::arg_list< |
682 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
683 | , ::boost::parameter::aux::arg_list< |
684 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
685 | > |
686 | >( |
687 | *this |
688 | , ::boost::parameter::aux::arg_list< |
689 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
690 | >(x, ::boost::parameter::aux::empty_arg_list()) |
691 | ); |
692 | } |
693 | |
694 | // Accessor interface. |
695 | inline BOOST_CONSTEXPR reference get_value() const |
696 | { |
697 | return this->value; |
698 | } |
699 | |
700 | inline BOOST_CONSTEXPR reference |
701 | operator[](::boost::parameter::keyword<Keyword> const&) const |
702 | { |
703 | return this->get_value(); |
704 | } |
705 | |
706 | #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || \ |
707 | BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) |
708 | template <typename KW, typename Default> |
709 | inline BOOST_CONSTEXPR Default& |
710 | get_with_default( |
711 | ::boost::parameter::aux::default_<KW,Default> const& x |
712 | , int |
713 | ) const |
714 | { |
715 | return x.value; |
716 | } |
717 | |
718 | template <typename Default> |
719 | inline BOOST_CONSTEXPR reference |
720 | get_with_default( |
721 | ::boost::parameter::aux::default_<key_type,Default> const& |
722 | , long |
723 | ) const |
724 | { |
725 | return this->get_value(); |
726 | } |
727 | |
728 | template <typename KW, typename Default> |
729 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
730 | binding |
731 | , KW |
732 | , Default& |
733 | , ::boost::mpl::true_ |
734 | >::type |
735 | operator[]( |
736 | ::boost::parameter::aux::default_<KW,Default> const& x |
737 | ) const |
738 | { |
739 | return this->get_with_default(x, 0L); |
740 | } |
741 | |
742 | template <typename KW, typename F> |
743 | inline BOOST_CONSTEXPR |
744 | typename ::boost::parameter::aux::result_of0<F>::type |
745 | get_with_lazy_default( |
746 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
747 | , int |
748 | ) const |
749 | { |
750 | return x.compute_default(); |
751 | } |
752 | |
753 | template <typename F> |
754 | inline BOOST_CONSTEXPR reference |
755 | get_with_lazy_default( |
756 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
757 | , long |
758 | ) const |
759 | { |
760 | return this->get_value(); |
761 | } |
762 | |
763 | template <typename KW, typename F> |
764 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
765 | binding |
766 | , KW |
767 | , typename ::boost::parameter::aux::result_of0<F>::type |
768 | , ::boost::mpl::true_ |
769 | >::type |
770 | operator[]( |
771 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
772 | ) const |
773 | { |
774 | return this->get_with_lazy_default(x, 0L); |
775 | } |
776 | #else // No function template ordering or Borland workarounds needed. |
777 | template <typename Default> |
778 | inline BOOST_CONSTEXPR reference |
779 | operator[]( |
780 | ::boost::parameter::aux::default_<key_type,Default> const& |
781 | ) const |
782 | { |
783 | return this->get_value(); |
784 | } |
785 | |
786 | template <typename F> |
787 | inline BOOST_CONSTEXPR reference |
788 | operator[]( |
789 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
790 | ) const |
791 | { |
792 | return this->get_value(); |
793 | } |
794 | |
795 | template <typename KW, typename Default> |
796 | inline BOOST_CONSTEXPR Default& |
797 | operator[]( |
798 | ::boost::parameter::aux::default_<KW,Default> const& x |
799 | ) const |
800 | { |
801 | return x.value; |
802 | } |
803 | |
804 | template <typename KW, typename F> |
805 | inline BOOST_CONSTEXPR |
806 | typename ::boost::parameter::aux::result_of0<F>::type |
807 | operator[]( |
808 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
809 | ) const |
810 | { |
811 | return x.compute_default(); |
812 | } |
813 | |
814 | template <typename ParameterRequirements> |
815 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
816 | satisfies(ParameterRequirements*); |
817 | |
818 | template <typename HasDefault, typename Predicate> |
819 | static BOOST_CONSTEXPR |
820 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
821 | satisfies( |
822 | ::boost::parameter::aux::parameter_requirements< |
823 | key_type |
824 | , Predicate |
825 | , HasDefault |
826 | >* |
827 | ); |
828 | #endif // Function template ordering, Borland workarounds needed. |
829 | |
830 | // MPL sequence support |
831 | // Convenience for users |
832 | typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type; |
833 | // For the benefit of iterators |
834 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
835 | // For dispatching to sequence intrinsics |
836 | typedef ::boost::parameter::aux::arg_list_tag tag; |
837 | |
838 | #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) |
839 | // warning suppression |
840 | private: |
841 | void operator=(type const&); |
842 | #endif |
843 | }; |
844 | }}} // namespace boost::parameter::aux |
845 | |
846 | #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING |
847 | |
848 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
849 | |
850 | namespace boost { namespace parameter { namespace aux { |
851 | |
852 | template <typename TaggedArg> |
853 | struct tagged_argument_list_of_1 : public TaggedArg |
854 | { |
855 | using base_type = TaggedArg; |
856 | |
857 | inline explicit BOOST_CONSTEXPR tagged_argument_list_of_1( |
858 | typename base_type::reference x |
859 | ) : base_type(static_cast<typename base_type::reference>(x)) |
860 | { |
861 | } |
862 | |
863 | inline BOOST_CONSTEXPR tagged_argument_list_of_1( |
864 | tagged_argument_list_of_1 const& copy |
865 | ) : base_type(static_cast<base_type const&>(copy)) |
866 | { |
867 | } |
868 | |
869 | using base_type::operator[]; |
870 | using base_type::satisfies; |
871 | |
872 | template <typename TA2> |
873 | inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< |
874 | ::boost::parameter::aux |
875 | ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg> |
876 | , ::boost::parameter::aux::flat_like_arg_tuple< |
877 | typename TA2::base_type::key_type |
878 | , typename TA2::base_type |
879 | > |
880 | > |
881 | operator,(TA2 const& x) const |
882 | { |
883 | return boost::parameter::aux::flat_like_arg_list< |
884 | ::boost::parameter::aux |
885 | ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg> |
886 | , ::boost::parameter::aux::flat_like_arg_tuple< |
887 | typename TA2::base_type::key_type |
888 | , typename TA2::base_type |
889 | > |
890 | >( |
891 | static_cast<base_type const&>(*this) |
892 | , ::boost::parameter::aux::arg_list<typename TA2::base_type>( |
893 | static_cast<typename TA2::base_type const&>(x) |
894 | , ::boost::parameter::aux::empty_arg_list() |
895 | ) |
896 | ); |
897 | } |
898 | }; |
899 | }}} // namespace boost::parameter::aux |
900 | |
901 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
902 | #endif // include guard |
903 | |
904 | |