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_KEYWORD_HPP
8 #define BOOST_PARAMETER_KEYWORD_HPP
9 
10 #include <boost/parameter/aux_/tag.hpp>
11 #include <boost/parameter/aux_/default.hpp>
12 #include <boost/parameter/keyword_fwd.hpp>
13 #include <boost/parameter/config.hpp>
14 
15 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
16 #include <boost/core/enable_if.hpp>
17 #include <utility>
18 
19 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
20 #include <boost/mp11/integral.hpp>
21 #include <boost/mp11/utility.hpp>
22 #include <type_traits>
23 #else
24 #include <boost/mpl/bool.hpp>
25 #include <boost/mpl/if.hpp>
26 #include <boost/mpl/eval_if.hpp>
27 #include <boost/type_traits/is_same.hpp>
28 #include <boost/type_traits/is_scalar.hpp>
29 #include <boost/type_traits/is_const.hpp>
30 #endif
31 
32 namespace boost { namespace parameter {
33 
34     // Instances of unique specializations of keyword<...> serve to
35     // associate arguments with parameter names.  For example:
36     //
37     //     struct rate_;             // parameter names
38     //     struct skew_;
39     //
40     //     namespace
41     //     {
42     //         keyword<rate_> rate;  // keywords
43     //         keyword<skew_> skew;
44     //     }
45     //
46     //     ...
47     //
48     //     f(rate = 1, skew = 2.4);
49     template <typename Tag>
50     struct keyword
51     {
52         typedef Tag tag;
53 
keywordboost::parameter::keyword54         inline BOOST_CONSTEXPR keyword()
55         {
56         }
57 
58         template <typename T>
59         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
60 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
61             ::boost::mp11::mp_if<
62                 ::std::is_scalar<T>
63               , ::boost::mp11::mp_true
64               , ::boost::mp11::mp_if<
65                     ::std::is_same<
66                         typename Tag::qualifier
67                       , ::boost::parameter::in_reference
68                     >
69                   , ::boost::mp11::mp_true
70                   , ::std::is_same<
71                         typename Tag::qualifier
72                       , ::boost::parameter::forward_reference
73                     >
74                 >
75             >
76 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
77             typename ::boost::mpl::eval_if<
78                 ::boost::is_scalar<T>
79               , ::boost::mpl::true_
80               , ::boost::mpl::eval_if<
81                     ::boost::is_same<
82                         typename Tag::qualifier
83                       , ::boost::parameter::in_reference
84                     >
85                   , ::boost::mpl::true_
86                   , ::boost::mpl::if_<
87                         ::boost::is_same<
88                             typename Tag::qualifier
89                           , ::boost::parameter::forward_reference
90                         >
91                       , ::boost::mpl::true_
92                       , ::boost::mpl::false_
93                     >
94                 >
95             >::type
96 #endif  // BOOST_PARAMETER_CAN_USE_MP11
97           , ::boost::parameter::aux::tag<Tag,T const&>
98         >::type
operator =boost::parameter::keyword99             operator=(T const& x) const
100         {
101             typedef typename ::boost::parameter::aux
102             ::tag<Tag,T const&>::type result;
103             return result(x);
104         }
105 
106         template <typename Default>
107         inline BOOST_CONSTEXPR typename ::boost::enable_if<
108 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
109             ::boost::mp11::mp_if<
110                 ::std::is_scalar<Default>
111               , ::boost::mp11::mp_true
112               , ::boost::mp11::mp_if<
113                     ::std::is_same<
114                         typename Tag::qualifier
115                       , ::boost::parameter::in_reference
116                     >
117                   , ::boost::mp11::mp_true
118                   , ::std::is_same<
119                         typename Tag::qualifier
120                       , ::boost::parameter::forward_reference
121                     >
122                 >
123             >
124 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
125             typename ::boost::mpl::eval_if<
126                 ::boost::is_scalar<Default>
127               , ::boost::mpl::true_
128               , ::boost::mpl::eval_if<
129                     ::boost::is_same<
130                         typename Tag::qualifier
131                       , ::boost::parameter::in_reference
132                     >
133                   , ::boost::mpl::true_
134                   , ::boost::mpl::if_<
135                         ::boost::is_same<
136                             typename Tag::qualifier
137                           , ::boost::parameter::forward_reference
138                         >
139                       , ::boost::mpl::true_
140                       , ::boost::mpl::false_
141                     >
142                 >
143             >::type
144 #endif  // BOOST_PARAMETER_CAN_USE_MP11
145           , ::boost::parameter::aux::default_<Tag,Default const>
146         >::type
operator |boost::parameter::keyword147             operator|(Default const& d) const
148         {
149             return ::boost::parameter::aux::default_<Tag,Default const>(d);
150         }
151 
152         template <typename T>
153         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
154 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
155             ::boost::mp11::mp_if<
156                 ::boost::mp11::mp_if<
157                     ::std::is_same<
158                         typename Tag::qualifier
159                       , ::boost::parameter::out_reference
160                     >
161                   , ::boost::mp11::mp_true
162                   , ::std::is_same<
163                         typename Tag::qualifier
164                       , ::boost::parameter::forward_reference
165                     >
166                 >
167               , ::boost::mp11::mp_if<
168                     ::std::is_const<T>
169                   , ::boost::mp11::mp_false
170                   , ::boost::mp11::mp_true
171                 >
172               , ::boost::mp11::mp_false
173             >
174 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
175             typename ::boost::mpl::eval_if<
176                 typename ::boost::mpl::if_<
177                     ::boost::is_same<
178                         typename Tag::qualifier
179                       , ::boost::parameter::out_reference
180                     >
181                   , ::boost::mpl::true_
182                   , ::boost::is_same<
183                         typename Tag::qualifier
184                       , ::boost::parameter::forward_reference
185                     >
186                 >::type
187               , ::boost::mpl::if_<
188                     ::boost::is_const<T>
189                   , ::boost::mpl::false_
190                   , ::boost::mpl::true_
191                 >
192               , ::boost::mpl::false_
193             >::type
194 #endif  // BOOST_PARAMETER_CAN_USE_MP11
195           , ::boost::parameter::aux::tag<Tag,T&>
196         >::type
operator =boost::parameter::keyword197             operator=(T& x) const
198         {
199             typedef typename ::boost::parameter::aux
200             ::tag<Tag,T&>::type result;
201             return result(x);
202         }
203 
204         template <typename Default>
205         inline BOOST_CONSTEXPR typename ::boost::enable_if<
206 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
207             ::boost::mp11::mp_if<
208                 ::boost::mp11::mp_if<
209                     ::std::is_same<
210                         typename Tag::qualifier
211                       , ::boost::parameter::out_reference
212                     >
213                   , ::boost::mp11::mp_true
214                   , ::std::is_same<
215                         typename Tag::qualifier
216                       , ::boost::parameter::forward_reference
217                     >
218                 >
219               , ::boost::mp11::mp_if<
220                     ::std::is_const<Default>
221                   , ::boost::mp11::mp_false
222                   , ::boost::mp11::mp_true
223                 >
224               , ::boost::mp11::mp_false
225             >
226 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
227             typename ::boost::mpl::eval_if<
228                 typename ::boost::mpl::if_<
229                     ::boost::is_same<
230                         typename Tag::qualifier
231                       , ::boost::parameter::out_reference
232                     >
233                   , ::boost::mpl::true_
234                   , ::boost::is_same<
235                         typename Tag::qualifier
236                       , ::boost::parameter::forward_reference
237                     >
238                 >::type
239               , ::boost::mpl::if_<
240                     ::boost::is_const<Default>
241                   , ::boost::mpl::false_
242                   , ::boost::mpl::true_
243                 >
244               , ::boost::mpl::false_
245             >::type
246 #endif  // BOOST_PARAMETER_CAN_USE_MP11
247           , ::boost::parameter::aux::default_<Tag,Default>
248         >::type
operator |boost::parameter::keyword249             operator|(Default& d) const
250         {
251             return ::boost::parameter::aux::default_<Tag,Default>(d);
252         }
253 
254         template <typename Default>
255         inline BOOST_CONSTEXPR
256         ::boost::parameter::aux::lazy_default<Tag,Default const>
operator ||boost::parameter::keyword257             operator||(Default const& d) const
258         {
259             return ::boost::parameter::aux
260             ::lazy_default<Tag,Default const>(d);
261         }
262 
263         template <typename Default>
264         inline BOOST_CONSTEXPR
265         ::boost::parameter::aux::lazy_default<Tag,Default>
operator ||boost::parameter::keyword266             operator||(Default& d) const
267         {
268             return ::boost::parameter::aux::lazy_default<Tag,Default>(d);
269         }
270 
271         template <typename T>
272         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
273 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
274             ::boost::mp11::mp_if<
275                 ::std::is_scalar<T>
276               , ::boost::mp11::mp_false
277               , ::boost::mp11::mp_if<
278                     ::std::is_same<
279                         typename Tag::qualifier
280                       , ::boost::parameter::in_reference
281                     >
282                   , ::boost::mp11::mp_true
283                   , ::std::is_same<
284                         typename Tag::qualifier
285                       , ::boost::parameter::forward_reference
286                     >
287                 >
288             >
289 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
290             typename ::boost::mpl::eval_if<
291                 ::boost::is_scalar<T>
292               , ::boost::mpl::false_
293               , ::boost::mpl::eval_if<
294                     ::boost::is_same<
295                         typename Tag::qualifier
296                       , ::boost::parameter::in_reference
297                     >
298                   , ::boost::mpl::true_
299                   , ::boost::mpl::if_<
300                         ::boost::is_same<
301                             typename Tag::qualifier
302                           , ::boost::parameter::forward_reference
303                         >
304                       , ::boost::mpl::true_
305                       , ::boost::mpl::false_
306                     >
307                 >
308             >::type
309 #endif  // BOOST_PARAMETER_CAN_USE_MP11
310           , ::boost::parameter::aux::tag<Tag,T const>
311         >::type
operator =boost::parameter::keyword312             operator=(T const&& x) const
313         {
314             typedef typename ::boost::parameter::aux
315             ::tag<Tag,T const>::type result;
316             return result(::std::forward<T const>(x));
317         }
318 
319         template <typename T>
320         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
321 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
322             ::boost::mp11::mp_if<
323                 ::std::is_scalar<T>
324               , ::boost::mp11::mp_false
325               , ::boost::mp11::mp_if<
326                     ::std::is_same<
327                         typename Tag::qualifier
328                       , ::boost::parameter::consume_reference
329                     >
330                   , ::boost::mp11::mp_true
331                   , ::std::is_same<
332                         typename Tag::qualifier
333                       , ::boost::parameter::forward_reference
334                     >
335                 >
336             >
337 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
338             typename ::boost::mpl::eval_if<
339                 ::boost::is_scalar<T>
340               , ::boost::mpl::false_
341               , ::boost::mpl::eval_if<
342                     ::boost::is_same<
343                         typename Tag::qualifier
344                       , ::boost::parameter::consume_reference
345                     >
346                   , ::boost::mpl::true_
347                   , ::boost::mpl::if_<
348                         ::boost::is_same<
349                             typename Tag::qualifier
350                           , ::boost::parameter::forward_reference
351                         >
352                       , ::boost::mpl::true_
353                       , ::boost::mpl::false_
354                     >
355                 >
356             >::type
357 #endif  // BOOST_PARAMETER_CAN_USE_MP11
358           , ::boost::parameter::aux::tag<Tag,T>
359         >::type
operator =boost::parameter::keyword360             operator=(T&& x) const
361         {
362             typedef typename ::boost::parameter::aux::tag<Tag,T>::type result;
363             return result(::std::forward<T>(x));
364         }
365 
366         template <typename Default>
367         inline BOOST_CONSTEXPR typename ::boost::enable_if<
368 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
369             ::boost::mp11::mp_if<
370                 ::std::is_scalar<Default>
371               , ::boost::mp11::mp_false
372               , ::boost::mp11::mp_if<
373                     ::std::is_same<
374                         typename Tag::qualifier
375                       , ::boost::parameter::in_reference
376                     >
377                   , ::boost::mp11::mp_true
378                   , ::std::is_same<
379                         typename Tag::qualifier
380                       , ::boost::parameter::forward_reference
381                     >
382                 >
383             >
384 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
385             typename ::boost::mpl::eval_if<
386                 ::boost::is_scalar<Default>
387               , ::boost::mpl::false_
388               , ::boost::mpl::eval_if<
389                     ::boost::is_same<
390                         typename Tag::qualifier
391                       , ::boost::parameter::in_reference
392                     >
393                   , ::boost::mpl::true_
394                   , ::boost::mpl::if_<
395                         ::boost::is_same<
396                             typename Tag::qualifier
397                           , ::boost::parameter::forward_reference
398                         >
399                       , ::boost::mpl::true_
400                       , ::boost::mpl::false_
401                     >
402                 >
403             >::type
404 #endif  // BOOST_PARAMETER_CAN_USE_MP11
405           , ::boost::parameter::aux::default_r_<Tag,Default const>
406         >::type
operator |boost::parameter::keyword407             operator|(Default const&& d) const
408         {
409             return ::boost::parameter::aux::default_r_<Tag,Default const>(
410                 ::std::forward<Default const>(d)
411             );
412         }
413 
414         template <typename Default>
415         inline BOOST_CONSTEXPR typename ::boost::enable_if<
416 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
417             ::boost::mp11::mp_if<
418                 ::std::is_scalar<Default>
419               , ::boost::mp11::mp_false
420               , ::boost::mp11::mp_if<
421                     ::std::is_same<
422                         typename Tag::qualifier
423                       , ::boost::parameter::consume_reference
424                     >
425                   , ::boost::mp11::mp_true
426                   , ::std::is_same<
427                         typename Tag::qualifier
428                       , ::boost::parameter::forward_reference
429                     >
430                 >
431             >
432 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
433             typename ::boost::mpl::eval_if<
434                 ::boost::is_scalar<Default>
435               , ::boost::mpl::false_
436               , ::boost::mpl::eval_if<
437                     ::boost::is_same<
438                         typename Tag::qualifier
439                       , ::boost::parameter::consume_reference
440                     >
441                   , ::boost::mpl::true_
442                   , ::boost::mpl::if_<
443                         ::boost::is_same<
444                             typename Tag::qualifier
445                           , ::boost::parameter::forward_reference
446                         >
447                       , ::boost::mpl::true_
448                       , ::boost::mpl::false_
449                     >
450                 >
451             >::type
452 #endif  // BOOST_PARAMETER_CAN_USE_MP11
453           , ::boost::parameter::aux::default_r_<Tag,Default>
454         >::type
operator |boost::parameter::keyword455             operator|(Default&& d) const
456         {
457             return ::boost::parameter::aux
458             ::default_r_<Tag,Default>(::std::forward<Default>(d));
459         }
460 
461      public: // Insurance against ODR violations
462         // Users will need to define their keywords in header files.  To
463         // prevent ODR violations, it's important that the keyword used in
464         // every instantiation of a function template is the same object.
465         // We provide a reference to a common instance of each keyword
466         // object and prevent construction by users.
467         static ::boost::parameter::keyword<Tag> const instance;
468 
469         // This interface is deprecated.
getboost::parameter::keyword470         static ::boost::parameter::keyword<Tag>& get()
471         {
472             return const_cast< ::boost::parameter::keyword<Tag>&>(instance);
473         }
474     };
475 
476     template <typename Tag>
477     ::boost::parameter::keyword<Tag> const ::boost::parameter
478     ::keyword<Tag>::instance = ::boost::parameter::keyword<Tag>();
479 }} // namespace boost::parameter
480 
481 #else   // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
482 
483 #if !defined(BOOST_NO_SFINAE)
484 #include <boost/mpl/bool.hpp>
485 #include <boost/mpl/if.hpp>
486 #include <boost/mpl/eval_if.hpp>
487 #include <boost/core/enable_if.hpp>
488 #include <boost/type_traits/is_same.hpp>
489 #include <boost/type_traits/is_scalar.hpp>
490 #include <boost/type_traits/is_const.hpp>
491 #endif  // BOOST_NO_SFINAE
492 
493 namespace boost { namespace parameter {
494 
495     // Instances of unique specializations of keyword<...> serve to
496     // associate arguments with parameter names.  For example:
497     //
498     //     struct rate_;             // parameter names
499     //     struct skew_;
500     //
501     //     namespace
502     //     {
503     //         keyword<rate_> rate;  // keywords
504     //         keyword<skew_> skew;
505     //     }
506     //
507     //     ...
508     //
509     //     f(rate = 1, skew = 2.4);
510     template <typename Tag>
511     struct keyword
512     {
513         typedef Tag tag;
514 
keywordboost::parameter::keyword515         inline BOOST_CONSTEXPR keyword()
516         {
517         }
518 
519         template <typename T>
520 #if defined(BOOST_NO_SFINAE)
521         inline typename ::boost::parameter::aux::tag<Tag,T const&>::type
522 #else
523         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
524             typename ::boost::mpl::eval_if<
525                 ::boost::is_scalar<T>
526               , ::boost::mpl::true_
527               , ::boost::mpl::eval_if<
528                     ::boost::is_same<
529                         typename Tag::qualifier
530                       , ::boost::parameter::in_reference
531                     >
532                   , ::boost::mpl::true_
533                   , ::boost::mpl::if_<
534                         ::boost::is_same<
535                             typename Tag::qualifier
536                           , ::boost::parameter::forward_reference
537                         >
538                       , ::boost::mpl::true_
539                       , ::boost::mpl::false_
540                     >
541                 >
542             >::type
543           , ::boost::parameter::aux::tag<Tag,T const&>
544         >::type
545 #endif  // BOOST_NO_SFINAE
operator =boost::parameter::keyword546             operator=(T const& x) const
547         {
548             typedef typename ::boost::parameter::aux
549             ::tag<Tag,T const&>::type result;
550             return result(x);
551         }
552 
553         template <typename Default>
554 #if defined(BOOST_NO_SFINAE)
555         inline ::boost::parameter::aux::default_<Tag,Default const>
556 #else
557         inline BOOST_CONSTEXPR typename ::boost::enable_if<
558             typename ::boost::mpl::eval_if<
559                 ::boost::is_scalar<Default>
560               , ::boost::mpl::true_
561               , ::boost::mpl::eval_if<
562                     ::boost::is_same<
563                         typename Tag::qualifier
564                       , ::boost::parameter::in_reference
565                     >
566                   , ::boost::mpl::true_
567                   , ::boost::mpl::if_<
568                         ::boost::is_same<
569                             typename Tag::qualifier
570                           , ::boost::parameter::forward_reference
571                         >
572                       , ::boost::mpl::true_
573                       , ::boost::mpl::false_
574                     >
575                 >
576             >::type
577           , ::boost::parameter::aux::default_<Tag,Default const>
578         >::type
579 #endif  // BOOST_NO_SFINAE
operator |boost::parameter::keyword580             operator|(Default const& d) const
581         {
582             return ::boost::parameter::aux::default_<Tag,Default const>(d);
583         }
584 
585         template <typename T>
586 #if defined(BOOST_NO_SFINAE)
587         inline typename ::boost::parameter::aux::tag<Tag,T&>::type
588 #else
589         inline BOOST_CONSTEXPR typename ::boost::lazy_enable_if<
590             typename ::boost::mpl::eval_if<
591                 typename ::boost::mpl::if_<
592                     ::boost::is_same<
593                         typename Tag::qualifier
594                       , ::boost::parameter::out_reference
595                     >
596                   , ::boost::mpl::true_
597                   , ::boost::is_same<
598                         typename Tag::qualifier
599                       , ::boost::parameter::forward_reference
600                     >
601                 >::type
602               , ::boost::mpl::if_<
603                     ::boost::is_const<T>
604                   , ::boost::mpl::false_
605                   , ::boost::mpl::true_
606                 >
607               , ::boost::mpl::false_
608             >::type
609           , ::boost::parameter::aux::tag<Tag,T&>
610         >::type
611 #endif  // BOOST_NO_SFINAE
operator =boost::parameter::keyword612             operator=(T& x) const
613         {
614             typedef typename ::boost::parameter::aux
615             ::tag<Tag,T&>::type result;
616             return result(x);
617         }
618 
619         template <typename Default>
620 #if defined(BOOST_NO_SFINAE)
621         inline ::boost::parameter::aux::default_<Tag,Default>
622 #else
623         inline BOOST_CONSTEXPR typename ::boost::enable_if<
624             typename ::boost::mpl::eval_if<
625                 typename ::boost::mpl::if_<
626                     ::boost::is_same<
627                         typename Tag::qualifier
628                       , ::boost::parameter::out_reference
629                     >
630                   , ::boost::mpl::true_
631                   , ::boost::is_same<
632                         typename Tag::qualifier
633                       , ::boost::parameter::forward_reference
634                     >
635                 >::type
636               , ::boost::mpl::if_<
637                     ::boost::is_const<Default>
638                   , ::boost::mpl::false_
639                   , ::boost::mpl::true_
640                 >
641               , ::boost::mpl::false_
642             >::type
643           , ::boost::parameter::aux::default_<Tag,Default>
644         >::type
645 #endif  // BOOST_NO_SFINAE
operator |boost::parameter::keyword646             operator|(Default& d) const
647         {
648             return ::boost::parameter::aux::default_<Tag,Default>(d);
649         }
650 
651         template <typename Default>
652         inline BOOST_CONSTEXPR
653         ::boost::parameter::aux::lazy_default<Tag,Default const>
operator ||boost::parameter::keyword654             operator||(Default const& d) const
655         {
656             return ::boost::parameter::aux
657             ::lazy_default<Tag,Default const>(d);
658         }
659 
660         template <typename Default>
661         inline BOOST_CONSTEXPR
662         ::boost::parameter::aux::lazy_default<Tag,Default>
operator ||boost::parameter::keyword663             operator||(Default& d) const
664         {
665             return ::boost::parameter::aux::lazy_default<Tag,Default>(d);
666         }
667 
668      public: // Insurance against ODR violations
669         // Users will need to define their keywords in header files.  To
670         // prevent ODR violations, it's important that the keyword used in
671         // every instantiation of a function template is the same object.
672         // We provide a reference to a common instance of each keyword
673         // object and prevent construction by users.
674         static ::boost::parameter::keyword<Tag> const instance;
675 
676         // This interface is deprecated.
getboost::parameter::keyword677         static ::boost::parameter::keyword<Tag>& get()
678         {
679             return const_cast< ::boost::parameter::keyword<Tag>&>(instance);
680         }
681     };
682 
683     template <typename Tag>
684     ::boost::parameter::keyword<Tag> const ::boost::parameter
685     ::keyword<Tag>::instance = ::boost::parameter::keyword<Tag>();
686 }} // namespace boost::parameter
687 
688 #endif  // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
689 
690 #include <boost/parameter/aux_/name.hpp>
691 #include <boost/preprocessor/stringize.hpp>
692 
693 // Reduces boilerplate required to declare and initialize keywords without
694 // violating ODR.  Declares a keyword tag type with the given name in
695 // namespace tag_namespace, and declares and initializes a reference in an
696 // anonymous namespace to a singleton instance of that type.
697 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
698 #define BOOST_PARAMETER_KEYWORD(tag_namespace, name)                         \
699     namespace tag_namespace                                                  \
700     {                                                                        \
701         struct name                                                          \
702         {                                                                    \
703             static BOOST_CONSTEXPR char const* keyword_name()                \
704             {                                                                \
705                 return BOOST_PP_STRINGIZE(name);                             \
706             }                                                                \
707             using _ = BOOST_PARAMETER_TAG_PLACEHOLDER_TYPE(name);            \
708             using _1 = _;                                                    \
709             BOOST_PARAMETER_TAG_MP11_PLACEHOLDER_BINDING(binding_fn, name);  \
710             BOOST_PARAMETER_TAG_MP11_PLACEHOLDER_VALUE(fn, name);            \
711             using qualifier = ::boost::parameter::forward_reference;         \
712         };                                                                   \
713     }                                                                        \
714     namespace                                                                \
715     {                                                                        \
716         ::boost::parameter::keyword<tag_namespace::name> const& name         \
717             = ::boost::parameter::keyword<tag_namespace::name>::instance;    \
718     }
719 /**/
720 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
721 #define BOOST_PARAMETER_KEYWORD(tag_namespace, name)                         \
722     namespace tag_namespace                                                  \
723     {                                                                        \
724         struct name                                                          \
725         {                                                                    \
726             static BOOST_CONSTEXPR char const* keyword_name()                \
727             {                                                                \
728                 return BOOST_PP_STRINGIZE(name);                             \
729             }                                                                \
730             typedef BOOST_PARAMETER_TAG_PLACEHOLDER_TYPE(name) _;            \
731             typedef BOOST_PARAMETER_TAG_PLACEHOLDER_TYPE(name) _1;           \
732             typedef ::boost::parameter::forward_reference qualifier;         \
733         };                                                                   \
734     }                                                                        \
735     namespace                                                                \
736     {                                                                        \
737         ::boost::parameter::keyword<tag_namespace::name> const& name         \
738             = ::boost::parameter::keyword<tag_namespace::name>::instance;    \
739     }
740 /**/
741 #endif  // BOOST_PARAMETER_CAN_USE_MP11
742 
743 #endif  // include guard
744 
745