From 4cdb4e9daaba4bfdaf28552344f3d6aff49884d3 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Fri, 27 Aug 2021 09:28:03 +0200 Subject: [PATCH] LIB: Add a way to do the `if (ptr) free(ptr)` in a generic way --- src/Lib/Audio.hh | 37 ++++++++++++++----------------------- src/Lib/Utils.hh | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/Lib/Audio.hh b/src/Lib/Audio.hh index 3a7ad817..ee0efab5 100644 --- a/src/Lib/Audio.hh +++ b/src/Lib/Audio.hh @@ -37,24 +37,17 @@ public: class Stream final { VIVY_UNMOVABLE_OBJECT(Stream) - // All the needed deleters - static inline constexpr auto codecContexteleter = [](AVCodecContext *ptr) noexcept -> void { - if (ptr) - avcodec_free_context(&ptr); - }; - static constexpr inline auto dataDeleter = [](double *ptr) noexcept -> void { - if (ptr) - av_free(ptr); - }; - static constexpr inline auto avFrameDeleter = [](AVFrame *ptr) noexcept -> void { - if (ptr) - av_frame_free(&ptr); - }; - - static constexpr inline auto swrContenxtDeleter = [](SwrContext *swr) noexcept -> void { - if (swr) - swr_free(&swr); - }; + static inline Utils::DeleterFunctionType<double> dataDeleter = + std::bind_front(Utils::freePtrIfNotNull<double>, av_free); + + static inline Utils::DeleterFunctionType<AVCodecContext> codecContexteleter = + std::bind_front(Utils::freePPtrIfNotNull<AVCodecContext>, avcodec_free_context); + + static inline Utils::DeleterFunctionType<AVFrame> avFrameDeleter = + std::bind_front(Utils::freePPtrIfNotNull<AVFrame>, av_frame_free); + + static inline Utils::DeleterFunctionType<SwrContext> swrContenxtDeleter = + std::bind_front(Utils::freePPtrIfNotNull<SwrContext>, swr_free); // All the used types using AVCodecContextPtr = std::unique_ptr<AVCodecContext, decltype(codecContexteleter)>; @@ -135,11 +128,9 @@ public: private: // Regarding the format - static inline constexpr auto avFormatContextDeleter = - [](AVFormatContext *ptr) noexcept -> void { - if (ptr) - avformat_free_context(ptr); - }; + static inline Utils::DeleterFunctionType<AVFormatContext> avFormatContextDeleter = + std::bind_front(Utils::freePtrIfNotNull<AVFormatContext>, avformat_free_context); + using AVFormatContextPtr = std::unique_ptr<AVFormatContext, decltype(avFormatContextDeleter)>; AVFormatContextPtr format{ avformat_alloc_context(), avFormatContextDeleter }; diff --git a/src/Lib/Utils.hh b/src/Lib/Utils.hh index 3f065353..bf4d0025 100644 --- a/src/Lib/Utils.hh +++ b/src/Lib/Utils.hh @@ -172,6 +172,22 @@ QString getBaseName(const QString &) noexcept; void writeAssertLocation(const char *msg); +template <typename T> using DeleterFunctionType = const std::function<void(T *)>; + +template <typename Type> static inline void +freePtrIfNotNull(DeleterFunctionType<Type> callback, Type *ptr) noexcept +{ + if (ptr != nullptr) + callback(ptr); +} + +template <typename Type> static inline void +freePPtrIfNotNull(DeleterFunctionType<Type *> callback, Type *ptr) noexcept +{ + if (ptr != nullptr) + callback(&ptr); +} + struct OsSpecificAspects final { private: OsSpecificAspects() {} -- GitLab