Skip to content

Commit 44619d2

Browse files
committed
Added casting constructor from owner for basic_observer_ptr for #12
1 parent bae27a3 commit 44619d2

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

include/oup/observable_unique_ptr.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,26 @@ class basic_observer_ptr final {
986986
}
987987
}
988988

989+
/**
990+
* \brief Create an observer pointer from an owning pointer of a different type.
991+
* \param manager The owner pointer to copy the observed data from
992+
* \param value The casted pointer value to observe
993+
* \note The raw pointer `value` may or may not be related to the raw pointer
994+
* owner by `manager`. This could be a pointer to any other object which is known
995+
* to have the same lifetime.
996+
*/
997+
template<
998+
typename U,
999+
typename D,
1000+
typename P,
1001+
typename enable = std::enable_if_t<std::is_same_v<Policy, typename P::observer_policy>>>
1002+
basic_observer_ptr(const basic_observable_ptr<U, D, P>& manager, T* value) noexcept :
1003+
block(manager.block), data(value) {
1004+
if (block) {
1005+
block->push_ref();
1006+
}
1007+
}
1008+
9891009
/**
9901010
* \brief Copy an existing @ref basic_observer_ptr instance
9911011
* \param value The existing observer pointer to copy

tests/runtime_tests.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,94 @@ TEST_CASE("observer explicit conversion copy constructor subobject", "[observer_
19491949
REQUIRE(mem_track.double_del() == 0u);
19501950
}
19511951

1952+
TEST_CASE("observer from null owner constructor", "[observer_construction]") {
1953+
memory_tracker mem_track;
1954+
1955+
{
1956+
test_ptr ptr_owner;
1957+
{
1958+
test_optr ptr{ptr_owner};
1959+
REQUIRE(instances == 0);
1960+
REQUIRE(ptr.get() == ptr_owner.get());
1961+
REQUIRE(ptr.expired() == true);
1962+
}
1963+
1964+
REQUIRE(instances == 0);
1965+
}
1966+
1967+
REQUIRE(instances == 0);
1968+
REQUIRE(mem_track.leaks() == 0u);
1969+
REQUIRE(mem_track.double_del() == 0u);
1970+
}
1971+
1972+
TEST_CASE("observer from owner constructor", "[observer_construction]") {
1973+
memory_tracker mem_track;
1974+
1975+
{
1976+
test_ptr ptr_owner{new test_object};
1977+
{
1978+
test_optr ptr{ptr_owner};
1979+
REQUIRE(instances == 1);
1980+
REQUIRE(ptr.get() == ptr_owner.get());
1981+
REQUIRE(ptr.expired() == false);
1982+
1983+
ptr_owner.reset();
1984+
REQUIRE(ptr.get() == nullptr);
1985+
REQUIRE(ptr.expired() == true);
1986+
}
1987+
1988+
REQUIRE(instances == 0);
1989+
}
1990+
1991+
REQUIRE(instances == 0);
1992+
REQUIRE(mem_track.leaks() == 0u);
1993+
REQUIRE(mem_track.double_del() == 0u);
1994+
}
1995+
1996+
TEST_CASE("observer from null owner casting constructor", "[observer_construction]") {
1997+
memory_tracker mem_track;
1998+
1999+
{
2000+
test_ptr ptr_owner;
2001+
{
2002+
test_optr ptr{ptr_owner, static_cast<test_object*>(nullptr)};
2003+
REQUIRE(instances == 0);
2004+
REQUIRE(ptr.get() == ptr_owner.get());
2005+
REQUIRE(ptr.expired() == true);
2006+
}
2007+
2008+
REQUIRE(instances == 0);
2009+
}
2010+
2011+
REQUIRE(instances == 0);
2012+
REQUIRE(mem_track.leaks() == 0u);
2013+
REQUIRE(mem_track.double_del() == 0u);
2014+
}
2015+
2016+
TEST_CASE("observer from owner casting constructor", "[observer_construction]") {
2017+
memory_tracker mem_track;
2018+
2019+
{
2020+
test_ptr ptr_owner{new test_object_derived};
2021+
{
2022+
test_optr ptr{ptr_owner, dynamic_cast<test_object_derived*>(ptr_owner.get())};
2023+
REQUIRE(instances == 1);
2024+
REQUIRE(ptr.get() == ptr_owner.get());
2025+
REQUIRE(ptr.expired() == false);
2026+
2027+
ptr_owner.reset();
2028+
REQUIRE(ptr.get() == nullptr);
2029+
REQUIRE(ptr.expired() == true);
2030+
}
2031+
2032+
REQUIRE(instances == 0);
2033+
}
2034+
2035+
REQUIRE(instances == 0);
2036+
REQUIRE(mem_track.leaks() == 0u);
2037+
REQUIRE(mem_track.double_del() == 0u);
2038+
}
2039+
19522040
TEST_CASE("observer move constructor", "[observer_construction]") {
19532041
memory_tracker mem_track;
19542042

0 commit comments

Comments
 (0)