1 // Copyright David Abrahams 2002.
2 // Distributed under 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 #ifndef KEYWORDS_DWA2002323_HPP
6 # define KEYWORDS_DWA2002323_HPP
7
8 # include <boost/python/detail/prefix.hpp>
9
10 # include <boost/python/args_fwd.hpp>
11 # include <boost/config.hpp>
12 # include <boost/python/detail/preprocessor.hpp>
13 # include <boost/python/detail/type_list.hpp>
14 # include <boost/python/detail/type_traits.hpp>
15
16 # include <boost/preprocessor/enum_params.hpp>
17 # include <boost/preprocessor/repeat.hpp>
18 # include <boost/preprocessor/facilities/intercept.hpp>
19 # include <boost/preprocessor/iteration/local.hpp>
20
21 # include <boost/python/detail/mpl_lambda.hpp>
22 # include <boost/python/object_core.hpp>
23
24 # include <boost/mpl/bool.hpp>
25
26 # include <cstddef>
27 # include <algorithm>
28
29 namespace boost { namespace python {
30
31 typedef detail::keywords<1> arg;
32 typedef arg arg_; // gcc 2.96 workaround
33
34 namespace detail
35 {
36 template <std::size_t nkeywords>
37 struct keywords_base
38 {
39 BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
40
rangeboost::python::detail::keywords_base41 keyword_range range() const
42 {
43 return keyword_range(elements, elements + nkeywords);
44 }
45
46 keyword elements[nkeywords];
47
48 keywords<nkeywords+1>
49 operator,(python::arg const &k) const;
50
51 keywords<nkeywords + 1>
52 operator,(char const *name) const;
53 };
54
55 template <std::size_t nkeywords>
56 struct keywords : keywords_base<nkeywords>
57 {
58 };
59
60 template <>
61 struct keywords<1> : keywords_base<1>
62 {
keywordsboost::python::detail::keywords63 explicit keywords(char const *name)
64 {
65 elements[0].name = name;
66 }
67
68 template <class T>
operator =boost::python::detail::keywords69 python::arg& operator=(T const& value)
70 {
71 object z(value);
72 elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
73 return *this;
74 }
75
operator detail::keyword const&boost::python::detail::keywords76 operator detail::keyword const&() const
77 {
78 return elements[0];
79 }
80 };
81
82 template <std::size_t nkeywords>
83 inline
84 keywords<nkeywords+1>
operator ,(python::arg const & k) const85 keywords_base<nkeywords>::operator,(python::arg const &k) const
86 {
87 keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
88 python::detail::keywords<nkeywords+1> res;
89 std::copy(l.elements, l.elements+nkeywords, res.elements);
90 res.elements[nkeywords] = k.elements[0];
91 return res;
92 }
93
94 template <std::size_t nkeywords>
95 inline
96 keywords<nkeywords + 1>
operator ,(char const * name) const97 keywords_base<nkeywords>::operator,(char const *name) const
98 {
99 return this->operator,(python::arg(name));
100 }
101
102 template<typename T>
103 struct is_keywords
104 {
105 BOOST_STATIC_CONSTANT(bool, value = false);
106 };
107
108 template<std::size_t nkeywords>
109 struct is_keywords<keywords<nkeywords> >
110 {
111 BOOST_STATIC_CONSTANT(bool, value = true);
112 };
113 template <class T>
114 struct is_reference_to_keywords
115 {
116 BOOST_STATIC_CONSTANT(bool, is_ref = detail::is_reference<T>::value);
117 typedef typename detail::remove_reference<T>::type deref;
118 typedef typename detail::remove_cv<deref>::type key_t;
119 BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
120 BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
121
122 typedef mpl::bool_<value> type;
123 BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
124 };
125 }
126
args(char const * name)127 inline detail::keywords<1> args(char const* name)
128 {
129 return detail::keywords<1>(name);
130 }
131
132 # define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
133 # define BOOST_PP_LOCAL_MACRO(n) \
134 inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
135 { \
136 detail::keywords<n> result; \
137 BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _) \
138 return result; \
139 }
140 # define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
141 # include BOOST_PP_LOCAL_ITERATE()
142
143 }} // namespace boost::python
144
145
146 # endif // KEYWORDS_DWA2002323_HPP
147