change for selective Backtrace (SENF_BACKTRACE). Included via autoconf if SENF_DEBUG...
[senf.git] / boost_ext / boost / parameter / keyword.hpp
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 #include <boost/noncopyable.hpp>
13
14 namespace boost { namespace parameter {
15
16 // Instances of unique specializations of keyword<...> serve to
17 // associate arguments with parameter names.  For example:
18 //
19 //    struct rate_;           // parameter names
20 //    struct skew_;
21 //    namespace
22 //    {
23 //      keyword<rate_> rate;  // keywords
24 //      keyword<skew_> skew;
25 //    }
26 //
27 //    ...
28 //
29 //    f(rate = 1, skew = 2.4);
30 //
31 template <class Tag>
32 struct keyword : noncopyable
33 {
34     template <class T>
35     typename aux::tag<Tag, T>::type
36     operator=(T& x) const
37     {
38         typedef typename aux::tag<Tag, T>::type result;
39         return result(x);
40     }
41
42     template <class Default>
43     aux::default_<Tag, Default>
44     operator|(Default& default_) const
45     {
46         return aux::default_<Tag, Default>(default_);
47     }
48
49     template <class Default>
50     aux::lazy_default<Tag, Default>
51     operator||(Default& default_) const
52     {
53         return aux::lazy_default<Tag, Default>(default_);
54     }
55
56 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)  // avoid partial ordering bugs
57     template <class T>
58     typename aux::tag<Tag, T const>::type
59     operator=(T const& x) const
60     {
61         typedef typename aux::tag<Tag, T const>::type result;
62         return result(x);
63     }
64 #endif 
65
66 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)  // avoid partial ordering bugs
67     template <class Default>
68     aux::default_<Tag, const Default>
69     operator|(const Default& default_) const
70 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
71         volatile
72 #endif 
73     {
74         return aux::default_<Tag, const Default>(default_);
75     }
76
77     template <class Default>
78     aux::lazy_default<Tag, Default>
79     operator||(Default const& default_) const
80 #if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
81         volatile
82 #endif 
83     {
84         return aux::lazy_default<Tag, Default>(default_);
85     }
86 #endif
87
88  public: // Insurance against ODR violations
89     
90     // People will need to define these keywords in header files.  To
91     // prevent ODR violations, it's important that the keyword used in
92     // every instantiation of a function template is the same object.
93     // We provide a reference to a common instance of each keyword
94     // object and prevent construction by users.
95     
96     static keyword<Tag>& get()
97     {
98         static keyword<Tag> result;
99         return result;
100     }
101     
102  private:
103     keyword() {}
104 };
105
106 // Reduces boilerplate required to declare and initialize keywords
107 // without violating ODR.  Declares a keyword tag type with the given
108 // name in namespace tag_namespace, and declares and initializes a
109 // reference in an anonymous namespace to a singleton instance of that
110 // type.
111
112 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
113
114 # define BOOST_PARAMETER_KEYWORD(tag_namespace,name)                \
115     namespace tag_namespace { struct name; }                        \
116     static ::boost::parameter::keyword<tag_namespace::name>& name   \
117        = ::boost::parameter::keyword<tag_namespace::name>::get();
118
119 #else
120
121 #define BOOST_PARAMETER_KEYWORD(tag_namespace,name)                 \
122     namespace tag_namespace { struct name; }                        \
123     namespace                                                       \
124     {                                                               \
125        ::boost::parameter::keyword<tag_namespace::name>& name       \
126        = ::boost::parameter::keyword<tag_namespace::name>::get();   \
127     }
128
129 #endif
130
131 }} // namespace boost::parameter
132
133 #endif // KEYWORD_050328_HPP
134