From: Jérémie Galarneau Date: Thu, 28 Apr 2022 15:28:15 +0000 (-0400) Subject: Add make_unique_wrapper() X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=8802d23ba9c07d32d0da22213d8e76ed102d553f;p=lttng-tools.git Add make_unique_wrapper() make_unique_wrapper is intended to facilitate the use of std::unique_ptr to wrap C-style APIs that don't provide RAII resource management facilities. Usage example: // API struct my_c_struct { // ... }; struct my_c_struct *create_my_c_struct(void); void destroy_my_c_struct(struct my_c_struct *value); // Creating a unique_ptr to my_c_struct. auto safe_c_struct = lttng::make_unique_wrapper( create_my_c_struct()); Note that this facility is intended for use in the scope of a function. If you need to return this unique_ptr instance, you should consider writting a proper, idiomatic, wrapper. Signed-off-by: Jérémie Galarneau Change-Id: I429fc6f62896efb04af95fc26143096043206265 --- diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b0191dd47..928f8d30b 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -87,6 +87,7 @@ libcommon_lgpl_la_SOURCES = \ kernel-probe.cpp \ location.cpp \ log-level-rule.cpp \ + make-unique-wrapper.hpp \ mi-lttng.cpp mi-lttng.hpp \ notification.cpp \ payload.cpp payload.hpp \ diff --git a/src/common/make-unique-wrapper.hpp b/src/common/make-unique-wrapper.hpp new file mode 100644 index 000000000..50d1916f2 --- /dev/null +++ b/src/common/make-unique-wrapper.hpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2022 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_MAKE_UNIQUE_WRAPPER_H +#define LTTNG_MAKE_UNIQUE_WRAPPER_H + +#include + +#include + +namespace lttng { + +/* + * make_unique_wrapper is intended to facilitate the use of std::unique_ptr + * to wrap C-style APIs that don't provide RAII resource management facilities. + * + * Usage example: + * + * // API + * struct my_c_struct { + * // ... + * }; + * + * struct my_c_struct *create_my_c_struct(void); + * void destroy_my_c_struct(struct my_c_struct *value); + * + * // Creating a unique_ptr to my_c_struct. + * auto safe_c_struct = + * lttng::make_unique_wrapper( + * create_my_c_struct()); + * + * Note that this facility is intended for use in the scope of a function. + * If you need to return this unique_ptr instance, you should consider writting + * a proper, idiomatic, wrapper. + */ + +namespace details +{ +template +struct create_unique_class { + struct deleter { + void operator()(WrappedType *instance) const + { + DeleterFunction(instance); + } + }; + + std::unique_ptr operator()(WrappedType *instance) const + { + return std::unique_ptr(instance); + } +}; +} /* namespace details */ + +/* + * 'free' is a utility function for use with make_unique_wrapper. It makes it easier to + * wrap raw pointers that have to be deleted with `free`. Using libc's 'free' as + * a make_unique_wrapper template argument will result in an error as 'WrappedType *' will + * not match free's 'void *' argument. + */ +template +void free(Type *ptr) +{ + std::free(ptr); +} + +template +std::unique_ptr::deleter> +make_unique_wrapper(WrappedType *instance) +{ + const details::create_unique_class unique_deleter; + + return unique_deleter(instance); +} + +} /* namespace lttng */ + +#endif /* LTTNG_MAKE_UNIQUE_WRAPPER_H */