1 // Copyright David Abrahams 2003.
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 PURE_VIRTUAL_DWA2003810_HPP
6 # define PURE_VIRTUAL_DWA2003810_HPP
8 # include <boost/python/def_visitor.hpp>
9 # include <boost/python/default_call_policies.hpp>
10 # include <boost/mpl/push_front.hpp>
11 # include <boost/mpl/pop_front.hpp>
13 # include <boost/python/detail/nullary_function_adaptor.hpp>
15 namespace boost
{ namespace python
{
20 // @group Helpers for pure_virtual_visitor. {
23 // Raises a Python RuntimeError reporting that a pure virtual
24 // function was called.
25 void BOOST_PYTHON_DECL
pure_virtual_called();
27 // Replace the two front elements of S with T1 and T2
28 template <class S
, class T1
, class T2
>
31 // Metafunction forwarding seemed to confound vc6
32 typedef typename
mpl::push_front
<
33 typename
mpl::push_front
<
34 typename
mpl::pop_front
<
35 typename
mpl::pop_front
<
45 // Given an MPL sequence representing a member function [object]
46 // signature, returns a new MPL sequence whose return type is
47 // replaced by void, and whose first argument is replaced by C&.
48 template <class C
, class S
>
49 typename replace_front2
<S
,void,C
&>::type
50 error_signature(S
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(C
))
52 typedef typename replace_front2
<S
,void,C
&>::type r
;
61 // A def_visitor which defines a method as usual, then adds a
62 // corresponding function which raises a "pure virtual called"
63 // exception unless it's been overridden.
65 template <class PointerToMemberFunction
>
66 struct pure_virtual_visitor
67 : def_visitor
<pure_virtual_visitor
<PointerToMemberFunction
> >
69 pure_virtual_visitor(PointerToMemberFunction pmf
)
74 friend class python::def_visitor_access
;
76 template <class C_
, class Options
>
77 void visit(C_
& c
, char const* name
, Options
& options
) const
79 // This should probably be a nicer error message
80 BOOST_STATIC_ASSERT(!Options::has_default_implementation
);
82 // Add the virtual function dispatcher
91 typedef BOOST_DEDUCED_TYPENAME
C_::metadata::held_type held_type
;
93 // Add the default implementation which raises the exception
97 detail::nullary_function_adaptor
<void(*)()>(pure_virtual_called
)
98 , default_call_policies()
99 , detail::error_signature
<held_type
>(detail::get_signature(m_pmf
))
104 private: // data members
105 PointerToMemberFunction m_pmf
;
110 // Passed a pointer to member function, generates a def_visitor which
111 // creates a method that only dispatches to Python if the function has
112 // been overridden, either in C++ or in Python, raising a "pure
113 // virtual called" exception otherwise.
115 template <class PointerToMemberFunction
>
116 detail::pure_virtual_visitor
<PointerToMemberFunction
>
117 pure_virtual(PointerToMemberFunction pmf
)
119 return detail::pure_virtual_visitor
<PointerToMemberFunction
>(pmf
);
122 }} // namespace boost::python
124 #endif // PURE_VIRTUAL_DWA2003810_HPP