]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/parameter/aux_/arg_list.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / parameter / aux_ / arg_list.hpp
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 ARG_LIST_050329_HPP
8 #define ARG_LIST_050329_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