diff --git a/include/xo/cxxutil/demangle.hpp b/include/xo/cxxutil/demangle.hpp index 8b8b8ba3..e2184f5d 100644 --- a/include/xo/cxxutil/demangle.hpp +++ b/include/xo/cxxutil/demangle.hpp @@ -8,85 +8,85 @@ #include // std::index_sequence namespace xo { - namespace reflect { + namespace reflect { - template - constexpr auto - substring_as_array(std::string_view str, - std::index_sequence indexes) - { - //return std::array{str[Idxs]..., '\n'}; - return std::array{str[Idxs]...}; - } /*substring_as_array*/ + template + constexpr auto + substring_as_array(std::string_view str, + std::index_sequence indexes) + { + //return std::array{str[Idxs]..., '\n'}; + return std::array{str[Idxs]...}; + } /*substring_as_array*/ - template constexpr auto type_name_array() { + template constexpr auto type_name_array() { #if defined(__clang__) - constexpr auto prefix = std::string_view{"[T = "}; - constexpr auto suffix = std::string_view{"]"}; - constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; + constexpr auto prefix = std::string_view{"[T = "}; + constexpr auto suffix = std::string_view{"]"}; + constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; #elif defined(__GNUC__) - constexpr auto prefix = std::string_view{"with T = "}; - constexpr auto suffix = std::string_view{"]"}; - constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; + constexpr auto prefix = std::string_view{"with T = "}; + constexpr auto suffix = std::string_view{"]"}; + constexpr auto function = std::string_view{__PRETTY_FUNCTION__}; #elif defined(_MSC_VER) - constexpr auto prefix = std::string_view{"type_name_array<"}; - constexpr auto suffix = std::string_view{">(void)"}; - constexpr auto function = std::string_view{__FUNCSIG__}; + constexpr auto prefix = std::string_view{"type_name_array<"}; + constexpr auto suffix = std::string_view{">(void)"}; + constexpr auto function = std::string_view{__FUNCSIG__}; #else # error type_name_array: Unsupported compiler #endif - constexpr auto start = function.find(prefix) + prefix.size(); - constexpr auto end = function.rfind(suffix); + constexpr auto start = function.find(prefix) + prefix.size(); + 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{}; + constexpr auto ixseq = std::make_index_sequence{}; - return substring_as_array(name, ixseq); - } /*type_name_array*/ + return substring_as_array(name, ixseq); + } /*type_name_array*/ - template - struct type_name_holder { - static inline constexpr auto value = type_name_array(); - }; - - template - constexpr auto type_name() -> std::string_view - { - constexpr auto& value = type_name_holder::value; - return std::string_view{value.data(), value.size()}; - } + template + struct type_name_holder { + static inline constexpr auto value = type_name_array(); + }; + + template + constexpr auto type_name() -> std::string_view + { + constexpr auto& value = type_name_holder::value; + return std::string_view{value.data(), value.size()}; + } #ifdef NOT_IN_USE - template - struct join - { - // Join all strings into a single std::array of chars - static constexpr auto impl() noexcept - { - constexpr std::size_t len = (Strs.size() + ... + 0); - std::array arr{}; - auto append = [i = 0, &arr](auto const& s) mutable { - for (auto c : s) arr[i++] = c; + template + struct join + { + // Join all strings into a single std::array of chars + static constexpr auto impl() noexcept + { + constexpr std::size_t len = (Strs.size() + ... + 0); + std::array arr{}; + auto append = [i = 0, &arr](auto const& s) mutable { + 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 - template - static constexpr auto join_v = join::value; + // Helper to get the value out + template + static constexpr auto join_v = join::value; #endif - } /*namespace reflect*/ + } /*namespace reflect*/ } /*namespace xo*/ /* end demangle.hpp */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4622ad44..1b90ed07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,4 +2,8 @@ set(SELF_LIB refcnt) set(SELF_SRCS Refcounted.cpp Displayable.cpp) 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) diff --git a/utest/intrusive_ptr.test.cpp b/utest/intrusive_ptr.test.cpp index 2b87f1d2..112268a9 100644 --- a/utest/intrusive_ptr.test.cpp +++ b/utest/intrusive_ptr.test.cpp @@ -7,295 +7,295 @@ #include namespace xo { - using xo::ref::Refcount; - using xo::ref::Borrow; - using xo::ref::rp; - using xo::ref::brw; - using xo::ref::intrusive_ptr_refcount; - using xo::ref::intrusive_ptr_add_ref; - using xo::ref::intrusive_ptr_release; + using xo::ref::Refcount; + using xo::ref::Borrow; + using xo::ref::rp; + using xo::ref::brw; + using xo::ref::intrusive_ptr_refcount; + using xo::ref::intrusive_ptr_add_ref; + using xo::ref::intrusive_ptr_release; - namespace ut { - namespace { - static uint32_t ctor_count = 0; - static uint32_t dtor_count = 0; + namespace ut { + namespace { + static uint32_t ctor_count = 0; + static uint32_t dtor_count = 0; - /* empty object, except for refcount */ - class JustRefcount : public ref::Refcount { - public: - JustRefcount() { ++ctor_count; } - ~JustRefcount() { ++dtor_count; } - }; /*JustRefcount*/ + /* empty object, except for refcount */ + class JustRefcount : public ref::Refcount { + public: + JustRefcount() { ++ctor_count; } + ~JustRefcount() { ++dtor_count; } + }; /*JustRefcount*/ - inline std::ostream & operator<<(std::ostream & os, JustRefcount & x) { - os << "JustRefcount"; - return os; - } /*operator<<*/ - } /*namespace*/ + inline std::ostream & operator<<(std::ostream & os, JustRefcount & x) { + os << "JustRefcount"; + return os; + } /*operator<<*/ + } /*namespace*/ - TEST_CASE("refcount", "[refcnt][trivial]") { - REQUIRE(std::is_default_constructible() == true); - REQUIRE(std::has_virtual_destructor() == true); + TEST_CASE("refcount", "[refcnt][trivial]") { + REQUIRE(std::is_default_constructible() == true); + REQUIRE(std::has_virtual_destructor() == true); - /* refcount object self-initializes to 0 */ - Refcount x; - REQUIRE(x.reference_counter() == 0); - } /*TEST_CASE(refcount)*/ + /* refcount object self-initializes to 0 */ + Refcount x; + REQUIRE(x.reference_counter() == 0); + } /*TEST_CASE(refcount)*/ - TEST_CASE("null-intrusive-ptr", "[refcnt][trivial]") { - //constexpr std::string_view c_self = "TEST_CASE:null-intrusive-ptr"; + TEST_CASE("null-intrusive-ptr", "[refcnt][trivial]") { + //constexpr std::string_view c_self = "TEST_CASE:null-intrusive-ptr"; - REQUIRE(std::has_virtual_destructor() == true); + REQUIRE(std::has_virtual_destructor() == true); - rp p1; - rp p2; + rp p1; + rp p2; - REQUIRE(sizeof(p1) == sizeof(JustRefcount*)); + REQUIRE(sizeof(p1) == sizeof(JustRefcount*)); - REQUIRE(p1.get() == nullptr); - REQUIRE(p1.operator->() == nullptr); + REQUIRE(p1.get() == nullptr); + REQUIRE(p1.operator->() == nullptr); - REQUIRE(p2.get() == nullptr); - REQUIRE(p2.operator->() == nullptr); + REQUIRE(p2.get() == nullptr); + REQUIRE(p2.operator->() == nullptr); - /* can assign a nullptr */ - rp p3; + /* can assign a nullptr */ + rp p3; - REQUIRE(p3.get() == nullptr); - p3 = p1; - REQUIRE(p3.get() == nullptr); + REQUIRE(p3.get() == nullptr); + p3 = p1; + REQUIRE(p3.get() == nullptr); - /* can use aux functions on null pointers */ - REQUIRE(intrusive_ptr_refcount(p1.get()) == 0); + /* can use aux functions on null pointers */ + REQUIRE(intrusive_ptr_refcount(p1.get()) == 0); - intrusive_ptr_add_ref(nullptr); - intrusive_ptr_release(nullptr); + intrusive_ptr_add_ref(nullptr); + intrusive_ptr_release(nullptr); - /* can borrow a null intrusive_ptr */ - brw p1_brw = p1.borrow(); - brw p2_brw = p2.borrow(); + /* can borrow a null intrusive_ptr */ + brw p1_brw = p1.borrow(); + brw p2_brw = p2.borrow(); - REQUIRE(p1_brw.get() == nullptr); - REQUIRE(p1_brw.operator->() == nullptr); - /* null borrow is false-y */ - REQUIRE(p1_brw == false); + REQUIRE(p1_brw.get() == nullptr); + REQUIRE(p1_brw.operator->() == nullptr); + /* null borrow is false-y */ + REQUIRE(p1_brw == false); - /* can promote a borrowed pointer */ - rp pp = p1_brw.promote(); + /* can promote a borrowed pointer */ + rp pp = p1_brw.promote(); - REQUIRE(p1.get() == pp.get()); + REQUIRE(p1.get() == pp.get()); - /* comparisons */ - REQUIRE(Borrow::compare(p1_brw, p2_brw) == 0); - REQUIRE(p1_brw == p2_brw); - REQUIRE((p1_brw != p2_brw) == false); - REQUIRE(p1 == p1_brw); - REQUIRE((p1 != p1_brw) == false); - REQUIRE(p1_brw == p1); - REQUIRE((p1_brw != p1) == false); - } /*TEST_CASE(null-intrusive_ptr)*/ + /* comparisons */ + REQUIRE(Borrow::compare(p1_brw, p2_brw) == 0); + REQUIRE(p1_brw == p2_brw); + REQUIRE((p1_brw != p2_brw) == false); + REQUIRE(p1 == p1_brw); + REQUIRE((p1 != p1_brw) == false); + REQUIRE(p1_brw == p1); + REQUIRE((p1_brw != p1) == false); + } /*TEST_CASE(null-intrusive_ptr)*/ - TEST_CASE("intrusive-ptr-identity", "[refcnt][identity]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("intrusive-ptr-identity", "[refcnt][identity]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); + rp p1(new JustRefcount()); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1.get() == p1.operator->()); - REQUIRE(intrusive_ptr_refcount(p1.get()) == 1); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1.get() == p1.operator->()); + REQUIRE(intrusive_ptr_refcount(p1.get()) == 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(dtor_count == dc); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - rp p2(new JustRefcount()); + rp p2(new JustRefcount()); - REQUIRE(ctor_count == cc + 2); - REQUIRE(dtor_count == dc); + REQUIRE(ctor_count == cc + 2); + REQUIRE(dtor_count == dc); - REQUIRE(p2.get() != nullptr); - REQUIRE(p2.get() != p1.get()); - REQUIRE(p2.get() == p2.operator->()); - REQUIRE(p2->reference_counter() == 1); + REQUIRE(p2.get() != nullptr); + REQUIRE(p2.get() != p1.get()); + REQUIRE(p2.get() == p2.operator->()); + REQUIRE(p2->reference_counter() == 1); - /* can borrow a non-null intrusive-ptr */ - brw p1_brw = p1.borrow(); + /* can borrow a non-null intrusive-ptr */ + brw p1_brw = p1.borrow(); - REQUIRE(p1_brw.get() == p1.get()); + REQUIRE(p1_brw.get() == p1.get()); - /* borrowing does not change refcount, borrow not tracked */ - REQUIRE(ctor_count == cc + 2); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get()->reference_counter() == 1); + /* borrowing does not change refcount, borrow not tracked */ + REQUIRE(ctor_count == cc + 2); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get()->reference_counter() == 1); - /* copying borrowed pointer does not touch refcount */ - brw p1_brw2 = p1_brw; + /* copying borrowed pointer does not touch refcount */ + brw p1_brw2 = p1_brw; - REQUIRE(ctor_count == cc + 2); - REQUIRE(dtor_count == dc); - REQUIRE(p1_brw2.get() == p1.get()); + REQUIRE(ctor_count == cc + 2); + REQUIRE(dtor_count == dc); + REQUIRE(p1_brw2.get() == p1.get()); - REQUIRE(p1.get()->reference_counter() == 1); - } /*TEST_CASE(identity-intrusive-ptr)*/ + REQUIRE(p1.get()->reference_counter() == 1); + } /*TEST_CASE(identity-intrusive-ptr)*/ - TEST_CASE("intrusive-ptr-release", "[refcnt][release]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("intrusive-ptr-release", "[refcnt][release]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); + rp p1(new JustRefcount()); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1->reference_counter() == 1); - /* reference count going to 0 -> delete object */ - p1 = nullptr; + /* reference count going to 0 -> delete object */ + p1 = nullptr; - REQUIRE(p1.get() == nullptr); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc + 1); - } /*TEST_CASE(intrusive-ptr-release)*/ + REQUIRE(p1.get() == nullptr); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc + 1); + } /*TEST_CASE(intrusive-ptr-release)*/ - TEST_CASE("intrusive-ptr-copy", "[refcnt][copy]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("intrusive-ptr-copy", "[refcnt][copy]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); - JustRefcount * p1_native = p1.get(); + rp p1(new JustRefcount()); + JustRefcount * p1_native = p1.get(); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1->reference_counter() == 1); - /* copy ctor ran to make copy of p1, did not allocate */ - rp p2(p1); + /* copy ctor ran to make copy of p1, did not allocate */ + rp p2(p1); - REQUIRE(p1->reference_counter() == 2); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p1->reference_counter() == 2); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - } /*TEST_CASE(intrusive-ptr-copy)*/ + } /*TEST_CASE(intrusive-ptr-copy)*/ - TEST_CASE("intrusive-ptr-move", "[refcnt][move]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("intrusive-ptr-move", "[refcnt][move]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); - JustRefcount * p1_native = p1.get(); + rp p1(new JustRefcount()); + JustRefcount * p1_native = p1.get(); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1->reference_counter() == 1); - rp p2{std::move(p1)}; + rp p2{std::move(p1)}; - REQUIRE(p2->reference_counter() == 1); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p2->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p2 = nullptr; + p2 = nullptr; - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc + 1); - } /*TEST_CASE(intrusive-ptr-move)*/ + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc + 1); + } /*TEST_CASE(intrusive-ptr-move)*/ - TEST_CASE("instrusive-ptr-assign", "[refcnt][assign]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("instrusive-ptr-assign", "[refcnt][assign]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); - JustRefcount * p1_native = p1.get(); + rp p1(new JustRefcount()); + JustRefcount * p1_native = p1.get(); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1->reference_counter() == 1); - rp p2; + rp p2; - REQUIRE(p2.get() == nullptr); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p2.get() == nullptr); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p2 = p1; + p2 = p1; - REQUIRE(p2.get() == p1.get()); - REQUIRE(p2->reference_counter() == 2); + REQUIRE(p2.get() == p1.get()); + REQUIRE(p2->reference_counter() == 2); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p1 = nullptr; + p1 = nullptr; - REQUIRE(p2->reference_counter() == 1); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p2->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p2 = nullptr; + p2 = nullptr; - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc + 1); - } /*TEST_CASE(intrusive-ptr-assign)*/ + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc + 1); + } /*TEST_CASE(intrusive-ptr-assign)*/ - TEST_CASE("intrusive-ptr-move-assign", "[refcnt][move-assign]") - { - uint32_t cc = ctor_count; - uint32_t dc = dtor_count; + TEST_CASE("intrusive-ptr-move-assign", "[refcnt][move-assign]") + { + uint32_t cc = ctor_count; + uint32_t dc = dtor_count; - rp p1(new JustRefcount()); - JustRefcount * p1_native = p1.get(); + rp p1(new JustRefcount()); + JustRefcount * p1_native = p1.get(); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); - REQUIRE(p1.get() != nullptr); - REQUIRE(p1->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); + REQUIRE(p1.get() != nullptr); + REQUIRE(p1->reference_counter() == 1); - rp p2; + rp p2; - REQUIRE(p2.get() == nullptr); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p2.get() == nullptr); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p2 = std::move(p1); + p2 = std::move(p1); - REQUIRE(p1.get() == nullptr); - REQUIRE(p2.get() == p1_native); - REQUIRE(p2->reference_counter() == 1); + REQUIRE(p1.get() == nullptr); + REQUIRE(p2.get() == p1_native); + REQUIRE(p2->reference_counter() == 1); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p1 = nullptr; /*no-op*/ + p1 = nullptr; /*no-op*/ - REQUIRE(p2->reference_counter() == 1); - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc); + REQUIRE(p2->reference_counter() == 1); + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc); - p2 = nullptr; + p2 = nullptr; - REQUIRE(ctor_count == cc + 1); - REQUIRE(dtor_count == dc + 1); - } /*TEST_CASE(intrusive-ptr-move-assign)*/ - } /*namespace ut*/ + REQUIRE(ctor_count == cc + 1); + REQUIRE(dtor_count == dc + 1); + } /*TEST_CASE(intrusive-ptr-move-assign)*/ + } /*namespace ut*/ } /*namespace xo*/ /* end intrusive_ptr.test.cpp */