]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 DEF_HELPER_DWA200287_HPP | |
6 | # define DEF_HELPER_DWA200287_HPP | |
7 | ||
8 | # include <boost/python/args.hpp> | |
9 | # include <boost/type_traits/same_traits.hpp> | |
10 | # include <boost/python/detail/indirect_traits.hpp> | |
11 | # include <boost/mpl/not.hpp> | |
12 | # include <boost/mpl/and.hpp> | |
13 | # include <boost/mpl/or.hpp> | |
14 | # include <boost/type_traits/add_reference.hpp> | |
15 | # include <boost/mpl/lambda.hpp> | |
16 | # include <boost/mpl/apply.hpp> | |
17 | # include <boost/tuple/tuple.hpp> | |
18 | # include <boost/python/detail/not_specified.hpp> | |
19 | # include <boost/python/detail/def_helper_fwd.hpp> | |
20 | ||
21 | namespace boost { namespace python { | |
22 | ||
23 | struct default_call_policies; | |
24 | ||
25 | namespace detail | |
26 | { | |
27 | // tuple_extract<Tuple,Predicate>::extract(t) returns the first | |
28 | // element of a Tuple whose type E satisfies the given Predicate | |
29 | // applied to add_reference<E>. The Predicate must be an MPL | |
30 | // metafunction class. | |
31 | template <class Tuple, class Predicate> | |
32 | struct tuple_extract; | |
33 | ||
34 | // Implementation class for when the tuple's head type does not | |
35 | // satisfy the Predicate | |
36 | template <bool matched> | |
37 | struct tuple_extract_impl | |
38 | { | |
39 | template <class Tuple, class Predicate> | |
40 | struct apply | |
41 | { | |
42 | typedef typename Tuple::head_type result_type; | |
43 | ||
44 | static typename Tuple::head_type extract(Tuple const& x) | |
45 | { | |
46 | return x.get_head(); | |
47 | } | |
48 | }; | |
49 | }; | |
50 | ||
51 | // Implementation specialization for when the tuple's head type | |
52 | // satisfies the predicate | |
53 | template <> | |
54 | struct tuple_extract_impl<false> | |
55 | { | |
56 | template <class Tuple, class Predicate> | |
57 | struct apply | |
58 | { | |
59 | // recursive application of tuple_extract on the tail of the tuple | |
60 | typedef tuple_extract<typename Tuple::tail_type, Predicate> next; | |
61 | typedef typename next::result_type result_type; | |
62 | ||
63 | static result_type extract(Tuple const& x) | |
64 | { | |
65 | return next::extract(x.get_tail()); | |
66 | } | |
67 | }; | |
68 | }; | |
69 | ||
70 | // A metafunction which selects a version of tuple_extract_impl to | |
71 | // use for the implementation of tuple_extract | |
72 | template <class Tuple, class Predicate> | |
73 | struct tuple_extract_base_select | |
74 | { | |
75 | typedef typename Tuple::head_type head_type; | |
76 | typedef typename mpl::apply1<Predicate, typename add_reference<head_type>::type>::type match_t; | |
77 | BOOST_STATIC_CONSTANT(bool, match = match_t::value); | |
78 | typedef typename tuple_extract_impl<match>::template apply<Tuple,Predicate> type; | |
79 | }; | |
80 | ||
81 | template <class Tuple, class Predicate> | |
82 | struct tuple_extract | |
83 | : tuple_extract_base_select< | |
84 | Tuple | |
85 | , typename mpl::lambda<Predicate>::type | |
86 | >::type | |
87 | { | |
88 | }; | |
89 | ||
90 | ||
91 | // | |
92 | // Specialized extractors for the docstring, keywords, CallPolicies, | |
93 | // and default implementation of virtual functions | |
94 | // | |
95 | ||
96 | template <class Tuple> | |
97 | struct doc_extract | |
98 | : tuple_extract< | |
99 | Tuple | |
100 | , mpl::not_< | |
101 | mpl::or_< | |
102 | indirect_traits::is_reference_to_class<mpl::_1> | |
103 | , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > | |
104 | > | |
105 | > | |
106 | > | |
107 | { | |
108 | }; | |
109 | ||
110 | template <class Tuple> | |
111 | struct keyword_extract | |
112 | : tuple_extract<Tuple, is_reference_to_keywords<mpl::_1 > > | |
113 | { | |
114 | }; | |
115 | ||
116 | template <class Tuple> | |
117 | struct policy_extract | |
118 | : tuple_extract< | |
119 | Tuple | |
120 | , mpl::and_< | |
121 | mpl::not_<is_same<not_specified const&,mpl::_1> > | |
122 | , indirect_traits::is_reference_to_class<mpl::_1 > | |
123 | , mpl::not_<is_reference_to_keywords<mpl::_1 > > | |
124 | > | |
125 | > | |
126 | { | |
127 | }; | |
128 | ||
129 | template <class Tuple> | |
130 | struct default_implementation_extract | |
131 | : tuple_extract< | |
132 | Tuple | |
133 | , indirect_traits::is_reference_to_member_function_pointer<mpl::_1 > | |
134 | > | |
135 | { | |
136 | }; | |
137 | ||
138 | // | |
139 | // A helper class for decoding the optional arguments to def() | |
140 | // invocations, which can be supplied in any order and are | |
141 | // discriminated by their type properties. The template parameters | |
142 | // are expected to be the types of the actual (optional) arguments | |
143 | // passed to def(). | |
144 | // | |
145 | template <class T1, class T2, class T3, class T4> | |
146 | struct def_helper | |
147 | { | |
148 | // A tuple type which begins with references to the supplied | |
149 | // arguments and ends with actual representatives of the default | |
150 | // types. | |
151 | typedef boost::tuples::tuple< | |
152 | T1 const& | |
153 | , T2 const& | |
154 | , T3 const& | |
155 | , T4 const& | |
156 | , default_call_policies | |
157 | , detail::keywords<0> | |
158 | , char const* | |
159 | , void(not_specified::*)() // A function pointer type which is never an | |
160 | // appropriate default implementation | |
161 | > all_t; | |
162 | ||
163 | // Constructors; these initialize an member of the tuple type | |
164 | // shown above. | |
165 | def_helper(T1 const& a1) : m_all(a1,m_nil,m_nil,m_nil) {} | |
166 | def_helper(T1 const& a1, T2 const& a2) : m_all(a1,a2,m_nil,m_nil) {} | |
167 | def_helper(T1 const& a1, T2 const& a2, T3 const& a3) : m_all(a1,a2,a3,m_nil) {} | |
168 | def_helper(T1 const& a1, T2 const& a2, T3 const& a3, T4 const& a4) : m_all(a1,a2,a3,a4) {} | |
169 | ||
170 | private: // types | |
171 | typedef typename default_implementation_extract<all_t>::result_type default_implementation_t; | |
172 | ||
173 | public: // Constants which can be used for static assertions. | |
174 | ||
175 | // Users must not supply a default implementation for non-class | |
176 | // methods. | |
177 | BOOST_STATIC_CONSTANT( | |
178 | bool, has_default_implementation = ( | |
179 | !is_same<default_implementation_t, void(not_specified::*)()>::value)); | |
180 | ||
181 | public: // Extractor functions which pull the appropriate value out | |
182 | // of the tuple | |
183 | char const* doc() const | |
184 | { | |
185 | return doc_extract<all_t>::extract(m_all); | |
186 | } | |
187 | ||
188 | typename keyword_extract<all_t>::result_type keywords() const | |
189 | { | |
190 | return keyword_extract<all_t>::extract(m_all); | |
191 | } | |
192 | ||
193 | typename policy_extract<all_t>::result_type policies() const | |
194 | { | |
195 | return policy_extract<all_t>::extract(m_all); | |
196 | } | |
197 | ||
198 | default_implementation_t default_implementation() const | |
199 | { | |
200 | return default_implementation_extract<all_t>::extract(m_all); | |
201 | } | |
202 | ||
203 | private: // data members | |
204 | all_t m_all; | |
205 | not_specified m_nil; // for filling in not_specified slots | |
206 | }; | |
207 | } | |
208 | ||
209 | }} // namespace boost::python::detail | |
210 | ||
211 | #endif // DEF_HELPER_DWA200287_HPP |