@ -52,6 +52,16 @@ bool is_alias(Cpp<Class> *ptr) {
template < typename /*Class*/ >
template < typename /*Class*/ >
constexpr bool is_alias ( void * ) { return false ; }
constexpr bool is_alias ( void * ) { return false ; }
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
// back to brace aggregate initiailization so that for aggregate initialization can be used with
// py::init, e.g. `py::init<int, int>` to initialize a `struct T { int a; int b; }`. For
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
template < typename Class , typename . . . Args , detail : : enable_if_t < std : : is_constructible < Class , Args . . . > : : value , int > = 0 >
inline Class * construct_or_initialize ( Args & & . . . args ) { return new Class ( std : : forward < Args > ( args ) . . . ) ; }
template < typename Class , typename . . . Args , detail : : enable_if_t < ! std : : is_constructible < Class , Args . . . > : : value , int > = 0 >
inline Class * construct_or_initialize ( Args & & . . . args ) { return new Class { std : : forward < Args > ( args ) . . . } ; }
// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with
// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with
// an alias to provide only a single Cpp factory function as long as the Alias can be
// an alias to provide only a single Cpp factory function as long as the Alias can be
// constructed from an rvalue reference of the base Cpp type. This means that Alias classes
// constructed from an rvalue reference of the base Cpp type. This means that Alias classes
@ -161,7 +171,7 @@ struct constructor {
template < typename Class , typename . . . Extra , enable_if_t < ! Class : : has_alias , int > = 0 >
template < typename Class , typename . . . Extra , enable_if_t < ! Class : : has_alias , int > = 0 >
static void execute ( Class & cl , const Extra & . . . extra ) {
static void execute ( Class & cl , const Extra & . . . extra ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
v_h . value_ptr ( ) = new Cpp < Class > { std : : forward < Args > ( args ) . . . } ;
v_h . value_ptr ( ) = co nstruct_or_initializ e< Cpp < Class > > ( std : : forward < Args > ( args ) . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
}
}
@ -171,9 +181,9 @@ struct constructor {
static void execute ( Class & cl , const Extra & . . . extra ) {
static void execute ( Class & cl , const Extra & . . . extra ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
if ( Py_TYPE ( v_h . inst ) = = v_h . type - > type )
if ( Py_TYPE ( v_h . inst ) = = v_h . type - > type )
v_h . value_ptr ( ) = new Cpp < Class > { std : : forward < Args > ( args ) . . . } ;
v_h . value_ptr ( ) = co nstruct_or_initializ e< Cpp < Class > > ( std : : forward < Args > ( args ) . . . ) ;
else
else
v_h . value_ptr ( ) = new Alias < Class > { std : : forward < Args > ( args ) . . . } ;
v_h . value_ptr ( ) = co nstruct_or_initializ e< Alias < Class > > ( std : : forward < Args > ( args ) . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
}
}
@ -182,7 +192,7 @@ struct constructor {
! std : : is_constructible < Cpp < Class > , Args . . . > : : value , int > = 0 >
! std : : is_constructible < Cpp < Class > , Args . . . > : : value , int > = 0 >
static void execute ( Class & cl , const Extra & . . . extra ) {
static void execute ( Class & cl , const Extra & . . . extra ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
v_h . value_ptr ( ) = new Alias < Class > { std : : forward < Args > ( args ) . . . } ;
v_h . value_ptr ( ) = co nstruct_or_initializ e< Alias < Class > > ( std : : forward < Args > ( args ) . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
}
}
} ;
} ;
@ -193,7 +203,7 @@ template <typename... Args> struct alias_constructor {
enable_if_t < Class : : has_alias & & std : : is_constructible < Alias < Class > , Args . . . > : : value , int > = 0 >
enable_if_t < Class : : has_alias & & std : : is_constructible < Alias < Class > , Args . . . > : : value , int > = 0 >
static void execute ( Class & cl , const Extra & . . . extra ) {
static void execute ( Class & cl , const Extra & . . . extra ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
cl . def ( " __init__ " , [ ] ( value_and_holder & v_h , Args . . . args ) {
v_h . value_ptr ( ) = new Alias < Class > { std : : forward < Args > ( args ) . . . } ;
v_h . value_ptr ( ) = co nstruct_or_initializ e< Alias < Class > > ( std : : forward < Args > ( args ) . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
} , is_new_style_constructor ( ) , extra . . . ) ;
}
}
} ;
} ;