All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pyOverride.h
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 #ifndef PXR_BASE_TF_PY_OVERRIDE_H
25 #define PXR_BASE_TF_PY_OVERRIDE_H
26 
27 #include "pxr/pxr.h"
28 
29 #include "pxr/base/tf/pyLock.h"
30 #include "pxr/base/tf/pyObjWrapper.h"
31 
32 #include <boost/python/override.hpp>
33 
34 PXR_NAMESPACE_OPEN_SCOPE
35 
46 {
47 private:
49  friend class TfPyOverride;
50  explicit TfPyMethodResult(PyObject* x)
51  : m_obj(x)
52  {}
53 
54 public:
56  TfPyMethodResult(TfPyMethodResult const &other);
57 
60 
63 
64  template <class T>
65  operator T()
66  {
67  TfPyLock lock;
68  boost::python::converter::return_from_python<T> converter;
69  return converter(m_obj.release());
70  }
71 
72  template <class T>
73  operator T&() const
74  {
75  TfPyLock lock;
76  boost::python::converter::return_from_python<T&> converter;
77  return converter(
78  const_cast<boost::python::handle<>&>(m_obj).release());
79  }
80 
81  template <class T>
82  T as(boost::type<T>* = 0)
83  {
84  TfPyLock lock;
85  boost::python::converter::return_from_python<T> converter;
86  return converter(m_obj.release());
87  }
88 
89  template <class T>
90  T unchecked(boost::type<T>* = 0)
91  {
92  TfPyLock lock;
93  return boost::python::extract<T>(m_obj)();
94  }
95 
96 private:
97  mutable boost::python::handle<> m_obj;
98 };
99 
115 {
116  // Helper to generate Py_BuildValue-style format strings at compile time.
117  template <typename Arg>
118  constexpr static char _PyObjArg()
119  {
120  return 'O';
121  }
122 
123 public:
125  TfPyOverride(boost::python::handle<> callable)
126  : TfPyObjWrapper(boost::python::object(callable))
127  {}
128 
131  template <typename... Args>
133  operator()(Args const&... args) const
134  {
135  TfPyLock lock;
136  // Use the Args parameter pack together with the _PyObjArg helper to
137  // unpack the right number of 'O' elements into the format string.
138  static const char pyCallFormat[] =
139  { '(', _PyObjArg<Args>()..., ')', '\0' };
140 
142  PyEval_CallFunction(
143  this->ptr(),
144  const_cast<char*>(pyCallFormat),
145  boost::python::converter::arg_to_python<Args>(args).get()...));
146  return x;
147  }
148 };
149 
150 PXR_NAMESPACE_CLOSE_SCOPE
151 
152 #endif // PXR_BASE_TF_PY_OVERRIDE_H
TF_API PyObject * ptr() const
Underlying PyObject* access.
TfPyMethodResult & operator=(TfPyMethodResult const &other)
Implement assign to do python refcounting while holding the GIL.
TfPyMethodResult operator()(Args const &...args) const
Call the override.
Definition: pyOverride.h:133
TfPyOverride(boost::python::handle<> callable)
Clients must hold the GIL to construct.
Definition: pyOverride.h:125
A reimplementation of boost::python::override.
Definition: pyOverride.h:114
~TfPyMethodResult()
Implement dtor to do python refcounting while holding the GIL.
Boost Python object wrapper.
Definition: pyObjWrapper.h:66
A reimplementation of boost::python::detail::method_result.
Definition: pyOverride.h:45