[+] Improved AuSwap

[*] AuWin32CloseHandle should work without including windows.h
[*] AU_CFG_ID_SHIP disables null pointer checks (shared ptr abi)
This commit is contained in:
Reece Wilson 2022-11-17 02:48:58 +00:00
parent dba4a884ca
commit 0c3f6c4158
4 changed files with 75 additions and 27 deletions

View File

@ -54,6 +54,10 @@
// Memory, AuSPtr, and Friends // Memory, AuSPtr, and Friends
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
#if defined(AU_CFG_ID_SHIP)
#define AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED
#endif
#if defined(AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED) #if defined(AURORA_ROXTL_NULL_POINTER_CHECKS_DISABLED)
#define _AURORA_NULLEXPT_ENABLE_UB #define _AURORA_NULLEXPT_ENABLE_UB
#endif #endif

View File

@ -14,27 +14,20 @@
namespace __audetail namespace __audetail
{ {
template <class T> #define _AUROXTL_DETAIAL_HAS(name) \
struct AuHascapacity template <class T> \
{ struct AuHas ## name \
template <class C> static constexpr AuTrueType Test(decltype(&C::capacity)); { \
template <class C> static constexpr AuFalseType Test(...); template <class C> static constexpr AuTrueType Test(decltype(&C::name)); \
using type = decltype(Test<T>(0)); template <class C> static constexpr AuFalseType Test(...); \
}; using type = decltype(Test<T>(0)); \
}; \
\
template <class T> \
constexpr inline bool AuHas ## name ## _v = AuHas ## name<T>::type::value;
template <class T> _AUROXTL_DETAIAL_HAS(capacity)
constexpr inline bool AuHascapacity_v = AuHascapacity<T>::type::value; _AUROXTL_DETAIAL_HAS(reserve)
template <class T>
struct AuHasreserve
{
template <class C> static constexpr AuTrueType Test(decltype(&C::reserve));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
constexpr inline bool AuHasreserve_v = AuHasreserve<T>::type::value;
template <class T> template <class T>
constexpr inline bool AuIsPreallocatable_v = AuHascapacity_v<T> && AuHasreserve_v<T>; constexpr inline bool AuIsPreallocatable_v = AuHascapacity_v<T> && AuHasreserve_v<T>;

View File

@ -6,6 +6,31 @@
***/ ***/
#pragma once #pragma once
namespace __audetail
{
template <class T>
struct AuHasSwap
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void(C:: *)(C &) const>(&C::Swap)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
struct AuHasswap
{
template <class C> static constexpr AuTrueType Test(decltype(static_cast<void(C:: *)(C &) const>(&C::swap)));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<T>(0));
};
template <class T>
constexpr inline bool AuAuHasSwap_v = AuHasSwap<T>::type::value;
template <class T>
constexpr inline bool AuAuHasswap_v = AuHasswap<T>::type::value;
}
template <class T, class U = T> template <class T, class U = T>
inline T AuExchange(T &obj, U &&newValue) inline T AuExchange(T &obj, U &&newValue)
{ {
@ -14,11 +39,29 @@ inline T AuExchange(T &obj, U &&newValue)
return oldValue; return oldValue;
} }
#if !defined(AURORA_RUNTIME_SWAP) #if !defined(AURORA_RUNTIME_SWAP) && !defined(AURORA_SWAP_COCKBLOCK)
#define AURORA_RUNTIME_SWAP std::swap #define AURORA_RUNTIME_SWAP std::swap
#endif #endif
template <class T> template <class T>
inline void AuSwap(T &a, T &b) inline void AuSwap(T &a, T &b)
{ {
if constexpr (__audetail::AuAuHasSwap_v<T>)
{
a.Swap(b);
return;
}
if constexpr (__audetail::AuAuHasswap_v<T>)
{
a.swap(b);
return;
}
#if defined(AURORA_RUNTIME_SWAP)
AURORA_RUNTIME_SWAP(a, b); AURORA_RUNTIME_SWAP(a, b);
return;
#else
static_assert(false, "cannot swap T");
#endif
} }

View File

@ -10,17 +10,25 @@
***/ ***/
#pragma once #pragma once
#if defined(AURORA_IS_MODERNNT_DERIVED) && (defined(_WINDOWS_) || defined(_OTHER_MS_MAIN_HEADER_GUARDS_HERE)) #if defined(AURORA_IS_MODERNNT_DERIVED)
#define _AU_SAW_WIN32_EARLY extern "C"
static auline void AuWin32CloseHandle(HANDLE &handle)
{ {
HANDLE local; __declspec(dllimport) int __stdcall CloseHandle(
void *hObject
);
}
if ((local = AuExchange(handle, INVALID_HANDLE_VALUE)) != INVALID_HANDLE_VALUE) static auline void AuWin32CloseHandle(void *&handle)
{
void *local;
static void *const kInvalidHandle = (void *)((AuUInt)-1);
if ((local = AuExchange(handle, kInvalidHandle)) != kInvalidHandle)
{ {
CloseHandle(local); CloseHandle(local);
} }
} }
#endif #endif