125 lines
2.8 KiB
C++
125 lines
2.8 KiB
C++
|
|
#include <boost/parameter.hpp>
|
|
#include <boost/mpl/is_sequence.hpp>
|
|
#include <boost/noncopyable.hpp>
|
|
#include <memory>
|
|
#include <boost/config.hpp>
|
|
|
|
using namespace boost::parameter;
|
|
using boost::mpl::_;
|
|
|
|
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)
|
|
|
|
}}
|
|
namespace boost { namespace python {
|
|
|
|
namespace detail { struct bases_base {}; }
|
|
|
|
template <class A0 = void, class A1 = void, class A2 = void >
|
|
struct bases : detail::bases_base
|
|
{};
|
|
|
|
}}
|
|
|
|
|
|
#include <boost/type_traits/is_class.hpp>
|
|
namespace boost { namespace python {
|
|
typedef parameter::parameters<
|
|
required<tag::class_type, is_class<_> >
|
|
|
|
, parameter::optional<
|
|
deduced<tag::base_list>
|
|
, is_base_and_derived<detail::bases_base,_>
|
|
>
|
|
|
|
, parameter::optional<
|
|
deduced<tag::held_type>
|
|
, mpl::not_<
|
|
mpl::or_<
|
|
is_base_and_derived<detail::bases_base,_>
|
|
, is_same<noncopyable,_>
|
|
>
|
|
>
|
|
>
|
|
|
|
, parameter::optional<deduced<tag::copyable>, is_same<noncopyable,_> >
|
|
|
|
> class_signature;
|
|
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;
|
|
};
|
|
|
|
}}
|
|
|
|
|
|
|
|
struct B {};
|
|
struct D {};
|
|
|
|
using boost::python::bases;
|
|
typedef boost::python::class_<B, boost::noncopyable> c1;
|
|
|
|
#if defined(BOOST_NO_CXX11_SMART_PTR)
|
|
|
|
typedef boost::python::class_<D, std::auto_ptr<D>, bases<B> > c2;
|
|
|
|
#else
|
|
|
|
typedef boost::python::class_<D, std::unique_ptr<D>, bases<B> > c2;
|
|
|
|
#endif
|
|
|
|
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>));
|