125 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			125 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// Copyright David Abrahams 2003.
							 | 
						||
| 
								 | 
							
								// Distributed under the Boost Software License, Version 1.0. (See
							 | 
						||
| 
								 | 
							
								// accompanying file LICENSE_1_0.txt or copy at
							 | 
						||
| 
								 | 
							
								// http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								#ifndef PURE_VIRTUAL_DWA2003810_HPP
							 | 
						||
| 
								 | 
							
								# define PURE_VIRTUAL_DWA2003810_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# include <boost/python/def_visitor.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/python/default_call_policies.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/mpl/push_front.hpp>
							 | 
						||
| 
								 | 
							
								# include <boost/mpl/pop_front.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# include <boost/python/detail/nullary_function_adaptor.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost { namespace python { 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace detail
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  // @group Helpers for pure_virtual_visitor. {
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  // Raises a Python RuntimeError reporting that a pure virtual
							 | 
						||
| 
								 | 
							
								  // function was called.
							 | 
						||
| 
								 | 
							
								  void BOOST_PYTHON_DECL pure_virtual_called();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Replace the two front elements of S with T1 and T2
							 | 
						||
| 
								 | 
							
								  template <class S, class T1, class T2>
							 | 
						||
| 
								 | 
							
								  struct replace_front2
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								      // Metafunction forwarding seemed to confound vc6 
							 | 
						||
| 
								 | 
							
								      typedef typename mpl::push_front<
							 | 
						||
| 
								 | 
							
								          typename mpl::push_front<
							 | 
						||
| 
								 | 
							
								              typename mpl::pop_front<
							 | 
						||
| 
								 | 
							
								                  typename mpl::pop_front<
							 | 
						||
| 
								 | 
							
								                      S
							 | 
						||
| 
								 | 
							
								                  >::type
							 | 
						||
| 
								 | 
							
								              >::type
							 | 
						||
| 
								 | 
							
								            , T2
							 | 
						||
| 
								 | 
							
								          >::type
							 | 
						||
| 
								 | 
							
								        , T1
							 | 
						||
| 
								 | 
							
								      >::type type;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Given an MPL sequence representing a member function [object]
							 | 
						||
| 
								 | 
							
								  // signature, returns a new MPL sequence whose return type is
							 | 
						||
| 
								 | 
							
								  // replaced by void, and whose first argument is replaced by C&.
							 | 
						||
| 
								 | 
							
								  template <class C, class S>
							 | 
						||
| 
								 | 
							
								  typename replace_front2<S,void,C&>::type
							 | 
						||
| 
								 | 
							
								  error_signature(S)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								      typedef typename replace_front2<S,void,C&>::type r;
							 | 
						||
| 
								 | 
							
								      return r();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  // } 
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  // A def_visitor which defines a method as usual, then adds a
							 | 
						||
| 
								 | 
							
								  // corresponding function which raises a "pure virtual called"
							 | 
						||
| 
								 | 
							
								  // exception unless it's been overridden.
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  template <class PointerToMemberFunction>
							 | 
						||
| 
								 | 
							
								  struct pure_virtual_visitor
							 | 
						||
| 
								 | 
							
								    : def_visitor<pure_virtual_visitor<PointerToMemberFunction> >
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								      pure_virtual_visitor(PointerToMemberFunction pmf)
							 | 
						||
| 
								 | 
							
								        : m_pmf(pmf)
							 | 
						||
| 
								 | 
							
								      {}
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								   private:
							 | 
						||
| 
								 | 
							
								      friend class python::def_visitor_access;
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								      template <class C_, class Options>
							 | 
						||
| 
								 | 
							
								      void visit(C_& c, char const* name, Options& options) const
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								          // This should probably be a nicer error message
							 | 
						||
| 
								 | 
							
								          BOOST_STATIC_ASSERT(!Options::has_default_implementation);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // Add the virtual function dispatcher
							 | 
						||
| 
								 | 
							
								          c.def(
							 | 
						||
| 
								 | 
							
								              name
							 | 
						||
| 
								 | 
							
								            , m_pmf
							 | 
						||
| 
								 | 
							
								            , options.doc()
							 | 
						||
| 
								 | 
							
								            , options.keywords()
							 | 
						||
| 
								 | 
							
								            , options.policies()
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          typedef BOOST_DEDUCED_TYPENAME C_::metadata::held_type held_type;
							 | 
						||
| 
								 | 
							
								          
							 | 
						||
| 
								 | 
							
								          // Add the default implementation which raises the exception
							 | 
						||
| 
								 | 
							
								          c.def(
							 | 
						||
| 
								 | 
							
								              name
							 | 
						||
| 
								 | 
							
								            , make_function(
							 | 
						||
| 
								 | 
							
								                  detail::nullary_function_adaptor<void(*)()>(pure_virtual_called)
							 | 
						||
| 
								 | 
							
								                , default_call_policies()
							 | 
						||
| 
								 | 
							
								                , detail::error_signature<held_type>(detail::get_signature(m_pmf))
							 | 
						||
| 
								 | 
							
								              )
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								   private: // data members
							 | 
						||
| 
								 | 
							
								      PointerToMemberFunction m_pmf;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Passed a pointer to member function, generates a def_visitor which
							 | 
						||
| 
								 | 
							
								// creates a method that only dispatches to Python if the function has
							 | 
						||
| 
								 | 
							
								// been overridden, either in C++ or in Python, raising a "pure
							 | 
						||
| 
								 | 
							
								// virtual called" exception otherwise.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								template <class PointerToMemberFunction>
							 | 
						||
| 
								 | 
							
								detail::pure_virtual_visitor<PointerToMemberFunction>
							 | 
						||
| 
								 | 
							
								pure_virtual(PointerToMemberFunction pmf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return detail::pure_virtual_visitor<PointerToMemberFunction>(pmf);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}} // namespace boost::python
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // PURE_VIRTUAL_DWA2003810_HPP
							 |