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 | |
123 | |