From 9c16603da6389de2bb08f8ac09bde53b50944fb7 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 11 Jun 2025 20:13:49 +0100 Subject: [PATCH] Codechange: Add AutoRelease helper to use function as unique_ptr deleter. (#14353) This allows passing the function as a template parameter instead of requiring a custom deleter functor. --- src/fileio_type.h | 11 ++--------- src/misc/CMakeLists.txt | 1 + src/misc/autorelease.hpp | 27 +++++++++++++++++++++++++++ src/soundloader_opus.cpp | 13 +++---------- 4 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 src/misc/autorelease.hpp diff --git a/src/fileio_type.h b/src/fileio_type.h index 6e35596e87..ab1fee9c9c 100644 --- a/src/fileio_type.h +++ b/src/fileio_type.h @@ -11,6 +11,7 @@ #define FILEIO_TYPE_H #include "core/enum_type.hpp" +#include "misc/autorelease.hpp" /** The different abstract types of files that the system knows about. */ enum AbstractFileType : uint8_t { @@ -142,15 +143,7 @@ public: } private: - /** Helper to close a FILE * with a \c std::unique_ptr. */ - struct FileDeleter { - void operator ()(FILE *f) - { - if (f != nullptr) fclose(f); - } - }; - - std::unique_ptr f; + AutoRelease f; FileHandle(FILE *f) : f(f) { assert(this->f != nullptr); } }; diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt index 031ad3e000..f6df9b38eb 100644 --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -1,5 +1,6 @@ add_files( alternating_iterator.hpp + autorelease.hpp binaryheap.hpp dbg_helpers.cpp dbg_helpers.h diff --git a/src/misc/autorelease.hpp b/src/misc/autorelease.hpp new file mode 100644 index 0000000000..78f5d87226 --- /dev/null +++ b/src/misc/autorelease.hpp @@ -0,0 +1,27 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file autorelease.hpp Helper for std::unique_ptr to use an arbitrary function as the deleter. */ + +#ifndef AUTORELEASE_HPP +#define AUTORELEASE_HPP + +/** Deleter that calls a function rather than deleting the pointer. */ +template +struct DeleterFromFunc { + template + constexpr void operator()(T *arg) const + { + if (arg != nullptr) Tfunc(arg); + } +}; + +/** Specialisation of std::unique_ptr for objects which must be deleted by calling a function. */ +template +using AutoRelease = std::unique_ptr>; + +#endif /* AUTORELEASE_HPP */ diff --git a/src/soundloader_opus.cpp b/src/soundloader_opus.cpp index 5a9645759b..5cf92c571c 100644 --- a/src/soundloader_opus.cpp +++ b/src/soundloader_opus.cpp @@ -8,6 +8,8 @@ /** @file sound_opus.cpp Loading of opus sounds. */ #include "stdafx.h" + +#include "misc/autorelease.hpp" #include "random_access_file_type.h" #include "sound_type.h" #include "soundloader_type.h" @@ -51,7 +53,7 @@ public: sound.file->ReadBlock(tmp.data(), tmp.size()); int error = 0; - auto of = std::unique_ptr(op_open_memory(tmp.data(), tmp.size(), &error)); + auto of = AutoRelease(op_open_memory(tmp.data(), tmp.size(), &error)); if (error != 0) return false; size_t datapos = 0; @@ -81,15 +83,6 @@ public: return true; } - -private: - /** Helper class to RAII release an OggOpusFile. */ - struct OggOpusFileDeleter { - void operator()(OggOpusFile *of) - { - if (of != nullptr) op_free(of); - } - }; }; static SoundLoader_Opus s_sound_loader_opus;