From ce78a29fc810907cbc1debd8537fedbe84b9094b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 27 Jan 2023 18:11:26 +0530 Subject: [PATCH] Outsmart clang clang insists INVALID_HANDLE_VALUE is not a constexpr because it is defined as (void*)-1 So it wont let us use it a template paramter. Make the template paramter a function instead that returns the constant value. Hopefully compilers are smart enough to just inline the function call so there is no performance impact. Dont have the patience to check the assembly to make sure. --- src/calibre/utils/cpp_binding.h | 17 ++++++++++------- src/calibre/utils/windows/common.h | 30 +++--------------------------- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/src/calibre/utils/cpp_binding.h b/src/calibre/utils/cpp_binding.h index 1fd9e52932..d5e8712c3e 100644 --- a/src/calibre/utils/cpp_binding.h +++ b/src/calibre/utils/cpp_binding.h @@ -18,7 +18,10 @@ #define arraysz(x) (sizeof(x)/sizeof(x[0])) -template(NULL)> +template +static inline T generic_null_getter(void) { return T{}; } + +template class generic_raii { private: generic_raii( const generic_raii & ) noexcept; @@ -28,23 +31,23 @@ class generic_raii { T handle; public: - explicit generic_raii(T h = null) noexcept : handle(h) {} + generic_raii() noexcept { handle = null_getter(); } + explicit generic_raii(T h) noexcept : handle(h) {} ~generic_raii() noexcept { release(); } void release() noexcept { - if (handle != null) { + if (handle != null_getter()) { T temp = handle; - handle = null; + handle = null_getter(); free_T(temp); } } T ptr() noexcept { return handle; } - T detach() noexcept { T ans = handle; handle = null; return ans; } + T detach() noexcept { T ans = handle; handle = null_getter(); return ans; } void attach(T val) noexcept { release(); handle = val; } T* unsafe_address() noexcept { return &handle; } - explicit operator bool() const noexcept { return handle != null; } - + explicit operator bool() const noexcept { return handle != null_getter(); } }; template diff --git a/src/calibre/utils/windows/common.h b/src/calibre/utils/windows/common.h index 1ae3b57e99..e37feafaa6 100644 --- a/src/calibre/utils/windows/common.h +++ b/src/calibre/utils/windows/common.h @@ -64,33 +64,9 @@ typedef generic_raii com_wchar_raii; static inline void mapping_raii_free(void *x) { UnmapViewOfFile(x); } typedef generic_raii mapping_raii; - -class handle_raii { - private: - handle_raii( const handle_raii & ) noexcept; - handle_raii & operator=( const handle_raii & ) noexcept ; - - protected: - HANDLE handle; - - public: - explicit handle_raii(HANDLE h = INVALID_HANDLE_VALUE) noexcept : handle(h) {} - ~handle_raii() noexcept { release(); } - - void release() noexcept { - if (handle != INVALID_HANDLE_VALUE) { - HANDLE temp = handle; - handle = INVALID_HANDLE_VALUE; - CloseHandle(temp); - } - } - - HANDLE ptr() noexcept { return handle; } - HANDLE detach() noexcept { HANDLE ans = handle; handle = INVALID_HANDLE_VALUE; return ans; } - void attach(HANDLE val) noexcept { release(); handle = val; } - explicit operator bool() const noexcept { return handle != INVALID_HANDLE_VALUE; } -}; - +static inline HANDLE invalid_handle_value_getter(void) { return INVALID_HANDLE_VALUE; } +static inline void close_handle(HANDLE x) { CloseHandle(x); } +typedef generic_raii handle_raii; struct prop_variant : PROPVARIANT { prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }