Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/python/pure_virtual.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright David Abrahams 2003.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef PURE_VIRTUAL_DWA2003810_HPP
0006 # define PURE_VIRTUAL_DWA2003810_HPP
0007 
0008 # include <boost/python/def_visitor.hpp>
0009 # include <boost/python/default_call_policies.hpp>
0010 # include <boost/mpl/push_front.hpp>
0011 # include <boost/mpl/pop_front.hpp>
0012 
0013 # include <boost/python/detail/nullary_function_adaptor.hpp>
0014 
0015 namespace boost { namespace python { 
0016 
0017 namespace detail
0018 {
0019   //
0020   // @group Helpers for pure_virtual_visitor. {
0021   //
0022   
0023   // Raises a Python RuntimeError reporting that a pure virtual
0024   // function was called.
0025   void BOOST_PYTHON_DECL pure_virtual_called();
0026 
0027   // Replace the two front elements of S with T1 and T2
0028   template <class S, class T1, class T2>
0029   struct replace_front2
0030   {
0031       // Metafunction forwarding seemed to confound vc6 
0032       typedef typename mpl::push_front<
0033           typename mpl::push_front<
0034               typename mpl::pop_front<
0035                   typename mpl::pop_front<
0036                       S
0037                   >::type
0038               >::type
0039             , T2
0040           >::type
0041         , T1
0042       >::type type;
0043   };
0044 
0045   // Given an MPL sequence representing a member function [object]
0046   // signature, returns a new MPL sequence whose return type is
0047   // replaced by void, and whose first argument is replaced by C&.
0048   template <class C, class S>
0049   typename replace_front2<S,void,C&>::type
0050   error_signature(S)
0051   {
0052       typedef typename replace_front2<S,void,C&>::type r;
0053       return r();
0054   }
0055 
0056   //
0057   // } 
0058   //
0059 
0060   //
0061   // A def_visitor which defines a method as usual, then adds a
0062   // corresponding function which raises a "pure virtual called"
0063   // exception unless it's been overridden.
0064   //
0065   template <class PointerToMemberFunction>
0066   struct pure_virtual_visitor
0067     : def_visitor<pure_virtual_visitor<PointerToMemberFunction> >
0068   {
0069       pure_virtual_visitor(PointerToMemberFunction pmf)
0070         : m_pmf(pmf)
0071       {}
0072       
0073    private:
0074       friend class python::def_visitor_access;
0075       
0076       template <class C_, class Options>
0077       void visit(C_& c, char const* name, Options& options) const
0078       {
0079           // This should probably be a nicer error message
0080           BOOST_STATIC_ASSERT(!Options::has_default_implementation);
0081 
0082           // Add the virtual function dispatcher
0083           c.def(
0084               name
0085             , m_pmf
0086             , options.doc()
0087             , options.keywords()
0088             , options.policies()
0089           );
0090 
0091           typedef BOOST_DEDUCED_TYPENAME C_::metadata::held_type held_type;
0092           
0093           // Add the default implementation which raises the exception
0094           c.def(
0095               name
0096             , make_function(
0097                   detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
0098                 , default_call_policies()
0099                 , detail::error_signature<held_type>(detail::get_signature(m_pmf))
0100               )
0101           );
0102       }
0103       
0104    private: // data members
0105       PointerToMemberFunction m_pmf;
0106   };
0107 }
0108 
0109 //
0110 // Passed a pointer to member function, generates a def_visitor which
0111 // creates a method that only dispatches to Python if the function has
0112 // been overridden, either in C++ or in Python, raising a "pure
0113 // virtual called" exception otherwise.
0114 //
0115 template <class PointerToMemberFunction>
0116 detail::pure_virtual_visitor<PointerToMemberFunction>
0117 pure_virtual(PointerToMemberFunction pmf)
0118 {
0119     return detail::pure_virtual_visitor<PointerToMemberFunction>(pmf);
0120 }
0121 
0122 }} // namespace boost::python
0123 
0124 #endif // PURE_VIRTUAL_DWA2003810_HPP