-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copying files as-is from pybind/pybind11#2834
The PR will be closed. Using this repo as attic. Original git log: ``` commit 7fe7c96ad47f1e289f23a779566ec9ad3207a0af Author: Ralf W. Grosse-Kunstleve <[email protected]> Date: Mon Mar 8 11:38:40 2021 -0800 Tracing CpCtor, MvCtor, removing smart-pointer casters, renaming, more comments. commit 64abe68d7236725825a545f15891e8ee683e45a9 Author: Ralf W. Grosse-Kunstleve <[email protected]> Date: Fri Jan 29 14:00:26 2021 -0800 Adding comment, simplifying naming, cmake addition. commit 7c1471ea612ed9a72c6559ba515c86ba6255f28f Author: Ralf W. Grosse-Kunstleve <[email protected]> Date: Fri Jan 29 13:42:52 2021 -0800 Copying files as-is from branch test_unique_ptr_member (PR #2672). ```
- Loading branch information
Ralf W. Grosse-Kunstleve
committed
Jul 2, 2021
1 parent
6afa5a2
commit faec6cb
Showing
2 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copied as-is from https://github.com/pybind/pybind11/pull/2834 | ||
|
||
// Systematically exercises the detail::type_caster<> interface. This is going a step in the | ||
// direction of an integration test, to ensure multiple components of pybind11 work together | ||
// correctly. It is also useful to show the type_caster<> interface virtually clutter-free. | ||
|
||
// The entire type_caster load logic is intentionally omitted. The only purpose of this test is to | ||
// trace the behavior of the `static handle cast()` functions and the type_caster `operator`s. | ||
// Variable names are intentionally terse, to not distract from the more important function | ||
// signatures: valu(e), ref(erence), ptr (pointer), r = rvalue, m = mutable, c = const. | ||
|
||
#include "pybind11_tests.h" | ||
|
||
#include <string> | ||
|
||
namespace pybind11_tests { | ||
namespace type_caster_bare_interface { | ||
|
||
struct atyp { // Short for "any type". | ||
std::string trace; | ||
atyp() : trace("default") {} | ||
atyp(atyp const &other) { trace = other.trace + "_CpCtor"; } | ||
atyp(atyp &&other) { trace = other.trace + "_MvCtor"; } | ||
}; | ||
|
||
// clang-format off | ||
|
||
atyp rtrn_valu() { static atyp obj; obj.trace = "valu"; return obj; } | ||
atyp&& rtrn_rref() { static atyp obj; obj.trace = "rref"; return std::move(obj); } | ||
atyp const& rtrn_cref() { static atyp obj; obj.trace = "cref"; return obj; } | ||
atyp& rtrn_mref() { static atyp obj; obj.trace = "mref"; return obj; } | ||
atyp const* rtrn_cptr() { static atyp obj; obj.trace = "cptr"; return &obj; } | ||
atyp* rtrn_mptr() { static atyp obj; obj.trace = "mptr"; return &obj; } | ||
|
||
std::string pass_valu(atyp obj) { return "pass_valu:" + obj.trace; } | ||
std::string pass_rref(atyp&& obj) { return "pass_rref:" + obj.trace; } | ||
std::string pass_cref(atyp const& obj) { return "pass_cref:" + obj.trace; } | ||
std::string pass_mref(atyp& obj) { return "pass_mref:" + obj.trace; } | ||
std::string pass_cptr(atyp const* obj) { return "pass_cptr:" + obj->trace; } | ||
std::string pass_mptr(atyp* obj) { return "pass_mptr:" + obj->trace; } | ||
|
||
// clang-format on | ||
|
||
} // namespace type_caster_bare_interface | ||
} // namespace pybind11_tests | ||
|
||
namespace pybind11 { | ||
namespace detail { | ||
|
||
using namespace pybind11_tests::type_caster_bare_interface; | ||
|
||
template <> | ||
struct type_caster<atyp> { | ||
static constexpr auto name = _<atyp>(); | ||
|
||
// static handle cast(atyp, ...) | ||
// is redundant (leads to ambiguous overloads). | ||
|
||
static handle cast(atyp &&src, return_value_policy /*policy*/, handle /*parent*/) { | ||
return str("cast_rref:" + src.trace).release(); | ||
} | ||
|
||
static handle cast(atyp const &src, return_value_policy /*policy*/, handle /*parent*/) { | ||
return str("cast_cref:" + src.trace).release(); | ||
} | ||
|
||
static handle cast(atyp &src, return_value_policy /*policy*/, handle /*parent*/) { | ||
return str("cast_mref:" + src.trace).release(); | ||
} | ||
|
||
static handle cast(atyp const *src, return_value_policy /*policy*/, handle /*parent*/) { | ||
return str("cast_cptr:" + src->trace).release(); | ||
} | ||
|
||
static handle cast(atyp *src, return_value_policy /*policy*/, handle /*parent*/) { | ||
return str("cast_mptr:" + src->trace).release(); | ||
} | ||
|
||
template <typename T_> | ||
using cast_op_type = conditional_t< | ||
std::is_same<remove_reference_t<T_>, atyp const *>::value, | ||
atyp const *, | ||
conditional_t< | ||
std::is_same<remove_reference_t<T_>, atyp *>::value, | ||
atyp *, | ||
conditional_t< | ||
std::is_same<T_, atyp const &>::value, | ||
atyp const &, | ||
conditional_t<std::is_same<T_, atyp &>::value, | ||
atyp &, | ||
conditional_t<std::is_same<T_, atyp &&>::value, atyp &&, atyp>>>>>; | ||
|
||
// clang-format off | ||
|
||
operator atyp() { static atyp obj; obj.trace = "valu"; return obj; } | ||
operator atyp&&() { static atyp obj; obj.trace = "rref"; return std::move(obj); } | ||
operator atyp const&() { static atyp obj; obj.trace = "cref"; return obj; } | ||
operator atyp&() { static atyp obj; obj.trace = "mref"; return obj; } | ||
operator atyp const*() { static atyp obj; obj.trace = "cptr"; return &obj; } | ||
operator atyp*() { static atyp obj; obj.trace = "mptr"; return &obj; } | ||
|
||
// clang-format on | ||
|
||
// The entire load logic is intentionally omitted. | ||
bool load(handle /*src*/, bool /*convert*/) { return true; } | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace pybind11 | ||
|
||
TEST_SUBMODULE(type_caster_bare_interface, m) { | ||
namespace py = pybind11; | ||
using namespace pybind11_tests::type_caster_bare_interface; | ||
|
||
m.def("rtrn_valu", rtrn_valu); | ||
m.def("rtrn_rref", rtrn_rref); | ||
m.def("rtrn_cref", rtrn_cref); | ||
m.def("rtrn_mref", rtrn_mref); | ||
m.def("rtrn_cptr", rtrn_cptr); | ||
m.def("rtrn_mptr", rtrn_mptr); | ||
|
||
m.def("pass_valu", pass_valu); | ||
m.def("pass_rref", pass_rref); | ||
m.def("pass_cref", pass_cref); | ||
m.def("pass_mref", pass_mref); | ||
m.def("pass_cptr", pass_cptr); | ||
m.def("pass_mptr", pass_mptr); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copied as-is from https://github.com/pybind/pybind11/pull/2834 | ||
import re | ||
|
||
import pytest | ||
|
||
from pybind11_tests import type_caster_bare_interface as m | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"rtrn_f, expected", | ||
[ | ||
(m.rtrn_valu, "cast_rref:valu_CpCtor"), | ||
(m.rtrn_rref, "cast_rref:rref"), | ||
(m.rtrn_cref, "cast_cref:cref"), | ||
(m.rtrn_mref, "cast_mref:mref"), | ||
(m.rtrn_cptr, "cast_cptr:cptr"), | ||
(m.rtrn_mptr, "cast_mptr:mptr"), | ||
], | ||
) | ||
def test_cast(rtrn_f, expected): | ||
assert re.match(expected, rtrn_f()) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"pass_f, expected", | ||
[ | ||
(m.pass_valu, "pass_valu:rref_MvCtor"), | ||
(m.pass_rref, "pass_rref:rref"), | ||
(m.pass_cref, "pass_cref:cref"), | ||
(m.pass_mref, "pass_mref:mref"), | ||
(m.pass_cptr, "pass_cptr:cptr"), | ||
(m.pass_mptr, "pass_mptr:mptr"), | ||
], | ||
) | ||
def test_operator(pass_f, expected): | ||
assert re.match(expected, pass_f(None)) |