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