Attempts to side-step various platform-specific issues.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-06-20 09:45:39 -07:00 committed by Ralf W. Grosse-Kunstleve
parent 6214137c8d
commit e04196e82b
2 changed files with 25 additions and 13 deletions

View File

@ -13,15 +13,22 @@ namespace {
struct Sft : std::enable_shared_from_this<Sft> {
std::string history;
explicit Sft(const std::string &history) : history{history} {}
long use_count() const { return this->shared_from_this().use_count(); }
long use_count() const {
#if defined(__cpp_lib_enable_shared_from_this) && (!defined(_MSC_VER) || _MSC_VER >= 1912)
return this->shared_from_this().use_count();
#else
return -1;
#endif
}
virtual ~Sft() = default;
#if defined(__clang__)
// "Group of 4" begin.
// This group is not meant to be used, but will leave a trace in the
// history in case something goes wrong.
Sft(const Sft &other) : std::enable_shared_from_this<Sft>{} {
history = other.history + "_CpCtor";
}
// However, compilers other than clang have a variety of issues. It is not
// worth the trouble covering all platforms.
Sft(const Sft &other) { history = other.history + "_CpCtor"; }
Sft(Sft &&other) { history = other.history + "_MvCtor"; }
@ -35,6 +42,7 @@ struct Sft : std::enable_shared_from_this<Sft> {
return *this;
}
// "Group of 4" end.
#endif
};
struct SftSharedPtrStash {

View File

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
import env # noqa: F401
import pybind11_tests.class_sh_trampoline_shared_from_this as m
import gc
@ -13,13 +15,13 @@ class PySft(m.Sft):
def test_pass_shared_ptr():
obj = PySft("PySft")
assert obj.history == "PySft"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1] # TODO: Be smarter/stricter.
m.pass_shared_ptr(obj)
assert obj.history == "PySft_PassSharedPtr"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
m.pass_shared_ptr(obj)
assert obj.history == "PySft_PassSharedPtr_PassSharedPtr"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
def test_pass_shared_ptr_while_stashed():
@ -28,19 +30,19 @@ def test_pass_shared_ptr_while_stashed():
stash1 = m.SftSharedPtrStash(1)
stash1.Add(obj)
assert obj.history == "PySft_Stash1Add"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
m.pass_shared_ptr(obj)
assert obj.history == "PySft_Stash1Add_PassSharedPtr"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
stash2 = m.SftSharedPtrStash(2)
stash2.Add(obj)
assert obj.history == "PySft_Stash1Add_PassSharedPtr_Stash2Add"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
assert stash2.history(0) == "PySft_Stash1Add_PassSharedPtr_Stash2Add"
assert stash2.use_count(0) == 1 # TODO: this is not great.
stash2.Add(obj)
assert obj.history == "PySft_Stash1Add_PassSharedPtr_Stash2Add_Stash2Add"
assert obj.use_count() == 2
assert obj.use_count() in [2, -1]
assert stash1.use_count(0) == 1
assert stash1.history(0) == "PySft_Stash1Add_PassSharedPtr_Stash2Add_Stash2Add"
assert stash2.use_count(0) == 1
@ -58,7 +60,8 @@ def test_pass_shared_ptr_while_stashed():
assert stash1.history(0) == "PySft_Stash1Add_PassSharedPtr_Stash2Add_Stash2Add"
del stash1
gc.collect()
assert obj_wr() is None
if not env.PYPY:
assert obj_wr() is None
def test_pass_shared_ptr_while_stashed_with_shared_from_this():
@ -75,4 +78,5 @@ def test_pass_shared_ptr_while_stashed_with_shared_from_this():
del obj
del stash1
gc.collect()
assert obj_wr() is None
if not env.PYPY:
assert obj_wr() is None