Adding rvalue_ref, renaming const_value_ref to lvalue_ref & removing const.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-01-11 20:34:23 -08:00
parent 6bdd58a115
commit fe5427fc23
2 changed files with 40 additions and 14 deletions

View File

@ -158,13 +158,21 @@ struct smart_holder {
} }
template <typename T> template <typename T>
const T& const_value_ref() const { T& lvalue_ref() const {
static const char* context = "const_value_ref"; static const char* context = "lvalue_ref";
ensure_compatible_rtti_held<T>(context); ensure_compatible_rtti_held<T>(context);
ensure_has_pointee(context); ensure_has_pointee(context);
return *static_cast<T*>(vptr.get()); return *static_cast<T*>(vptr.get());
} }
template <typename T>
T&& rvalue_ref() const {
static const char* context = "rvalue_ref";
ensure_compatible_rtti_held<T>(context);
ensure_has_pointee(context);
return std::move(*static_cast<T*>(vptr.get()));
}
template <typename T> template <typename T>
static smart_holder from_raw_ptr_take_ownership(T* raw_ptr) { static smart_holder from_raw_ptr_take_ownership(T* raw_ptr) {
smart_holder hld; smart_holder hld;

View File

@ -7,6 +7,15 @@ using pybindit::memory::smart_holder;
namespace helpers { namespace helpers {
struct movable_int {
int valu;
movable_int(int v) : valu{v} {}
movable_int(movable_int&& other) {
valu = other.valu;
other.valu = 91;
}
};
template <typename T> template <typename T>
struct functor_builtin_delete { struct functor_builtin_delete {
void operator()(T* ptr) { delete ptr; } void operator()(T* ptr) { delete ptr; }
@ -23,10 +32,20 @@ TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_unowned", "[S]") {
REQUIRE(*hld.as_raw_ptr_unowned<int>() == 19); REQUIRE(*hld.as_raw_ptr_unowned<int>() == 19);
} }
TEST_CASE("from_raw_ptr_unowned+const_value_ref", "[S]") { TEST_CASE("from_raw_ptr_unowned+lvalue_ref", "[S]") {
static int value = 19; static int value = 19;
auto hld = smart_holder::from_raw_ptr_unowned(&value); auto hld = smart_holder::from_raw_ptr_unowned(&value);
REQUIRE(hld.const_value_ref<int>() == 19); REQUIRE(hld.lvalue_ref<int>() == 19);
}
TEST_CASE("from_raw_ptr_unowned+rvalue_ref", "[S]") {
helpers::movable_int orig(19);
{
auto hld = smart_holder::from_raw_ptr_unowned(&orig);
helpers::movable_int othr(hld.rvalue_ref<helpers::movable_int>());
REQUIRE(othr.valu == 19);
REQUIRE(orig.valu == 91);
}
} }
TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") {
@ -61,10 +80,10 @@ TEST_CASE("from_raw_ptr_unowned+as_shared_ptr", "[S]") {
REQUIRE(*hld.as_shared_ptr<int>() == 19); REQUIRE(*hld.as_shared_ptr<int>() == 19);
} }
TEST_CASE("from_raw_ptr_take_ownership+const_value_ref", "[S]") { TEST_CASE("from_raw_ptr_take_ownership+lvalue_ref", "[S]") {
auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19));
REQUIRE(hld.has_pointee()); REQUIRE(hld.has_pointee());
REQUIRE(hld.const_value_ref<int>() == 19); REQUIRE(hld.lvalue_ref<int>() == 19);
} }
TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") { TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") {
@ -114,11 +133,11 @@ TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") {
REQUIRE(*new_owner == 19); REQUIRE(*new_owner == 19);
} }
TEST_CASE("from_unique_ptr+const_value_ref", "[S]") { TEST_CASE("from_unique_ptr+lvalue_ref", "[S]") {
std::unique_ptr<int> orig_owner(new int(19)); std::unique_ptr<int> orig_owner(new int(19));
auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
REQUIRE(orig_owner.get() == nullptr); REQUIRE(orig_owner.get() == nullptr);
REQUIRE(hld.const_value_ref<int>() == 19); REQUIRE(hld.lvalue_ref<int>() == 19);
} }
TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") { TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") {
@ -180,12 +199,12 @@ TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") {
REQUIRE(*new_owner == 19); REQUIRE(*new_owner == 19);
} }
TEST_CASE("from_unique_ptr_with_deleter+const_value_ref", "[S]") { TEST_CASE("from_unique_ptr_with_deleter+lvalue_ref", "[S]") {
std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner( std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(
new int(19)); new int(19));
auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner));
REQUIRE(orig_owner.get() == nullptr); REQUIRE(orig_owner.get() == nullptr);
REQUIRE(hld.const_value_ref<int>() == 19); REQUIRE(hld.lvalue_ref<int>() == 19);
} }
TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") {
@ -242,10 +261,10 @@ TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") {
REQUIRE(*new_owner == 19); REQUIRE(*new_owner == 19);
} }
TEST_CASE("from_shared_ptr+const_value_ref", "[S]") { TEST_CASE("from_shared_ptr+lvalue_ref", "[S]") {
std::shared_ptr<int> orig_owner(new int(19)); std::shared_ptr<int> orig_owner(new int(19));
auto hld = smart_holder::from_shared_ptr(orig_owner); auto hld = smart_holder::from_shared_ptr(orig_owner);
REQUIRE(hld.const_value_ref<int>() == 19); REQUIRE(hld.lvalue_ref<int>() == 19);
} }
TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") {
@ -296,6 +315,5 @@ TEST_CASE("error_incompatible_type", "[E]") {
TEST_CASE("error_disowned_holder", "[E]") { TEST_CASE("error_disowned_holder", "[E]") {
auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19));
hld.as_unique_ptr<int>(); hld.as_unique_ptr<int>();
REQUIRE_THROWS_WITH(hld.const_value_ref<int>(), REQUIRE_THROWS_WITH(hld.lvalue_ref<int>(), "Disowned holder (lvalue_ref).");
"Disowned holder (const_value_ref).");
} }