Chris@16
|
1 // Copyright David Abrahams 2003.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
3 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 #ifndef PURE_VIRTUAL_DWA2003810_HPP
|
Chris@16
|
6 # define PURE_VIRTUAL_DWA2003810_HPP
|
Chris@16
|
7
|
Chris@16
|
8 # include <boost/python/def_visitor.hpp>
|
Chris@16
|
9 # include <boost/python/default_call_policies.hpp>
|
Chris@16
|
10 # include <boost/mpl/push_front.hpp>
|
Chris@16
|
11 # include <boost/mpl/pop_front.hpp>
|
Chris@16
|
12
|
Chris@16
|
13 # include <boost/python/detail/nullary_function_adaptor.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 namespace boost { namespace python {
|
Chris@16
|
16
|
Chris@16
|
17 namespace detail
|
Chris@16
|
18 {
|
Chris@16
|
19 //
|
Chris@16
|
20 // @group Helpers for pure_virtual_visitor. {
|
Chris@16
|
21 //
|
Chris@16
|
22
|
Chris@16
|
23 // Raises a Python RuntimeError reporting that a pure virtual
|
Chris@16
|
24 // function was called.
|
Chris@16
|
25 void BOOST_PYTHON_DECL pure_virtual_called();
|
Chris@16
|
26
|
Chris@16
|
27 // Replace the two front elements of S with T1 and T2
|
Chris@16
|
28 template <class S, class T1, class T2>
|
Chris@16
|
29 struct replace_front2
|
Chris@16
|
30 {
|
Chris@16
|
31 // Metafunction forwarding seemed to confound vc6
|
Chris@16
|
32 typedef typename mpl::push_front<
|
Chris@16
|
33 typename mpl::push_front<
|
Chris@16
|
34 typename mpl::pop_front<
|
Chris@16
|
35 typename mpl::pop_front<
|
Chris@16
|
36 S
|
Chris@16
|
37 >::type
|
Chris@16
|
38 >::type
|
Chris@16
|
39 , T2
|
Chris@16
|
40 >::type
|
Chris@16
|
41 , T1
|
Chris@16
|
42 >::type type;
|
Chris@16
|
43 };
|
Chris@16
|
44
|
Chris@16
|
45 // Given an MPL sequence representing a member function [object]
|
Chris@16
|
46 // signature, returns a new MPL sequence whose return type is
|
Chris@16
|
47 // replaced by void, and whose first argument is replaced by C&.
|
Chris@16
|
48 template <class C, class S>
|
Chris@16
|
49 typename replace_front2<S,void,C&>::type
|
Chris@16
|
50 error_signature(S BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C))
|
Chris@16
|
51 {
|
Chris@16
|
52 typedef typename replace_front2<S,void,C&>::type r;
|
Chris@16
|
53 return r();
|
Chris@16
|
54 }
|
Chris@16
|
55
|
Chris@16
|
56 //
|
Chris@16
|
57 // }
|
Chris@16
|
58 //
|
Chris@16
|
59
|
Chris@16
|
60 //
|
Chris@16
|
61 // A def_visitor which defines a method as usual, then adds a
|
Chris@16
|
62 // corresponding function which raises a "pure virtual called"
|
Chris@16
|
63 // exception unless it's been overridden.
|
Chris@16
|
64 //
|
Chris@16
|
65 template <class PointerToMemberFunction>
|
Chris@16
|
66 struct pure_virtual_visitor
|
Chris@16
|
67 : def_visitor<pure_virtual_visitor<PointerToMemberFunction> >
|
Chris@16
|
68 {
|
Chris@16
|
69 pure_virtual_visitor(PointerToMemberFunction pmf)
|
Chris@16
|
70 : m_pmf(pmf)
|
Chris@16
|
71 {}
|
Chris@16
|
72
|
Chris@16
|
73 private:
|
Chris@16
|
74 friend class python::def_visitor_access;
|
Chris@16
|
75
|
Chris@16
|
76 template <class C_, class Options>
|
Chris@16
|
77 void visit(C_& c, char const* name, Options& options) const
|
Chris@16
|
78 {
|
Chris@16
|
79 // This should probably be a nicer error message
|
Chris@16
|
80 BOOST_STATIC_ASSERT(!Options::has_default_implementation);
|
Chris@16
|
81
|
Chris@16
|
82 // Add the virtual function dispatcher
|
Chris@16
|
83 c.def(
|
Chris@16
|
84 name
|
Chris@16
|
85 , m_pmf
|
Chris@16
|
86 , options.doc()
|
Chris@16
|
87 , options.keywords()
|
Chris@16
|
88 , options.policies()
|
Chris@16
|
89 );
|
Chris@16
|
90
|
Chris@16
|
91 typedef BOOST_DEDUCED_TYPENAME C_::metadata::held_type held_type;
|
Chris@16
|
92
|
Chris@16
|
93 // Add the default implementation which raises the exception
|
Chris@16
|
94 c.def(
|
Chris@16
|
95 name
|
Chris@16
|
96 , make_function(
|
Chris@16
|
97 detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
|
Chris@16
|
98 , default_call_policies()
|
Chris@16
|
99 , detail::error_signature<held_type>(detail::get_signature(m_pmf))
|
Chris@16
|
100 )
|
Chris@16
|
101 );
|
Chris@16
|
102 }
|
Chris@16
|
103
|
Chris@16
|
104 private: // data members
|
Chris@16
|
105 PointerToMemberFunction m_pmf;
|
Chris@16
|
106 };
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 //
|
Chris@16
|
110 // Passed a pointer to member function, generates a def_visitor which
|
Chris@16
|
111 // creates a method that only dispatches to Python if the function has
|
Chris@16
|
112 // been overridden, either in C++ or in Python, raising a "pure
|
Chris@16
|
113 // virtual called" exception otherwise.
|
Chris@16
|
114 //
|
Chris@16
|
115 template <class PointerToMemberFunction>
|
Chris@16
|
116 detail::pure_virtual_visitor<PointerToMemberFunction>
|
Chris@16
|
117 pure_virtual(PointerToMemberFunction pmf)
|
Chris@16
|
118 {
|
Chris@16
|
119 return detail::pure_virtual_visitor<PointerToMemberFunction>(pmf);
|
Chris@16
|
120 }
|
Chris@16
|
121
|
Chris@16
|
122 }} // namespace boost::python
|
Chris@16
|
123
|
Chris@16
|
124 #endif // PURE_VIRTUAL_DWA2003810_HPP
|