From 7697a576115c8634b2ce514c1965f1e59b9f2eb4 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 7 Nov 2019 19:54:11 +0100 Subject: [PATCH] Backport rs_unique_cast from grouter_missing_key branch --- libretroshare/src/util/rsmemory.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/libretroshare/src/util/rsmemory.h b/libretroshare/src/util/rsmemory.h index 8bbbc335a..01dc4d8d8 100644 --- a/libretroshare/src/util/rsmemory.h +++ b/libretroshare/src/util/rsmemory.h @@ -62,6 +62,35 @@ bool myFunnyFunction( */ #define RS_DEFAULT_STORAGE_PARAM(Type,...) *std::unique_ptr(new Type(__VA_ARGS__)) + +/** @brief Safely dynamic cast between std::unique_ptr of different types + * std::unique_ptr semantic rely on the invariant that only one instance own + * the object, when casting between differents types one would be tempted to do + * it in a one liner that easly end up breaking that condition ending up in a + * double delete and crash or in a silent memleak. + * With this function one can do that with same comfort of a plain dynamic_cast, + * plus the std::unique_ptr safety. + * @param[inout] src reference to source pointer. If the cast is successfull it + * is released, otherwise it is left untouched. + * @param[out] dst reference to destination pointer. If the cast is successful + * it get reseated to the object address, otherwise it is left untouched. + * @return true on success, false otherwise + */ +template +bool rs_unique_cast( + std::unique_ptr& src, std::unique_ptr& dst ) +{ + T_DST* dstPtr = dynamic_cast(src.get()); + if(dstPtr) + { + src.release(); + dst.reset(dstPtr); + return true; + } + return false; +} + + void *rs_malloc(size_t size) ; // This is a scope guard to release the memory block when going of of the current scope.