diff --git a/src/ref_ptr.hh b/src/ref_ptr.hh index a061cff9..279686b3 100644 --- a/src/ref_ptr.hh +++ b/src/ref_ptr.hh @@ -6,12 +6,20 @@ namespace Kakoune { -struct WorstMatch { [[gnu::always_inline]] WorstMatch(...) {} }; +struct RefCountable +{ + int refcount = 0; + virtual ~RefCountable() = default; +}; -[[gnu::always_inline]] -inline void ref_ptr_moved(WorstMatch, void*, void*) noexcept {} +struct RefCountablePolicy +{ + static void inc_ref(RefCountable* r, void*) { ++r->refcount; } + static void dec_ref(RefCountable* r, void*) { if (--r->refcount == 0) delete r; } + static void ptr_moved(RefCountable*, void*, void*) noexcept {} +}; -template +template struct RefPtr { RefPtr() = default; @@ -83,40 +91,23 @@ private: void acquire() { if (m_ptr) - inc_ref_count(static_cast(m_ptr), this); + Policy::inc_ref(m_ptr, this); } [[gnu::always_inline]] void release() { if (m_ptr) - dec_ref_count(static_cast(m_ptr), this); + Policy::dec_ref(m_ptr, this); m_ptr = nullptr; } [[gnu::always_inline]] void moved(void* from) - noexcept(noexcept(ref_ptr_moved(static_cast(nullptr), nullptr, nullptr))) + noexcept(noexcept(Policy::ptr_moved(nullptr, nullptr, nullptr))) { if (m_ptr) - ref_ptr_moved(static_cast(m_ptr), from, this); - } -}; - -struct RefCountable -{ - int refcount = 0; - virtual ~RefCountable() = default; - - friend void inc_ref_count(RefCountable* r, void*) - { - ++r->refcount; - } - - friend void dec_ref_count(RefCountable* r, void*) - { - if (--r->refcount == 0) - delete r; + Policy::ptr_moved(m_ptr, from, this); } }; diff --git a/src/safe_ptr.hh b/src/safe_ptr.hh index 12a9b4a3..b9f53709 100644 --- a/src/safe_ptr.hh +++ b/src/safe_ptr.hh @@ -33,37 +33,8 @@ public: #endif } - friend void inc_ref_count(const SafeCountable* sc, void* ptr) - { - ++sc->m_count; - #ifdef SAFE_PTR_TRACK_CALLSTACKS - sc->m_callstacks.emplace_back(ptr); - #endif - } - - friend void dec_ref_count(const SafeCountable* sc, void* ptr) - { - --sc->m_count; - kak_assert(sc->m_count >= 0); - #ifdef SAFE_PTR_TRACK_CALLSTACKS - auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(), - [=](const Callstack& cs) { return cs.ptr == ptr; }); - kak_assert(it != sc->m_callstacks.end()); - sc->m_callstacks.erase(it); - #endif - } - - friend void ref_ptr_moved(const SafeCountable* sc, void* from, void* to) - { - #ifdef SAFE_PTR_TRACK_CALLSTACKS - auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(), - [=](const Callstack& cs) { return cs.ptr == from; }); - kak_assert(it != sc->m_callstacks.end()); - it->ptr = to; - #endif - } - private: + friend struct SafeCountablePolicy; #ifdef SAFE_PTR_TRACK_CALLSTACKS struct Callstack { @@ -75,20 +46,50 @@ private: mutable Vector m_callstacks; #endif mutable int m_count; -#else - [[gnu::always_inline]] - friend void inc_ref_count(const SafeCountable* sc, void* ptr) {} - - [[gnu::always_inline]] - friend void dec_ref_count(const SafeCountable* sc, void* ptr) {} #endif }; -template -using PropagateConst = typename std::conditional::value, const U, U>::type; +struct SafeCountablePolicy +{ +#ifdef KAK_DEBUG + static void inc_ref(const SafeCountable* sc, void* ptr) + { + ++sc->m_count; + #ifdef SAFE_PTR_TRACK_CALLSTACKS + sc->m_callstacks.emplace_back(ptr); + #endif + } + + static void dec_ref(const SafeCountable* sc, void* ptr) + { + --sc->m_count; + kak_assert(sc->m_count >= 0); + #ifdef SAFE_PTR_TRACK_CALLSTACKS + auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(), + [=](const Callstack& cs) { return cs.ptr == ptr; }); + kak_assert(it != sc->m_callstacks.end()); + sc->m_callstacks.erase(it); + #endif + } + + static void ptr_moved(const SafeCountable* sc, void* from, void* to) + { + #ifdef SAFE_PTR_TRACK_CALLSTACKS + auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(), + [=](const Callstack& cs) { return cs.ptr == from; }); + kak_assert(it != sc->m_callstacks.end()); + it->ptr = to; + #endif + } +#else + static void inc_ref(const SafeCountable*, void* ptr) {} + static void dec_ref(const SafeCountable*, void* ptr) {} + static void ptr_moved(const SafeCountable*, void*, void*) {} +#endif +}; template -using SafePtr = RefPtr>; +using SafePtr = RefPtr; } diff --git a/src/shared_string.hh b/src/shared_string.hh index 112b67f2..49bbdb4c 100644 --- a/src/shared_string.hh +++ b/src/shared_string.hh @@ -24,7 +24,14 @@ struct StringData : UseMemoryDomain [[gnu::always_inline]] StringView strview() const { return {data(), length}; } - static RefPtr create(StringView str, char back = 0) + struct PtrPolicy + { + static void inc_ref(StringData* r, void*) { ++r->refcount; } + static void dec_ref(StringData* r, void*) { if (--r->refcount == 0) delete r; } + static void ptr_moved(StringData*, void*, void*) noexcept {} + }; + + static RefPtr create(StringView str, char back = 0) { const int len = (int)str.length() + (back != 0 ? 1 : 0); void* ptr = StringData::operator new(sizeof(StringData) + len + 1); @@ -34,7 +41,7 @@ struct StringData : UseMemoryDomain res->data()[len-1] = back; res->data()[len] = 0; res->hash = hash_data(res->data(), res->length); - return RefPtr(res); + return RefPtr{res}; } static void destroy(StringData* s) @@ -54,7 +61,7 @@ struct StringData : UseMemoryDomain } }; -using StringDataPtr = RefPtr; +using StringDataPtr = RefPtr; class StringRegistry : public Singleton {