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