Drake
wrap_pybind.h
Go to the documentation of this file.
1 /// @file
2 /// Defines convenience utilities to wrap pybind11 methods and classes.
3 
4 #pragma once
5 
6 #include <string>
7 #include <utility>
8 
9 #include "pybind11/pybind11.h"
10 
13 
14 namespace drake {
15 namespace pydrake {
16 
17 /// Defines a function in object `a` and mirrors `def` calls to object `b`.
18 ///
19 /// @tparam A Type of object `a`
20 /// @tparam B Type of object `b`
21 template <typename A, typename B>
22 class MirrorDef {
23  public:
25 
26  MirrorDef(A* a, B* b)
27  : a_(a), b_(b) {}
28 
29  /// Calls `def` for both `a` and `b`.
30  template <typename... Args>
31  MirrorDef& def(const char* name, Args&&... args) {
32  a_->def(name, std::forward<Args>(args)...);
33  b_->def(name, std::forward<Args>(args)...);
34  return *this;
35  }
36 
37  private:
38  A* const a_{};
39  B* const b_{};
40 };
41 
42 namespace detail {
43 
44 template <typename T, typename = void>
45 struct wrap_ref_ptr : public wrap_arg_default<T> {};
46 
47 template <typename T>
48 using is_generic_pybind =
49  std::is_base_of<py::detail::type_caster_generic, py::detail::make_caster<T>>;
50 
51 template <typename T>
53  // NOLINTNEXTLINE[runtime/references]: Intentional.
54  static T* wrap(T& arg) { return &arg; }
55  static T& unwrap(T* arg_wrapped) { return *arg_wrapped; }
56 };
57 
58 template <typename T, typename = void>
59 struct wrap_callback : public wrap_arg_default<T> {};
60 
61 template <typename Signature>
62 struct wrap_callback<const std::function<Signature>&>
63  : public wrap_arg_function<wrap_ref_ptr, Signature> {};
64 
65 template <typename Signature>
66 struct wrap_callback<std::function<Signature>>
67  : public wrap_callback<const std::function<Signature>&> {};
68 
69 } // namespace detail
70 
71 /// Ensures that any `std::function<>` arguments are wrapped such that any `T&`
72 /// (which can infer for `T = const U`) is wrapped as `U*` (and conversely
73 /// unwrapped when returned).
74 /// Use this when you have a callback in C++ that has a lvalue reference (const
75 /// or mutable) to a C++ argument or return value.
76 /// Otherwise, `pybind11` may try and copy the object, will be bad if either
77 /// the type is a non-copyable or if you are trying to mutate the object; in
78 /// this case, the copy is mutated, but not the original you care about.
79 /// For more information, see: https://github.com/pybind/pybind11/issues/1241
80 template <typename Func>
81 auto WrapCallbacks(Func&& func) {
82  return WrapFunction<detail::wrap_callback, false>(std::forward<Func>(func));
83 }
84 
85 /// Idempotent to pybind11's `def_readwrite()`, with the exception that the
86 /// setter is protected with keep_alive on a `member` variable that is a bare
87 /// pointer. Should not be used for unique_ptr members.
88 ///
89 /// @tparam PyClass the python class.
90 /// @tparam Class the C++ class.
91 /// @tparam T type for the member we wish to apply keep alive semantics.
92 template <typename PyClass, typename Class, typename T>
93 void DefReadWriteKeepAlive(PyClass* cls, const char* name, T Class::*member) {
94  auto getter = [member](const Class* obj) { return obj->*member; };
95  auto setter = [member](Class* obj, const T& value) { obj->*member = value; };
96  cls->def_property(
97  name,
98  py::cpp_function(getter),
99  py::cpp_function(setter,
100  // Keep alive, reference: `self` keeps `value` alive.
101  py::keep_alive<1, 2>()));
102 }
103 
104 } // namespace pydrake
105 } // namespace drake
typename detail::wrap_function_impl< wrap_arg_policy >::template wrap_arg< std::function< Signature >> wrap_arg_function
Policy for explicitly wrapping functions for a given policy.
Definition: wrap_function.h:263
Definition: wrap_pybind.h:45
double value
Definition: wrap_test_util_py.cc:12
Definition: bullet_model.cc:22
std::is_base_of< py::detail::type_caster_generic, py::detail::make_caster< T >> is_generic_pybind
Definition: wrap_pybind.h:49
MirrorDef(A *a, B *b)
Definition: wrap_pybind.h:26
STL namespace.
Defines a function in object a and mirrors def calls to object b.
Definition: wrap_pybind.h:22
double T
Definition: benchmarks_py.cc:14
void DefReadWriteKeepAlive(PyClass *cls, const char *name, T Class::*member)
Idempotent to pybind11&#39;s def_readwrite(), with the exception that the setter is protected with keep_a...
Definition: wrap_pybind.h:93
std::vector< snopt::doublereal > A
Definition: snopt_solver.cc:93
Definition: wrap_pybind.h:59
auto WrapCallbacks(Func &&func)
Ensures that any std::function<> arguments are wrapped such that any T& (which can infer for T = cons...
Definition: wrap_pybind.h:81
MirrorDef & def(const char *name, Args &&...args)
Calls def for both a and b.
Definition: wrap_pybind.h:31
Default case for argument wrapping, with pure pass-through.
Definition: wrap_function.h:249
const MyValue * member
Definition: wrap_test_util_py.cc:17
#define DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(Classname)
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN deletes the special member functions for copy-construction, copy-assignment, move-construction, and move-assignment.
Definition: drake_copyable.h:33
std::string name
Definition: geometry_base_test.cc:343
const char * func
Definition: drake_throw.h:16
Provides careful macros to selectively enable or disable the special member functions for copy-constr...