os/ossrv/ossrv_pub/boost_apis/boost/python/pure_virtual.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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