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

Revision 857, 3.7 KB checked in by igarcia, 18 years ago (diff)
Line 
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
7
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>
12
13# include <boost/python/detail/nullary_function_adaptor.hpp>
14
15namespace boost { namespace python {
16
17namespace detail
18{
19  //
20  // @group Helpers for pure_virtual_visitor. {
21  //
22 
23  // Raises a Python RuntimeError reporting that a pure virtual
24  // function was called.
25  void BOOST_PYTHON_DECL pure_virtual_called();
26
27  // Replace the two front elements of S with T1 and T2
28  template <class S, class T1, class T2>
29  struct replace_front2
30  {
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<
36                      S
37                  >::type
38              >::type
39            , T2
40          >::type
41        , T1
42      >::type type;
43  };
44
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))
51  {
52      typedef typename replace_front2<S,void,C&>::type r;
53      return r();
54  }
55
56  //
57  // }
58  //
59
60  //
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.
64  //
65  template <class PointerToMemberFunction>
66  struct pure_virtual_visitor
67    : def_visitor<pure_virtual_visitor<PointerToMemberFunction> >
68  {
69      pure_virtual_visitor(PointerToMemberFunction pmf)
70        : m_pmf(pmf)
71      {}
72     
73   private:
74      friend class python::def_visitor_access;
75     
76      template <class C_, class Options>
77      void visit(C_& c, char const* name, Options& options) const
78      {
79          // This should probably be a nicer error message
80          BOOST_STATIC_ASSERT(!Options::has_default_implementation);
81
82          // Add the virtual function dispatcher
83          c.def(
84              name
85            , m_pmf
86            , options.doc()
87            , options.keywords()
88            , options.policies()
89          );
90
91          typedef BOOST_DEDUCED_TYPENAME C_::metadata::held_type held_type;
92         
93          // Add the default implementation which raises the exception
94          c.def(
95              name
96            , make_function(
97                  detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
98                , default_call_policies()
99                , detail::error_signature<held_type>(detail::get_signature(m_pmf))
100              )
101          );
102      }
103     
104   private: // data members
105      PointerToMemberFunction m_pmf;
106  };
107}
108
109//
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.
114//
115template <class PointerToMemberFunction>
116detail::pure_virtual_visitor<PointerToMemberFunction>
117pure_virtual(PointerToMemberFunction pmf)
118{
119    return detail::pure_virtual_visitor<PointerToMemberFunction>(pmf);
120}
121
122}} // namespace boost::python
123
124#endif // PURE_VIRTUAL_DWA2003810_HPP
Note: See TracBrowser for help on using the repository browser.