mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
Make overload_cast_impl
available in C++11 mode. (#1581)
* Make `overload_cast_impl` available in C++11 mode. Narrow the scope of the `#if defined(PYBIND11_CPP14)` block around overload_cast to only cover the parts where C++14 is stricly required. Thus, the implementation in `pybind11::details::overload_cast_impl` is still available in C++11 mode. * PR #1581: Modify test to use overload_cast_impl, update docs and change log
This commit is contained in:
parent
04c8f4b56e
commit
19189b4c2c
@ -10,7 +10,9 @@ Starting with version 1.8.0, pybind11 releases use a `semantic versioning
|
|||||||
v2.3.1 (Not yet released)
|
v2.3.1 (Not yet released)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
* TBA
|
* ``py::details::overload_cast_impl`` is available in C++11 mode, can be used
|
||||||
|
like ``overload_cast`` with an additional set of parantheses.
|
||||||
|
`1581 <https://github.com/pybind/pybind11/pull/1581>`_.
|
||||||
|
|
||||||
v2.3.0 (June 11, 2019)
|
v2.3.0 (June 11, 2019)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
@ -105,7 +107,6 @@ v2.3.0 (June 11, 2019)
|
|||||||
`#1744 <https://github.com/pybind/pybind11/pull/1744>`_,
|
`#1744 <https://github.com/pybind/pybind11/pull/1744>`_,
|
||||||
`#1670 <https://github.com/pybind/pybind11/pull/1670>`_.
|
`#1670 <https://github.com/pybind/pybind11/pull/1670>`_.
|
||||||
|
|
||||||
|
|
||||||
v2.2.4 (September 11, 2018)
|
v2.2.4 (September 11, 2018)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
@ -422,6 +422,17 @@ on constness, the ``py::const_`` tag should be used:
|
|||||||
.def("foo_mutable", py::overload_cast<int, float>(&Widget::foo))
|
.def("foo_mutable", py::overload_cast<int, float>(&Widget::foo))
|
||||||
.def("foo_const", py::overload_cast<int, float>(&Widget::foo, py::const_));
|
.def("foo_const", py::overload_cast<int, float>(&Widget::foo, py::const_));
|
||||||
|
|
||||||
|
If you prefer the ``py::overload_cast`` syntax but have a C++11 compatible compiler only,
|
||||||
|
you can use ``py::detail::overload_cast_impl`` with an additional set of parentheses:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;
|
||||||
|
|
||||||
|
py::class_<Pet>(m, "Pet")
|
||||||
|
.def("set", overload_cast_<int>()(&Pet::set), "Set the pet's age")
|
||||||
|
.def("set", overload_cast_<const std::string &>()(&Pet::set), "Set the pet's name");
|
||||||
|
|
||||||
.. [#cpp14] A compiler which supports the ``-std=c++14`` flag
|
.. [#cpp14] A compiler which supports the ``-std=c++14`` flag
|
||||||
or Visual Studio 2015 Update 2 and newer.
|
or Visual Studio 2015 Update 2 and newer.
|
||||||
|
@ -720,10 +720,6 @@ struct error_scope {
|
|||||||
/// Dummy destructor wrapper that can be used to expose classes with a private destructor
|
/// Dummy destructor wrapper that can be used to expose classes with a private destructor
|
||||||
struct nodelete { template <typename T> void operator()(T*) { } };
|
struct nodelete { template <typename T> void operator()(T*) { } };
|
||||||
|
|
||||||
// overload_cast requires variable templates: C++14
|
|
||||||
#if defined(PYBIND11_CPP14)
|
|
||||||
#define PYBIND11_OVERLOAD_CAST 1
|
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
struct overload_cast_impl {
|
struct overload_cast_impl {
|
||||||
@ -743,19 +739,23 @@ struct overload_cast_impl {
|
|||||||
};
|
};
|
||||||
NAMESPACE_END(detail)
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
|
// overload_cast requires variable templates: C++14
|
||||||
|
#if defined(PYBIND11_CPP14)
|
||||||
|
#define PYBIND11_OVERLOAD_CAST 1
|
||||||
/// Syntax sugar for resolving overloaded function pointers:
|
/// Syntax sugar for resolving overloaded function pointers:
|
||||||
/// - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
|
/// - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
|
||||||
/// - sweet: overload_cast<Arg0, Arg1, Arg2>(&Class::func)
|
/// - sweet: overload_cast<Arg0, Arg1, Arg2>(&Class::func)
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
static constexpr detail::overload_cast_impl<Args...> overload_cast = {};
|
static constexpr detail::overload_cast_impl<Args...> overload_cast = {};
|
||||||
// MSVC 2015 only accepts this particular initialization syntax for this variable template.
|
// MSVC 2015 only accepts this particular initialization syntax for this variable template.
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Const member function selector for overload_cast
|
/// Const member function selector for overload_cast
|
||||||
/// - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
|
/// - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
|
||||||
/// - sweet: overload_cast<Arg>(&Class::func, const_)
|
/// - sweet: overload_cast<Arg>(&Class::func, const_)
|
||||||
static constexpr auto const_ = std::true_type{};
|
static constexpr auto const_ = std::true_type{};
|
||||||
|
|
||||||
#else // no overload_cast: providing something that static_assert-fails:
|
#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails:
|
||||||
template <typename... Args> struct overload_cast {
|
template <typename... Args> struct overload_cast {
|
||||||
static_assert(detail::deferred_t<std::false_type, Args...>::value,
|
static_assert(detail::deferred_t<std::false_type, Args...>::value,
|
||||||
"pybind11::overload_cast<...> requires compiling in C++14 mode");
|
"pybind11::overload_cast<...> requires compiling in C++14 mode");
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
#include "pybind11_tests.h"
|
#include "pybind11_tests.h"
|
||||||
#include "constructor_stats.h"
|
#include "constructor_stats.h"
|
||||||
|
|
||||||
|
#if !defined(PYBIND11_OVERLOAD_CAST)
|
||||||
|
template <typename... Args>
|
||||||
|
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;
|
||||||
|
#endif
|
||||||
|
|
||||||
class ExampleMandA {
|
class ExampleMandA {
|
||||||
public:
|
public:
|
||||||
ExampleMandA() { print_default_created(this); }
|
ExampleMandA() { print_default_created(this); }
|
||||||
@ -242,15 +247,16 @@ TEST_SUBMODULE(methods_and_attributes, m) {
|
|||||||
.def("overloaded_const", py::overload_cast<int, int>(&ExampleMandA::overloaded, py::const_))
|
.def("overloaded_const", py::overload_cast<int, int>(&ExampleMandA::overloaded, py::const_))
|
||||||
.def("overloaded_const", py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))
|
.def("overloaded_const", py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))
|
||||||
#else
|
#else
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)()>(&ExampleMandA::overloaded))
|
// Use both the traditional static_cast method and the C++11 compatible overload_cast_
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)(int)>(&ExampleMandA::overloaded))
|
.def("overloaded", overload_cast_<>()(&ExampleMandA::overloaded))
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)(int, float)>(&ExampleMandA::overloaded))
|
.def("overloaded", overload_cast_<int>()(&ExampleMandA::overloaded))
|
||||||
|
.def("overloaded", overload_cast_<int, float>()(&ExampleMandA::overloaded))
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)(float, int)>(&ExampleMandA::overloaded))
|
.def("overloaded", static_cast<py::str (ExampleMandA::*)(float, int)>(&ExampleMandA::overloaded))
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded))
|
.def("overloaded", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded))
|
||||||
.def("overloaded", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
|
.def("overloaded", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
|
||||||
.def("overloaded_float", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))
|
.def("overloaded_float", overload_cast_<float, float>()(&ExampleMandA::overloaded))
|
||||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int ) const>(&ExampleMandA::overloaded))
|
.def("overloaded_const", overload_cast_<int >()(&ExampleMandA::overloaded, py::const_))
|
||||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, float) const>(&ExampleMandA::overloaded))
|
.def("overloaded_const", overload_cast_<int, float>()(&ExampleMandA::overloaded, py::const_))
|
||||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, int) const>(&ExampleMandA::overloaded))
|
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, int) const>(&ExampleMandA::overloaded))
|
||||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, int) const>(&ExampleMandA::overloaded))
|
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, int) const>(&ExampleMandA::overloaded))
|
||||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))
|
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))
|
||||||
|
Loading…
Reference in New Issue
Block a user