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_AUX_ARG_LIST_HPP |
8 | #define BOOST_PARAMETER_AUX_ARG_LIST_HPP |
9 | |
10 | namespace boost { namespace parameter { namespace aux { |
11 | |
12 | // |
13 | // Structures used to build the tuple of actual arguments. The tuple is a |
14 | // nested cons-style list of arg_list specializations terminated by an |
15 | // empty_arg_list. |
16 | // |
17 | // Each specialization of arg_list is derived from its successor in the |
18 | // list type. This feature is used along with using declarations to build |
19 | // member function overload sets that can match against keywords. |
20 | // |
21 | |
22 | // MPL sequence support |
23 | struct arg_list_tag; |
24 | |
25 | template <typename T> |
26 | struct get_reference |
27 | { |
28 | typedef typename T::reference type; |
29 | }; |
30 | }}} // namespace boost::parameter::aux |
31 | |
32 | #include <boost/parameter/config.hpp> |
33 | |
34 | #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
35 | |
36 | namespace boost { namespace parameter { namespace aux { |
37 | |
38 | struct value_type_is_void |
39 | { |
40 | }; |
41 | |
42 | struct value_type_is_not_void |
43 | { |
44 | }; |
45 | }}} // namespace boost::parameter::aux |
46 | |
47 | #endif |
48 | |
49 | #include <boost/parameter/aux_/void.hpp> |
50 | #include <boost/parameter/aux_/yesno.hpp> |
51 | #include <boost/parameter/aux_/result_of0.hpp> |
52 | #include <boost/parameter/aux_/default.hpp> |
53 | |
54 | #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
55 | #include <utility> |
56 | |
57 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
58 | #include <boost/mp11/integral.hpp> |
59 | #include <boost/mp11/list.hpp> |
60 | #include <boost/mp11/utility.hpp> |
61 | #include <type_traits> |
62 | #endif |
63 | |
64 | namespace boost { namespace parameter { namespace aux { |
65 | |
66 | // Terminates arg_list<> and represents an empty list. Since this is just |
67 | // the terminating case, you might want to look at arg_list first to get a |
68 | // feel for what's really happening here. |
69 | struct empty_arg_list |
70 | { |
71 | struct tagged_arg |
72 | { |
73 | typedef ::boost::parameter::void_ value_type; |
74 | }; |
75 | |
76 | // Variadic constructor also serves as default constructor. |
77 | template <typename ...Args> |
78 | inline BOOST_CONSTEXPR empty_arg_list(Args&&...) |
79 | { |
80 | } |
81 | |
82 | // A metafunction class that, given a keyword and a default type, |
83 | // returns the appropriate result type for a keyword lookup given |
84 | // that default. |
85 | struct binding |
86 | { |
87 | template <typename KW, typename Default, typename Reference> |
88 | struct apply |
89 | { |
90 | typedef Default type; |
91 | }; |
92 | |
93 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
94 | template <typename KW, typename Default, typename Reference> |
95 | using fn = Default; |
96 | #endif |
97 | }; |
98 | |
99 | // Terminator for has_key, indicating that the keyword is unique. |
100 | template <typename KW> |
101 | static ::boost::parameter::aux::no_tag has_key(KW*); |
102 | |
103 | // If either of these operators are called, it means there is no |
104 | // argument in the list that matches the supplied keyword. Just |
105 | // return the default value. |
106 | template <typename K, typename Default> |
107 | inline BOOST_CONSTEXPR Default& |
108 | operator[](::boost::parameter::aux::default_<K,Default> x) const |
109 | { |
110 | return x.value; |
111 | } |
112 | |
113 | template <typename K, typename Default> |
114 | inline BOOST_CONSTEXPR Default&& |
115 | operator[](::boost::parameter::aux::default_r_<K,Default> x) const |
116 | { |
117 | return ::std::forward<Default>(x.value); |
118 | } |
119 | |
120 | // If this operator is called, it means there is no argument in the |
121 | // list that matches the supplied keyword. Just evaluate and return |
122 | // the default value. |
123 | template <typename K, typename F> |
124 | inline BOOST_CONSTEXPR |
125 | typename ::boost::parameter::aux::result_of0<F>::type |
126 | operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const |
127 | { |
128 | return x.compute_default(); |
129 | } |
130 | |
131 | // No argument corresponding to ParameterRequirements::key_type |
132 | // was found if we match this overload, so unless that parameter |
133 | // has a default, we indicate that the actual arguments don't |
134 | // match the function's requirements. |
135 | template <typename ParameterRequirements, typename ArgPack> |
136 | static typename ParameterRequirements::has_default |
137 | satisfies(ParameterRequirements*, ArgPack*); |
138 | |
139 | // MPL sequence support |
140 | typedef ::boost::parameter::aux::empty_arg_list type; // convenience |
141 | // For dispatching to sequence intrinsics |
142 | typedef ::boost::parameter::aux::arg_list_tag tag; |
143 | }; |
144 | }}} // namespace boost::parameter::aux |
145 | |
146 | #include <boost/parameter/aux_/preprocessor/nullptr.hpp> |
147 | #include <boost/parameter/aux_/yesno.hpp> |
148 | #include <boost/parameter/aux_/is_maybe.hpp> |
149 | #include <boost/parameter/aux_/tagged_argument_fwd.hpp> |
150 | #include <boost/parameter/aux_/parameter_requirements.hpp> |
151 | #include <boost/parameter/aux_/augment_predicate.hpp> |
152 | #include <boost/parameter/keyword_fwd.hpp> |
153 | #include <boost/mpl/bool.hpp> |
154 | #include <boost/mpl/if.hpp> |
155 | #include <boost/mpl/eval_if.hpp> |
156 | #include <boost/mpl/apply_wrap.hpp> |
157 | #include <boost/mpl/assert.hpp> |
158 | #include <boost/type_traits/is_same.hpp> |
159 | #include <boost/core/enable_if.hpp> |
160 | |
161 | namespace boost { namespace parameter { namespace aux { |
162 | |
163 | // A tuple of tagged arguments, terminated with empty_arg_list. Every |
164 | // TaggedArg is an instance of tagged_argument<> or |
165 | // tagged_argument_rref<>. |
166 | template < |
167 | typename TaggedArg |
168 | , typename Next = ::boost::parameter::aux::empty_arg_list |
169 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
170 | , typename EmitsErrors = ::boost::mp11::mp_true |
171 | #else |
172 | , typename EmitsErrors = ::boost::mpl::true_ |
173 | #endif |
174 | > |
175 | class arg_list : public Next |
176 | { |
177 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
178 | using _holds_maybe = typename ::boost::parameter::aux |
179 | ::is_maybe<typename TaggedArg::value_type>::type; |
180 | #else |
181 | typedef typename ::boost::parameter::aux |
182 | ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe; |
183 | #endif |
184 | |
185 | TaggedArg arg; // Stores the argument |
186 | |
187 | public: |
188 | typedef TaggedArg tagged_arg; |
189 | typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self; |
190 | typedef typename TaggedArg::key_type key_type; |
191 | |
192 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
193 | using reference = typename ::boost::mp11::mp_if< |
194 | _holds_maybe |
195 | , ::boost::parameter::aux |
196 | ::get_reference<typename TaggedArg::value_type> |
197 | , ::boost::parameter::aux::get_reference<TaggedArg> |
198 | >::type; |
199 | |
200 | using value_type = ::boost::mp11 |
201 | ::mp_if<_holds_maybe,reference,typename TaggedArg::value_type>; |
202 | #else // !defined(BOOST_PARAMETER_CAN_USE_MP11) |
203 | typedef typename ::boost::mpl::eval_if< |
204 | _holds_maybe |
205 | , ::boost::parameter::aux |
206 | ::get_reference<typename TaggedArg::value_type> |
207 | , ::boost::parameter::aux::get_reference<TaggedArg> |
208 | >::type reference; |
209 | |
210 | typedef typename ::boost::mpl::if_< |
211 | _holds_maybe |
212 | , reference |
213 | , typename TaggedArg::value_type |
214 | >::type value_type; |
215 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
216 | |
217 | // Create a new list by prepending arg to a copy of tail. Used when |
218 | // incrementally building this structure with the comma operator. |
219 | inline BOOST_CONSTEXPR arg_list( |
220 | TaggedArg const& head |
221 | , Next const& tail |
222 | ) : Next(tail), arg(head) |
223 | { |
224 | } |
225 | |
226 | // Store the arguments in successive nodes of this list. |
227 | // Use tag dispatching to determine whether to forward all arguments |
228 | // to the Next constructor, or store the first argument and forward |
229 | // the rest. -- Cromwell D. Enage |
230 | template <typename A0> |
231 | inline BOOST_CONSTEXPR arg_list( |
232 | ::boost::parameter::aux::value_type_is_not_void |
233 | , A0&& a0 |
234 | ) : Next( |
235 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
236 | ::boost::mp11::mp_if< |
237 | ::std::is_same< |
238 | #else |
239 | typename ::boost::mpl::if_< |
240 | ::boost::is_same< |
241 | #endif |
242 | typename Next::tagged_arg::value_type |
243 | , ::boost::parameter::void_ |
244 | > |
245 | , ::boost::parameter::aux::value_type_is_void |
246 | , ::boost::parameter::aux::value_type_is_not_void |
247 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
248 | >() |
249 | #else |
250 | >::type() |
251 | #endif |
252 | ) |
253 | , arg(::std::forward<A0>(a0)) |
254 | { |
255 | } |
256 | |
257 | template <typename ...Args> |
258 | inline BOOST_CONSTEXPR arg_list( |
259 | ::boost::parameter::aux::value_type_is_void |
260 | , Args&&... args |
261 | ) : Next( |
262 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
263 | ::boost::mp11::mp_if< |
264 | ::std::is_same< |
265 | #else |
266 | typename ::boost::mpl::if_< |
267 | ::boost::is_same< |
268 | #endif |
269 | typename Next::tagged_arg::value_type |
270 | , ::boost::parameter::void_ |
271 | > |
272 | , ::boost::parameter::aux::value_type_is_void |
273 | , ::boost::parameter::aux::value_type_is_not_void |
274 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
275 | >() |
276 | #else |
277 | >::type() |
278 | #endif |
279 | , ::std::forward<Args>(args)... |
280 | ) |
281 | , arg(::boost::parameter::aux::void_reference()) |
282 | { |
283 | } |
284 | |
285 | template <typename A0, typename A1, typename ...Args> |
286 | inline BOOST_CONSTEXPR arg_list( |
287 | ::boost::parameter::aux::value_type_is_not_void |
288 | , A0&& a0 |
289 | , A1&& a1 |
290 | , Args&&... args |
291 | ) : Next( |
292 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
293 | ::boost::mp11::mp_if< |
294 | ::std::is_same< |
295 | #else |
296 | typename ::boost::mpl::if_< |
297 | ::boost::is_same< |
298 | #endif |
299 | typename Next::tagged_arg::value_type |
300 | , ::boost::parameter::void_ |
301 | > |
302 | , ::boost::parameter::aux::value_type_is_void |
303 | , ::boost::parameter::aux::value_type_is_not_void |
304 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
305 | >() |
306 | #else |
307 | >::type() |
308 | #endif |
309 | , ::std::forward<A1>(a1) |
310 | , ::std::forward<Args>(args)... |
311 | ) |
312 | , arg(::std::forward<A0>(a0)) |
313 | { |
314 | } |
315 | |
316 | // A metafunction class that, given a keyword and a default type, |
317 | // returns the appropriate result type for a keyword lookup given |
318 | // that default. |
319 | struct binding |
320 | { |
321 | typedef typename Next::binding next_binding; |
322 | |
323 | template <typename KW, typename Default, typename Reference> |
324 | struct apply |
325 | { |
326 | typedef typename ::boost::mpl::eval_if< |
327 | ::boost::is_same<KW,key_type> |
328 | , ::boost::mpl::if_<Reference,reference,value_type> |
329 | , ::boost::mpl |
330 | ::apply_wrap3<next_binding,KW,Default,Reference> |
331 | >::type type; |
332 | }; |
333 | |
334 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
335 | template <typename KW, typename Default, typename Reference> |
336 | using fn = ::boost::mp11::mp_if< |
337 | ::std::is_same<KW,key_type> |
338 | , ::boost::mp11::mp_if<Reference,reference,value_type> |
339 | , ::boost::mp11::mp_apply_q< |
340 | next_binding |
341 | , ::boost::mp11::mp_list<KW,Default,Reference> |
342 | > |
343 | >; |
344 | #endif |
345 | }; |
346 | |
347 | // Overload for key_type, so the assert below will fire |
348 | // if the same keyword is used again. |
349 | static ::boost::parameter::aux::yes_tag has_key(key_type*); |
350 | using Next::has_key; |
351 | |
352 | private: |
353 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
354 | using _has_unique_key = ::boost::mp11::mp_bool< |
355 | #else |
356 | typedef ::boost::mpl::bool_< |
357 | #endif |
358 | sizeof( |
359 | Next::has_key( |
360 | static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR) |
361 | ) |
362 | ) == sizeof(::boost::parameter::aux::no_tag) |
363 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
364 | >; |
365 | #else |
366 | > _has_unique_key; |
367 | #endif |
368 | |
369 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
370 | static_assert( |
371 | !(EmitsErrors::value) || (_has_unique_key::value) |
372 | , "duplicate keyword" |
373 | ); |
374 | #else |
375 | BOOST_MPL_ASSERT_MSG( |
376 | !(EmitsErrors::value) || (_has_unique_key::value) |
377 | , duplicate_keyword |
378 | , (key_type) |
379 | ); |
380 | #endif |
381 | |
382 | // |
383 | // Begin implementation of indexing operators |
384 | // for looking up specific arguments by name. |
385 | // |
386 | |
387 | // Helpers that handle the case when TaggedArg is empty<T>. |
388 | template <typename D> |
389 | inline BOOST_CONSTEXPR reference |
390 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
391 | get_default(D const&, ::boost::mp11::mp_false) const |
392 | #else |
393 | get_default(D const&, ::boost::mpl::false_) const |
394 | #endif |
395 | { |
396 | return this->arg.get_value(); |
397 | } |
398 | |
399 | template <typename D> |
400 | inline BOOST_CONSTEXPR reference |
401 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
402 | get_default(D const& d, ::boost::mp11::mp_true) const |
403 | #else |
404 | get_default(D const& d, ::boost::mpl::true_) const |
405 | #endif |
406 | { |
407 | return ( |
408 | this->arg.get_value() |
409 | ? this->arg.get_value().get() |
410 | : this->arg.get_value().construct(d.value) |
411 | ); |
412 | } |
413 | |
414 | public: |
415 | inline BOOST_CONSTEXPR reference |
416 | operator[](::boost::parameter::keyword<key_type> const&) const |
417 | { |
418 | #if !defined(BOOST_NO_CXX14_CONSTEXPR) |
419 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
420 | static_assert(!_holds_maybe::value, "must not hold maybe" ); |
421 | #elif !( \ |
422 | BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \ |
423 | BOOST_WORKAROUND(BOOST_GCC, < 40900) \ |
424 | ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \ |
425 | !BOOST_WORKAROUND(BOOST_MSVC, < 1910) |
426 | BOOST_MPL_ASSERT_NOT((_holds_maybe)); |
427 | #endif |
428 | #endif |
429 | return this->arg.get_value(); |
430 | } |
431 | |
432 | template <typename Default> |
433 | inline BOOST_CONSTEXPR reference |
434 | operator[]( |
435 | ::boost::parameter::aux::default_<key_type,Default> const& d |
436 | ) const |
437 | { |
438 | return this->get_default(d, _holds_maybe()); |
439 | } |
440 | |
441 | template <typename Default> |
442 | inline BOOST_CONSTEXPR reference |
443 | operator[]( |
444 | ::boost::parameter::aux::default_r_<key_type,Default> const& d |
445 | ) const |
446 | { |
447 | return this->get_default(d, _holds_maybe()); |
448 | } |
449 | |
450 | template <typename Default> |
451 | inline BOOST_CONSTEXPR reference |
452 | operator[]( |
453 | BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const& |
454 | ) const |
455 | { |
456 | #if !defined(BOOST_NO_CXX14_CONSTEXPR) |
457 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
458 | static_assert(!_holds_maybe::value, "must not hold maybe" ); |
459 | #elif !( \ |
460 | BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \ |
461 | BOOST_WORKAROUND(BOOST_GCC, < 40900) \ |
462 | ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \ |
463 | !BOOST_WORKAROUND(BOOST_MSVC, < 1910) |
464 | BOOST_MPL_ASSERT_NOT((_holds_maybe)); |
465 | #endif |
466 | #endif |
467 | return this->arg.get_value(); |
468 | } |
469 | |
470 | // Builds an overload set including operator[]s defined |
471 | // in base classes. |
472 | using Next::operator[]; |
473 | |
474 | // |
475 | // End of indexing support |
476 | // |
477 | |
478 | // For parameter_requirements matching this node's key_type, return |
479 | // a bool constant wrapper indicating whether the requirements are |
480 | // satisfied by TaggedArg. Used only for compile-time computation |
481 | // and never really called, so a declaration is enough. |
482 | template <typename HasDefault, typename Predicate, typename ArgPack> |
483 | static typename ::boost::lazy_enable_if< |
484 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
485 | ::boost::mp11::mp_if< |
486 | EmitsErrors |
487 | , ::boost::mp11::mp_true |
488 | , _has_unique_key |
489 | > |
490 | , ::boost::parameter::aux::augment_predicate_mp11< |
491 | #else |
492 | typename ::boost::mpl::if_< |
493 | EmitsErrors |
494 | , ::boost::mpl::true_ |
495 | , _has_unique_key |
496 | >::type |
497 | , ::boost::parameter::aux::augment_predicate< |
498 | #endif |
499 | Predicate |
500 | , reference |
501 | , key_type |
502 | , value_type |
503 | , ArgPack |
504 | > |
505 | >::type |
506 | satisfies( |
507 | ::boost::parameter::aux::parameter_requirements< |
508 | key_type |
509 | , Predicate |
510 | , HasDefault |
511 | >* |
512 | , ArgPack* |
513 | ); |
514 | |
515 | // Builds an overload set including satisfies functions defined |
516 | // in base classes. |
517 | using Next::satisfies; |
518 | |
519 | // Comma operator to compose argument list without using parameters<>. |
520 | // Useful for argument lists with undetermined length. |
521 | template <typename KW, typename T2> |
522 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
523 | ::boost::parameter::aux::tagged_argument<KW,T2> |
524 | , self |
525 | > |
526 | operator,( |
527 | ::boost::parameter::aux::tagged_argument<KW,T2> const& x |
528 | ) const |
529 | { |
530 | return ::boost::parameter::aux::arg_list< |
531 | ::boost::parameter::aux::tagged_argument<KW,T2> |
532 | , self |
533 | >(x, *this); |
534 | } |
535 | |
536 | template <typename KW, typename T2> |
537 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
538 | ::boost::parameter::aux::tagged_argument_rref<KW,T2> |
539 | , self |
540 | > |
541 | operator,( |
542 | ::boost::parameter::aux::tagged_argument_rref<KW,T2> const& x |
543 | ) const |
544 | { |
545 | return ::boost::parameter::aux::arg_list< |
546 | ::boost::parameter::aux::tagged_argument_rref<KW,T2> |
547 | , self |
548 | >(x, *this); |
549 | } |
550 | |
551 | // MPL sequence support |
552 | typedef self type; // Convenience for users |
553 | typedef Next tail_type; // For the benefit of iterators |
554 | // For dispatching to sequence intrinsics |
555 | typedef ::boost::parameter::aux::arg_list_tag tag; |
556 | }; |
557 | }}} // namespace boost::parameter::aux |
558 | |
559 | #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
560 | |
561 | #include <boost/preprocessor/repetition/enum_params.hpp> |
562 | #include <boost/preprocessor/facilities/intercept.hpp> |
563 | |
564 | namespace boost { namespace parameter { namespace aux { |
565 | |
566 | // Terminates arg_list<> and represents an empty list. Since this is just |
567 | // the terminating case, you might want to look at arg_list first to get a |
568 | // feel for what's really happening here. |
569 | struct empty_arg_list |
570 | { |
571 | inline BOOST_CONSTEXPR empty_arg_list() |
572 | { |
573 | } |
574 | |
575 | // Constructor taking BOOST_PARAMETER_COMPOSE_MAX_ARITY empty_arg_list |
576 | // arguments; this makes initialization. |
577 | inline BOOST_CONSTEXPR empty_arg_list( |
578 | BOOST_PP_ENUM_PARAMS( |
579 | BOOST_PARAMETER_COMPOSE_MAX_ARITY |
580 | , ::boost::parameter::void_ BOOST_PP_INTERCEPT |
581 | ) |
582 | ) |
583 | { |
584 | } |
585 | |
586 | // A metafunction class that, given a keyword and a default type, |
587 | // returns the appropriate result type for a keyword lookup given |
588 | // that default. |
589 | struct binding |
590 | { |
591 | template <typename KW, typename Default, typename Reference> |
592 | struct apply |
593 | { |
594 | typedef Default type; |
595 | }; |
596 | }; |
597 | |
598 | // Terminator for has_key, indicating that the keyword is unique. |
599 | template <typename KW> |
600 | static ::boost::parameter::aux::no_tag has_key(KW*); |
601 | |
602 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
603 | // The overload set technique doesn't work with these older compilers, |
604 | // so they need some explicit handholding. |
605 | |
606 | // A metafunction class that, given a keyword, returns the type of the |
607 | // base sublist whose get() function can produce the value for that key. |
608 | struct key_owner |
609 | { |
610 | template <typename KW> |
611 | struct apply |
612 | { |
613 | typedef ::boost::parameter::aux::empty_arg_list type; |
614 | }; |
615 | }; |
616 | #endif // Borland workarounds needed |
617 | |
618 | // If either of these operators are called, it means there is no |
619 | // argument in the list that matches the supplied keyword. Just |
620 | // return the default value. |
621 | template <typename K, typename Default> |
622 | inline BOOST_CONSTEXPR Default& |
623 | operator[](::boost::parameter::aux::default_<K,Default> x) const |
624 | { |
625 | return x.value; |
626 | } |
627 | |
628 | // If this operator is called, it means there is no argument in the |
629 | // list that matches the supplied keyword. Just evaluate and return |
630 | // the default value. |
631 | template <typename K, typename F> |
632 | inline BOOST_CONSTEXPR |
633 | typename ::boost::parameter::aux::result_of0<F>::type |
634 | operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const |
635 | { |
636 | return x.compute_default(); |
637 | } |
638 | |
639 | // No argument corresponding to ParameterRequirements::key_type |
640 | // was found if we match this overload, so unless that parameter |
641 | // has a default, we indicate that the actual arguments don't |
642 | // match the function's requirements. |
643 | template <typename ParameterRequirements, typename ArgPack> |
644 | static typename ParameterRequirements::has_default |
645 | satisfies(ParameterRequirements*, ArgPack*); |
646 | |
647 | // MPL sequence support |
648 | typedef ::boost::parameter::aux::empty_arg_list type; // convenience |
649 | // For dispatching to sequence intrinsics |
650 | typedef ::boost::parameter::aux::arg_list_tag tag; |
651 | }; |
652 | }}} // namespace boost::parameter::aux |
653 | |
654 | #include <boost/parameter/aux_/yesno.hpp> |
655 | #include <boost/parameter/aux_/is_maybe.hpp> |
656 | #include <boost/parameter/aux_/tagged_argument_fwd.hpp> |
657 | #include <boost/parameter/aux_/parameter_requirements.hpp> |
658 | #include <boost/parameter/aux_/augment_predicate.hpp> |
659 | #include <boost/parameter/keyword_fwd.hpp> |
660 | #include <boost/mpl/bool.hpp> |
661 | #include <boost/mpl/if.hpp> |
662 | #include <boost/mpl/eval_if.hpp> |
663 | #include <boost/mpl/apply_wrap.hpp> |
664 | #include <boost/mpl/assert.hpp> |
665 | #include <boost/type_traits/is_same.hpp> |
666 | #include <boost/preprocessor/repetition/enum_binary_params.hpp> |
667 | #include <boost/preprocessor/repetition/enum_shifted_params.hpp> |
668 | |
669 | #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) |
670 | #include <boost/core/enable_if.hpp> |
671 | #endif |
672 | |
673 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
674 | #include <boost/parameter/aux_/preprocessor/nullptr.hpp> |
675 | #endif |
676 | |
677 | namespace boost { namespace parameter { namespace aux { |
678 | |
679 | // A tuple of tagged arguments, terminated with empty_arg_list. Every |
680 | // TaggedArg is an instance of tagged_argument<>. |
681 | template < |
682 | typename TaggedArg |
683 | , typename Next = ::boost::parameter::aux::empty_arg_list |
684 | , typename EmitsErrors = ::boost::mpl::true_ |
685 | > |
686 | class arg_list : public Next |
687 | { |
688 | typedef typename ::boost::parameter::aux |
689 | ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe; |
690 | |
691 | TaggedArg arg; // Stores the argument |
692 | |
693 | public: |
694 | typedef TaggedArg tagged_arg; |
695 | typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self; |
696 | typedef typename TaggedArg::key_type key_type; |
697 | |
698 | typedef typename ::boost::mpl::eval_if< |
699 | _holds_maybe |
700 | , ::boost::parameter::aux |
701 | ::get_reference<typename TaggedArg::value_type> |
702 | , ::boost::parameter::aux::get_reference<TaggedArg> |
703 | >::type reference; |
704 | |
705 | typedef typename ::boost::mpl::if_< |
706 | _holds_maybe |
707 | , reference |
708 | , typename TaggedArg::value_type |
709 | >::type value_type; |
710 | |
711 | // Create a new list by prepending arg to a copy of tail. Used when |
712 | // incrementally building this structure with the comma operator. |
713 | inline BOOST_CONSTEXPR arg_list( |
714 | TaggedArg const& head |
715 | , Next const& tail |
716 | ) : Next(tail), arg(head) |
717 | { |
718 | } |
719 | |
720 | // Store the arguments in successive nodes of this list. |
721 | template < |
722 | // typename A0, typename A1, ... |
723 | BOOST_PP_ENUM_PARAMS( |
724 | BOOST_PARAMETER_COMPOSE_MAX_ARITY |
725 | , typename A |
726 | ) |
727 | > |
728 | inline BOOST_CONSTEXPR arg_list( |
729 | // A0& a0, A1& a1, ... |
730 | BOOST_PP_ENUM_BINARY_PARAMS( |
731 | BOOST_PARAMETER_COMPOSE_MAX_ARITY |
732 | , A |
733 | , & a |
734 | ) |
735 | ) : Next( |
736 | // a1, a2, ... |
737 | BOOST_PP_ENUM_SHIFTED_PARAMS( |
738 | BOOST_PARAMETER_COMPOSE_MAX_ARITY |
739 | , a |
740 | ) |
741 | , ::boost::parameter::aux::void_reference() |
742 | ) |
743 | , arg(a0) |
744 | { |
745 | } |
746 | |
747 | // A metafunction class that, given a keyword and a default type, |
748 | // returns the appropriate result type for a keyword lookup given |
749 | // that default. |
750 | struct binding |
751 | { |
752 | typedef typename Next::binding next_binding; |
753 | |
754 | template <typename KW, typename Default, typename Reference> |
755 | struct apply |
756 | { |
757 | typedef typename ::boost::mpl::eval_if< |
758 | ::boost::is_same<KW,key_type> |
759 | , ::boost::mpl::if_<Reference,reference,value_type> |
760 | , ::boost::mpl::apply_wrap3< |
761 | next_binding |
762 | , KW |
763 | , Default |
764 | , Reference |
765 | > |
766 | >::type type; |
767 | }; |
768 | }; |
769 | |
770 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
771 | // Overload for key_type, so the assert below will fire |
772 | // if the same keyword is used again. |
773 | static ::boost::parameter::aux::yes_tag has_key(key_type*); |
774 | using Next::has_key; |
775 | |
776 | private: |
777 | #if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800) |
778 | BOOST_MPL_ASSERT_MSG( |
779 | sizeof( |
780 | Next::has_key( |
781 | static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR) |
782 | ) |
783 | ) == sizeof(::boost::parameter::aux::no_tag) |
784 | , duplicate_keyword |
785 | , (key_type) |
786 | ); |
787 | #else |
788 | typedef ::boost::mpl::bool_< |
789 | sizeof( |
790 | Next::has_key( |
791 | static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR) |
792 | ) |
793 | ) == sizeof(::boost::parameter::aux::no_tag) |
794 | > _has_unique_key; |
795 | |
796 | BOOST_MPL_ASSERT_MSG( |
797 | !(EmitsErrors::value) || (_has_unique_key::value) |
798 | , duplicate_keyword |
799 | , (key_type) |
800 | ); |
801 | #endif // SFINAE/MSVC workarounds needed |
802 | #endif // Borland workarounds not needed |
803 | |
804 | private: |
805 | // |
806 | // Begin implementation of indexing operators |
807 | // for looking up specific arguments by name. |
808 | // |
809 | |
810 | // Helpers that handle the case when TaggedArg is empty<T>. |
811 | template <typename D> |
812 | inline BOOST_CONSTEXPR reference |
813 | get_default(D const&, ::boost::mpl::false_) const |
814 | { |
815 | return this->arg.get_value(); |
816 | } |
817 | |
818 | template <typename D> |
819 | inline BOOST_CONSTEXPR reference |
820 | get_default(D const& d, ::boost::mpl::true_) const |
821 | { |
822 | return ( |
823 | this->arg.get_value() |
824 | ? this->arg.get_value().get() |
825 | : this->arg.get_value().construct(d.value) |
826 | ); |
827 | } |
828 | |
829 | public: |
830 | #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
831 | // These older compilers don't support the overload set creation |
832 | // idiom well, so we need to do all the return type calculation |
833 | // for the compiler and dispatch through an outer function template. |
834 | |
835 | // A metafunction class that, given a keyword, returns the base |
836 | // sublist whose get() function can produce the value for that key. |
837 | struct key_owner |
838 | { |
839 | typedef typename Next::key_owner next_key_owner; |
840 | |
841 | template <typename KW> |
842 | struct apply |
843 | { |
844 | typedef typename ::boost::mpl::eval_if< |
845 | ::boost::is_same<KW,key_type> |
846 | , ::boost::mpl::identity< |
847 | ::boost::parameter::aux::arg_list<TaggedArg,Next> |
848 | > |
849 | , ::boost::mpl::apply_wrap1<next_key_owner,KW> |
850 | >::type type; |
851 | }; |
852 | }; |
853 | |
854 | // Outer indexing operators that dispatch to the right node's |
855 | // get() function. |
856 | template <typename KW> |
857 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
858 | binding |
859 | , KW |
860 | , ::boost::parameter::void_ |
861 | , ::boost::mpl::true_ |
862 | >::type |
863 | operator[](::boost::parameter::keyword<KW> const& x) const |
864 | { |
865 | typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const& |
866 | sublist = *this; |
867 | return sublist.get(x); |
868 | } |
869 | |
870 | template <typename KW, typename Default> |
871 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
872 | binding |
873 | , KW |
874 | , Default& |
875 | , ::boost::mpl::true_ |
876 | >::type |
877 | operator[]( |
878 | ::boost::parameter::aux::default_<KW,Default> const& x |
879 | ) const |
880 | { |
881 | typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const& |
882 | sublist = *this; |
883 | return sublist.get(x); |
884 | } |
885 | |
886 | template <typename KW, typename F> |
887 | inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3< |
888 | binding |
889 | , KW |
890 | , typename ::boost::parameter::aux::result_of0<F>::type |
891 | , ::boost::mpl::true_ |
892 | >::type |
893 | operator[]( |
894 | BOOST_PARAMETER_lazy_default_fallback<KW,F> const& x |
895 | ) const |
896 | { |
897 | typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const& |
898 | sublist = *this; |
899 | return sublist.get(x); |
900 | } |
901 | |
902 | // These just return the stored value; when empty_arg_list is reached, |
903 | // indicating no matching argument was passed, the default is |
904 | // returned, or if no default_ or lazy_default was passed, compilation |
905 | // fails. |
906 | inline BOOST_CONSTEXPR reference |
907 | get(::boost::parameter::keyword<key_type> const&) const |
908 | { |
909 | BOOST_MPL_ASSERT_NOT((_holds_maybe)); |
910 | return this->arg.get_value(); |
911 | } |
912 | |
913 | template <typename Default> |
914 | inline BOOST_CONSTEXPR reference |
915 | get( |
916 | ::boost::parameter::aux::default_<key_type,Default> const& d |
917 | ) const |
918 | { |
919 | return this->get_default(d, _holds_maybe()); |
920 | } |
921 | |
922 | template <typename Default> |
923 | inline BOOST_CONSTEXPR reference |
924 | get( |
925 | BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const& |
926 | ) const |
927 | { |
928 | return this->arg.get_value(); |
929 | } |
930 | #else // !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) |
931 | inline BOOST_CONSTEXPR reference |
932 | operator[](::boost::parameter::keyword<key_type> const&) const |
933 | { |
934 | BOOST_MPL_ASSERT_NOT((_holds_maybe)); |
935 | return this->arg.get_value(); |
936 | } |
937 | |
938 | template <typename Default> |
939 | inline BOOST_CONSTEXPR reference |
940 | operator[]( |
941 | ::boost::parameter::aux::default_<key_type,Default> const& d |
942 | ) const |
943 | { |
944 | return this->get_default(d, _holds_maybe()); |
945 | } |
946 | |
947 | template <typename Default> |
948 | inline BOOST_CONSTEXPR reference |
949 | operator[]( |
950 | BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const& |
951 | ) const |
952 | { |
953 | BOOST_MPL_ASSERT_NOT((_holds_maybe)); |
954 | return this->arg.get_value(); |
955 | } |
956 | |
957 | // Builds an overload set including operator[]s defined |
958 | // in base classes. |
959 | using Next::operator[]; |
960 | |
961 | // |
962 | // End of indexing support |
963 | // |
964 | |
965 | // For parameter_requirements matching this node's key_type, return |
966 | // a bool constant wrapper indicating whether the requirements are |
967 | // satisfied by TaggedArg. Used only for compile-time computation |
968 | // and never really called, so a declaration is enough. |
969 | template <typename HasDefault, typename Predicate, typename ArgPack> |
970 | static typename |
971 | #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) |
972 | ::boost::lazy_enable_if< |
973 | typename ::boost::mpl::if_< |
974 | EmitsErrors |
975 | , ::boost::mpl::true_ |
976 | , _has_unique_key |
977 | >::type, |
978 | #endif |
979 | ::boost::parameter::aux::augment_predicate< |
980 | Predicate |
981 | , reference |
982 | , key_type |
983 | , value_type |
984 | , ArgPack |
985 | #if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) |
986 | > |
987 | #endif |
988 | >::type |
989 | satisfies( |
990 | ::boost::parameter::aux::parameter_requirements< |
991 | key_type |
992 | , Predicate |
993 | , HasDefault |
994 | >* |
995 | , ArgPack* |
996 | ); |
997 | |
998 | // Builds an overload set including satisfies functions defined |
999 | // in base classes. |
1000 | using Next::satisfies; |
1001 | #endif // Borland workarounds needed |
1002 | |
1003 | // Comma operator to compose argument list without using parameters<>. |
1004 | // Useful for argument lists with undetermined length. |
1005 | template <typename KW, typename T2> |
1006 | inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list< |
1007 | ::boost::parameter::aux::tagged_argument<KW,T2> |
1008 | , self |
1009 | > |
1010 | operator,( |
1011 | ::boost::parameter::aux::tagged_argument<KW,T2> const& x |
1012 | ) const |
1013 | { |
1014 | return ::boost::parameter::aux::arg_list< |
1015 | ::boost::parameter::aux::tagged_argument<KW,T2> |
1016 | , self |
1017 | >(x, *this); |
1018 | } |
1019 | |
1020 | // MPL sequence support |
1021 | typedef self type; // Convenience for users |
1022 | typedef Next tail_type; // For the benefit of iterators |
1023 | // For dispatching to sequence intrinsics |
1024 | typedef ::boost::parameter::aux::arg_list_tag tag; |
1025 | }; |
1026 | }}} // namespace boost::parameter::aux |
1027 | |
1028 | #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING |
1029 | |
1030 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
1031 | |
1032 | namespace boost { namespace parameter { namespace aux { |
1033 | |
1034 | template <typename ...ArgTuples> |
1035 | struct arg_list_cons; |
1036 | |
1037 | template <> |
1038 | struct arg_list_cons<> |
1039 | { |
1040 | using type = ::boost::parameter::aux::empty_arg_list; |
1041 | }; |
1042 | |
1043 | template <typename ArgTuple0, typename ...Tuples> |
1044 | struct arg_list_cons<ArgTuple0,Tuples...> |
1045 | { |
1046 | using type = ::boost::parameter::aux::arg_list< |
1047 | typename ArgTuple0::tagged_arg |
1048 | , typename ::boost::parameter::aux::arg_list_cons<Tuples...>::type |
1049 | , typename ArgTuple0::emits_errors |
1050 | >; |
1051 | }; |
1052 | |
1053 | template < |
1054 | typename Keyword |
1055 | , typename TaggedArg |
1056 | , typename EmitsErrors = ::boost::mp11::mp_true |
1057 | > |
1058 | struct flat_like_arg_tuple |
1059 | { |
1060 | using tagged_arg = TaggedArg; |
1061 | using emits_errors = EmitsErrors; |
1062 | }; |
1063 | |
1064 | template <typename ...ArgTuples> |
1065 | class flat_like_arg_list |
1066 | : public ::boost::parameter::aux::arg_list_cons<ArgTuples...>::type |
1067 | { |
1068 | using _base_type = typename ::boost::parameter::aux |
1069 | ::arg_list_cons<ArgTuples...>::type; |
1070 | |
1071 | public: |
1072 | inline BOOST_CONSTEXPR flat_like_arg_list( |
1073 | typename _base_type::tagged_arg const& head |
1074 | , typename _base_type::tail_type const& tail |
1075 | ) : _base_type(head, tail) |
1076 | { |
1077 | } |
1078 | |
1079 | template <typename ...Args> |
1080 | inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args) |
1081 | : _base_type(::std::forward<Args>(args)...) |
1082 | { |
1083 | } |
1084 | |
1085 | using _base_type::operator[]; |
1086 | using _base_type::satisfies; |
1087 | |
1088 | // Comma operator to compose argument list without using parameters<>. |
1089 | // Useful for argument lists with undetermined length. |
1090 | template <typename TaggedArg> |
1091 | inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< |
1092 | ::boost::parameter::aux::flat_like_arg_tuple< |
1093 | typename TaggedArg::base_type::key_type |
1094 | , typename TaggedArg::base_type |
1095 | > |
1096 | , ArgTuples... |
1097 | > |
1098 | operator,(TaggedArg const& x) const |
1099 | { |
1100 | return ::boost::parameter::aux::flat_like_arg_list< |
1101 | ::boost::parameter::aux::flat_like_arg_tuple< |
1102 | typename TaggedArg::base_type::key_type |
1103 | , typename TaggedArg::base_type |
1104 | > |
1105 | , ArgTuples... |
1106 | >( |
1107 | static_cast<typename TaggedArg::base_type const&>(x) |
1108 | , static_cast<_base_type const&>(*this) |
1109 | ); |
1110 | } |
1111 | }; |
1112 | |
1113 | template <> |
1114 | class flat_like_arg_list<> |
1115 | : public ::boost::parameter::aux::empty_arg_list |
1116 | { |
1117 | using _base_type = ::boost::parameter::aux::empty_arg_list; |
1118 | |
1119 | public: |
1120 | template <typename ...Args> |
1121 | inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args) |
1122 | : _base_type(::std::forward<Args>(args)...) |
1123 | { |
1124 | } |
1125 | |
1126 | using _base_type::operator[]; |
1127 | using _base_type::satisfies; |
1128 | |
1129 | // Comma operator to compose argument list without using parameters<>. |
1130 | // Useful for argument lists with undetermined length. |
1131 | template <typename TaggedArg> |
1132 | inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list< |
1133 | ::boost::parameter::aux::flat_like_arg_tuple< |
1134 | typename TaggedArg::base_type::key_type |
1135 | , typename TaggedArg::base_type |
1136 | > |
1137 | > |
1138 | operator,(TaggedArg const& x) const |
1139 | { |
1140 | return ::boost::parameter::aux::flat_like_arg_list< |
1141 | ::boost::parameter::aux::flat_like_arg_tuple< |
1142 | typename TaggedArg::base_type::key_type |
1143 | , typename TaggedArg::base_type |
1144 | > |
1145 | >( |
1146 | static_cast<typename TaggedArg::base_type const&>(x) |
1147 | , static_cast<_base_type const&>(*this) |
1148 | ); |
1149 | } |
1150 | }; |
1151 | }}} // namespace boost::parameter::aux |
1152 | |
1153 | #endif // BOOST_PARAMETER_CAN_USE_MP11 |
1154 | |
1155 | #include <boost/mpl/iterator_tags.hpp> |
1156 | |
1157 | namespace boost { namespace parameter { namespace aux { |
1158 | |
1159 | // MPL sequence support |
1160 | template <typename ArgumentPack> |
1161 | struct arg_list_iterator |
1162 | { |
1163 | typedef ::boost::mpl::forward_iterator_tag category; |
1164 | |
1165 | // The incremented iterator |
1166 | typedef ::boost::parameter::aux |
1167 | ::arg_list_iterator<typename ArgumentPack::tail_type> next; |
1168 | |
1169 | // dereferencing yields the key type |
1170 | typedef typename ArgumentPack::key_type type; |
1171 | }; |
1172 | |
1173 | template <> |
1174 | struct arg_list_iterator< ::boost::parameter::aux::empty_arg_list> |
1175 | { |
1176 | }; |
1177 | }}} // namespace boost::parameter::aux |
1178 | |
1179 | #include <boost/mpl/begin_end_fwd.hpp> |
1180 | |
1181 | // MPL sequence support |
1182 | namespace boost { namespace mpl { |
1183 | |
1184 | template <> |
1185 | struct begin_impl< ::boost::parameter::aux::arg_list_tag> |
1186 | { |
1187 | template <typename S> |
1188 | struct apply |
1189 | { |
1190 | typedef ::boost::parameter::aux::arg_list_iterator<S> type; |
1191 | }; |
1192 | }; |
1193 | |
1194 | template <> |
1195 | struct end_impl< ::boost::parameter::aux::arg_list_tag> |
1196 | { |
1197 | template <typename> |
1198 | struct apply |
1199 | { |
1200 | typedef ::boost::parameter::aux::arg_list_iterator< |
1201 | ::boost::parameter::aux::empty_arg_list |
1202 | > type; |
1203 | }; |
1204 | }; |
1205 | }} // namespace boost::mpl |
1206 | |
1207 | #include <boost/parameter/value_type.hpp> |
1208 | #include <boost/mpl/has_key_fwd.hpp> |
1209 | #include <boost/type_traits/is_void.hpp> |
1210 | |
1211 | namespace boost { namespace mpl { |
1212 | |
1213 | template <> |
1214 | struct has_key_impl< ::boost::parameter::aux::arg_list_tag> |
1215 | { |
1216 | template <typename ArgList, typename Keyword> |
1217 | struct apply |
1218 | { |
1219 | typedef typename ::boost::mpl::if_< |
1220 | ::boost::is_void< |
1221 | typename ::boost::parameter |
1222 | ::value_type<ArgList,Keyword,void>::type |
1223 | > |
1224 | , ::boost::mpl::false_ |
1225 | , ::boost::mpl::true_ |
1226 | >::type type; |
1227 | }; |
1228 | }; |
1229 | }} // namespace boost::mpl |
1230 | |
1231 | #include <boost/mpl/count_fwd.hpp> |
1232 | #include <boost/mpl/int.hpp> |
1233 | |
1234 | namespace boost { namespace mpl { |
1235 | |
1236 | template <> |
1237 | struct count_impl< ::boost::parameter::aux::arg_list_tag> |
1238 | { |
1239 | template <typename ArgList, typename Keyword> |
1240 | struct apply |
1241 | { |
1242 | typedef typename ::boost::mpl::if_< |
1243 | ::boost::is_void< |
1244 | typename ::boost::parameter |
1245 | ::value_type<ArgList,Keyword,void>::type |
1246 | > |
1247 | , ::boost::mpl::int_<0> |
1248 | , ::boost::mpl::int_<1> |
1249 | >::type type; |
1250 | }; |
1251 | }; |
1252 | }} // namespace boost::mpl |
1253 | |
1254 | #include <boost/mpl/key_type_fwd.hpp> |
1255 | #include <boost/mpl/identity.hpp> |
1256 | |
1257 | namespace boost { namespace mpl { |
1258 | |
1259 | template <> |
1260 | struct key_type_impl< ::boost::parameter::aux::arg_list_tag> |
1261 | { |
1262 | template <typename ArgList, typename Keyword> |
1263 | struct apply |
1264 | { |
1265 | typedef typename ::boost::mpl::eval_if< |
1266 | ::boost::is_void< |
1267 | typename ::boost::parameter |
1268 | ::value_type<ArgList,Keyword,void>::type |
1269 | > |
1270 | , void |
1271 | , ::boost::mpl::identity<Keyword> |
1272 | >::type type; |
1273 | }; |
1274 | }; |
1275 | }} // namespace boost::mpl |
1276 | |
1277 | #include <boost/mpl/value_type_fwd.hpp> |
1278 | |
1279 | namespace boost { namespace mpl { |
1280 | |
1281 | template <> |
1282 | struct value_type_impl< ::boost::parameter::aux::arg_list_tag> |
1283 | : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag> |
1284 | { |
1285 | }; |
1286 | }} // namespace boost::mpl |
1287 | |
1288 | #include <boost/mpl/at_fwd.hpp> |
1289 | |
1290 | namespace boost { namespace mpl { |
1291 | |
1292 | template <> |
1293 | struct at_impl< ::boost::parameter::aux::arg_list_tag> |
1294 | : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag> |
1295 | { |
1296 | }; |
1297 | }} // namespace boost::mpl |
1298 | |
1299 | #include <boost/mpl/order_fwd.hpp> |
1300 | #include <boost/mpl/void.hpp> |
1301 | #include <boost/mpl/find.hpp> |
1302 | #include <boost/mpl/distance.hpp> |
1303 | |
1304 | namespace boost { namespace mpl { |
1305 | |
1306 | template <> |
1307 | struct order_impl< ::boost::parameter::aux::arg_list_tag> |
1308 | { |
1309 | template <typename ArgList, typename Keyword> |
1310 | struct apply |
1311 | { |
1312 | typedef typename ::boost::mpl::find<ArgList,Keyword>::type Itr; |
1313 | typedef typename ::boost::mpl::eval_if< |
1314 | ::boost::is_void< |
1315 | typename ::boost::parameter |
1316 | ::value_type<ArgList,Keyword,void>::type |
1317 | > |
1318 | , ::boost::mpl::identity< ::boost::mpl::void_> |
1319 | , ::boost::mpl::distance< |
1320 | Itr |
1321 | , ::boost::parameter::aux::arg_list_iterator< |
1322 | ::boost::parameter::aux::empty_arg_list |
1323 | > |
1324 | > |
1325 | >::type type; |
1326 | }; |
1327 | }; |
1328 | }} // namespace boost::mpl |
1329 | |
1330 | #endif // include guard |
1331 | |
1332 | |