]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright Daniel Wallin, David Abrahams 2005. Use, modification and |
2 | // distribution is subject to the Boost Software License, Version 1.0. (See | |
3 | // accompanying file LICENSE_1_0.txt or copy at | |
4 | // http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #ifndef KEYWORD_050328_HPP | |
7 | #define KEYWORD_050328_HPP | |
8 | ||
9 | #include <boost/parameter/aux_/unwrap_cv_reference.hpp> | |
10 | #include <boost/parameter/aux_/tag.hpp> | |
11 | #include <boost/parameter/aux_/default.hpp> | |
12 | ||
13 | namespace boost { namespace parameter { | |
14 | ||
15 | // Instances of unique specializations of keyword<...> serve to | |
16 | // associate arguments with parameter names. For example: | |
17 | // | |
18 | // struct rate_; // parameter names | |
19 | // struct skew_; | |
20 | // namespace | |
21 | // { | |
22 | // keyword<rate_> rate; // keywords | |
23 | // keyword<skew_> skew; | |
24 | // } | |
25 | // | |
26 | // ... | |
27 | // | |
28 | // f(rate = 1, skew = 2.4); | |
29 | // | |
30 | template <class Tag> | |
31 | struct keyword | |
32 | { | |
33 | template <class T> | |
34 | typename aux::tag<Tag, T>::type const | |
35 | operator=(T& x) const | |
36 | { | |
37 | typedef typename aux::tag<Tag, T>::type result; | |
38 | return result(x); | |
39 | } | |
40 | ||
41 | template <class Default> | |
42 | aux::default_<Tag, Default> | |
43 | operator|(Default& default_) const | |
44 | { | |
45 | return aux::default_<Tag, Default>(default_); | |
46 | } | |
47 | ||
48 | template <class Default> | |
49 | aux::lazy_default<Tag, Default> | |
50 | operator||(Default& default_) const | |
51 | { | |
52 | return aux::lazy_default<Tag, Default>(default_); | |
53 | } | |
54 | ||
55 | template <class T> | |
56 | typename aux::tag<Tag, T const>::type const | |
57 | operator=(T const& x) const | |
58 | { | |
59 | typedef typename aux::tag<Tag, T const>::type result; | |
60 | return result(x); | |
61 | } | |
62 | ||
63 | template <class Default> | |
64 | aux::default_<Tag, const Default> | |
65 | operator|(const Default& default_) const | |
66 | { | |
67 | return aux::default_<Tag, const Default>(default_); | |
68 | } | |
69 | ||
70 | template <class Default> | |
71 | aux::lazy_default<Tag, Default> | |
72 | operator||(Default const& default_) const | |
73 | { | |
74 | return aux::lazy_default<Tag, Default>(default_); | |
75 | } | |
76 | ||
77 | public: // Insurance against ODR violations | |
78 | ||
79 | // People will need to define these keywords in header files. To | |
80 | // prevent ODR violations, it's important that the keyword used in | |
81 | // every instantiation of a function template is the same object. | |
82 | // We provide a reference to a common instance of each keyword | |
83 | // object and prevent construction by users. | |
84 | static keyword<Tag> const instance; | |
85 | ||
86 | // This interface is deprecated | |
87 | static keyword<Tag>& get() | |
88 | { | |
89 | return const_cast<keyword<Tag>&>(instance); | |
90 | } | |
91 | }; | |
92 | ||
93 | template <class Tag> | |
94 | keyword<Tag> const keyword<Tag>::instance = {}; | |
95 | ||
96 | // Reduces boilerplate required to declare and initialize keywords | |
97 | // without violating ODR. Declares a keyword tag type with the given | |
98 | // name in namespace tag_namespace, and declares and initializes a | |
99 | // reference in an anonymous namespace to a singleton instance of that | |
100 | // type. | |
101 | ||
102 | #define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \ | |
103 | namespace tag_namespace \ | |
104 | { \ | |
105 | struct name \ | |
106 | { \ | |
107 | static char const* keyword_name() \ | |
108 | { \ | |
109 | return #name; \ | |
110 | } \ | |
111 | }; \ | |
112 | } \ | |
113 | namespace \ | |
114 | { \ | |
115 | ::boost::parameter::keyword<tag_namespace::name> const& name \ | |
116 | = ::boost::parameter::keyword<tag_namespace::name>::instance;\ | |
117 | } | |
118 | ||
119 | }} // namespace boost::parameter | |
120 | ||
121 | #endif // KEYWORD_050328_HPP | |
122 |