From b046ffe152bee5937296889b8526036b52de8411 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 25 Jul 2019 13:51:24 +0200 Subject: [PATCH] Introduce Shared --- lib/base/CMakeLists.txt | 1 + lib/base/shared.hpp | 101 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 lib/base/shared.hpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 100ca27a7..3e4d8a7cf 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -60,6 +60,7 @@ set(base_SOURCES scriptglobal.cpp scriptglobal.hpp scriptutils.cpp scriptutils.hpp serializer.cpp serializer.hpp + shared.hpp singleton.hpp socket.cpp socket.hpp stacktrace.cpp stacktrace.hpp diff --git a/lib/base/shared.hpp b/lib/base/shared.hpp new file mode 100644 index 000000000..33e0bcfc3 --- /dev/null +++ b/lib/base/shared.hpp @@ -0,0 +1,101 @@ +/* Icinga 2 | (c) 2019 Icinga GmbH | GPLv2+ */ + +#ifndef SHARED_H +#define SHARED_H + +#include "base/atomic.hpp" +#include +#include +#include + +namespace icinga +{ + +template +class Shared; + +template +inline void intrusive_ptr_add_ref(Shared *object) +{ + object->m_References.fetch_add(1); +} + +template +inline void intrusive_ptr_release(Shared *object) +{ + if (object->m_References.fetch_sub(1) == 1u) { + delete object; + } +} + +/** + * Seemless wrapper for any class to create shared pointers of. + * Saves a memory allocation compared to std::shared_ptr. + * + * @ingroup base + */ +template +class Shared : public T +{ + friend void intrusive_ptr_add_ref<>(Shared *object); + friend void intrusive_ptr_release<>(Shared *object); + +public: + typedef boost::intrusive_ptr Ptr; + + /** + * Like std::make_shared, but for this class. + * + * @param args Constructor arguments + * + * @return Ptr + */ + template + static inline + Ptr Make(Args&&... args) + { + return new Shared(std::forward(args)...); + } + + inline Shared(const Shared& origin) : Shared((const T&)origin) + { + } + + inline Shared(Shared&& origin) : Shared((T&&)origin) + { + } + + template + inline Shared(Args&&... args) : T(std::forward(args)...), m_References(0) + { + } + + inline Shared& operator=(const Shared& rhs) + { + return operator=((const T&)rhs); + } + + inline Shared& operator=(Shared&& rhs) + { + return operator=((T&&)rhs); + } + + inline Shared& operator=(const T& rhs) + { + T::operator=(rhs); + return *this; + } + + inline Shared& operator=(T&& rhs) + { + T::operator=(std::move(rhs)); + return *this; + } + +private: + Atomic m_References; +}; + +} + +#endif /* SHARED_H */