text: 
  #include <boost/parameter.hpp>
  #include <boost/mpl/is_sequence.hpp>
  #include <boost/noncopyable.hpp>
  #include <boost/type_traits/is_class.hpp>
  #include <memory>
  #include <boost/config.hpp>
  
  using namespace boost::parameter;
  
  namespace boost { namespace python {
  
  BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
  BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)
  
  template <class B = int>
  struct bases
  {};
  
  }}
  namespace boost { namespace python {
  
  using boost::mpl::_;
  
  typedef parameter::parameters<
      required<tag::class_type, boost::is_class<_> >
    , parameter::optional<tag::base_list, mpl::is_sequence<_> >
    , parameter::optional<tag::held_type>
    , parameter::optional<tag::copyable>
  > class_signature;
  
  }}
  
  namespace boost { namespace python {
  
  template <
      class A0
    , class A1 = parameter::void_
    , class A2 = parameter::void_
    , class A3 = parameter::void_
  >
  struct class_
  {
      // Create ArgumentPack
      typedef typename
        class_signature::bind<A0,A1,A2,A3>::type
      args;
  
      // Extract first logical parameter.
      typedef typename parameter::value_type<
        args, tag::class_type>::type class_type;
  
      typedef typename parameter::value_type<
        args, tag::base_list, bases<> >::type base_list;
  
      typedef typename parameter::value_type<
        args, tag::held_type, class_type>::type held_type;
  
      typedef typename parameter::value_type<
        args, tag::copyable, void>::type copyable;
  };
  
  }}
  
  
  using boost::python::class_type;
  using boost::python::copyable;
  using boost::python::held_type;
  using boost::python::base_list;
  using boost::python::bases;
  
  struct B {};
  struct D {};
  typedef boost::python::class_<
      class_type<B>, copyable<boost::noncopyable>
  > c1;
  
  typedef boost::python::class_<
  
  #if defined(BOOST_NO_CXX11_SMART_PTR)
  
      D, held_type<std::auto_ptr<D> >, base_list<bases<B> >
      
  #else
  
      D, held_type<std::unique_ptr<D> >, base_list<bases<B> >
      
  #endif
  
  > c2;
  
  BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
  BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
  BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
  BOOST_MPL_ASSERT((
       boost::is_same<c1::copyable, boost::noncopyable>
  ));
  
  BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
  BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
  
  #if defined(BOOST_NO_CXX11_SMART_PTR)
  
  BOOST_MPL_ASSERT((
      boost::is_same<c2::held_type, std::auto_ptr<D> >
  ));
  
  #else
  
  BOOST_MPL_ASSERT((
      boost::is_same<c2::held_type, std::unique_ptr<D> >
  ));
  
  #endif
  
  BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));
  