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])) #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 { class generic_raii {
private: private:
generic_raii( const generic_raii & ) noexcept; generic_raii( const generic_raii & ) noexcept;
@ -28,23 +31,23 @@ class generic_raii {
T handle; T handle;
public: 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(); } ~generic_raii() noexcept { release(); }
void release() noexcept { void release() noexcept {
if (handle != null) { if (handle != null_getter()) {
T temp = handle; T temp = handle;
handle = null; handle = null_getter();
free_T(temp); free_T(temp);
} }
} }
T ptr() noexcept { return handle; } 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; } void attach(T val) noexcept { release(); handle = val; }
T* unsafe_address() noexcept { return &handle; } 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> 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); } static inline void mapping_raii_free(void *x) { UnmapViewOfFile(x); }
typedef generic_raii<void*, mapping_raii_free> mapping_raii; typedef generic_raii<void*, mapping_raii_free> mapping_raii;
static inline HANDLE invalid_handle_value_getter(void) { return INVALID_HANDLE_VALUE; }
class handle_raii { static inline void close_handle(HANDLE x) { CloseHandle(x); }
private: typedef generic_raii<HANDLE, close_handle, invalid_handle_value_getter> handle_raii;
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; }
};
struct prop_variant : PROPVARIANT { struct prop_variant : PROPVARIANT {
prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; } prop_variant(VARTYPE vt=VT_EMPTY) noexcept : PROPVARIANT{} { PropVariantInit(this); this->vt = vt; }