source: NonGTP/Boost/boost/python/args.hpp @ 857

Revision 857, 5.1 KB checked in by igarcia, 18 years ago (diff)
Line 
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
15# include <boost/type_traits/is_reference.hpp>
16# include <boost/type_traits/remove_reference.hpp>
17# include <boost/type_traits/remove_cv.hpp>
18
19# include <boost/preprocessor/enum_params.hpp>
20# include <boost/preprocessor/repeat.hpp>
21# include <boost/preprocessor/facilities/intercept.hpp>
22# include <boost/preprocessor/iteration/local.hpp>
23
24# include <boost/python/detail/mpl_lambda.hpp>
25# include <boost/python/object_core.hpp>
26
27# include <boost/mpl/bool.hpp>
28
29# include <cstddef>
30# include <algorithm>
31
32namespace boost { namespace python {
33
34typedef detail::keywords<1> arg;
35typedef arg arg_; // gcc 2.96 workaround
36
37namespace detail
38{
39  template <std::size_t nkeywords>
40  struct keywords_base
41  {
42      BOOST_STATIC_CONSTANT(std::size_t, size = nkeywords);
43     
44      keyword_range range() const
45      {
46          return keyword_range(elements, elements + nkeywords);
47      }
48
49      keyword elements[nkeywords];
50
51      keywords<nkeywords+1>
52      operator,(python::arg const &k) const;
53
54      keywords<nkeywords + 1>
55      operator,(char const *name) const;
56  };
57 
58  template <std::size_t nkeywords>
59  struct keywords : keywords_base<nkeywords>
60  {
61  };
62
63  template <>
64  struct keywords<1> : keywords_base<1>
65  {
66      explicit keywords(char const *name)
67      {
68          elements[0].name = name;
69      }
70   
71      template <class T>
72      python::arg& operator=(T const& value)
73      {
74          object z(value);
75          elements[0].default_value = handle<>(python::borrowed(object(value).ptr()));
76          return *this;
77      }
78   
79      operator detail::keyword const&() const
80      {
81          return elements[0];
82      }
83  };
84
85  template <std::size_t nkeywords>
86  inline
87  keywords<nkeywords+1>
88  keywords_base<nkeywords>::operator,(python::arg const &k) const
89  {
90      keywords<nkeywords> const& l = *static_cast<keywords<nkeywords> const*>(this);
91      python::detail::keywords<nkeywords+1> res;
92      std::copy(l.elements, l.elements+nkeywords, res.elements);
93      res.elements[nkeywords] = k.elements[0];
94      return res;
95  }
96
97  template <std::size_t nkeywords>
98  inline
99  keywords<nkeywords + 1>
100  keywords_base<nkeywords>::operator,(char const *name) const
101  {
102      return this->operator,(python::arg(name));
103  }
104
105# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
106  template<typename T>
107  struct is_keywords
108  {
109      BOOST_STATIC_CONSTANT(bool, value = false);
110  };
111
112  template<std::size_t nkeywords>
113  struct is_keywords<keywords<nkeywords> >
114  {
115      BOOST_STATIC_CONSTANT(bool, value = true);
116  };
117  template <class T>
118  struct is_reference_to_keywords
119  {
120      BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
121      typedef typename remove_reference<T>::type deref;
122      typedef typename remove_cv<deref>::type key_t;
123      BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
124      BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
125     
126      typedef mpl::bool_<value> type;
127      BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
128  };
129# else
130  typedef char (&yes_keywords_t)[1];
131  typedef char (&no_keywords_t)[2];
132     
133  no_keywords_t is_keywords_test(...);
134
135  template<std::size_t nkeywords>
136  yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords>&));
137
138  template<std::size_t nkeywords>
139  yes_keywords_t is_keywords_test(void (*)(keywords<nkeywords> const&));
140
141  template<typename T>
142  class is_reference_to_keywords
143  {
144   public:
145      BOOST_STATIC_CONSTANT(
146          bool, value = (
147              sizeof(detail::is_keywords_test( (void (*)(T))0 ))
148              == sizeof(detail::yes_keywords_t)));
149
150      typedef mpl::bool_<value> type;
151      BOOST_PYTHON_MPL_LAMBDA_SUPPORT(1,is_reference_to_keywords,(T))
152  };
153# endif
154}
155
156inline detail::keywords<1> args(char const* name)
157{
158    return detail::keywords<1>(name);
159}
160
161#  define BOOST_PYTHON_ASSIGN_NAME(z, n, _) result.elements[n].name = name##n;
162#  define BOOST_PP_LOCAL_MACRO(n)                                               \
163inline detail::keywords<n> args(BOOST_PP_ENUM_PARAMS_Z(1, n, char const* name)) \
164{                                                                               \
165    detail::keywords<n> result;                                                 \
166    BOOST_PP_REPEAT_1(n, BOOST_PYTHON_ASSIGN_NAME, _)                           \
167    return result;                                                              \
168}
169#  define BOOST_PP_LOCAL_LIMITS (2, BOOST_PYTHON_MAX_ARITY)
170#  include BOOST_PP_LOCAL_ITERATE()
171
172}} // namespace boost::python
173
174
175# endif // KEYWORDS_DWA2002323_HPP
Note: See TracBrowser for help on using the repository browser.