25 #ifndef PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
26 #define PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
33 # define TF_MAX_ARITY 7
34 #endif // TF_MAX_ARITY
50 #include <hboost/python/def_visitor.hpp>
51 #include <hboost/python/dict.hpp>
52 #include <hboost/python/errors.hpp>
53 #include <hboost/python/list.hpp>
54 #include <hboost/python/object/iterator.hpp>
55 #include <hboost/python/raw_function.hpp>
56 #include <hboost/python/tuple.hpp>
57 #include <hboost/python/type_id.hpp>
61 #include <type_traits>
102 namespace Tf_MakePyConstructor {
104 namespace bp = hboost::python;
106 template <
typename CTOR>
112 template <
typename CLS>
114 c.def(
"__init__", CTOR::template init_callable<CLS>(),
_doc.c_str());
117 template <
class CLS,
class Options>
118 void visit(CLS &
c,
char const*
name, Options& options)
const {
120 c.def(name, CTOR::template init_callable<CLS>(options),
_doc.c_str());
129 template <
typename CTOR>
135 template <
typename CLS>
149 if (PyObject_HasAttrString(c.ptr(),
"__new__"))
150 c.attr(
"__new__") = c.attr(
"__new__");
151 c.def(
"__new__", CTOR::template __new__<CLS>,
_doc.c_str());
152 c.staticmethod(
"__new__");
155 c.def(
"__init__", bp::raw_function(
_DummyInit));
158 template <
class CLS,
class Options>
159 void visit(CLS &
c,
char const*
name, Options& options)
const {
172 if (PyObject_HasAttrString(c.ptr(),
"__new__"))
173 c.attr(
"__new__") = c.attr(
"__new__");
174 c.def(
"__new__", CTOR::template __new__<CLS>,
180 c.staticmethod(
"__new__");
183 c.def(
"__init__", bp::raw_function(
_DummyInit));
191 template <
typename T>
198 template <
typename T>
201 "Type T must support refcount unique changed notification.");
203 const void *uniqueId) {
211 template <
typename CLS,
typename T>
215 typedef typename CLS::metadata::holder Holder;
216 typedef typename bp::objects::instance<Holder> instance_t;
218 typedef typename CLS::metadata::held_type HeldType;
223 allocate(
self.
ptr(), offsetof(instance_t,
storage),
sizeof(Holder));
226 Holder *holder = (
new (
memory) Holder(held));
229 bp::throw_error_already_set();
235 bp::detail::initialize_wrapper(
self.
ptr(), &(*(held.operator->())));
236 holder->install(
self.
ptr());
241 Policy::PostInstall(
self, t, held.GetUniqueIdentifier());
244 Holder::deallocate(
self.
ptr(), memory);
throw;
250 template <
typename WeakPtr,
typename P>
252 typedef std::remove_reference_t<P>
Ptr;
262 WeakPtr ptr(static_cast<typename WeakPtr::DataType *>
267 return bp::incref(Py_None);
272 Policy::PostInstall(result, p, ptr.GetUniqueIdentifier());
273 return bp::incref(result.ptr());
278 return hboost::python::objects::registered_class_object(
279 hboost::python::type_id<typename WeakPtr::DataType>()).get();
283 template <
typename WeakPtr =
void>
285 template <
typename FactoryResultPtr>
300 template <
typename SIG,
size_t EXTRA_ARITY = 0>
313 "Duplicate will be ignored.",
320 template <
typename SIG,
size_t EXTRA_ARITY>
321 SIG *CtorBase<SIG, EXTRA_ARITY>::_func =
nullptr;
332 template <
typename T>
342 template <
typename T>
352 template <
typename T>
362 template <
typename T>
372 template <
typename T>
383 template <
typename T =
void>
391 template <
typename T>
398 template <
typename T>
405 using namespace hboost::python;
410 hboost::python::list l;
411 for (
typename SeqType::const_iterator i = seq.begin();
412 i != seq.end(); ++i) {
413 l.append(
object(
handle<>(RefPtrFactory()(*i))));
415 return hboost::python::incref(l.ptr());
424 namespace Tf_MakePyConstructor {
426 template <
typename R,
typename... Args>
433 template <
typename CLS>
435 return bp::make_function(__init__<CLS>);
438 template <
typename CLS,
typename Options>
440 return bp::make_function(__init__<CLS>, o.policies(), o.keywords()) ;
443 template <
typename CLS>
446 Install<CLS>(
self, Base::_func(
args...), m);
450 template <
typename R,
typename... Args>
458 typedef typename CLS::metadata::held_type HeldType;
460 R r((Base::_func(
args...)));
463 bp::throw_error_already_set();
469 bp::detail::initialize_wrapper(ret.ptr(),
get_pointer(h));
471 bp::setattr(ret,
"__class__", cls);
478 template <
typename R,
typename... Args>
495 typename Base::Traits::template NthArg<(
Arity::value-2)>>) &&
498 typename Base::Traits::template NthArg<(
Arity::value-1)>>),
499 "InitCtorWithVarArgs requires a function of form "
500 "(..., const tuple&, const dict&)");
502 template <
typename CLS>
507 return bp::raw_function(__init__<CLS>, 1);
510 template <
typename CLS,
typename Options>
514 return bp::raw_function(
515 bp::make_function(__init__<CLS>, options.policies()),
519 template <
typename CLS,
size_t... I>
521 const bp::dict& kwargs,
522 std::index_sequence<I...>) {
527 const unsigned int expectedNamedArgs =
Arity::value - 2;
529 const unsigned int positionalArgs = bp::len(args) - 1;
530 if (positionalArgs < expectedNamedArgs) {
532 positionalArgTypes = {{
533 (bp::type_id<typename Base::Traits::template NthArg<I>>().
name())...
539 if (!joinedTypes.empty()) {
546 "Arguments to __init__ did not match C++ signature:\n"
547 "\t__init__(%s...)", joinedTypes.c_str()
559 typename Base::Traits::template NthArg<I>>>(args[I + 1])...,
560 bp::tuple(args.slice(expectedNamedArgs + 1, bp::len(args))), kwargs),
566 template <
typename CLS>
568 const bp::dict& kwargs) {
569 return __init__impl<CLS>(
580 template <
typename R,
typename SelfRef,
typename... Args>
587 template <
typename CLS>
589 return bp::make_function(__init__<CLS>);
592 template <
typename CLS,
typename Options>
594 return bp::make_function(__init__<CLS>, o.policies(), o.keywords());
597 template <
typename CLS>
600 Install<CLS>(
self, Base::_func(
self, args...), m);
604 template <
typename R,
typename ClsRef,
typename... Args>
613 typedef typename CLS::metadata::held_type HeldType;
615 R r(Base::_func(cls, args...));
618 bp::throw_error_already_set();
624 bp::detail::initialize_wrapper(ret.ptr(),
get_pointer(h));
626 bp::setattr(ret,
"__class__", cls);
636 #endif // PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
GLsizei GLenum GLsizei GLsizei GLuint memory
Tf_MakePyConstructor::NewVisitor< typename Tf_MakePyConstructor::NewCtor< T > > TfMakePyNew(T *func, const std::string &doc=std::string())
TF_API std::string TfStringPrintf(const char *fmt,...)
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtor< T > > TfMakePyConstructor(T *func, const std::string &doc=std::string())
CtorBase< R(SelfRef, Args...)> Base
friend class bp::def_visitor_access
static bp::object __new__(ClsRef cls, Args...args)
_RefPtrFactoryConverter< WeakPtrType, FactoryResultPtr > type
getFileOption("OpenEXR:storage") storage
typename std::conditional< B, T, F >::type conditional_t
GLsizei const GLchar *const * string
GLsizei const GLfloat * value
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtorWithVarArgs< T > > TfMakePyConstructorWithVarArgs(T *func, const std::string &doc=std::string())
Tf_PySequenceToListConverterRefPtrFactory< T > type
PyObject * operator()(Ptr const &p) const
static bp::object __init__impl(const bp::tuple &args, const bp::dict &kwargs, std::index_sequence< I...>)
TfMetaLength< Args...> Arity
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
static bp::object init_callable(Options &o)
static void SetFunc(Sig *func)
**But if you need a result
PyTypeObject const * get_pytype() const
PyTypeObject const * get_pytype() const
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtorWithBackReference< T > > TfMakePyConstructorWithBackReference(T *func, const std::string &doc=std::string())
PXR_NAMESPACE_OPEN_SCOPE TF_API bool TfPyConvertTfErrorsToPythonException(TfErrorMark const &m)
Tf_MakePyConstructor::NewVisitor< typename Tf_MakePyConstructor::NewCtorWithClassReference< T > > TfMakePyNewWithClassReference(T *func, const std::string &doc=std::string())
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
std::decay_t< decltype(make_index_sequence_impl< N >())> make_index_sequence
OIIO_FORCEINLINE bool extract(const vbool4 &a)
InitCtorWithBackReference(Sig *func)
friend class bp::def_visitor_access
InitCtorWithVarArgs(Sig *func)
std::weak_ptr< T > WeakPtr
NewVisitor(const std::string &doc=std::string())
static bp::object __new__(object &cls, Args...args)
InitVisitor(const std::string &doc=std::string())
PyObject * operator()(T seq) const
TF_API void TfPyThrowTypeError(const char *msg)
typename std::remove_reference< T >::type remove_reference_t
CtorBase< R(Args...)> Base
hboost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
GLuint const GLchar * name
std::remove_reference_t< T > SeqType
static bp::object init_callable()
std::string TfStringJoin(ForwardIterator begin, ForwardIterator end, const char *separator=" ")
static void __init__(SelfRef self, Args...args)
static bp::object init_callable()
void visit(CLS &c, char const *name, Options &options) const
GLfloat GLfloat GLfloat GLfloat h
std::enable_if_t< Tf_PyIsRefPtr< Ptr >::value > Tf_PySetPythonIdentity(Ptr const &, PyObject *)
CtorBase< R(ClsRef, Args...)> Base
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
static void __init__(object &self, Args...args)
void Tf_PyAddPythonOwnership(Ptr const &t, const void *uniqueId, PyObject *obj)
TF_API bp::object _DummyInit(bp::tuple const &, bp::dict const &)
#define PXR_NAMESPACE_CLOSE_SCOPE
void Install(object const &self, T const &t, TfErrorMark const &m)
**If you just want to fire and args
std::conditional_t< std::is_same< WeakPtr, void >::value, TfWeakPtr< typename FactoryResultPtr::DataType >, WeakPtr > WeakPtrType
NewCtorWithClassReference(Sig *func)
static bp::object init_callable(Options &options)
TfFunctionTraits< R(SelfRef, Args...)* > Traits
CtorBase< R(Args...)> Base
static void PostInstall(object const &self, TfRefPtr< T > const &ptr, const void *uniqueId)
typename Tf_GetFuncSig< Fn >::Type TfFunctionTraits
static void PostInstall(object const &self, T const &t, const void *)
TF_API bool TfPyIsNone(hboost::python::object const &obj)
Return true iff obj is None.
static bp::object init_callable()
TF_API void TfPyThrowRuntimeError(const char *msg)
static bp::object __init__(const bp::tuple &args, const bp::dict &kwargs)
CtorBase< R(Args...), 2 > Base
void visit(CLS &c, char const *name, Options &options) const
static bp::object init_callable(Options &o)
std::remove_reference_t< P > Ptr
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.