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