Merge branch 'main' of github.com:Rconybea/refcnt
This commit is contained in:
commit
0680b7b1fc
3 changed files with 274 additions and 270 deletions
|
|
@ -8,85 +8,85 @@
|
||||||
#include <utility> // std::index_sequence
|
#include <utility> // std::index_sequence
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
namespace reflect {
|
namespace reflect {
|
||||||
|
|
||||||
template <std::size_t...Idxs>
|
template <std::size_t...Idxs>
|
||||||
constexpr auto
|
constexpr auto
|
||||||
substring_as_array(std::string_view str,
|
substring_as_array(std::string_view str,
|
||||||
std::index_sequence<Idxs...> indexes)
|
std::index_sequence<Idxs...> indexes)
|
||||||
{
|
{
|
||||||
//return std::array<char, indexes.size()+1>{str[Idxs]..., '\n'};
|
//return std::array<char, indexes.size()+1>{str[Idxs]..., '\n'};
|
||||||
return std::array<char, indexes.size()>{str[Idxs]...};
|
return std::array<char, indexes.size()>{str[Idxs]...};
|
||||||
} /*substring_as_array*/
|
} /*substring_as_array*/
|
||||||
|
|
||||||
template <typename T> constexpr auto type_name_array() {
|
template <typename T> constexpr auto type_name_array() {
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
constexpr auto prefix = std::string_view{"[T = "};
|
constexpr auto prefix = std::string_view{"[T = "};
|
||||||
constexpr auto suffix = std::string_view{"]"};
|
constexpr auto suffix = std::string_view{"]"};
|
||||||
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
|
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
constexpr auto prefix = std::string_view{"with T = "};
|
constexpr auto prefix = std::string_view{"with T = "};
|
||||||
constexpr auto suffix = std::string_view{"]"};
|
constexpr auto suffix = std::string_view{"]"};
|
||||||
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
|
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
constexpr auto prefix = std::string_view{"type_name_array<"};
|
constexpr auto prefix = std::string_view{"type_name_array<"};
|
||||||
constexpr auto suffix = std::string_view{">(void)"};
|
constexpr auto suffix = std::string_view{">(void)"};
|
||||||
constexpr auto function = std::string_view{__FUNCSIG__};
|
constexpr auto function = std::string_view{__FUNCSIG__};
|
||||||
#else
|
#else
|
||||||
# error type_name_array: Unsupported compiler
|
# error type_name_array: Unsupported compiler
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr auto start = function.find(prefix) + prefix.size();
|
constexpr auto start = function.find(prefix) + prefix.size();
|
||||||
constexpr auto end = function.rfind(suffix);
|
constexpr auto end = function.rfind(suffix);
|
||||||
|
|
||||||
//static_assert(start < end);
|
//static_assert(start < end);
|
||||||
|
|
||||||
constexpr auto name = function.substr(start, (end - start));
|
constexpr auto name = function.substr(start, (end - start));
|
||||||
|
|
||||||
constexpr auto ixseq = std::make_index_sequence<name.size()>{};
|
constexpr auto ixseq = std::make_index_sequence<name.size()>{};
|
||||||
|
|
||||||
return substring_as_array(name, ixseq);
|
return substring_as_array(name, ixseq);
|
||||||
} /*type_name_array*/
|
} /*type_name_array*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct type_name_holder {
|
struct type_name_holder {
|
||||||
static inline constexpr auto value = type_name_array<T>();
|
static inline constexpr auto value = type_name_array<T>();
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr auto type_name() -> std::string_view
|
constexpr auto type_name() -> std::string_view
|
||||||
{
|
{
|
||||||
constexpr auto& value = type_name_holder<T>::value;
|
constexpr auto& value = type_name_holder<T>::value;
|
||||||
return std::string_view{value.data(), value.size()};
|
return std::string_view{value.data(), value.size()};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NOT_IN_USE
|
#ifdef NOT_IN_USE
|
||||||
template <std::string_view const&... Strs>
|
template <std::string_view const&... Strs>
|
||||||
struct join
|
struct join
|
||||||
{
|
{
|
||||||
// Join all strings into a single std::array of chars
|
// Join all strings into a single std::array of chars
|
||||||
static constexpr auto impl() noexcept
|
static constexpr auto impl() noexcept
|
||||||
{
|
{
|
||||||
constexpr std::size_t len = (Strs.size() + ... + 0);
|
constexpr std::size_t len = (Strs.size() + ... + 0);
|
||||||
std::array<char, len + 1> arr{};
|
std::array<char, len + 1> arr{};
|
||||||
auto append = [i = 0, &arr](auto const& s) mutable {
|
auto append = [i = 0, &arr](auto const& s) mutable {
|
||||||
for (auto c : s) arr[i++] = c;
|
for (auto c : s) arr[i++] = c;
|
||||||
|
};
|
||||||
|
(append(Strs), ...);
|
||||||
|
arr[len] = 0;
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
// Give the joined string static storage
|
||||||
|
static constexpr auto arr = impl();
|
||||||
|
// View as a std::string_view
|
||||||
|
static constexpr std::string_view value {arr.data(), arr.size() - 1};
|
||||||
};
|
};
|
||||||
(append(Strs), ...);
|
|
||||||
arr[len] = 0;
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
// Give the joined string static storage
|
|
||||||
static constexpr auto arr = impl();
|
|
||||||
// View as a std::string_view
|
|
||||||
static constexpr std::string_view value {arr.data(), arr.size() - 1};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper to get the value out
|
// Helper to get the value out
|
||||||
template <std::string_view const&... Strs>
|
template <std::string_view const&... Strs>
|
||||||
static constexpr auto join_v = join<Strs...>::value;
|
static constexpr auto join_v = join<Strs...>::value;
|
||||||
#endif
|
#endif
|
||||||
} /*namespace reflect*/
|
} /*namespace reflect*/
|
||||||
} /*namespace xo*/
|
} /*namespace xo*/
|
||||||
|
|
||||||
/* end demangle.hpp */
|
/* end demangle.hpp */
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,8 @@ set(SELF_LIB refcnt)
|
||||||
set(SELF_SRCS Refcounted.cpp Displayable.cpp)
|
set(SELF_SRCS Refcounted.cpp Displayable.cpp)
|
||||||
|
|
||||||
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
||||||
|
|
||||||
|
# NOTE:
|
||||||
|
# dependency set here must be kept consistent with refcnt/cmake/refcntConfig.cmake.in
|
||||||
|
#
|
||||||
xo_dependency(${SELF_LIB} indentlog)
|
xo_dependency(${SELF_LIB} indentlog)
|
||||||
|
|
|
||||||
|
|
@ -7,295 +7,295 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
using xo::ref::Refcount;
|
using xo::ref::Refcount;
|
||||||
using xo::ref::Borrow;
|
using xo::ref::Borrow;
|
||||||
using xo::ref::rp;
|
using xo::ref::rp;
|
||||||
using xo::ref::brw;
|
using xo::ref::brw;
|
||||||
using xo::ref::intrusive_ptr_refcount;
|
using xo::ref::intrusive_ptr_refcount;
|
||||||
using xo::ref::intrusive_ptr_add_ref;
|
using xo::ref::intrusive_ptr_add_ref;
|
||||||
using xo::ref::intrusive_ptr_release;
|
using xo::ref::intrusive_ptr_release;
|
||||||
|
|
||||||
namespace ut {
|
namespace ut {
|
||||||
namespace {
|
namespace {
|
||||||
static uint32_t ctor_count = 0;
|
static uint32_t ctor_count = 0;
|
||||||
static uint32_t dtor_count = 0;
|
static uint32_t dtor_count = 0;
|
||||||
|
|
||||||
/* empty object, except for refcount */
|
/* empty object, except for refcount */
|
||||||
class JustRefcount : public ref::Refcount {
|
class JustRefcount : public ref::Refcount {
|
||||||
public:
|
public:
|
||||||
JustRefcount() { ++ctor_count; }
|
JustRefcount() { ++ctor_count; }
|
||||||
~JustRefcount() { ++dtor_count; }
|
~JustRefcount() { ++dtor_count; }
|
||||||
}; /*JustRefcount*/
|
}; /*JustRefcount*/
|
||||||
|
|
||||||
inline std::ostream & operator<<(std::ostream & os, JustRefcount & x) {
|
inline std::ostream & operator<<(std::ostream & os, JustRefcount & x) {
|
||||||
os << "JustRefcount";
|
os << "JustRefcount";
|
||||||
return os;
|
return os;
|
||||||
} /*operator<<*/
|
} /*operator<<*/
|
||||||
} /*namespace*/
|
} /*namespace*/
|
||||||
|
|
||||||
TEST_CASE("refcount", "[refcnt][trivial]") {
|
TEST_CASE("refcount", "[refcnt][trivial]") {
|
||||||
REQUIRE(std::is_default_constructible<ref::Refcount>() == true);
|
REQUIRE(std::is_default_constructible<ref::Refcount>() == true);
|
||||||
REQUIRE(std::has_virtual_destructor<ref::Refcount>() == true);
|
REQUIRE(std::has_virtual_destructor<ref::Refcount>() == true);
|
||||||
|
|
||||||
/* refcount object self-initializes to 0 */
|
/* refcount object self-initializes to 0 */
|
||||||
Refcount x;
|
Refcount x;
|
||||||
REQUIRE(x.reference_counter() == 0);
|
REQUIRE(x.reference_counter() == 0);
|
||||||
} /*TEST_CASE(refcount)*/
|
} /*TEST_CASE(refcount)*/
|
||||||
|
|
||||||
TEST_CASE("null-intrusive-ptr", "[refcnt][trivial]") {
|
TEST_CASE("null-intrusive-ptr", "[refcnt][trivial]") {
|
||||||
//constexpr std::string_view c_self = "TEST_CASE:null-intrusive-ptr";
|
//constexpr std::string_view c_self = "TEST_CASE:null-intrusive-ptr";
|
||||||
|
|
||||||
REQUIRE(std::has_virtual_destructor<JustRefcount>() == true);
|
REQUIRE(std::has_virtual_destructor<JustRefcount>() == true);
|
||||||
|
|
||||||
rp<JustRefcount> p1;
|
rp<JustRefcount> p1;
|
||||||
rp<JustRefcount> p2;
|
rp<JustRefcount> p2;
|
||||||
|
|
||||||
REQUIRE(sizeof(p1) == sizeof(JustRefcount*));
|
REQUIRE(sizeof(p1) == sizeof(JustRefcount*));
|
||||||
|
|
||||||
REQUIRE(p1.get() == nullptr);
|
REQUIRE(p1.get() == nullptr);
|
||||||
REQUIRE(p1.operator->() == nullptr);
|
REQUIRE(p1.operator->() == nullptr);
|
||||||
|
|
||||||
REQUIRE(p2.get() == nullptr);
|
REQUIRE(p2.get() == nullptr);
|
||||||
REQUIRE(p2.operator->() == nullptr);
|
REQUIRE(p2.operator->() == nullptr);
|
||||||
|
|
||||||
/* can assign a nullptr */
|
/* can assign a nullptr */
|
||||||
rp<JustRefcount> p3;
|
rp<JustRefcount> p3;
|
||||||
|
|
||||||
REQUIRE(p3.get() == nullptr);
|
REQUIRE(p3.get() == nullptr);
|
||||||
p3 = p1;
|
p3 = p1;
|
||||||
REQUIRE(p3.get() == nullptr);
|
REQUIRE(p3.get() == nullptr);
|
||||||
|
|
||||||
/* can use aux functions on null pointers */
|
/* can use aux functions on null pointers */
|
||||||
REQUIRE(intrusive_ptr_refcount(p1.get()) == 0);
|
REQUIRE(intrusive_ptr_refcount(p1.get()) == 0);
|
||||||
|
|
||||||
intrusive_ptr_add_ref(nullptr);
|
intrusive_ptr_add_ref(nullptr);
|
||||||
intrusive_ptr_release(nullptr);
|
intrusive_ptr_release(nullptr);
|
||||||
|
|
||||||
/* can borrow a null intrusive_ptr */
|
/* can borrow a null intrusive_ptr */
|
||||||
brw<JustRefcount> p1_brw = p1.borrow();
|
brw<JustRefcount> p1_brw = p1.borrow();
|
||||||
brw<JustRefcount> p2_brw = p2.borrow();
|
brw<JustRefcount> p2_brw = p2.borrow();
|
||||||
|
|
||||||
REQUIRE(p1_brw.get() == nullptr);
|
REQUIRE(p1_brw.get() == nullptr);
|
||||||
REQUIRE(p1_brw.operator->() == nullptr);
|
REQUIRE(p1_brw.operator->() == nullptr);
|
||||||
/* null borrow is false-y */
|
/* null borrow is false-y */
|
||||||
REQUIRE(p1_brw == false);
|
REQUIRE(p1_brw == false);
|
||||||
|
|
||||||
/* can promote a borrowed pointer */
|
/* can promote a borrowed pointer */
|
||||||
rp<JustRefcount> pp = p1_brw.promote();
|
rp<JustRefcount> pp = p1_brw.promote();
|
||||||
|
|
||||||
REQUIRE(p1.get() == pp.get());
|
REQUIRE(p1.get() == pp.get());
|
||||||
|
|
||||||
/* comparisons */
|
/* comparisons */
|
||||||
REQUIRE(Borrow<JustRefcount>::compare(p1_brw, p2_brw) == 0);
|
REQUIRE(Borrow<JustRefcount>::compare(p1_brw, p2_brw) == 0);
|
||||||
REQUIRE(p1_brw == p2_brw);
|
REQUIRE(p1_brw == p2_brw);
|
||||||
REQUIRE((p1_brw != p2_brw) == false);
|
REQUIRE((p1_brw != p2_brw) == false);
|
||||||
REQUIRE(p1 == p1_brw);
|
REQUIRE(p1 == p1_brw);
|
||||||
REQUIRE((p1 != p1_brw) == false);
|
REQUIRE((p1 != p1_brw) == false);
|
||||||
REQUIRE(p1_brw == p1);
|
REQUIRE(p1_brw == p1);
|
||||||
REQUIRE((p1_brw != p1) == false);
|
REQUIRE((p1_brw != p1) == false);
|
||||||
} /*TEST_CASE(null-intrusive_ptr)*/
|
} /*TEST_CASE(null-intrusive_ptr)*/
|
||||||
|
|
||||||
TEST_CASE("intrusive-ptr-identity", "[refcnt][identity]")
|
TEST_CASE("intrusive-ptr-identity", "[refcnt][identity]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1.get() == p1.operator->());
|
REQUIRE(p1.get() == p1.operator->());
|
||||||
REQUIRE(intrusive_ptr_refcount(p1.get()) == 1);
|
REQUIRE(intrusive_ptr_refcount(p1.get()) == 1);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
intrusive_ptr_add_ref(p1.get());
|
intrusive_ptr_add_ref(p1.get());
|
||||||
|
|
||||||
REQUIRE(intrusive_ptr_refcount(p1.get()) == 2);
|
REQUIRE(intrusive_ptr_refcount(p1.get()) == 2);
|
||||||
|
|
||||||
intrusive_ptr_release(p1.get());
|
intrusive_ptr_release(p1.get());
|
||||||
|
|
||||||
REQUIRE(intrusive_ptr_refcount(p1.get()) == 1);
|
REQUIRE(intrusive_ptr_refcount(p1.get()) == 1);
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
rp<JustRefcount> p2(new JustRefcount());
|
rp<JustRefcount> p2(new JustRefcount());
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 2);
|
REQUIRE(ctor_count == cc + 2);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
REQUIRE(p2.get() != nullptr);
|
REQUIRE(p2.get() != nullptr);
|
||||||
REQUIRE(p2.get() != p1.get());
|
REQUIRE(p2.get() != p1.get());
|
||||||
REQUIRE(p2.get() == p2.operator->());
|
REQUIRE(p2.get() == p2.operator->());
|
||||||
REQUIRE(p2->reference_counter() == 1);
|
REQUIRE(p2->reference_counter() == 1);
|
||||||
|
|
||||||
/* can borrow a non-null intrusive-ptr */
|
/* can borrow a non-null intrusive-ptr */
|
||||||
brw<JustRefcount> p1_brw = p1.borrow();
|
brw<JustRefcount> p1_brw = p1.borrow();
|
||||||
|
|
||||||
REQUIRE(p1_brw.get() == p1.get());
|
REQUIRE(p1_brw.get() == p1.get());
|
||||||
|
|
||||||
/* borrowing does not change refcount, borrow not tracked */
|
/* borrowing does not change refcount, borrow not tracked */
|
||||||
REQUIRE(ctor_count == cc + 2);
|
REQUIRE(ctor_count == cc + 2);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get()->reference_counter() == 1);
|
REQUIRE(p1.get()->reference_counter() == 1);
|
||||||
|
|
||||||
/* copying borrowed pointer does not touch refcount */
|
/* copying borrowed pointer does not touch refcount */
|
||||||
brw<JustRefcount> p1_brw2 = p1_brw;
|
brw<JustRefcount> p1_brw2 = p1_brw;
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 2);
|
REQUIRE(ctor_count == cc + 2);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1_brw2.get() == p1.get());
|
REQUIRE(p1_brw2.get() == p1.get());
|
||||||
|
|
||||||
REQUIRE(p1.get()->reference_counter() == 1);
|
REQUIRE(p1.get()->reference_counter() == 1);
|
||||||
} /*TEST_CASE(identity-intrusive-ptr)*/
|
} /*TEST_CASE(identity-intrusive-ptr)*/
|
||||||
|
|
||||||
TEST_CASE("intrusive-ptr-release", "[refcnt][release]")
|
TEST_CASE("intrusive-ptr-release", "[refcnt][release]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
/* reference count going to 0 -> delete object */
|
/* reference count going to 0 -> delete object */
|
||||||
p1 = nullptr;
|
p1 = nullptr;
|
||||||
|
|
||||||
REQUIRE(p1.get() == nullptr);
|
REQUIRE(p1.get() == nullptr);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc + 1);
|
REQUIRE(dtor_count == dc + 1);
|
||||||
} /*TEST_CASE(intrusive-ptr-release)*/
|
} /*TEST_CASE(intrusive-ptr-release)*/
|
||||||
|
|
||||||
TEST_CASE("intrusive-ptr-copy", "[refcnt][copy]")
|
TEST_CASE("intrusive-ptr-copy", "[refcnt][copy]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
JustRefcount * p1_native = p1.get();
|
JustRefcount * p1_native = p1.get();
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
/* copy ctor ran to make copy of p1, did not allocate */
|
/* copy ctor ran to make copy of p1, did not allocate */
|
||||||
rp<JustRefcount> p2(p1);
|
rp<JustRefcount> p2(p1);
|
||||||
|
|
||||||
REQUIRE(p1->reference_counter() == 2);
|
REQUIRE(p1->reference_counter() == 2);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
} /*TEST_CASE(intrusive-ptr-copy)*/
|
} /*TEST_CASE(intrusive-ptr-copy)*/
|
||||||
|
|
||||||
TEST_CASE("intrusive-ptr-move", "[refcnt][move]")
|
TEST_CASE("intrusive-ptr-move", "[refcnt][move]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
JustRefcount * p1_native = p1.get();
|
JustRefcount * p1_native = p1.get();
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
rp<JustRefcount> p2{std::move(p1)};
|
rp<JustRefcount> p2{std::move(p1)};
|
||||||
|
|
||||||
REQUIRE(p2->reference_counter() == 1);
|
REQUIRE(p2->reference_counter() == 1);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p2 = nullptr;
|
p2 = nullptr;
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc + 1);
|
REQUIRE(dtor_count == dc + 1);
|
||||||
} /*TEST_CASE(intrusive-ptr-move)*/
|
} /*TEST_CASE(intrusive-ptr-move)*/
|
||||||
|
|
||||||
TEST_CASE("instrusive-ptr-assign", "[refcnt][assign]")
|
TEST_CASE("instrusive-ptr-assign", "[refcnt][assign]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
JustRefcount * p1_native = p1.get();
|
JustRefcount * p1_native = p1.get();
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
rp<JustRefcount> p2;
|
rp<JustRefcount> p2;
|
||||||
|
|
||||||
REQUIRE(p2.get() == nullptr);
|
REQUIRE(p2.get() == nullptr);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p2 = p1;
|
p2 = p1;
|
||||||
|
|
||||||
REQUIRE(p2.get() == p1.get());
|
REQUIRE(p2.get() == p1.get());
|
||||||
REQUIRE(p2->reference_counter() == 2);
|
REQUIRE(p2->reference_counter() == 2);
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p1 = nullptr;
|
p1 = nullptr;
|
||||||
|
|
||||||
REQUIRE(p2->reference_counter() == 1);
|
REQUIRE(p2->reference_counter() == 1);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p2 = nullptr;
|
p2 = nullptr;
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc + 1);
|
REQUIRE(dtor_count == dc + 1);
|
||||||
} /*TEST_CASE(intrusive-ptr-assign)*/
|
} /*TEST_CASE(intrusive-ptr-assign)*/
|
||||||
|
|
||||||
TEST_CASE("intrusive-ptr-move-assign", "[refcnt][move-assign]")
|
TEST_CASE("intrusive-ptr-move-assign", "[refcnt][move-assign]")
|
||||||
{
|
{
|
||||||
uint32_t cc = ctor_count;
|
uint32_t cc = ctor_count;
|
||||||
uint32_t dc = dtor_count;
|
uint32_t dc = dtor_count;
|
||||||
|
|
||||||
rp<JustRefcount> p1(new JustRefcount());
|
rp<JustRefcount> p1(new JustRefcount());
|
||||||
JustRefcount * p1_native = p1.get();
|
JustRefcount * p1_native = p1.get();
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
REQUIRE(p1.get() != nullptr);
|
REQUIRE(p1.get() != nullptr);
|
||||||
REQUIRE(p1->reference_counter() == 1);
|
REQUIRE(p1->reference_counter() == 1);
|
||||||
|
|
||||||
rp<JustRefcount> p2;
|
rp<JustRefcount> p2;
|
||||||
|
|
||||||
REQUIRE(p2.get() == nullptr);
|
REQUIRE(p2.get() == nullptr);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p2 = std::move(p1);
|
p2 = std::move(p1);
|
||||||
|
|
||||||
REQUIRE(p1.get() == nullptr);
|
REQUIRE(p1.get() == nullptr);
|
||||||
REQUIRE(p2.get() == p1_native);
|
REQUIRE(p2.get() == p1_native);
|
||||||
REQUIRE(p2->reference_counter() == 1);
|
REQUIRE(p2->reference_counter() == 1);
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p1 = nullptr; /*no-op*/
|
p1 = nullptr; /*no-op*/
|
||||||
|
|
||||||
REQUIRE(p2->reference_counter() == 1);
|
REQUIRE(p2->reference_counter() == 1);
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc);
|
REQUIRE(dtor_count == dc);
|
||||||
|
|
||||||
p2 = nullptr;
|
p2 = nullptr;
|
||||||
|
|
||||||
REQUIRE(ctor_count == cc + 1);
|
REQUIRE(ctor_count == cc + 1);
|
||||||
REQUIRE(dtor_count == dc + 1);
|
REQUIRE(dtor_count == dc + 1);
|
||||||
} /*TEST_CASE(intrusive-ptr-move-assign)*/
|
} /*TEST_CASE(intrusive-ptr-move-assign)*/
|
||||||
} /*namespace ut*/
|
} /*namespace ut*/
|
||||||
} /*namespace xo*/
|
} /*namespace xo*/
|
||||||
|
|
||||||
/* end intrusive_ptr.test.cpp */
|
/* end intrusive_ptr.test.cpp */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue