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