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 F> |
299 | inline BOOST_CONSTEXPR reference |
300 | operator[]( |
301 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
302 | ) const |
303 | { |
304 | return this->get_value(); |
305 | } |
306 | |
307 | template <typename KW, typename Default> |
308 | inline BOOST_CONSTEXPR Default& |
309 | operator[]( |
310 | ::boost::parameter::aux::default_<KW,Default> const& x |
311 | ) const |
312 | { |
313 | return x.value; |
314 | } |
315 | |
316 | template <typename KW, typename Default> |
317 | inline BOOST_CONSTEXPR Default&& |
318 | operator[]( |
319 | ::boost::parameter::aux::default_r_<KW,Default> const& x |
320 | ) const |
321 | { |
322 | return ::std::forward<Default>(x.value); |
323 | } |
324 | |
325 | template <typename KW, typename F> |
326 | inline BOOST_CONSTEXPR |
327 | typename ::boost::parameter::aux::result_of0<F>::type |
328 | operator[]( |
329 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
330 | ) const |
331 | { |
332 | return x.compute_default(); |
333 | } |
334 | |
335 | template <typename ParameterRequirements> |
336 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
337 | satisfies(ParameterRequirements*); |
338 | |
339 | template <typename HasDefault, typename Predicate> |
340 | static BOOST_CONSTEXPR |
341 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
342 | satisfies( |
343 | ::boost::parameter::aux::parameter_requirements< |
344 | key_type |
345 | , Predicate |
346 | , HasDefault |
347 | >* |
348 | ); |
349 | |
350 | // MPL sequence support |
351 | // Convenience for users |
352 | typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type; |
353 | // For the benefit of iterators |
354 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
355 | // For dispatching to sequence intrinsics |
356 | typedef ::boost::parameter::aux::arg_list_tag tag; |
357 | }; |
358 | |
359 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
360 | template <typename Keyword> |
361 | using tagged_argument_rref_key = ::boost::mp11::mp_if< |
362 | ::std::is_same< |
363 | typename Keyword::qualifier |
364 | , ::boost::parameter::out_reference |
365 | > |
366 | , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter |
367 | , ::boost::mp11::mp_identity<Keyword> |
368 | >; |
369 | #endif |
370 | |
371 | // Holds an rvalue reference to an argument of type Arg associated with |
372 | // keyword Keyword |
373 | template <typename Keyword, typename Arg> |
374 | struct tagged_argument_rref |
375 | : ::boost::parameter::aux::tagged_argument_base |
376 | { |
377 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
378 | using key_type = typename ::boost::parameter::aux |
379 | ::tagged_argument_rref_key<Keyword>::type; |
380 | #else |
381 | typedef typename ::boost::mpl::eval_if< |
382 | ::boost::is_same< |
383 | typename Keyword::qualifier |
384 | , ::boost::parameter::out_reference |
385 | > |
386 | , ::boost::parameter::aux::error_rvalue_bound_to_out_parameter |
387 | , ::boost::mpl::identity<Keyword> |
388 | >::type key_type; |
389 | #endif |
390 | typedef Arg value_type; |
391 | typedef Arg&& reference; |
392 | |
393 | private: |
394 | reference value; |
395 | |
396 | public: |
397 | inline explicit BOOST_CONSTEXPR tagged_argument_rref(reference x) |
398 | : value(::std::forward<Arg>(x)) |
399 | { |
400 | } |
401 | |
402 | inline BOOST_CONSTEXPR tagged_argument_rref( |
403 | tagged_argument_rref const& copy |
404 | ) : value(::std::forward<Arg>(copy.value)) |
405 | { |
406 | } |
407 | |
408 | // A metafunction class that, given a keyword and a default type, |
409 | // returns the appropriate result type for a keyword lookup given |
410 | // that default. |
411 | struct binding |
412 | { |
413 | template <typename KW, typename Default, typename Reference> |
414 | struct apply |
415 | { |
416 | typedef typename ::boost::mpl::eval_if< |
417 | ::boost::is_same<KW,key_type> |
418 | , ::boost::mpl::if_<Reference,reference,value_type> |
419 | , ::boost::mpl::identity<Default> |
420 | >::type type; |
421 | }; |
422 | |
423 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
424 | template <typename KW, typename Default, typename Reference> |
425 | using fn = ::boost::mp11::mp_if< |
426 | ::std::is_same<KW,key_type> |
427 | , ::boost::mp11::mp_if<Reference,reference,value_type> |
428 | , Default |
429 | >; |
430 | #endif |
431 | }; |
432 | |
433 | #if !defined(BOOST_PARAMETER_CAN_USE_MP11) |
434 | // Comma operator to compose argument list without using parameters<>. |
435 | // Useful for argument lists with undetermined length. |
436 | template <typename Keyword2, typename Arg2> |
437 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
438 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
439 | , ::boost::parameter::aux::arg_list< |
440 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
441 | > |
442 | > |
443 | operator,( |
444 | ::boost::parameter::aux |
445 | ::tagged_argument<Keyword2,Arg2> const& x |
446 | ) const |
447 | { |
448 | return boost::parameter::aux::arg_list< |
449 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
450 | , ::boost::parameter::aux::arg_list< |
451 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
452 | > |
453 | >( |
454 | *this |
455 | , ::boost::parameter::aux::arg_list< |
456 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
457 | >(x, ::boost::parameter::aux::empty_arg_list()) |
458 | ); |
459 | } |
460 | |
461 | template <typename Keyword2, typename Arg2> |
462 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
463 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
464 | , ::boost::parameter::aux::arg_list< |
465 | ::boost::parameter::aux::tagged_argument_rref<Keyword2,Arg2> |
466 | > |
467 | > |
468 | operator,( |
469 | ::boost::parameter::aux |
470 | ::tagged_argument_rref<Keyword2,Arg2> const& x |
471 | ) const |
472 | { |
473 | return ::boost::parameter::aux::arg_list< |
474 | ::boost::parameter::aux::tagged_argument_rref<Keyword,Arg> |
475 | , ::boost::parameter::aux::arg_list< |
476 | ::boost::parameter::aux |
477 | ::tagged_argument_rref<Keyword2,Arg2> |
478 | > |
479 | >( |
480 | *this |
481 | , ::boost::parameter::aux::arg_list< |
482 | ::boost::parameter::aux::tagged_argument_rref< |
483 | Keyword2 |
484 | , Arg2 |
485 | > |
486 | >(x, ::boost::parameter::aux::empty_arg_list()) |
487 | ); |
488 | } |
489 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
490 | |
491 | // Accessor interface. |
492 | inline BOOST_CONSTEXPR reference get_value() const |
493 | { |
494 | return ::std::forward<Arg>(this->value); |
495 | } |
496 | |
497 | inline BOOST_CONSTEXPR reference |
498 | operator[](::boost::parameter::keyword<Keyword> const&) const |
499 | { |
500 | return this->get_value(); |
501 | } |
502 | |
503 | template <typename Default> |
504 | inline BOOST_CONSTEXPR reference |
505 | operator[]( |
506 | ::boost::parameter::aux::default_<key_type,Default> const& |
507 | ) 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_r_<key_type,Default> const& |
516 | ) const |
517 | { |
518 | return this->get_value(); |
519 | } |
520 | |
521 | template <typename F> |
522 | inline BOOST_CONSTEXPR reference |
523 | operator[]( |
524 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
525 | ) const |
526 | { |
527 | return this->get_value(); |
528 | } |
529 | |
530 | template <typename KW, typename Default> |
531 | inline BOOST_CONSTEXPR Default& |
532 | operator[]( |
533 | ::boost::parameter::aux::default_<KW,Default> const& x |
534 | ) const |
535 | { |
536 | return x.value; |
537 | } |
538 | |
539 | template <typename KW, typename Default> |
540 | inline BOOST_CONSTEXPR Default&& |
541 | operator[]( |
542 | ::boost::parameter::aux::default_r_<KW,Default> const& x |
543 | ) const |
544 | { |
545 | return ::std::forward<Default>(x.value); |
546 | } |
547 | |
548 | template <typename KW, typename F> |
549 | inline BOOST_CONSTEXPR |
550 | typename ::boost::parameter::aux::result_of0<F>::type |
551 | operator[]( |
552 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
553 | ) const |
554 | { |
555 | return x.compute_default(); |
556 | } |
557 | |
558 | template <typename ParameterRequirements> |
559 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
560 | satisfies(ParameterRequirements*); |
561 | |
562 | template <typename HasDefault, typename Predicate> |
563 | static BOOST_CONSTEXPR |
564 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
565 | satisfies( |
566 | ::boost::parameter::aux::parameter_requirements< |
567 | key_type |
568 | , Predicate |
569 | , HasDefault |
570 | >* |
571 | ); |
572 | |
573 | // MPL sequence support |
574 | // Convenience for users |
575 | typedef ::boost::parameter::aux |
576 | ::tagged_argument_rref<Keyword,Arg> type; |
577 | // For the benefit of iterators |
578 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
579 | // For dispatching to sequence intrinsics |
580 | typedef ::boost::parameter::aux::arg_list_tag tag; |
581 | }; |
582 | }}} // namespace boost::parameter::aux |
583 | |
584 | #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
585 | |
586 | namespace boost { namespace parameter { namespace aux { |
587 | |
588 | // Holds an lvalue reference to an argument of type Arg associated with |
589 | // keyword Keyword |
590 | template <typename Keyword, typename Arg> |
591 | class tagged_argument |
592 | : public ::boost::parameter::aux::tagged_argument_base |
593 | { |
594 | typedef typename ::boost::remove_const<Arg>::type arg_type; |
595 | |
596 | public: |
597 | typedef Keyword key_type; |
598 | |
599 | // Wrap plain (non-UDT) function objects in either |
600 | // a boost::function or a std::function. -- Cromwell D. Enage |
601 | typedef typename ::boost::mpl::if_< |
602 | ::boost::is_function<arg_type> |
603 | #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) |
604 | , ::boost::function<arg_type> |
605 | #else |
606 | , ::std::function<arg_type> |
607 | #endif |
608 | , Arg |
609 | >::type value_type; |
610 | |
611 | // If Arg is void_, then this type will evaluate to void_&. If the |
612 | // supplied argument is a plain function, then this type will evaluate |
613 | // to a reference-to-const function wrapper type. If the supplied |
614 | // argument is an lvalue, then Arg will be deduced to the lvalue |
615 | // reference. -- Cromwell D. Enage |
616 | typedef typename ::boost::mpl::if_< |
617 | ::boost::is_function<arg_type> |
618 | , value_type const& |
619 | , Arg& |
620 | >::type reference; |
621 | |
622 | private: |
623 | // Store plain functions by value, everything else by reference. |
624 | // -- Cromwell D. Enage |
625 | typename ::boost::mpl::if_< |
626 | ::boost::is_function<arg_type> |
627 | , value_type |
628 | , reference |
629 | >::type value; |
630 | |
631 | public: |
632 | inline explicit BOOST_CONSTEXPR tagged_argument(reference x) |
633 | : value(x) |
634 | { |
635 | } |
636 | |
637 | inline BOOST_CONSTEXPR tagged_argument(tagged_argument const& copy) |
638 | : value(copy.value) |
639 | { |
640 | } |
641 | |
642 | // A metafunction class that, given a keyword and a default type, |
643 | // returns the appropriate result type for a keyword lookup given |
644 | // that default. |
645 | struct binding |
646 | { |
647 | template <typename KW, typename Default, typename Reference> |
648 | struct apply |
649 | { |
650 | typedef typename ::boost::mpl::eval_if< |
651 | ::boost::is_same<KW,key_type> |
652 | , ::boost::mpl::if_<Reference,reference,value_type> |
653 | , ::boost::mpl::identity<Default> |
654 | >::type type; |
655 | }; |
656 | }; |
657 | |
658 | // Comma operator to compose argument list without using parameters<>. |
659 | // Useful for argument lists with undetermined length. |
660 | template <typename Keyword2, typename Arg2> |
661 | inline ::boost::parameter::aux::arg_list< |
662 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
663 | , ::boost::parameter::aux::arg_list< |
664 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
665 | > |
666 | > |
667 | operator,( |
668 | ::boost::parameter::aux |
669 | ::tagged_argument<Keyword2,Arg2> const& x |
670 | ) const |
671 | { |
672 | return ::boost::parameter::aux::arg_list< |
673 | ::boost::parameter::aux::tagged_argument<Keyword,Arg> |
674 | , ::boost::parameter::aux::arg_list< |
675 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
676 | > |
677 | >( |
678 | *this |
679 | , ::boost::parameter::aux::arg_list< |
680 | ::boost::parameter::aux::tagged_argument<Keyword2,Arg2> |
681 | >(x, ::boost::parameter::aux::empty_arg_list()) |
682 | ); |
683 | } |
684 | |
685 | // Accessor interface. |
686 | inline BOOST_CONSTEXPR reference get_value() const |
687 | { |
688 | return this->value; |
689 | } |
690 | |
691 | inline BOOST_CONSTEXPR reference |
692 | operator[](::boost::parameter::keyword<Keyword> const&) const |
693 | { |
694 | return this->get_value(); |
695 | } |
696 | |
697 | #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) || \ |
698 | BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
699 | template <typename KW, typename Default> |
700 | inline BOOST_CONSTEXPR Default& |
701 | get_with_default( |
702 | ::boost::parameter::aux::default_<KW,Default> const& x |
703 | , int |
704 | ) const |
705 | { |
706 | return x.value; |
707 | } |
708 | |
709 | template <typename Default> |
710 | inline BOOST_CONSTEXPR reference |
711 | get_with_default( |
712 | ::boost::parameter::aux::default_<key_type,Default> const& |
713 | , long |
714 | ) const |
715 | { |
716 | return this->get_value(); |
717 | } |
718 | |
719 | template <typename KW, typename Default> |
720 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
721 | binding |
722 | , KW |
723 | , Default& |
724 | , ::boost::mpl::true_ |
725 | >::type |
726 | operator[]( |
727 | ::boost::parameter::aux::default_<KW,Default> const& x |
728 | ) const |
729 | { |
730 | return this->get_with_default(x, 0L); |
731 | } |
732 | |
733 | template <typename KW, typename F> |
734 | inline BOOST_CONSTEXPR |
735 | typename ::boost::parameter::aux::result_of0<F>::type |
736 | get_with_lazy_default( |
737 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
738 | , int |
739 | ) const |
740 | { |
741 | return x.compute_default(); |
742 | } |
743 | |
744 | template <typename F> |
745 | inline BOOST_CONSTEXPR reference |
746 | get_with_lazy_default( |
747 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
748 | , long |
749 | ) const |
750 | { |
751 | return this->get_value(); |
752 | } |
753 | |
754 | template <typename KW, typename F> |
755 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
756 | binding |
757 | , KW |
758 | , typename ::boost::parameter::aux::result_of0<F>::type |
759 | , ::boost::mpl::true_ |
760 | >::type |
761 | operator[]( |
762 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
763 | ) const |
764 | { |
765 | return this->get_with_lazy_default(x, 0L); |
766 | } |
767 | #else // No function template ordering or Borland workarounds needed. |
768 | template <typename Default> |
769 | inline BOOST_CONSTEXPR reference |
770 | operator[]( |
771 | ::boost::parameter::aux::default_<key_type,Default> const& |
772 | ) const |
773 | { |
774 | return this->get_value(); |
775 | } |
776 | |
777 | template <typename F> |
778 | inline BOOST_CONSTEXPR reference |
779 | operator[]( |
780 | ::boost::parameter::aux::lazy_default<key_type,F> const& |
781 | ) const |
782 | { |
783 | return this->get_value(); |
784 | } |
785 | |
786 | template <typename KW, typename Default> |
787 | inline BOOST_CONSTEXPR Default& |
788 | operator[]( |
789 | ::boost::parameter::aux::default_<KW,Default> const& x |
790 | ) const |
791 | { |
792 | return x.value; |
793 | } |
794 | |
795 | template <typename KW, typename F> |
796 | inline BOOST_CONSTEXPR |
797 | typename ::boost::parameter::aux::result_of0<F>::type |
798 | operator[]( |
799 | ::boost::parameter::aux::lazy_default<KW,F> const& x |
800 | ) const |
801 | { |
802 | return x.compute_default(); |
803 | } |
804 | |
805 | template <typename ParameterRequirements> |
806 | static BOOST_CONSTEXPR typename ParameterRequirements::has_default |
807 | satisfies(ParameterRequirements*); |
808 | |
809 | template <typename HasDefault, typename Predicate> |
810 | static BOOST_CONSTEXPR |
811 | typename ::boost::mpl::apply_wrap1<Predicate,value_type>::type |
812 | satisfies( |
813 | ::boost::parameter::aux::parameter_requirements< |
814 | key_type |
815 | , Predicate |
816 | , HasDefault |
817 | >* |
818 | ); |
819 | #endif // Function template ordering, Borland workarounds needed. |
820 | |
821 | // MPL sequence support |
822 | // Convenience for users |
823 | typedef ::boost::parameter::aux::tagged_argument<Keyword,Arg> type; |
824 | // For the benefit of iterators |
825 | typedef ::boost::parameter::aux::empty_arg_list tail_type; |
826 | // For dispatching to sequence intrinsics |
827 | typedef ::boost::parameter::aux::arg_list_tag tag; |
828 | |
829 | #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) |
830 | // warning suppression |
831 | private: |
832 | void operator=(type const&); |
833 | #endif |
834 | }; |
835 | }}} // namespace boost::parameter::aux |
836 | |
837 | #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING |
838 | |
839 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
840 | |
841 | namespace boost { namespace parameter { namespace aux { |
842 | |
843 | template <typename TaggedArg> |
844 | struct tagged_argument_list_of_1 : public TaggedArg |
845 | { |
846 | using base_type = TaggedArg; |
847 | |
848 | inline explicit BOOST_CONSTEXPR tagged_argument_list_of_1( |
849 | typename base_type::reference x |
850 | ) : base_type(static_cast<typename base_type::reference>(x)) |
851 | { |
852 | } |
853 | |
854 | inline BOOST_CONSTEXPR tagged_argument_list_of_1( |
855 | tagged_argument_list_of_1 const& copy |
856 | ) : base_type(static_cast<base_type const&>(copy)) |
857 | { |
858 | } |
859 | |
860 | using base_type::operator[]; |
861 | using base_type::satisfies; |
862 | |
863 | template <typename TA2> |
864 | inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< |
865 | ::boost::parameter::aux |
866 | ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg> |
867 | , ::boost::parameter::aux::flat_like_arg_tuple< |
868 | typename TA2::base_type::key_type |
869 | , typename TA2::base_type |
870 | > |
871 | > |
872 | operator,(TA2 const& x) const |
873 | { |
874 | return boost::parameter::aux::flat_like_arg_list< |
875 | ::boost::parameter::aux |
876 | ::flat_like_arg_tuple<typename TaggedArg::key_type,TaggedArg> |
877 | , ::boost::parameter::aux::flat_like_arg_tuple< |
878 | typename TA2::base_type::key_type |
879 | , typename TA2::base_type |
880 | > |
881 | >( |
882 | static_cast<base_type const&>(*this) |
883 | , ::boost::parameter::aux::arg_list<typename TA2::base_type>( |
884 | static_cast<typename TA2::base_type const&>(x) |
885 | , ::boost::parameter::aux::empty_arg_list() |
886 | ) |
887 | ); |
888 | } |
889 | }; |
890 | }}} // namespace boost::parameter::aux |
891 | |
892 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
893 | #endif // include guard |
894 | |
895 | |