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.
This commit is contained in:
Kovid Goyal 2023-01-27 18:11:26 +05:30
parent ccd5fd83f4
commit ce78a29fc8
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 13 additions and 34 deletions

View File

@ -18,7 +18,10 @@
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
template<typename T=void*, void free_T(T)=free, T null=static_cast<T>(NULL)>
template<typename T>
static inline T generic_null_getter(void) { return T{}; }
template<typename T=void*, void free_T(T)=free, T null_getter(void)=generic_null_getter>
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<typename T>

View File

@ -64,33 +64,9 @@ typedef generic_raii<wchar_t*, co_task_mem_free> com_wchar_raii;
static inline void mapping_raii_free(void *x) { UnmapViewOfFile(x); }
typedef generic_raii<void*, mapping_raii_free> 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, close_handle, invalid_handle_value_getter> handle_raii;
struct prop_variant : PROPVARIANT {
prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }