@@ -11,8 +11,8 @@ instance. This is useful when writing generic binding code that manipulates
11
11
nanobind-based objects of various types.
12
12
13
13
Given a previous :cpp:class: `nb::class_\< ...\> <class_> ` binding declaration,
14
- this interface can be used to look up the Python type object associated with
15
- a C++ class named ``MyClass ``.
14
+ the :cpp:func: ` nb::type \< T \> () <type> ` template function can be used to look up
15
+ the Python type object associated with a C++ class named ``MyClass ``.
16
16
17
17
.. code-block :: cpp
18
18
@@ -28,9 +28,10 @@ redundant in this case):
28
28
29
29
assert(py_type.is_valid() && nb::type_check(py_type));
30
30
31
- nanobind knows the size, alignment, and C++ RTTI ``std::type_info ``
32
- record of all bound types. They can be queried on the fly in situations
33
- where this is useful.
31
+ nanobind knows the size, alignment, and C++ RTTI ``std::type_info `` record of
32
+ all bound types. They can be queried on the fly via :cpp:func: `nb::type_size()
33
+ <type_size> `, :cpp:func: `nb::type_align() <type_size> `, and
34
+ :cpp:func: `nb::type_info() <type_size> ` in situations where this is useful.
34
35
35
36
.. code-block :: cpp
36
37
@@ -47,9 +48,11 @@ to prevent undefined behavior. It must first be initialized.
47
48
48
49
nb::object py_inst = nb::inst_alloc(py_type);
49
50
50
- We can confirm that this newly created instance is managed by nanobind,
51
- that it has the correct type in Python, and that it is not ``ready ``
52
- (i.e. uninitialized):
51
+ We can confirm via :cpp:func: `nb::inst_check() <inst_check> ` that this newly
52
+ created instance is managed by nanobind, that it has the correct type in
53
+ Python. Calling :cpp:func: `nb::inst_ready() <inst_ready> ` reveals that the
54
+ *ready * flag of the instance is set to ``false `` (i.e., it is still
55
+ uninitialized).
53
56
54
57
.. code-block :: cpp
55
58
@@ -58,16 +61,17 @@ that it has the correct type in Python, and that it is not ``ready``
58
61
!nb::inst_ready(py_inst));
59
62
60
63
For simple *plain old data * (POD) types, the :cpp:func: `nb::inst_zero()
61
- <inst_zero> ` function can be used to zero-initialize the object and mark it
64
+ <inst_zero> ` function can be used to * zero-initialize * the object and mark it
62
65
as ready.
63
66
64
67
.. code-block :: cpp
65
68
66
69
nb::inst_zero(py_inst);
67
70
assert(nb::inst_ready(py_inst));
68
71
69
- We can destruct this default instance and convert it back to non-ready
70
- status. This memory region can then be reinitialized once more.
72
+ We can destruct this default instance via :cpp:func: `nb::inst_destruct()
73
+ <inst_destruct> ` and convert it back to non-ready status. This memory region
74
+ can then be reinitialized once more.
71
75
72
76
.. code-block :: cpp
73
77
@@ -88,9 +92,9 @@ by nanobind.
88
92
new (ptr) MyClass(/* constructor arguments go here */);
89
93
90
94
Following this constructor call, we must inform nanobind that the instance
91
- object is now fully constructed. When its reference count reaches zero,
92
- nanobind will automatically call the in-place destructor
93
- (``MyClass::~MyClass ``).
95
+ object is now fully constructed via :cpp:func: ` nb::inst_mark_ready()
96
+ <inst_mark_ready> `. When its reference count reaches zero, nanobind will then
97
+ automatically call the in-place destructor (``MyClass::~MyClass ``).
94
98
95
99
.. code-block :: cpp
96
100
@@ -105,12 +109,14 @@ the C++ destructor and mark the Python object as non-ready).
105
109
nb::inst_destruct(py_inst);
106
110
107
111
Another useful feature is that nanobind can copy- or move-construct ``py_inst ``
108
- from another instance of the same type. This calls the C++ copy or move
109
- constructor and transitions ``py_inst `` back to ``ready `` status. Note that
110
- this is equivalent to calling an in-place version of these constructors above
111
- but compiles to more compact code (the :cpp:class: `nb::class_\< MyClass\>
112
- <class_> ` declaration had already created bindings for both constructors, and
113
- this simply calls those bindings).
112
+ from another instance of the same type via :cpp:func: `nb::inst_copy()
113
+ <inst_copy> ` and :cpp:func: `nb::inst_move() <inst_move> `. These functions call
114
+ the C++ copy or move constructor and transition ``py_inst `` back to ``ready ``
115
+ status. This is equivalent to calling an in-place version of these constructors
116
+ followed by a call to :cpp:func: `nb::inst_mark_ready() <inst_mark_ready> ` but
117
+ compiles to more compact code (the :cpp:class: `nb::class_\< MyClass\> <class_> `
118
+ declaration had already created bindings for both constructors, and this simply
119
+ calls those bindings).
114
120
115
121
.. code-block :: cpp
116
122
@@ -119,6 +125,19 @@ this simply calls those bindings).
119
125
else
120
126
nb::inst_move(/* dst = */ py_inst, /* src = */ some_other_instance);
121
127
128
+ Both functions assume that the destination object is uninitialized. Two
129
+ alternative versions :cpp:func: `nb::inst_replace_copy() <inst_replace_copy> `
130
+ and :cpp:func: `nb::inst_replace_move() <inst_replace_move> ` destruct an
131
+ initialized instance and replace it with the contents of another by either
132
+ copying or moving.
133
+
134
+ .. code-block :: cpp
135
+
136
+ if (copy_instance)
137
+ nb::inst_replace_copy(/* dst = */ py_inst, /* src = */ some_other_instance);
138
+ else
139
+ nb::inst_replace_move(/* dst = */ py_inst, /* src = */ some_other_instance);
140
+
122
141
Note that these functions are all *unsafe * in the sense that they do not
123
142
verify that their input arguments are valid. This is done for
124
143
performance reasons, and such checks (if needed) are therefore the
@@ -127,10 +146,14 @@ only be called with nanobind type objects, and functions labeled
127
146
``nb::inst_* `` should only be called with nanobind instance objects.
128
147
129
148
The functions :cpp:func: `nb::type_check() <type_check> ` and
130
- :cpp:func: `nb::inst_check() <inst_check> ` are exceptions to this rule: they
131
- accept any Python object and test whether something is a nanobind type or
149
+ :cpp:func: `nb::inst_check() <inst_check> ` are exceptions to this rule:
150
+ they accept any Python object and test whether something is a nanobind type or
132
151
instance object.
133
152
153
+ Two further functions :cpp:func: `nb::type_name() <type_name> ` and
154
+ :cpp:func: `nb::inst_name() <inst_name> ` determine the type name associated with
155
+ a type or instance thereof. These also accept non-nanobind types and instances.
156
+
134
157
Even lower-level interface
135
158
--------------------------
136
159
@@ -149,18 +172,14 @@ The functions :cpp:func:`nb::inst_zero() <inst_zero>`,
149
172
flags to ``true ``, and :cpp:func: `nb::inst_destruct() <inst_destruct> ` sets
150
173
both of them to ``false ``.
151
174
152
- In rare situations, the destructor should *not * be invoked when the
153
- instance is garbage collected, for example when working with a nanobind
154
- instance representing a field of a parent instance created using the
175
+ In rare situations, the destructor should *not * be invoked when the instance is
176
+ garbage collected, for example when working with a nanobind instance
177
+ representing a field of a parent instance created using the
155
178
:cpp:enumerator: `nb::rv_policy::reference_internal
156
179
<rv_policy::reference_internal> ` return value policy. The library therefore
157
- exposes two more functions that can be used to read/write these two flags
158
- individually.
159
-
160
- .. code-block :: cpp
161
-
162
- void inst_set_state(handle h, bool ready, bool destruct);
163
- std::pair<bool, bool> inst_state(handle h);
180
+ exposes two more functions :cpp:func: `nb::inst_state() <inst_state> ` and
181
+ :cpp:func: `nb::inst_set_state() <inst_set_state> ` that can be used to access
182
+ them individually.
164
183
165
184
Referencing existing instances
166
185
------------------------------
@@ -178,19 +197,25 @@ with the binding ``py_type``.
178
197
... omitted, see the previous examples ...
179
198
180
199
What if the C++ instance already exists? nanobind also supports this case via
181
- the :cpp:func: `nb::inst_wrap() <inst_wrap> ` function—in this case, the Python
182
- object references the existing memory region, which is potentially (slightly)
183
- less efficient due to the need for an extra indirection.
200
+ the :cpp:func: `nb::inst_reference() <inst_reference> ` and
201
+ :cpp:func: `nb::inst_take_ownership() <inst_take_ownership> ` functions—in this
202
+ case, the Python object references the existing memory region, which is
203
+ potentially (slightly) less efficient due to the need for an extra indirection.
184
204
185
205
.. code-block :: cpp
186
206
187
207
MyClass *inst = new MyClass();
188
- nb::object py_inst = nb::inst_wrap(py_type, inst);
189
208
190
- // Mark as ready, garbage-collecting 'py_inst' will cause 'inst' to be
191
- // deleted as well. Call nb::inst_set_state (documented above) for more
192
- // fine-grained control.
193
- nb::inst_mark_ready(py_inst);
209
+ // Transfer ownership of 'inst' to Python (which will use a delete
210
+ // expression to free it when the Python instance is garbage collected)
211
+ nb::object py_inst = nb::inst_take_ownership(py_type, inst);
212
+
213
+ // We can also wrap C++ instances that should not be destructed since
214
+ // they represent offsets into another data structure. In this case,
215
+ // the optional 'parent' parameter ensures that 'py_inst' remains alive
216
+ // while 'py_subinst' exists to prevent undefined behavior.
217
+ nb::object py_subinst = nb::inst_reference(
218
+ py_field_type, &inst->field, /* parent = */ py_inst);
194
219
195
220
.. _supplement :
196
221
0 commit comments