mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-24 22:25:10 +00:00
Resolve empty statement warning when using PYBIND11_OVERLOAD_PURE_NAME and PYBIND11_OVERLOAD_PURE (#2325)
* Wrap PYBIND11_OVERLOAD_NAME and PYBIND11_OVERLOAD_PURE_NAME in do { ... } while (false), and resolve trailing semicolon * Deprecate PYBIND11_OVERLOAD_* and get_overload in favor of PYBIND11_OVERRIDE_* and get_override * Correct erroneous usage of 'overload' instead of 'override' in the implementation and internals * Fix tests to use non-deprecated PYBIND11_OVERRIDE_* macros * Update docs to use override instead of overload where appropriate, and add warning about deprecated aliases * Add semicolons to deprecated PYBIND11_OVERLOAD macros to match original behavior * Remove deprecation of PYBIND11_OVERLOAD_* macros and get_overload * Add note to changelog and upgrade guide
This commit is contained in:
parent
9df13835c8
commit
d65e34d61d
@ -29,9 +29,9 @@ The following Python snippet demonstrates the intended usage from the Python sid
|
|||||||
from example import print
|
from example import print
|
||||||
print(A())
|
print(A())
|
||||||
|
|
||||||
To register the necessary conversion routines, it is necessary to add
|
To register the necessary conversion routines, it is necessary to add an
|
||||||
a partial overload to the ``pybind11::detail::type_caster<T>`` template.
|
instantiation of the ``pybind11::detail::type_caster<T>`` template.
|
||||||
Although this is an implementation detail, adding partial overloads to this
|
Although this is an implementation detail, adding an instantiation of this
|
||||||
type is explicitly allowed.
|
type is explicitly allowed.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
@ -157,7 +157,7 @@ the declaration
|
|||||||
|
|
||||||
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
|
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
|
||||||
macro must be specified at the top level (and outside of any namespaces), since
|
macro must be specified at the top level (and outside of any namespaces), since
|
||||||
it instantiates a partial template overload. If your binding code consists of
|
it adds a template instantiation of ``type_caster``. If your binding code consists of
|
||||||
multiple compilation units, it must be present in every file (typically via a
|
multiple compilation units, it must be present in every file (typically via a
|
||||||
common header) preceding any usage of ``std::vector<int>``. Opaque types must
|
common header) preceding any usage of ``std::vector<int>``. Opaque types must
|
||||||
also have a corresponding ``class_`` declaration to associate them with a name
|
also have a corresponding ``class_`` declaration to associate them with a name
|
||||||
|
@ -71,7 +71,7 @@ helper class that is defined as follows:
|
|||||||
|
|
||||||
/* Trampoline (need one for each virtual function) */
|
/* Trampoline (need one for each virtual function) */
|
||||||
std::string go(int n_times) override {
|
std::string go(int n_times) override {
|
||||||
PYBIND11_OVERLOAD_PURE(
|
PYBIND11_OVERRIDE_PURE(
|
||||||
std::string, /* Return type */
|
std::string, /* Return type */
|
||||||
Animal, /* Parent class */
|
Animal, /* Parent class */
|
||||||
go, /* Name of function in C++ (must match Python name) */
|
go, /* Name of function in C++ (must match Python name) */
|
||||||
@ -80,10 +80,10 @@ helper class that is defined as follows:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
The macro :c:macro:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual
|
The macro :c:macro:`PYBIND11_OVERRIDE_PURE` should be used for pure virtual
|
||||||
functions, and :c:macro:`PYBIND11_OVERLOAD` should be used for functions which have
|
functions, and :c:macro:`PYBIND11_OVERRIDE` should be used for functions which have
|
||||||
a default implementation. There are also two alternate macros
|
a default implementation. There are also two alternate macros
|
||||||
:c:macro:`PYBIND11_OVERLOAD_PURE_NAME` and :c:macro:`PYBIND11_OVERLOAD_NAME` which
|
:c:macro:`PYBIND11_OVERRIDE_PURE_NAME` and :c:macro:`PYBIND11_OVERRIDE_NAME` which
|
||||||
take a string-valued name argument between the *Parent class* and *Name of the
|
take a string-valued name argument between the *Parent class* and *Name of the
|
||||||
function* slots, which defines the name of function in Python. This is required
|
function* slots, which defines the name of function in Python. This is required
|
||||||
when the C++ and Python versions of the
|
when the C++ and Python versions of the
|
||||||
@ -122,7 +122,7 @@ Bindings should be made against the actual class, not the trampoline helper clas
|
|||||||
|
|
||||||
Note, however, that the above is sufficient for allowing python classes to
|
Note, however, that the above is sufficient for allowing python classes to
|
||||||
extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the
|
extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the
|
||||||
necessary steps required to providing proper overload support for inherited
|
necessary steps required to providing proper overriding support for inherited
|
||||||
classes.
|
classes.
|
||||||
|
|
||||||
The Python session below shows how to override ``Animal::go`` and invoke it via
|
The Python session below shows how to override ``Animal::go`` and invoke it via
|
||||||
@ -181,15 +181,24 @@ Please take a look at the :ref:`macro_notes` before using this feature.
|
|||||||
|
|
||||||
- because in these cases there is no C++ variable to reference (the value
|
- because in these cases there is no C++ variable to reference (the value
|
||||||
is stored in the referenced Python variable), pybind11 provides one in
|
is stored in the referenced Python variable), pybind11 provides one in
|
||||||
the PYBIND11_OVERLOAD macros (when needed) with static storage duration.
|
the PYBIND11_OVERRIDE macros (when needed) with static storage duration.
|
||||||
Note that this means that invoking the overloaded method on *any*
|
Note that this means that invoking the overridden method on *any*
|
||||||
instance will change the referenced value stored in *all* instances of
|
instance will change the referenced value stored in *all* instances of
|
||||||
that type.
|
that type.
|
||||||
|
|
||||||
- Attempts to modify a non-const reference will not have the desired
|
- Attempts to modify a non-const reference will not have the desired
|
||||||
effect: it will change only the static cache variable, but this change
|
effect: it will change only the static cache variable, but this change
|
||||||
will not propagate to underlying Python instance, and the change will be
|
will not propagate to underlying Python instance, and the change will be
|
||||||
replaced the next time the overload is invoked.
|
replaced the next time the override is invoked.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The :c:macro:`PYBIND11_OVERRIDE` and accompanying macros used to be called
|
||||||
|
``PYBIND11_OVERLOAD`` up until pybind11 v2.5.0, and :func:`get_override`
|
||||||
|
used to be called ``get_overload``. This naming was corrected and the older
|
||||||
|
macro and function names have been deprecated, in order to reduce confusion
|
||||||
|
with overloaded functions and methods and ``py::overload_cast`` (see
|
||||||
|
:ref:`classes`).
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
@ -237,20 +246,20 @@ override the ``name()`` method):
|
|||||||
class PyAnimal : public Animal {
|
class PyAnimal : public Animal {
|
||||||
public:
|
public:
|
||||||
using Animal::Animal; // Inherit constructors
|
using Animal::Animal; // Inherit constructors
|
||||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Animal, go, n_times); }
|
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Animal, go, n_times); }
|
||||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Animal, name, ); }
|
std::string name() override { PYBIND11_OVERRIDE(std::string, Animal, name, ); }
|
||||||
};
|
};
|
||||||
class PyDog : public Dog {
|
class PyDog : public Dog {
|
||||||
public:
|
public:
|
||||||
using Dog::Dog; // Inherit constructors
|
using Dog::Dog; // Inherit constructors
|
||||||
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, Dog, go, n_times); }
|
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, Dog, go, n_times); }
|
||||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Dog, name, ); }
|
std::string name() override { PYBIND11_OVERRIDE(std::string, Dog, name, ); }
|
||||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, Dog, bark, ); }
|
std::string bark() override { PYBIND11_OVERRIDE(std::string, Dog, bark, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Note the trailing commas in the ``PYBIND11_OVERLOAD`` calls to ``name()``
|
Note the trailing commas in the ``PYBIND11_OVERIDE`` calls to ``name()``
|
||||||
and ``bark()``. These are needed to portably implement a trampoline for a
|
and ``bark()``. These are needed to portably implement a trampoline for a
|
||||||
function that does not take any arguments. For functions that take
|
function that does not take any arguments. For functions that take
|
||||||
a nonzero number of arguments, the trailing comma must be omitted.
|
a nonzero number of arguments, the trailing comma must be omitted.
|
||||||
@ -265,9 +274,9 @@ declare or override any virtual methods itself:
|
|||||||
class PyHusky : public Husky {
|
class PyHusky : public Husky {
|
||||||
public:
|
public:
|
||||||
using Husky::Husky; // Inherit constructors
|
using Husky::Husky; // Inherit constructors
|
||||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Husky, go, n_times); }
|
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Husky, go, n_times); }
|
||||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Husky, name, ); }
|
std::string name() override { PYBIND11_OVERRIDE(std::string, Husky, name, ); }
|
||||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, Husky, bark, ); }
|
std::string bark() override { PYBIND11_OVERRIDE(std::string, Husky, bark, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
There is, however, a technique that can be used to avoid this duplication
|
There is, however, a technique that can be used to avoid this duplication
|
||||||
@ -280,15 +289,15 @@ follows:
|
|||||||
template <class AnimalBase = Animal> class PyAnimal : public AnimalBase {
|
template <class AnimalBase = Animal> class PyAnimal : public AnimalBase {
|
||||||
public:
|
public:
|
||||||
using AnimalBase::AnimalBase; // Inherit constructors
|
using AnimalBase::AnimalBase; // Inherit constructors
|
||||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, AnimalBase, go, n_times); }
|
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, AnimalBase, go, n_times); }
|
||||||
std::string name() override { PYBIND11_OVERLOAD(std::string, AnimalBase, name, ); }
|
std::string name() override { PYBIND11_OVERRIDE(std::string, AnimalBase, name, ); }
|
||||||
};
|
};
|
||||||
template <class DogBase = Dog> class PyDog : public PyAnimal<DogBase> {
|
template <class DogBase = Dog> class PyDog : public PyAnimal<DogBase> {
|
||||||
public:
|
public:
|
||||||
using PyAnimal<DogBase>::PyAnimal; // Inherit constructors
|
using PyAnimal<DogBase>::PyAnimal; // Inherit constructors
|
||||||
// Override PyAnimal's pure virtual go() with a non-pure one:
|
// Override PyAnimal's pure virtual go() with a non-pure one:
|
||||||
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, DogBase, go, n_times); }
|
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, DogBase, go, n_times); }
|
||||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, DogBase, bark, ); }
|
std::string bark() override { PYBIND11_OVERRIDE(std::string, DogBase, bark, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
This technique has the advantage of requiring just one trampoline method to be
|
This technique has the advantage of requiring just one trampoline method to be
|
||||||
@ -341,7 +350,7 @@ valid for the trampoline class but not the registered class. This is primarily
|
|||||||
for performance reasons: when the trampoline class is not needed for anything
|
for performance reasons: when the trampoline class is not needed for anything
|
||||||
except virtual method dispatching, not initializing the trampoline class
|
except virtual method dispatching, not initializing the trampoline class
|
||||||
improves performance by avoiding needing to do a run-time check to see if the
|
improves performance by avoiding needing to do a run-time check to see if the
|
||||||
inheriting python instance has an overloaded method.
|
inheriting python instance has an overridden method.
|
||||||
|
|
||||||
Sometimes, however, it is useful to always initialize a trampoline class as an
|
Sometimes, however, it is useful to always initialize a trampoline class as an
|
||||||
intermediate class that does more than just handle virtual method dispatching.
|
intermediate class that does more than just handle virtual method dispatching.
|
||||||
@ -372,7 +381,7 @@ references (See also :ref:`faq_reference_arguments`). Another way of solving
|
|||||||
this is to use the method body of the trampoline class to do conversions to the
|
this is to use the method body of the trampoline class to do conversions to the
|
||||||
input and return of the Python method.
|
input and return of the Python method.
|
||||||
|
|
||||||
The main building block to do so is the :func:`get_overload`, this function
|
The main building block to do so is the :func:`get_override`, this function
|
||||||
allows retrieving a method implemented in Python from within the trampoline's
|
allows retrieving a method implemented in Python from within the trampoline's
|
||||||
methods. Consider for example a C++ method which has the signature
|
methods. Consider for example a C++ method which has the signature
|
||||||
``bool myMethod(int32_t& value)``, where the return indicates whether
|
``bool myMethod(int32_t& value)``, where the return indicates whether
|
||||||
@ -384,10 +393,10 @@ Python side by allowing the Python function to return ``None`` or an ``int``:
|
|||||||
bool MyClass::myMethod(int32_t& value)
|
bool MyClass::myMethod(int32_t& value)
|
||||||
{
|
{
|
||||||
pybind11::gil_scoped_acquire gil; // Acquire the GIL while in this scope.
|
pybind11::gil_scoped_acquire gil; // Acquire the GIL while in this scope.
|
||||||
// Try to look up the overloaded method on the Python side.
|
// Try to look up the overridden method on the Python side.
|
||||||
pybind11::function overload = pybind11::get_overload(this, "myMethod");
|
pybind11::function override = pybind11::get_override(this, "myMethod");
|
||||||
if (overload) { // method is found
|
if (override) { // method is found
|
||||||
auto obj = overload(value); // Call the Python function.
|
auto obj = override(value); // Call the Python function.
|
||||||
if (py::isinstance<py::int_>(obj)) { // check if it returned a Python integer type
|
if (py::isinstance<py::int_>(obj)) { // check if it returned a Python integer type
|
||||||
value = obj.cast<int32_t>(); // Cast it and assign it to the value.
|
value = obj.cast<int32_t>(); // Cast it and assign it to the value.
|
||||||
return true; // Return true; value should be used.
|
return true; // Return true; value should be used.
|
||||||
@ -1104,7 +1113,7 @@ described trampoline:
|
|||||||
|
|
||||||
class Trampoline : public A {
|
class Trampoline : public A {
|
||||||
public:
|
public:
|
||||||
int foo() const override { PYBIND11_OVERLOAD(int, A, foo, ); }
|
int foo() const override { PYBIND11_OVERRIDE(int, A, foo, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Publicist : public A {
|
class Publicist : public A {
|
||||||
|
@ -7,14 +7,14 @@ General notes regarding convenience macros
|
|||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
pybind11 provides a few convenience macros such as
|
pybind11 provides a few convenience macros such as
|
||||||
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERLOAD_*``. Since these
|
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERRIDE_*``. Since these
|
||||||
are "just" macros that are evaluated in the preprocessor (which has no concept
|
are "just" macros that are evaluated in the preprocessor (which has no concept
|
||||||
of types), they *will* get confused by commas in a template argument; for
|
of types), they *will* get confused by commas in a template argument; for
|
||||||
example, consider:
|
example, consider:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
PYBIND11_OVERLOAD(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
PYBIND11_OVERRIDE(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
||||||
|
|
||||||
The limitation of the C preprocessor interprets this as five arguments (with new
|
The limitation of the C preprocessor interprets this as five arguments (with new
|
||||||
arguments beginning after each comma) rather than three. To get around this,
|
arguments beginning after each comma) rather than three. To get around this,
|
||||||
@ -26,10 +26,10 @@ using the ``PYBIND11_TYPE`` macro:
|
|||||||
// Version 1: using a type alias
|
// Version 1: using a type alias
|
||||||
using ReturnType = MyReturnType<T1, T2>;
|
using ReturnType = MyReturnType<T1, T2>;
|
||||||
using ClassType = Class<T3, T4>;
|
using ClassType = Class<T3, T4>;
|
||||||
PYBIND11_OVERLOAD(ReturnType, ClassType, func);
|
PYBIND11_OVERRIDE(ReturnType, ClassType, func);
|
||||||
|
|
||||||
// Version 2: using the PYBIND11_TYPE macro:
|
// Version 2: using the PYBIND11_TYPE macro:
|
||||||
PYBIND11_OVERLOAD(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
PYBIND11_OVERRIDE(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
||||||
PYBIND11_TYPE(Class<T3, T4>), func)
|
PYBIND11_TYPE(Class<T3, T4>), func)
|
||||||
|
|
||||||
The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
|
The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
|
||||||
@ -59,7 +59,7 @@ could be realized as follows (important changes highlighted):
|
|||||||
/* Acquire GIL before calling Python code */
|
/* Acquire GIL before calling Python code */
|
||||||
py::gil_scoped_acquire acquire;
|
py::gil_scoped_acquire acquire;
|
||||||
|
|
||||||
PYBIND11_OVERLOAD_PURE(
|
PYBIND11_OVERRIDE_PURE(
|
||||||
std::string, /* Return type */
|
std::string, /* Return type */
|
||||||
Animal, /* Parent class */
|
Animal, /* Parent class */
|
||||||
go, /* Name of function */
|
go, /* Name of function */
|
||||||
|
@ -62,6 +62,12 @@ See :ref:`upgrade-guide-2.6` for help upgrading to the new version.
|
|||||||
`#2265 <https://github.com/pybind/pybind11/pull/2265>`_ and
|
`#2265 <https://github.com/pybind/pybind11/pull/2265>`_ and
|
||||||
`#2346 <https://github.com/pybind/pybind11/pull/2346>`_
|
`#2346 <https://github.com/pybind/pybind11/pull/2346>`_
|
||||||
|
|
||||||
|
* ``PYBIND11_OVERLOAD*`` macros and ``get_overload`` function replaced by
|
||||||
|
correctly-named ``PYBIND11_OVERRIDE*`` and ``get_override``, fixing
|
||||||
|
inconsistencies in the presene of a closing ``;`` in these macros.
|
||||||
|
``get_type_overload`` is deprecated.
|
||||||
|
`#2325 <https://github.com/pybind/pybind11/pull/2325>`_
|
||||||
|
|
||||||
Smaller or developer focused features:
|
Smaller or developer focused features:
|
||||||
|
|
||||||
* Error now thrown when ``__init__`` is forgotten on subclasses.
|
* Error now thrown when ``__init__`` is forgotten on subclasses.
|
||||||
|
@ -91,15 +91,15 @@ Inheritance
|
|||||||
|
|
||||||
See :doc:`/classes` and :doc:`/advanced/classes` for more detail.
|
See :doc:`/classes` and :doc:`/advanced/classes` for more detail.
|
||||||
|
|
||||||
.. doxygendefine:: PYBIND11_OVERLOAD
|
.. doxygendefine:: PYBIND11_OVERRIDE
|
||||||
|
|
||||||
.. doxygendefine:: PYBIND11_OVERLOAD_PURE
|
.. doxygendefine:: PYBIND11_OVERRIDE_PURE
|
||||||
|
|
||||||
.. doxygendefine:: PYBIND11_OVERLOAD_NAME
|
.. doxygendefine:: PYBIND11_OVERRIDE_NAME
|
||||||
|
|
||||||
.. doxygendefine:: PYBIND11_OVERLOAD_PURE_NAME
|
.. doxygendefine:: PYBIND11_OVERRIDE_PURE_NAME
|
||||||
|
|
||||||
.. doxygenfunction:: get_overload
|
.. doxygenfunction:: get_override
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
==========
|
==========
|
||||||
|
@ -21,6 +21,10 @@ If ``__eq__`` defined but not ``__hash__``, ``__hash__`` is now set to
|
|||||||
``None``, as in normal CPython. You should add ``__hash__`` if you intended the
|
``None``, as in normal CPython. You should add ``__hash__`` if you intended the
|
||||||
class to be hashable, possibly using the new ``py::hash`` shortcut.
|
class to be hashable, possibly using the new ``py::hash`` shortcut.
|
||||||
|
|
||||||
|
Usage of the ``PYBIND11_OVERLOAD*`` macros and ``get_overload`` function should
|
||||||
|
be replaced by ``PYBIND11_OVERRIDE*`` and ``get_override``. In the future, the
|
||||||
|
old macros may be deprecated and removed.
|
||||||
|
|
||||||
CMake support:
|
CMake support:
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -1797,16 +1797,16 @@ PYBIND11_NAMESPACE_BEGIN(detail)
|
|||||||
template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
|
template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
|
||||||
object object_or_cast(T &&o) { return pybind11::cast(std::forward<T>(o)); }
|
object object_or_cast(T &&o) { return pybind11::cast(std::forward<T>(o)); }
|
||||||
|
|
||||||
struct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro
|
struct override_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the PYBIND11_OVERRIDE_OVERRIDE macro
|
||||||
template <typename ret_type> using overload_caster_t = conditional_t<
|
template <typename ret_type> using override_caster_t = conditional_t<
|
||||||
cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, overload_unused>;
|
cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, override_unused>;
|
||||||
|
|
||||||
// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
|
// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
|
||||||
// store the result in the given variable. For other types, this is a no-op.
|
// store the result in the given variable. For other types, this is a no-op.
|
||||||
template <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, make_caster<T> &caster) {
|
template <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, make_caster<T> &caster) {
|
||||||
return cast_op<T>(load_type(caster, o));
|
return cast_op<T>(load_type(caster, o));
|
||||||
}
|
}
|
||||||
template <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, overload_unused &) {
|
template <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, override_unused &) {
|
||||||
pybind11_fail("Internal error: cast_ref fallback invoked"); }
|
pybind11_fail("Internal error: cast_ref fallback invoked"); }
|
||||||
|
|
||||||
// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even
|
// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even
|
||||||
@ -2222,7 +2222,7 @@ type type::of() {
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
|
/// Lets you pass a type containing a `,` through a macro parameter without needing a separate
|
||||||
/// typedef, e.g.: `PYBIND11_OVERLOAD(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
|
/// typedef, e.g.: `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
|
||||||
#define PYBIND11_TYPE(...) __VA_ARGS__
|
#define PYBIND11_TYPE(...) __VA_ARGS__
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
@ -82,10 +82,10 @@ struct type_equal_to {
|
|||||||
template <typename value_type>
|
template <typename value_type>
|
||||||
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
|
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
|
||||||
|
|
||||||
struct overload_hash {
|
struct override_hash {
|
||||||
inline size_t operator()(const std::pair<const PyObject *, const char *>& v) const {
|
inline size_t operator()(const std::pair<const PyObject *, const char *>& v) const {
|
||||||
size_t value = std::hash<const void *>()(v.first);
|
size_t value = std::hash<const void *>()(v.first);
|
||||||
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2);
|
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -97,7 +97,7 @@ struct internals {
|
|||||||
type_map<type_info *> registered_types_cpp; // std::type_index -> pybind11's type information
|
type_map<type_info *> registered_types_cpp; // std::type_index -> pybind11's type information
|
||||||
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s)
|
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s)
|
||||||
std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance*
|
std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance*
|
||||||
std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
|
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash> inactive_override_cache;
|
||||||
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
|
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
|
||||||
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
|
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
|
||||||
std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators;
|
std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators;
|
||||||
|
@ -2110,21 +2110,22 @@ error_already_set::~error_already_set() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
handle self = detail::get_object_handle(this_ptr, this_type);
|
inline function get_type_override(const void *this_ptr, const type_info *this_type, const char *name) {
|
||||||
|
handle self = get_object_handle(this_ptr, this_type);
|
||||||
if (!self)
|
if (!self)
|
||||||
return function();
|
return function();
|
||||||
handle type = self.get_type();
|
handle type = self.get_type();
|
||||||
auto key = std::make_pair(type.ptr(), name);
|
auto key = std::make_pair(type.ptr(), name);
|
||||||
|
|
||||||
/* Cache functions that aren't overloaded in Python to avoid
|
/* Cache functions that aren't overridden in Python to avoid
|
||||||
many costly Python dictionary lookups below */
|
many costly Python dictionary lookups below */
|
||||||
auto &cache = detail::get_internals().inactive_overload_cache;
|
auto &cache = get_internals().inactive_override_cache;
|
||||||
if (cache.find(key) != cache.end())
|
if (cache.find(key) != cache.end())
|
||||||
return function();
|
return function();
|
||||||
|
|
||||||
function overload = getattr(self, name, function());
|
function override = getattr(self, name, function());
|
||||||
if (overload.is_cpp_function()) {
|
if (override.is_cpp_function()) {
|
||||||
cache.insert(key);
|
cache.insert(key);
|
||||||
return function();
|
return function();
|
||||||
}
|
}
|
||||||
@ -2164,34 +2165,36 @@ inline function get_type_overload(const void *this_ptr, const detail::type_info
|
|||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return overload;
|
return override;
|
||||||
}
|
}
|
||||||
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr.
|
Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr.
|
||||||
|
|
||||||
:this_ptr: The pointer to the object the overload should be retrieved for. This should be the first
|
:this_ptr: The pointer to the object the overriden method should be retrieved for. This should be
|
||||||
non-trampoline class encountered in the inheritance chain.
|
the first non-trampoline class encountered in the inheritance chain.
|
||||||
:name: The name of the overloaded Python method to retrieve.
|
:name: The name of the overridden Python method to retrieve.
|
||||||
:return: The Python method by this name from the object or an empty function wrapper.
|
:return: The Python method by this name from the object or an empty function wrapper.
|
||||||
\endrst */
|
\endrst */
|
||||||
template <class T> function get_overload(const T *this_ptr, const char *name) {
|
template <class T> function get_override(const T *this_ptr, const char *name) {
|
||||||
auto tinfo = detail::get_type_info(typeid(T));
|
auto tinfo = detail::get_type_info(typeid(T));
|
||||||
return tinfo ? get_type_overload(this_ptr, tinfo, name) : function();
|
return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \
|
#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...) \
|
||||||
|
do { \
|
||||||
pybind11::gil_scoped_acquire gil; \
|
pybind11::gil_scoped_acquire gil; \
|
||||||
pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \
|
pybind11::function override = pybind11::get_override(static_cast<const cname *>(this), name); \
|
||||||
if (overload) { \
|
if (override) { \
|
||||||
auto o = overload(__VA_ARGS__); \
|
auto o = override(__VA_ARGS__); \
|
||||||
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
|
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
|
||||||
static pybind11::detail::overload_caster_t<ret_type> caster; \
|
static pybind11::detail::override_caster_t<ret_type> caster; \
|
||||||
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
||||||
} \
|
} \
|
||||||
else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
||||||
} \
|
} \
|
||||||
}
|
} while (false)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn'
|
Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn'
|
||||||
@ -2202,7 +2205,7 @@ template <class T> function get_overload(const T *this_ptr, const char *name) {
|
|||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
std::string toString() override {
|
std::string toString() override {
|
||||||
PYBIND11_OVERLOAD_NAME(
|
PYBIND11_OVERRIDE_NAME(
|
||||||
std::string, // Return type (ret_type)
|
std::string, // Return type (ret_type)
|
||||||
Animal, // Parent class (cname)
|
Animal, // Parent class (cname)
|
||||||
"__str__", // Name of method in Python (name)
|
"__str__", // Name of method in Python (name)
|
||||||
@ -2210,17 +2213,21 @@ template <class T> function get_overload(const T *this_ptr, const char *name) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
\endrst */
|
\endrst */
|
||||||
#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
|
#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...) \
|
||||||
PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
|
do { \
|
||||||
return cname::fn(__VA_ARGS__)
|
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
|
||||||
|
return cname::fn(__VA_ARGS__); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD_NAME`, except that it
|
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it
|
||||||
throws if no overload can be found.
|
throws if no override can be found.
|
||||||
\endrst */
|
\endrst */
|
||||||
#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
|
#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \
|
||||||
PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
|
do { \
|
||||||
pybind11::pybind11_fail("Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\"");
|
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
|
||||||
|
pybind11::pybind11_fail("Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\""); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
Macro to populate the virtual method in the trampoline class. This macro tries to look up the method
|
Macro to populate the virtual method in the trampoline class. This macro tries to look up the method
|
||||||
@ -2237,7 +2244,7 @@ template <class T> function get_overload(const T *this_ptr, const char *name) {
|
|||||||
|
|
||||||
// Trampoline (need one for each virtual function)
|
// Trampoline (need one for each virtual function)
|
||||||
std::string go(int n_times) override {
|
std::string go(int n_times) override {
|
||||||
PYBIND11_OVERLOAD_PURE(
|
PYBIND11_OVERRIDE_PURE(
|
||||||
std::string, // Return type (ret_type)
|
std::string, // Return type (ret_type)
|
||||||
Animal, // Parent class (cname)
|
Animal, // Parent class (cname)
|
||||||
go, // Name of function in C++ (must match Python name) (fn)
|
go, // Name of function in C++ (must match Python name) (fn)
|
||||||
@ -2246,15 +2253,39 @@ template <class T> function get_overload(const T *this_ptr, const char *name) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
\endrst */
|
\endrst */
|
||||||
#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
|
#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...) \
|
||||||
PYBIND11_OVERLOAD_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD`, except that it throws
|
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`, except that it throws
|
||||||
if no overload can be found.
|
if no override can be found.
|
||||||
\endrst */
|
\endrst */
|
||||||
|
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \
|
||||||
|
PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
// Deprecated versions
|
||||||
|
|
||||||
|
PYBIND11_DEPRECATED("get_type_overload has been deprecated")
|
||||||
|
inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
|
||||||
|
return detail::get_type_override(this_ptr, this_type, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline function get_overload(const T *this_ptr, const char *name) {
|
||||||
|
return get_override(this_ptr, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) \
|
||||||
|
PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)
|
||||||
|
#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
|
||||||
|
PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)
|
||||||
|
#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
|
||||||
|
PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);
|
||||||
|
#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
|
||||||
|
PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)
|
||||||
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \
|
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \
|
||||||
PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
|
PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ TEST_SUBMODULE(class_, m) {
|
|||||||
|
|
||||||
class TrampolineB : public ProtectedB {
|
class TrampolineB : public ProtectedB {
|
||||||
public:
|
public:
|
||||||
int foo() const override { PYBIND11_OVERLOAD(int, ProtectedB, foo, ); }
|
int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class PublicistB : public ProtectedB {
|
class PublicistB : public ProtectedB {
|
||||||
|
@ -30,7 +30,7 @@ private:
|
|||||||
class PyWidget final : public Widget {
|
class PyWidget final : public Widget {
|
||||||
using Widget::Widget;
|
using Widget::Widget;
|
||||||
|
|
||||||
int the_answer() const override { PYBIND11_OVERLOAD_PURE(int, Widget, the_answer); }
|
int the_answer() const override { PYBIND11_OVERRIDE_PURE(int, Widget, the_answer); }
|
||||||
};
|
};
|
||||||
|
|
||||||
PYBIND11_EMBEDDED_MODULE(widget_module, m) {
|
PYBIND11_EMBEDDED_MODULE(widget_module, m) {
|
||||||
|
@ -89,7 +89,7 @@ public:
|
|||||||
PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); }
|
PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); }
|
||||||
PyTF6(std::string s) : TestFactory6((int) s.size()) { alias = true; print_created(this, s); }
|
PyTF6(std::string s) : TestFactory6((int) s.size()) { alias = true; print_created(this, s); }
|
||||||
virtual ~PyTF6() { print_destroyed(this); }
|
virtual ~PyTF6() { print_destroyed(this); }
|
||||||
int get() override { PYBIND11_OVERLOAD(int, TestFactory6, get, /*no args*/); }
|
int get() override { PYBIND11_OVERRIDE(int, TestFactory6, get, /*no args*/); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestFactory7 {
|
class TestFactory7 {
|
||||||
@ -110,7 +110,7 @@ public:
|
|||||||
PyTF7(PyTF7 &&f) : TestFactory7(std::move(f)) { print_move_created(this); }
|
PyTF7(PyTF7 &&f) : TestFactory7(std::move(f)) { print_move_created(this); }
|
||||||
PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); }
|
PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); }
|
||||||
virtual ~PyTF7() { print_destroyed(this); }
|
virtual ~PyTF7() { print_destroyed(this); }
|
||||||
int get() override { PYBIND11_OVERLOAD(int, TestFactory7, get, /*no args*/); }
|
int get() override { PYBIND11_OVERRIDE(int, TestFactory7, get, /*no args*/); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,10 +22,10 @@ public:
|
|||||||
|
|
||||||
class PyVirtClass : public VirtClass {
|
class PyVirtClass : public VirtClass {
|
||||||
void virtual_func() override {
|
void virtual_func() override {
|
||||||
PYBIND11_OVERLOAD(void, VirtClass, virtual_func,);
|
PYBIND11_OVERRIDE(void, VirtClass, virtual_func,);
|
||||||
}
|
}
|
||||||
void pure_virtual_func() override {
|
void pure_virtual_func() override {
|
||||||
PYBIND11_OVERLOAD_PURE(void, VirtClass, pure_virtual_func,);
|
PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func,);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
int run(int value) override {
|
int run(int value) override {
|
||||||
/* Generate wrapping code that enables native function overloading */
|
/* Generate wrapping code that enables native function overloading */
|
||||||
PYBIND11_OVERLOAD(
|
PYBIND11_OVERRIDE(
|
||||||
int, /* Return type */
|
int, /* Return type */
|
||||||
ExampleVirt, /* Parent class */
|
ExampleVirt, /* Parent class */
|
||||||
run, /* Name of function */
|
run, /* Name of function */
|
||||||
@ -56,7 +56,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool run_bool() override {
|
bool run_bool() override {
|
||||||
PYBIND11_OVERLOAD_PURE(
|
PYBIND11_OVERRIDE_PURE(
|
||||||
bool, /* Return type */
|
bool, /* Return type */
|
||||||
ExampleVirt, /* Parent class */
|
ExampleVirt, /* Parent class */
|
||||||
run_bool, /* Name of function */
|
run_bool, /* Name of function */
|
||||||
@ -66,7 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pure_virtual() override {
|
void pure_virtual() override {
|
||||||
PYBIND11_OVERLOAD_PURE(
|
PYBIND11_OVERRIDE_PURE(
|
||||||
void, /* Return type */
|
void, /* Return type */
|
||||||
ExampleVirt, /* Parent class */
|
ExampleVirt, /* Parent class */
|
||||||
pure_virtual, /* Name of function */
|
pure_virtual, /* Name of function */
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
// We can return reference types for compatibility with C++ virtual interfaces that do so, but
|
// We can return reference types for compatibility with C++ virtual interfaces that do so, but
|
||||||
// note they have some significant limitations (see the documentation).
|
// note they have some significant limitations (see the documentation).
|
||||||
const std::string &get_string1() override {
|
const std::string &get_string1() override {
|
||||||
PYBIND11_OVERLOAD(
|
PYBIND11_OVERRIDE(
|
||||||
const std::string &, /* Return type */
|
const std::string &, /* Return type */
|
||||||
ExampleVirt, /* Parent class */
|
ExampleVirt, /* Parent class */
|
||||||
get_string1, /* Name of function */
|
get_string1, /* Name of function */
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::string *get_string2() override {
|
const std::string *get_string2() override {
|
||||||
PYBIND11_OVERLOAD(
|
PYBIND11_OVERRIDE(
|
||||||
const std::string *, /* Return type */
|
const std::string *, /* Return type */
|
||||||
ExampleVirt, /* Parent class */
|
ExampleVirt, /* Parent class */
|
||||||
get_string2, /* Name of function */
|
get_string2, /* Name of function */
|
||||||
@ -141,11 +141,11 @@ public:
|
|||||||
class NCVirtTrampoline : public NCVirt {
|
class NCVirtTrampoline : public NCVirt {
|
||||||
#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
|
#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)
|
||||||
NonCopyable get_noncopyable(int a, int b) override {
|
NonCopyable get_noncopyable(int a, int b) override {
|
||||||
PYBIND11_OVERLOAD(NonCopyable, NCVirt, get_noncopyable, a, b);
|
PYBIND11_OVERRIDE(NonCopyable, NCVirt, get_noncopyable, a, b);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Movable get_movable(int a, int b) override {
|
Movable get_movable(int a, int b) override {
|
||||||
PYBIND11_OVERLOAD_PURE(Movable, NCVirt, get_movable, a, b);
|
PYBIND11_OVERRIDE_PURE(Movable, NCVirt, get_movable, a, b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ struct Base {
|
|||||||
|
|
||||||
struct DispatchIssue : Base {
|
struct DispatchIssue : Base {
|
||||||
virtual std::string dispatch() const {
|
virtual std::string dispatch() const {
|
||||||
PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */);
|
PYBIND11_OVERRIDE_PURE(std::string, Base, dispatch, /* no arguments */);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ TEST_SUBMODULE(virtual_functions, m) {
|
|||||||
py::print("PyA.f()");
|
py::print("PyA.f()");
|
||||||
// This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to protect
|
// This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to protect
|
||||||
// a type containing a ,
|
// a type containing a ,
|
||||||
PYBIND11_OVERLOAD(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);
|
PYBIND11_OVERRIDE(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ TEST_SUBMODULE(virtual_functions, m) {
|
|||||||
~PyA2() { py::print("PyA2.~PyA2()"); }
|
~PyA2() { py::print("PyA2.~PyA2()"); }
|
||||||
void f() override {
|
void f() override {
|
||||||
py::print("PyA2.f()");
|
py::print("PyA2.f()");
|
||||||
PYBIND11_OVERLOAD(void, A2, f);
|
PYBIND11_OVERRIDE(void, A2, f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -304,19 +304,19 @@ TEST_SUBMODULE(virtual_functions, m) {
|
|||||||
class PyOverrideTest : public OverrideTest {
|
class PyOverrideTest : public OverrideTest {
|
||||||
public:
|
public:
|
||||||
using OverrideTest::OverrideTest;
|
using OverrideTest::OverrideTest;
|
||||||
std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); }
|
std::string str_value() override { PYBIND11_OVERRIDE(std::string, OverrideTest, str_value); }
|
||||||
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
|
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
|
||||||
// to a python numeric value, since we only copy values in the numeric type caster:
|
// to a python numeric value, since we only copy values in the numeric type caster:
|
||||||
// std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
|
// std::string &str_ref() override { PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref); }
|
||||||
// But we can work around it like this:
|
// But we can work around it like this:
|
||||||
private:
|
private:
|
||||||
std::string _tmp;
|
std::string _tmp;
|
||||||
std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); }
|
std::string str_ref_helper() { PYBIND11_OVERRIDE(std::string, OverrideTest, str_ref); }
|
||||||
public:
|
public:
|
||||||
std::string &str_ref() override { return _tmp = str_ref_helper(); }
|
std::string &str_ref() override { return _tmp = str_ref_helper(); }
|
||||||
|
|
||||||
A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
|
A A_value() override { PYBIND11_OVERRIDE(A, OverrideTest, A_value); }
|
||||||
A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
|
A &A_ref() override { PYBIND11_OVERRIDE(A &, OverrideTest, A_ref); }
|
||||||
};
|
};
|
||||||
|
|
||||||
py::class_<OverrideTest::A>(m, "OverrideTest_A")
|
py::class_<OverrideTest::A>(m, "OverrideTest_A")
|
||||||
@ -393,29 +393,29 @@ class D_Tpl : public C_Tpl { D_METHODS };
|
|||||||
class PyA_Repeat : public A_Repeat {
|
class PyA_Repeat : public A_Repeat {
|
||||||
public:
|
public:
|
||||||
using A_Repeat::A_Repeat;
|
using A_Repeat::A_Repeat;
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, A_Repeat, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, A_Repeat, unlucky_number, ); }
|
||||||
std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, A_Repeat, say_something, times); }
|
std::string say_something(unsigned times) override { PYBIND11_OVERRIDE(std::string, A_Repeat, say_something, times); }
|
||||||
};
|
};
|
||||||
class PyB_Repeat : public B_Repeat {
|
class PyB_Repeat : public B_Repeat {
|
||||||
public:
|
public:
|
||||||
using B_Repeat::B_Repeat;
|
using B_Repeat::B_Repeat;
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD(int, B_Repeat, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE(int, B_Repeat, unlucky_number, ); }
|
||||||
std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, B_Repeat, say_something, times); }
|
std::string say_something(unsigned times) override { PYBIND11_OVERRIDE(std::string, B_Repeat, say_something, times); }
|
||||||
double lucky_number() override { PYBIND11_OVERLOAD(double, B_Repeat, lucky_number, ); }
|
double lucky_number() override { PYBIND11_OVERRIDE(double, B_Repeat, lucky_number, ); }
|
||||||
};
|
};
|
||||||
class PyC_Repeat : public C_Repeat {
|
class PyC_Repeat : public C_Repeat {
|
||||||
public:
|
public:
|
||||||
using C_Repeat::C_Repeat;
|
using C_Repeat::C_Repeat;
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD(int, C_Repeat, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE(int, C_Repeat, unlucky_number, ); }
|
||||||
std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, C_Repeat, say_something, times); }
|
std::string say_something(unsigned times) override { PYBIND11_OVERRIDE(std::string, C_Repeat, say_something, times); }
|
||||||
double lucky_number() override { PYBIND11_OVERLOAD(double, C_Repeat, lucky_number, ); }
|
double lucky_number() override { PYBIND11_OVERRIDE(double, C_Repeat, lucky_number, ); }
|
||||||
};
|
};
|
||||||
class PyD_Repeat : public D_Repeat {
|
class PyD_Repeat : public D_Repeat {
|
||||||
public:
|
public:
|
||||||
using D_Repeat::D_Repeat;
|
using D_Repeat::D_Repeat;
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD(int, D_Repeat, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE(int, D_Repeat, unlucky_number, ); }
|
||||||
std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, D_Repeat, say_something, times); }
|
std::string say_something(unsigned times) override { PYBIND11_OVERRIDE(std::string, D_Repeat, say_something, times); }
|
||||||
double lucky_number() override { PYBIND11_OVERLOAD(double, D_Repeat, lucky_number, ); }
|
double lucky_number() override { PYBIND11_OVERRIDE(double, D_Repeat, lucky_number, ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inheritance approach 2: templated trampoline classes.
|
// Inheritance approach 2: templated trampoline classes.
|
||||||
@ -436,15 +436,15 @@ template <class Base = A_Tpl>
|
|||||||
class PyA_Tpl : public Base {
|
class PyA_Tpl : public Base {
|
||||||
public:
|
public:
|
||||||
using Base::Base; // Inherit constructors
|
using Base::Base; // Inherit constructors
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, Base, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, Base, unlucky_number, ); }
|
||||||
std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, Base, say_something, times); }
|
std::string say_something(unsigned times) override { PYBIND11_OVERRIDE(std::string, Base, say_something, times); }
|
||||||
};
|
};
|
||||||
template <class Base = B_Tpl>
|
template <class Base = B_Tpl>
|
||||||
class PyB_Tpl : public PyA_Tpl<Base> {
|
class PyB_Tpl : public PyA_Tpl<Base> {
|
||||||
public:
|
public:
|
||||||
using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)
|
using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)
|
||||||
int unlucky_number() override { PYBIND11_OVERLOAD(int, Base, unlucky_number, ); }
|
int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }
|
||||||
double lucky_number() override { PYBIND11_OVERLOAD(double, Base, lucky_number, ); }
|
double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }
|
||||||
};
|
};
|
||||||
// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can
|
// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can
|
||||||
// use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):
|
// use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):
|
||||||
|
Loading…
Reference in New Issue
Block a user