7 #ifndef PXR_BASE_TF_PY_POLYMORPHIC_H
8 #define PXR_BASE_TF_PY_POLYMORPHIC_H
23 #include "pxr/external/boost/python/object/class_detail.hpp"
24 #include "pxr/external/boost/python/wrapper.hpp"
25 #include "pxr/external/boost/python/has_back_reference.hpp"
28 #include <type_traits>
34 template <
typename Derived>
36 public TfType::PyPolymorphicBase,
37 public pxr_boost::python::wrapper<Derived>
45 using namespace pxr_boost::python;
51 PyObject * m_self = detail::wrapper_base_::get_owner(*
this);
57 if (handle<> m = handle<>(
59 PyObject_GetAttrString(
60 m_self, const_cast<char*>(func))))
65 type_handle typeHandle =
66 objects::registered_class_object(
68 PyTypeObject* class_object = typeHandle.get();
70 PyObject* func_object = 0;
73 PyMethod_Check(m.get())
74 && ((PyMethodObject*)m.get())->im_self == m_self
75 && class_object->tp_dict != 0
81 PyObject_GetAttrString(
82 (PyObject *)class_object,
83 const_cast<char*>(func))));
89 if (borrowed_f && PyCallable_Check(borrowed_f.get())) {
90 func_object = borrowed_f.get();
98 if (func_object != ((PyMethodObject*)m.get())->im_func)
104 return Override(handle<>(detail::none()));
116 (
"Pure virtual method '%s' called -- "
117 "must provide a python implementation.",
124 template <
typename Ret>
130 template <
class Ret,
class Cls,
typename... Arg>
131 std::function<Ret (Arg...)>
134 Ret (Cls::*defaultImpl)(Arg...));
136 template <
class Ret,
class Cls,
typename... Arg>
137 std::function<Ret (Arg...)>
140 Ret (Cls::*defaultImpl)(Arg...)
const)
const;
149 template <
class Ret,
class Cls,
typename... Args>
152 using MemFn =
typename std::conditional<
154 Ret (Cls::*)(Args...)
const, Ret (Cls::*)(Args...)>
::type;
156 _BindMemFn(MemFn memFn, Cls *obj)
162 operator()(Args...
args)
const
164 return (_obj->*_memFn)(
args...);
173 template <
typename Derived>
178 template <
typename Derived>
179 template <
class Ret,
class Cls,
typename... Args>
181 std::function<Ret (Args...)>
184 Ret (Cls::*defaultImpl)(Args...))
187 "This must be a base of Cls.");
191 return _BindMemFn<Ret, Cls, Args...>(
192 defaultImpl,
static_cast<Cls *
>(
this));
195 template <
typename Derived>
196 template <
class Ret,
class Cls,
typename... Args>
198 std::function<Ret (Args...)>
201 Ret (Cls::*defaultImpl)(Args...)
const)
const
204 "This must be a base of Cls.");
208 return _BindMemFn<Ret, Cls
const, Args...>(
209 defaultImpl,
static_cast<Cls
const *
>(
this));
216 namespace PXR_BOOST_NAMESPACE {
namespace python {
217 template <
typename T>
225 template <
typename Base,
typename Fn>
228 template <
typename Base,
typename Derived,
229 typename Ret,
typename... Args>
232 typedef Ret (Base::*
Type)(Args...);
235 template <
typename Base,
typename Derived,
236 typename Ret,
typename... Args>
239 typedef Ret (Base::*
Type)(Args...)
const;
242 template <
typename Base,
typename Fn>
248 return static_cast<Ret
>(fn);
253 #endif // PXR_BASE_TF_PY_POLYMORPHIC_H
TF_API std::string TfStringPrintf(const char *fmt,...)
virtual ~TfPyPolymorphic()
GLsizei const GLfloat * value
TfPyCall< Ret > CallPureVirtual(char const *func) const
TfPyPolymorphic< Derived > This
TF_API void TfPyConvertPythonExceptionToTfErrors()
Override GetOverride(char const *func) const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
#define PXR_NAMESPACE_CLOSE_SCOPE
**If you just want to fire and args
OIIO_UTIL_API const char * c_str(string_view str)
std::function< Ret(Arg...)> CallVirtual(char const *fname, Ret(Cls::*defaultImpl)(Arg...))
Tf_PyMemberFunctionPointerUpcast< Base, Fn >::Type TfPyProtectedVirtual(Fn fn)
Override GetPureOverride(char const *func) const