HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
makePyConstructor.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
26 #define PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
27 
28 /// \file tf/makePyConstructor.h
29 /// An injected constructor mechanism that works with polymorphic wrapped
30 /// classes.
31 
32 #ifndef TF_MAX_ARITY
33 # define TF_MAX_ARITY 7
34 #endif // TF_MAX_ARITY
35 
36 
37 #include "pxr/pxr.h"
38 #include "pxr/base/tf/api.h"
40 #include "pxr/base/tf/refPtr.h"
41 #include "pxr/base/tf/weakPtr.h"
42 #include "pxr/base/tf/diagnostic.h"
43 #include "pxr/base/tf/pyError.h"
44 #include "pxr/base/tf/pyIdentity.h"
45 #include "pxr/base/tf/pyUtils.h"
47 
48 #include "pxr/base/arch/demangle.h"
49 
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>
58 
59 #include <array>
60 #include <string>
61 #include <type_traits>
62 #include <utility>
63 
65 
66 // Helper for wrapping objects that are held by weak pointers, but may also be
67 // constructed from script. This lets one construct an object from script and
68 // stores a ref pointer to the C++ object inside the python object. This way,
69 // objects created from script are owned by script, but objects obtained from
70 // the C++ API cannot be owned by script. When the owning python object is
71 // collected, its ref pointer will go away and the C++ object will be
72 // deallocated.
73 //
74 // Example usage:
75 //
76 // class_<MyClass, MyClassPtr>("MyClass", no_init)
77 // .def(TfPyRefAndWeakPtr())
78 // .def(TfMakePyConstructor(MyClass::New))
79 // .def(...)
80 // ...
81 //
82 // TfMakePyConstructorWithVarArgs may be used to wrap an object so that it
83 // may be constructed with a variable number of positional and keyword
84 // arguments. The last two arguments of the function being wrapped must
85 // be a hboost::python::tuple and dict. These will contain the remaining
86 // positional and keyword args after required arguments are parsed.
87 //
88 // Example usage:
89 //
90 // static MyObjectRefPtr MyObjectFactory(
91 // int formalArg1, const std::string& formalArg2,
92 // const hboost::python::tuple& args, const hboost::python::dict& kwargs);
93 //
94 // class_<MyClass, MyClassPtr>("MyClass", no_init)
95 // .def(TfPyRefAndWeakPtr())
96 // .def(TfMakePyConstructorWithVarArgs(MyObjectFactory))
97 // .def(...)
98 //
99 // NOTE: The current implementation does not handle hboost::python::arg for
100 // specifying keywords for required arguments.
101 
102 namespace Tf_MakePyConstructor {
103 
104 namespace bp = hboost::python;
105 
106 template <typename CTOR>
107 struct InitVisitor : bp::def_visitor<InitVisitor<CTOR> > {
110  InitVisitor(const std::string &doc = std::string()) : _doc(doc) {}
111 
112  template <typename CLS>
113  void visit(CLS &c) const {
114  c.def("__init__", CTOR::template init_callable<CLS>(), _doc.c_str());
115  }
116 
117  template <class CLS, class Options>
118  void visit(CLS &c, char const* name, Options& options) const {
119  // Note: we ignore options.doc() in favor of _doc
120  c.def(name, CTOR::template init_callable<CLS>(options), _doc.c_str());
121  }
122 
123 };
124 
125 TF_API
126 bp::object _DummyInit(bp::tuple const & /* args */,
127  bp::dict const & /* kw */);
128 
129 template <typename CTOR>
130 struct NewVisitor : bp::def_visitor<NewVisitor<CTOR> > {
133  NewVisitor(const std::string &doc = std::string()) : _doc(doc) {}
134 
135  template <typename CLS>
136  void visit(CLS &c) const {
137  // If there's already a __new__ method, look through the staticmethod to
138  // get the underlying function, replace __new__ with that, then add the
139  // overload, and recreate the staticmethod. This is required because
140  // hboost python needs to have all overloads exported before you say
141  // .staticmethod.
142 
143  // Note that it looks like this should do nothing, but it actually does
144  // something! Here's what it does: looking up __new__ on c doesn't
145  // actually produce the staticmethod object -- it does a "descriptor
146  // __get__" which produces the underlying function. Replacing __new__
147  // with that underlying thing has the effect of unwrapping the
148  // staticmethod, which is exactly what we want.
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__");
153 
154  //c.def("__init__", CTOR::template __init__<CLS>, _doc.c_str());
155  c.def("__init__", bp::raw_function(_DummyInit));
156  }
157 
158  template <class CLS, class Options>
159  void visit(CLS &c, char const* name, Options& options) const {
160  // If there's already a __new__ method, look through the staticmethod to
161  // get the underlying function, replace __new__ with that, then add the
162  // overload, and recreate the staticmethod. This is required because
163  // hboost python needs to have all overloads exported before you say
164  // .staticmethod.
165 
166  // Note that it looks like this should do nothing, but it actually does
167  // something! Here's what it does: looking up __new__ on c doesn't
168  // actually produce the staticmethod object -- it does a "descriptor
169  // __get__" which produces the underlying function. Replacing __new__
170  // with that underlying thing has the effect of unwrapping the
171  // staticmethod, which is exactly what we want.
172  if (PyObject_HasAttrString(c.ptr(), "__new__"))
173  c.attr("__new__") = c.attr("__new__");
174  c.def("__new__", CTOR::template __new__<CLS>,
175  // Note: we ignore options.doc() in favor of _doc
176  _doc.c_str(),
177  options.keywords(),
178  options.policies()
179  );
180  c.staticmethod("__new__");
181 
182  //c.def("__init__", CTOR::template __init__<CLS>, _doc.c_str());
183  c.def("__init__", bp::raw_function(_DummyInit));
184  }
185 
186 };
187 
188 
190 
191 template <typename T>
193  static void PostInstall(object const &self, T const &t,
194  const void *) {}
195 };
196 
197 // Specialize install policy for refptrs.
198 template <typename T>
201  "Type T must support refcount unique changed notification.");
202  static void PostInstall(object const &self, TfRefPtr<T> const &ptr,
203  const void *uniqueId) {
204  // Stash a self-reference ref ptr into the python object that will
205  // keep the object alive. Need to get a ref ptr to the held type,
206  // since that's what's wrapped.
207  Tf_PyAddPythonOwnership(ptr, uniqueId, self.ptr());
208  }
209 };
210 
211 template <typename CLS, typename T>
212 void Install(object const &self, T const &t, TfErrorMark const &m) {
213  // Stick the weakptr into the python object self to complete
214  // construction.
215  typedef typename CLS::metadata::holder Holder;
216  typedef typename bp::objects::instance<Holder> instance_t;
217  typedef InstallPolicy<T> Policy;
218  typedef typename CLS::metadata::held_type HeldType;
219 
220  // CODE_COVERAGE_OFF
221  void *memory = Holder::
222  // CODE_COVERAGE_ON
223  allocate(self.ptr(), offsetof(instance_t, storage), sizeof(Holder));
224  try {
225  HeldType held(t);
226  Holder *holder = (new (memory) Holder(held));
227  // If there was a TfError, raise that back to python.
229  bp::throw_error_already_set();
230  // If no TfError, but object construction failed, raise a generic error
231  // back to python.
232  if (!held)
233  TfPyThrowRuntimeError("could not construct " +
234  ArchGetDemangled(typeid(HeldType)));
235  bp::detail::initialize_wrapper(self.ptr(), &(*(held.operator->())));
236  holder->install(self.ptr());
237 
238  // Set object identity
239  Tf_PySetPythonIdentity(held, self.ptr());
240 
241  Policy::PostInstall(self, t, held.GetUniqueIdentifier());
242 
243  } catch(...) {
244  Holder::deallocate(self.ptr(), memory); throw;
245  }
246 
247 }
248 
249 
250 template <typename WeakPtr, typename P>
252  typedef std::remove_reference_t<P> Ptr;
253  bool convertible() const {
254  // FIXME should actually check here... It's not really horrible because
255  // if the conversion will fail, we'll just get a runtime error down
256  // below when we try to create the resulting object. That's basically
257  // what we want anyway.
258  return true;
259  }
260  PyObject *operator()(Ptr const &p) const {
261  typedef InstallPolicy<Ptr> Policy;
262  WeakPtr ptr(static_cast<typename WeakPtr::DataType *>
263  (get_pointer(p)));
264 
265  // If resulting pointer is null, return None.
266  if (!ptr)
267  return bp::incref(Py_None);
268 
269  // The to-python converter will set identity here.
270  object result(ptr);
271 
272  Policy::PostInstall(result, p, ptr.GetUniqueIdentifier());
273  return bp::incref(result.ptr());
274  }
275  // Required for hboost.python signature generator, in play when
276  // HBOOST_PYTHON_NO_PY_SIGNATURES is undefined.
277  PyTypeObject const *get_pytype() const {
278  return hboost::python::objects::registered_class_object(
279  hboost::python::type_id<typename WeakPtr::DataType>()).get();
280  }
281 };
282 
283 template <typename WeakPtr = void>
285  template <typename FactoryResultPtr>
286  struct apply {
292  };
293 };
294 
295 // EXTRA_ARITY is added for InitCtorWithVarArgs backwards compatability.
296 // The previous HBOOST_PP implementation didn't count the tuple and dict
297 // against the arity limit while the new version does. A future change
298 // should remove EXTRA_ARITY and increase TF_MAX_ARITY now that the
299 // implementations are templated and no longer generated by HBOOST_PP
300 template <typename SIG, size_t EXTRA_ARITY = 0>
301 struct CtorBase {
302  typedef SIG Sig;
304  static_assert(Traits::Arity <= (TF_MAX_ARITY + EXTRA_ARITY));
305 
306  static Sig *_func;
307  static void SetFunc(Sig *func) {
308  if (!_func)
309  _func = func;
310  else {
311  // CODE_COVERAGE_OFF
312  TF_CODING_ERROR("Ctor with signature '%s' is already registered. "
313  "Duplicate will be ignored.",
314  ArchGetDemangled(typeid(Sig)).c_str());
315  // CODE_COVERAGE_ON
316  }
317  }
318 };
319 
320 template <typename SIG, size_t EXTRA_ARITY>
321 SIG *CtorBase<SIG, EXTRA_ARITY>::_func = nullptr;
322 
323 template <typename SIG> struct InitCtor;
324 template <typename SIG> struct InitCtorWithBackReference;
325 template <typename SIG> struct InitCtorWithVarArgs;
326 template <typename SIG> struct NewCtor;
327 template <typename SIG> struct NewCtorWithClassReference;
328 
329 }
330 
331 
332 template <typename T>
336  // Instantiate to set static constructor pointer, then return the visitor.
340 }
341 
342 template <typename T>
346  // Instantiate to set static constructor pointer, then return the visitor.
350 }
351 
352 template <typename T>
356  // Instantiate to set static constructor pointer, then return the visitor.
360 }
361 
362 template <typename T>
365 TfMakePyNew(T *func, const std::string &doc = std::string()) {
366  // Instantiate to set static constructor pointer, then return the visitor.
370 }
371 
372 template <typename T>
376  // Instantiate to set static constructor pointer, then return the visitor.
380 }
381 
382 
383 template <typename T = void>
385 
386 template <typename T> struct Tf_PySequenceToListConverterRefPtrFactory;
387 
388 /// A \c hboost::python result converter generator which converts standard
389 /// library sequences to lists of python owned objects.
391  template <typename T>
392  struct apply {
394  };
395 };
396 
397 // XXX: would be nicer to be able to compose converters with factory
398 template <typename T>
400  typedef std::remove_reference_t<T> SeqType;
401  bool convertible() const {
402  return true;
403  }
404  PyObject *operator()(T seq) const {
405  using namespace hboost::python;
406 
409 
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))));
414  }
415  return hboost::python::incref(l.ptr());
416  }
417  // Required for hboost.python signature generator, in play when
418  // HBOOST_PYTHON_NO_PY_SIGNATURES is undefined.
419  PyTypeObject const *get_pytype() const {
420  return &PyList_Type;
421  }
422 };
423 
424 namespace Tf_MakePyConstructor {
425 
426 template <typename R, typename... Args>
427 struct InitCtor<R(Args...)> : CtorBase<R(Args...)> {
428  typedef CtorBase<R(Args...)> Base;
429  typedef typename Base::Sig Sig;
430 
431  InitCtor(Sig* func) { Base::SetFunc(func); }
432 
433  template <typename CLS>
435  return bp::make_function(__init__<CLS>);
436  }
437 
438  template <typename CLS, typename Options>
439  static bp::object init_callable(Options& o) {
440  return bp::make_function(__init__<CLS>, o.policies(), o.keywords()) ;
441  }
442 
443  template <typename CLS>
444  static void __init__(object &self, Args... args) {
445  TfErrorMark m;
446  Install<CLS>(self, Base::_func(args...), m);
447  }
448 };
449 
450 template <typename R, typename... Args>
451 struct NewCtor<R(Args...)> : CtorBase<R(Args...)> {
452  typedef CtorBase<R(Args...)> Base;
453  typedef typename Base::Sig Sig;
454  NewCtor(Sig *func) { Base::SetFunc(func); }
455 
456  template <class CLS>
457  static bp::object __new__(object &cls, Args... args) {
458  typedef typename CLS::metadata::held_type HeldType;
459  TfErrorMark m;
460  R r((Base::_func(args...)));
461  HeldType h((r));
463  bp::throw_error_already_set();
464  bp::object ret = TfPyObject(h);
465  if (TfPyIsNone(ret))
466  TfPyThrowRuntimeError("could not construct " +
467  ArchGetDemangled(typeid(HeldType)));
468 
469  bp::detail::initialize_wrapper(ret.ptr(), get_pointer(h));
470  // make the object have the right class.
471  bp::setattr(ret, "__class__", cls);
472 
473  InstallPolicy<R>::PostInstall(ret, r, h.GetUniqueIdentifier());
474  return ret;
475  }
476 };
477 
478 template <typename R, typename... Args>
479 struct InitCtorWithVarArgs<R(Args...)> :
480  // Pad the arity for backwards compatability
481  CtorBase<R(Args...), /*EXTRA_ARITY*/ 2> {
482  typedef CtorBase<R(Args...), /*EXTRA_ARITY*/ 2> Base;
483  typedef typename Base::Sig Sig;
484 
485  // Ideally, Arity would be pulled from Base::Traits, but
486  // compilers have inconsistently allowed this. Redefine
487  // Arity as a workaround for now.
488  using Arity = TfMetaLength<Args...>;
489 
490  InitCtorWithVarArgs(Sig *func) { Base::SetFunc(func); }
491 
492  static_assert((Arity::value >= 2) &&
493  (std::is_same_v<
494  const bp::tuple&,
495  typename Base::Traits::template NthArg<(Arity::value-2)>>) &&
496  (std::is_same_v<
497  const bp::dict&,
498  typename Base::Traits::template NthArg<(Arity::value-1)>>),
499  "InitCtorWithVarArgs requires a function of form "
500  "(..., const tuple&, const dict&)");
501 
502  template <typename CLS>
504  // Specify min_args as 1 to account for just the 'self' argument.
505  // min_args really should be N + 1. However, we want to do this check
506  // ourselves later so we can emit a better error message.
507  return bp::raw_function(__init__<CLS>, /* min_args = */ 1);
508  }
509 
510  template <typename CLS, typename Options>
511  static bp::object init_callable(Options& options) {
512  // XXX: Note ignoring options.keywords(), current implementation can't
513  // handle that correctly.
514  return bp::raw_function(
515  bp::make_function(__init__<CLS>, options.policies()),
516  /* min_args = */ 1);
517  }
518 
519  template <typename CLS, size_t... I>
520  static bp::object __init__impl(const bp::tuple& args,
521  const bp::dict& kwargs,
522  std::index_sequence<I...>) {
523  TfErrorMark m;
524 
525  // We know that there are at least two args because the specialization only
526  // matches against (..., *args, **kwargs)
527  const unsigned int expectedNamedArgs = Arity::value - 2;
528  // self is included in the tuple, so it should always be at least 1
529  const unsigned int positionalArgs = bp::len(args) - 1;
530  if (positionalArgs < expectedNamedArgs) {
531  std::array<std::string, Arity::value - 2>
532  positionalArgTypes = {{
533  (bp::type_id<typename Base::Traits::template NthArg<I>>().name())...
534  }};
535  std::string joinedTypes = TfStringJoin(
536  std::begin(positionalArgTypes),
537  std::end(positionalArgTypes), ", "
538  );
539  if (!joinedTypes.empty()) {
540  joinedTypes += ", ";
541  }
542  // User didn't provide enough positional arguments for the factory
543  // function. Complain.
546  "Arguments to __init__ did not match C++ signature:\n"
547  "\t__init__(%s...)", joinedTypes.c_str()
548  )
549  );
550  return bp::object();
551  }
552 
553  Install<CLS>(
554  // self object for new instance is the first arg to __init__
555  args[0],
556  Base::_func(
557  bp::extract<
559  typename Base::Traits::template NthArg<I>>>(args[I + 1])...,
560  bp::tuple(args.slice(expectedNamedArgs + 1, bp::len(args))), kwargs),
561  m);
562 
563  return bp::object();
564  }
565 
566  template <typename CLS>
567  static bp::object __init__(const bp::tuple& args,
568  const bp::dict& kwargs) {
569  return __init__impl<CLS>(
570  args, kwargs, std::make_index_sequence<Arity::value - 2>());
571 
572  }
573 };
574 
575 // This is a variant of Ctor which includes a back reference to self
576 // (the Python object being initialized) in the args passed to the
577 // constructor. This is used to expose the factory methods for classes
578 // which we expect to subclass in Python. When the constructor is called,
579 // it can examine self and initialize itself appropriately.
580 template <typename R, typename SelfRef, typename... Args>
581 struct InitCtorWithBackReference<R(SelfRef, Args...)> :
582  CtorBase<R(SelfRef, Args...)> {
583  typedef CtorBase<R(SelfRef, Args...)> Base;
584  typedef typename Base::Sig Sig;
585  InitCtorWithBackReference(Sig *func) { Base::SetFunc(func); }
586 
587  template <typename CLS>
589  return bp::make_function(__init__<CLS>);
590  }
591 
592  template <typename CLS, typename Options>
593  static bp::object init_callable(Options& o) {
594  return bp::make_function(__init__<CLS>, o.policies(), o.keywords());
595  }
596 
597  template <typename CLS>
598  static void __init__(SelfRef self, Args... args) {
599  TfErrorMark m;
600  Install<CLS>(self, Base::_func(self, args...), m);
601  }
602 };
603 
604 template <typename R, typename ClsRef, typename... Args>
605 struct NewCtorWithClassReference<R(ClsRef, Args...)> :
606  CtorBase<R(ClsRef, Args...)> {
607  typedef CtorBase<R(ClsRef, Args...)> Base;
608  typedef typename Base::Sig Sig;
609  NewCtorWithClassReference(Sig *func) { Base::SetFunc(func); }
610 
611  template <class CLS>
612  static bp::object __new__(ClsRef cls, Args... args) {
613  typedef typename CLS::metadata::held_type HeldType;
614  TfErrorMark m;
615  R r(Base::_func(cls, args...));
616  HeldType h(r);
618  bp::throw_error_already_set();
619  bp::object ret = TfPyObject(h);
620  if (TfPyIsNone(ret))
621  TfPyThrowRuntimeError("could not construct " +
622  ArchGetDemangled(typeid(HeldType)));
623 
624  bp::detail::initialize_wrapper(ret.ptr(), get_pointer(h));
625  // make the object have the right class.
626  bp::setattr(ret, "__class__", cls);
627 
628  InstallPolicy<R>::PostInstall(ret, r, h.GetUniqueIdentifier());
629  return ret;
630  }
631 };
632 }
633 
635 
636 #endif // PXR_BASE_TF_MAKE_PY_CONSTRUCTOR_H
GLsizei GLenum GLsizei GLsizei GLuint memory
Definition: RE_OGL.h:202
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())
std::integral_constant< size_t, sizeof...(Xs)> TfMetaLength
Definition: meta.h:71
#define TF_API
Definition: api.h:40
_RefPtrFactoryConverter< WeakPtrType, FactoryResultPtr > type
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
typename std::conditional< B, T, F >::type conditional_t
Definition: core.h:322
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Tf_MakePyConstructor::InitVisitor< typename Tf_MakePyConstructor::InitCtorWithVarArgs< T > > TfMakePyConstructorWithVarArgs(T *func, const std::string &doc=std::string())
#define TF_CODING_ERROR
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...>)
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
static void SetFunc(Sig *func)
**But if you need a result
Definition: thread.h:613
#define TF_MAX_ARITY
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)
Definition: weakPtrFacade.h:83
std::decay_t< decltype(make_index_sequence_impl< N >())> make_index_sequence
Definition: Types.h:234
OIIO_FORCEINLINE bool extract(const vbool4 &a)
Definition: simd.h:3426
std::weak_ptr< T > WeakPtr
Definition: Types.h:115
NewVisitor(const std::string &doc=std::string())
static bp::object __new__(object &cls, Args...args)
InitVisitor(const std::string &doc=std::string())
GLuint GLuint end
Definition: glcorearb.h:475
TF_API void TfPyThrowTypeError(const char *msg)
typename std::remove_reference< T >::type remove_reference_t
Definition: core.h:325
hboost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Definition: pyUtils.h:144
GLuint const GLchar * name
Definition: glcorearb.h:786
std::string TfStringJoin(ForwardIterator begin, ForwardIterator end, const char *separator=" ")
Definition: stringUtils.h:374
GLdouble t
Definition: glad.h:2397
void visit(CLS &c, char const *name, Options &options) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
GLenum func
Definition: glcorearb.h:783
std::enable_if_t< Tf_PyIsRefPtr< Ptr >::value > Tf_PySetPythonIdentity(Ptr const &, PyObject *)
Definition: pyIdentity.h:231
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
static void __init__(object &self, Args...args)
void Tf_PyAddPythonOwnership(Ptr const &t, const void *uniqueId, PyObject *obj)
Definition: pyIdentity.h:261
auto ptr(T p) -> const void *
Definition: format.h:2448
TF_API bp::object _DummyInit(bp::tuple const &, bp::dict const &)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
void Install(object const &self, T const &t, TfErrorMark const &m)
**If you just want to fire and args
Definition: thread.h:609
std::conditional_t< std::is_same< WeakPtr, void >::value, TfWeakPtr< typename FactoryResultPtr::DataType >, WeakPtr > WeakPtrType
TfFunctionTraits< R(SelfRef, Args...)* > Traits
GLboolean r
Definition: glcorearb.h:1222
static void PostInstall(object const &self, TfRefPtr< T > const &ptr, const void *uniqueId)
typename Tf_GetFuncSig< Fn >::Type TfFunctionTraits
type
Definition: core.h:1059
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.
TF_API void TfPyThrowRuntimeError(const char *msg)
static bp::object __init__(const bp::tuple &args, const bp::dict &kwargs)
void visit(CLS &c, char const *name, Options &options) const
static bp::object init_callable(Options &o)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:558