diff --git a/include/fast_io_core_impl/allocation/mimalloc_driver.h b/include/fast_io_core_impl/allocation/mimalloc_driver.h index 391f14b42..0be7934e9 100644 --- a/include/fast_io_core_impl/allocation/mimalloc_driver.h +++ b/include/fast_io_core_impl/allocation/mimalloc_driver.h @@ -34,6 +34,7 @@ extern void * #endif #endif ; + #if defined(_MSC_VER) && !defined(__clang__) __declspec(dllimport) #elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) @@ -115,6 +116,114 @@ extern void * #endif ; +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if __has_cpp_attribute(__gnu__::__cdecl__) && ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +[[__gnu__::__cdecl__]] +#endif +extern void * +#if !__has_cpp_attribute(__gnu__::__cdecl__) && defined(_MSC_VER) + __cdecl +#endif + mi_malloc_aligned(::std::size_t size, ::std::size_t alignment) noexcept +#if (defined(__clang__) || defined(__GNUC__)) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) && \ + ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +#if !defined(__clang__) + __asm__("mi_malloc_aligned") +#else + __asm__("_mi_malloc_aligned") +#endif +#else + __asm__("mi_malloc_aligned") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if __has_cpp_attribute(__gnu__::__cdecl__) && ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +[[__gnu__::__cdecl__]] +#endif +extern void * +#if !__has_cpp_attribute(__gnu__::__cdecl__) && defined(_MSC_VER) + __cdecl +#endif + mi_ralloc_aligned(void *p, ::std::size_t size, ::std::size_t alignment) noexcept +#if (defined(__clang__) || defined(__GNUC__)) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) && \ + ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +#if !defined(__clang__) + __asm__("mi_ralloc_aligned") +#else + __asm__("_mi_ralloc_aligned") +#endif +#else + __asm__("mi_ralloc_aligned") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if __has_cpp_attribute(__gnu__::__cdecl__) && ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +[[__gnu__::__cdecl__]] +#endif +extern void * +#if !__has_cpp_attribute(__gnu__::__cdecl__) && defined(_MSC_VER) + __cdecl +#endif + mi_calloc_aligned(::std::size_t count, ::std::size_t size, ::std::size_t alignment) noexcept +#if (defined(__clang__) || defined(__GNUC__)) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) && \ + ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +#if !defined(__clang__) + __asm__("mi_calloc_aligned") +#else + __asm__("_mi_calloc_aligned") +#endif +#else + __asm__("mi_calloc_aligned") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if __has_cpp_attribute(__gnu__::__cdecl__) && ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +[[__gnu__::__cdecl__]] +#endif +extern void * +#if !__has_cpp_attribute(__gnu__::__cdecl__) && defined(_MSC_VER) + __cdecl +#endif + mi_free_aligned(void *p, ::std::size_t alignment) noexcept +#if (defined(__clang__) || defined(__GNUC__)) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) && \ + ((defined(_WIN32) && !defined(__WINE__)) || defined(__CYGWIN__)) +#if !defined(__clang__) + __asm__("mi_calloc_aligned") +#else + __asm__("_mi_calloc_aligned") +#endif +#else + __asm__("mi_calloc_aligned") +#endif +#endif + ; + } // namespace mimalloc class mimalloc_allocator @@ -123,8 +232,13 @@ class mimalloc_allocator #if __has_cpp_attribute(__gnu__::__returns_nonnull__) [[__gnu__::__returns_nonnull__]] #endif - static inline void *allocate(::std::size_t n) noexcept + static inline void * + allocate(::std::size_t n) noexcept { + if (n == 0) [[unlikely]] + { + n = 1; + } void *p = ::fast_io::mimalloc::mi_malloc(n); if (p == nullptr) { @@ -132,8 +246,17 @@ class mimalloc_allocator } return p; } - static inline void *reallocate(void *p, ::std::size_t n) noexcept + +#if __has_cpp_attribute(__gnu__::__returns_nonnull__) + [[__gnu__::__returns_nonnull__]] +#endif + static inline void * + reallocate(void *p, ::std::size_t n) noexcept { + if (n == 0) [[unlikely]] + { + n = 1; + } p = ::fast_io::mimalloc::mi_realloc(p, n); if (p == nullptr) { @@ -141,8 +264,17 @@ class mimalloc_allocator } return p; } - static inline void *allocate_zero(::std::size_t n) noexcept + +#if __has_cpp_attribute(__gnu__::__returns_nonnull__) + [[__gnu__::__returns_nonnull__]] +#endif + static inline void * + allocate_zero(::std::size_t n) noexcept { + if (n == 0) [[unlikely]] + { + n = 1; + } void *p = ::fast_io::mimalloc::mi_calloc(1, n); if (p == nullptr) { @@ -150,10 +282,73 @@ class mimalloc_allocator } return p; } - static inline void deallocate(void *p) noexcept + + inline static void deallocate(void *p) noexcept { ::fast_io::mimalloc::mi_free(p); } +#if __has_cpp_attribute(__gnu__::__returns_nonnull__) + [[__gnu__::__returns_nonnull__]] +#endif + static inline void * + allocate_aligned(::std::size_t alignment, ::std::size_t n) noexcept + { + if (n == 0) [[unlikely]] + { + n = 1; + } + void *p = ::fast_io::mimalloc::mi_malloc_aligned(n, alignment); + if (p == nullptr) + { + ::fast_io::fast_terminate(); + } + return p; + } + +#if __has_cpp_attribute(__gnu__::__returns_nonnull__) + [[__gnu__::__returns_nonnull__]] +#endif + static inline void * + reallocate_aligned(void *p, ::std::size_t alignment, ::std::size_t n) noexcept + { + if (n == 0) [[unlikely]] + { + n = 1; + } + p = ::fast_io::mimalloc::mi_ralloc_aligned(p, n, alignment); + if (p == nullptr) + { + ::fast_io::fast_terminate(); + } + return p; + } + +#if __has_cpp_attribute(__gnu__::__returns_nonnull__) + [[__gnu__::__returns_nonnull__]] +#endif + static inline void * + allocate_zero_aligned(::std::size_t n, ::std::size_t alignment) noexcept + { + if (n == 0) [[unlikely]] + { + n = 1; + } + void *p = ::fast_io::mimalloc::mi_calloc_aligned(1, n, alignment); + if (p == nullptr) + { + ::fast_io::fast_terminate(); + } + return p; + } + + inline static void deallocate_aligned(void *p, ::std::size_t alignment) noexcept + { + if (p == nullptr) + { + return; + } + ::fast_io::mimalloc::mi_free_aligned(p, alignment); + } }; -} // namespace fast_io \ No newline at end of file +} // namespace fast_io diff --git a/include/fast_io_core_impl/allocation/msvc/msvc_linker_32.h b/include/fast_io_core_impl/allocation/msvc/msvc_linker_32.h index 65a2cebf8..50e95ab8b 100644 --- a/include/fast_io_core_impl/allocation/msvc/msvc_linker_32.h +++ b/include/fast_io_core_impl/allocation/msvc/msvc_linker_32.h @@ -11,5 +11,17 @@ #pragma comment(linker, "/alternatename:__imp_?RtlGetCurrentPeb@nt@win32@fast_io@@YAPAUpeb@123@XZ=__imp_RtlGetCurrentPeb") #pragma comment(linker, "/alternatename:__imp_?RtlReAllocateHeap@nt@win32@fast_io@@YAPAXPAXI0I@Z=__imp_RtlReAllocateHeap") #pragma comment(linker, "/alternatename:__imp_?RtlSizeHeap@nt@win32@fast_io@@YAIPAXI0@Z=__imp_RtlSizeHeap") +#pragma comment(linker, "/alternatename:__imp_?VirtualAlloc@win32@fast_io@@YAPAXPAXIII@Z=__imp_VirtualAlloc") +#pragma comment(linker, "/alternatename:__imp_?VirtualProtect@win32@fast_io@@YAHPAXIIPAI@Z=__imp_VirtualProtect") +#pragma comment(linker, "/alternatename:__imp_?VirtualFree@win32@fast_io@@YAHPAXII@Z=__imp_VirtualFree") +#pragma comment(linker, "/alternatename:__imp_?VirtualQuery@win32@fast_io@@YAHPBXPAUmemory_basic_information@12@I@Z=__imp_VirtualQuery") +#pragma comment(linker, "/alternatename:__imp_?mi_malloc@mimalloc@fast_io@@YAPAXI@Z=mi_malloc") +#pragma comment(linker, "/alternatename:__imp_?mi_free@mimalloc@fast_io@@YAXPAX@Z=mi_free") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc@mimalloc@fast_io@@YAPAXII@Z=mi_calloc") +#pragma comment(linker, "/alternatename:__imp_?mi_realloc@mimalloc@fast_io@@YAPAXPAXI@Z=mi_realloc") +#pragma comment(linker, "/alternatename:__imp_?mi_malloc_aligned@mimalloc@fast_io@@YAPAXII@Z=mi_malloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_ralloc_aligned@mimalloc@fast_io@@YAPAXPAXII@Z=mi_ralloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc_aligned@mimalloc@fast_io@@YAPAXIII@Z=mi_calloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_free_aligned@mimalloc@fast_io@@YAPAXPAXI@Z=mi_free_aligned") // clang-format on diff --git a/include/fast_io_core_impl/allocation/msvc/msvc_linker_32_i686.h b/include/fast_io_core_impl/allocation/msvc/msvc_linker_32_i686.h index 510be5f21..0219f9ab5 100644 --- a/include/fast_io_core_impl/allocation/msvc/msvc_linker_32_i686.h +++ b/include/fast_io_core_impl/allocation/msvc/msvc_linker_32_i686.h @@ -11,5 +11,17 @@ #pragma comment(linker, "/alternatename:__imp_?RtlGetCurrentPeb@nt@win32@fast_io@@YGPAUpeb@123@XZ=__imp__RtlGetCurrentPeb@0") #pragma comment(linker, "/alternatename:__imp_?RtlReAllocateHeap@nt@win32@fast_io@@YGPAXPAXI0I@Z=__imp__RtlReAllocateHeap@16") #pragma comment(linker, "/alternatename:__imp_?RtlSizeHeap@nt@win32@fast_io@@YGIPAXI0@Z=__imp__RtlSizeHeap@12") +#pragma comment(linker, "/alternatename:__imp_?VirtualAlloc@win32@fast_io@@YGPAXPAXIII@Z=__imp__VirtualAlloc@16") +#pragma comment(linker, "/alternatename:__imp_?VirtualProtect@win32@fast_io@@YGHPAXIIPAI@Z=__imp__VirtualProtect@16") +#pragma comment(linker, "/alternatename:__imp_?VirtualFree@win32@fast_io@@YGHPAXII@Z=__imp__VirtualFree@12") +#pragma comment(linker, "/alternatename:__imp_?VirtualQuery@win32@fast_io@@YGHPBXPAUmemory_basic_information@12@I@Z=__imp__VirtualQuery@12") +#pragma comment(linker, "/alternatename:__imp_?mi_malloc@mimalloc@fast_io@@YAPAXI@Z=_mi_malloc") +#pragma comment(linker, "/alternatename:__imp_?mi_free@mimalloc@fast_io@@YAXPAX@Z=_mi_free") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc@mimalloc@fast_io@@YAPAXII@Z=_mi_calloc") +#pragma comment(linker, "/alternatename:__imp_?mi_realloc@mimalloc@fast_io@@YAPAXPAXI@Z=_mi_realloc") +#pragma comment(linker, "/alternatename:__imp_?mi_malloc_aligned@mimalloc@fast_io@@YAPAXII@Z=_mi_malloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_ralloc_aligned@mimalloc@fast_io@@YAPAXPAXII@Z=_mi_ralloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc_aligned@mimalloc@fast_io@@YAPAXIII@Z=_mi_calloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_free_aligned@mimalloc@fast_io@@YAPAXPAXI@Z=_mi_free_aligned") // clang-format on diff --git a/include/fast_io_core_impl/allocation/msvc/msvc_linker_64.h b/include/fast_io_core_impl/allocation/msvc/msvc_linker_64.h index dcedc7def..cc28ff169 100644 --- a/include/fast_io_core_impl/allocation/msvc/msvc_linker_64.h +++ b/include/fast_io_core_impl/allocation/msvc/msvc_linker_64.h @@ -11,5 +11,18 @@ #pragma comment(linker, "/alternatename:__imp_?RtlGetCurrentPeb@nt@win32@fast_io@@YAPEAUpeb@123@XZ=__imp_RtlGetCurrentPeb") #pragma comment(linker, "/alternatename:__imp_?RtlReAllocateHeap@nt@win32@fast_io@@YAPEAXPEAXI0_K@Z=__imp_RtlReAllocateHeap") #pragma comment(linker, "/alternatename:__imp_?RtlSizeHeap@nt@win32@fast_io@@YA_KPEAXI0@Z=__imp_RtlSizeHeap") +#pragma comment(linker, "/alternatename:__imp_?VirtualAlloc@win32@fast_io@@YAPEAXPEAX_KII@Z=__imp_VirtualAlloc") +#pragma comment(linker, "/alternatename:__imp_?VirtualProtect@win32@fast_io@@YAHPEAX_KIPEAI@Z=__imp_VirtualProtect") +#pragma comment(linker, "/alternatename:__imp_?VirtualFree@win32@fast_io@@YAHPEAX_KI@Z=__imp_VirtualFree") +#pragma comment(linker, "/alternatename:__imp_?__imp_?VirtualQuery@win32@fast_io@@YAHPEBXPEAUmemory_basic_information@12@_K@Z=__imp_VirtualQuery") + +#pragma comment(linker, "/alternatename:__imp_?mi_malloc@mimalloc@fast_io@@YAPEAX_K@Z=mi_malloc") +#pragma comment(linker, "/alternatename:__imp_?mi_free@mimalloc@fast_io@@YAXPEAX@Z=mi_free") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc@mimalloc@fast_io@@YAPEAX_K0@Z=mi_calloc") +#pragma comment(linker, "/alternatename:__imp_?mi_realloc@mimalloc@fast_io@@YAPEAXPEAX_K@Z=mi_realloc") +#pragma comment(linker, "/alternatename:__imp_?mi_malloc_aligned@mimalloc@fast_io@@YAPEAX_K0@Z=mi_malloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_ralloc_aligned@mimalloc@fast_io@@YAPEAXPEAX_K1@Z=mi_ralloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_calloc_aligned@mimalloc@fast_io@@YAPEAX_K00@Z=mi_calloc_aligned") +#pragma comment(linker, "/alternatename:__imp_?mi_free_aligned@mimalloc@fast_io@@YAPEAXPEAX_K@Z=mi_free_aligned") // clang-format on diff --git a/include/fast_io_core_impl/allocation/win32_heapalloc.h b/include/fast_io_core_impl/allocation/win32_heapalloc.h index eb3b80a3a..1232807e0 100644 --- a/include/fast_io_core_impl/allocation/win32_heapalloc.h +++ b/include/fast_io_core_impl/allocation/win32_heapalloc.h @@ -3,6 +3,23 @@ namespace fast_io { +namespace win32 +{ +struct memory_basic_information +{ + void *BaseAddress; + void *AllocationBase; + ::std::uint_least32_t AllocationProtect; +#if defined(_WIN64) + ::std::uint_least16_t PartitionId; +#endif + ::std::size_t RegionSize; + ::std::uint_least32_t State; + ::std::uint_least32_t Protect; + ::std::uint_least32_t Type; +}; +} // namespace win32 + namespace win32 { #if defined(_MSC_VER) && !defined(__clang__) @@ -141,6 +158,122 @@ extern ::std::size_t #endif ; +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +#if __has_cpp_attribute(__gnu__::__const__) +[[__gnu__::__const__]] +#endif +extern void * +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + VirtualAlloc(void *, ::std::size_t, ::std::uint_least32_t, ::std::uint_least32_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("VirtualAlloc@16") +#else + __asm__("_VirtualAlloc@16") +#endif +#else + __asm__("VirtualAlloc") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +#if __has_cpp_attribute(__gnu__::__const__) +[[__gnu__::__const__]] +#endif +extern int +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + VirtualProtect(void *, ::std::size_t, ::std::uint_least32_t, ::std::uint_least32_t *) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("VirtualProtect@16") +#else + __asm__("_VirtualProtect@16") +#endif +#else + __asm__("VirtualProtect") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +#if __has_cpp_attribute(__gnu__::__const__) +[[__gnu__::__const__]] +#endif +extern int +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + VirtualFree(void *, ::std::size_t, ::std::uint_least32_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("VirtualFree@12") +#else + __asm__("_VirtualFree@12") +#endif +#else + __asm__("VirtualFree") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +#if __has_cpp_attribute(__gnu__::__const__) +[[__gnu__::__const__]] +#endif +extern int +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + VirtualQuery(void const *, memory_basic_information *, ::std::size_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("VirtualQuery@12") +#else + __asm__("_VirtualQuery@12") +#endif +#else + __asm__("VirtualQuery") +#endif +#endif + ; + } // namespace win32 namespace details diff --git a/include/fast_io_core_impl/allocation/wincrt_malloc_dbg.h b/include/fast_io_core_impl/allocation/wincrt_malloc_dbg.h index d3872f998..beb1fa117 100644 --- a/include/fast_io_core_impl/allocation/wincrt_malloc_dbg.h +++ b/include/fast_io_core_impl/allocation/wincrt_malloc_dbg.h @@ -17,7 +17,7 @@ class wincrt_malloc_dbg_allocator { n = 1; } - void *p = ::fast_io::noexcept_call(_malloc_dbg, n, 1, __FILE__, __LINE__); + void *p = ::fast_io::noexcept_call(_malloc_dbg, n, _NORMAL_BLOCK, __FILE__, __LINE__); if (p == nullptr) { ::fast_io::fast_terminate(); @@ -33,7 +33,7 @@ class wincrt_malloc_dbg_allocator { n = 1; } - p = ::fast_io::noexcept_call(_realloc_dbg, p, n, 1, __FILE__, __LINE__); + p = ::fast_io::noexcept_call(_realloc_dbg, p, n, _NORMAL_BLOCK, __FILE__, __LINE__); if (p == nullptr) { ::fast_io::fast_terminate(); @@ -49,7 +49,7 @@ class wincrt_malloc_dbg_allocator { n = 1; } - void *p = ::fast_io::noexcept_call(_calloc_dbg, 1, n, 1, __FILE__, __LINE__); + void *p = ::fast_io::noexcept_call(_calloc_dbg, 1, n, _NORMAL_BLOCK, __FILE__, __LINE__); if (p == nullptr) { ::fast_io::fast_terminate(); @@ -62,24 +62,24 @@ class wincrt_malloc_dbg_allocator { return; } - ::fast_io::noexcept_call(_free_dbg, p, 1); + ::fast_io::noexcept_call(_free_dbg, p, _NORMAL_BLOCK); } #if 0 static inline allocation_least_result allocate_at_least(::std::size_t n) noexcept { auto p{::fast_io::wincrt_malloc_dbg_allocator::allocate(n)}; - return {p, ::fast_io::noexcept_call(_msize_dbg, p, 1)}; + return {p, ::fast_io::noexcept_call(_msize_dbg, p, _NORMAL_BLOCK)}; } static inline allocation_least_result allocate_zero_at_least(::std::size_t n) noexcept { auto p{::fast_io::wincrt_malloc_dbg_allocator::allocate_zero(n)}; - return {p, ::fast_io::noexcept_call(_msize_dbg, p, 1)}; + return {p, ::fast_io::noexcept_call(_msize_dbg, p, _NORMAL_BLOCK)}; } static inline allocation_least_result reallocate_at_least(void *oldp, ::std::size_t n) noexcept { auto p{::fast_io::wincrt_malloc_dbg_allocator::reallocate(oldp, n)}; - return {p, ::fast_io::noexcept_call(_msize_dbg, p, 1)}; + return {p, ::fast_io::noexcept_call(_msize_dbg, p, _NORMAL_BLOCK)}; } #endif }; diff --git a/include/fast_io_core_impl/codecvt/general.h b/include/fast_io_core_impl/codecvt/general.h index cae452077..e599a3803 100644 --- a/include/fast_io_core_impl/codecvt/general.h +++ b/include/fast_io_core_impl/codecvt/general.h @@ -197,7 +197,7 @@ general_code_cvt(src_char_type const *src_first, src_char_type const *src_last, if constexpr (src_encoding != encoding_scheme::utf_ebcdic && encoding != encoding_scheme::utf_ebcdic && 1 == sizeof(src_char_type) && (1 == sizeof(dest_char_type) || encoding_is_utf(encoding))) { - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { constexpr ::std::size_t m128i_size{16}; while (m128i_size < static_cast<::std::size_t>(src_last - src_first)) diff --git a/include/fast_io_core_impl/freestanding/algorithm.h b/include/fast_io_core_impl/freestanding/algorithm.h index 8a712dc97..6485e2002 100644 --- a/include/fast_io_core_impl/freestanding/algorithm.h +++ b/include/fast_io_core_impl/freestanding/algorithm.h @@ -140,6 +140,7 @@ inline constexpr Iter find(Iter first, Iter last, T t) } return last; } + #if 0 template <::std::input_iterator Iter, ::std::integral T> // requires (::std::is_trivially_copyable_v&&sizeof(T)<=sizeof(::std::uintmax_t)) @@ -156,6 +157,7 @@ inline constexpr Iter find_not(Iter first, Iter last, T t) return last; } #endif + template <::std::input_iterator Iter, ::std::input_iterator Iter2> struct mismatch_result { diff --git a/include/fast_io_core_impl/freestanding/cstr_len.h b/include/fast_io_core_impl/freestanding/cstr_len.h index 60164dfda..685388745 100644 --- a/include/fast_io_core_impl/freestanding/cstr_len.h +++ b/include/fast_io_core_impl/freestanding/cstr_len.h @@ -31,7 +31,7 @@ inline constexpr ::std::size_t dummy_cstr_nlen(char_type const *cstr, ::std::siz template <::std::integral char_type> inline constexpr ::std::size_t cstr_len(char_type const *cstr) noexcept { -#ifdef __cpp_if_consteval +#if __cpp_if_consteval >= 202106L if consteval { return details::dummy_cstr_len(cstr); @@ -66,7 +66,7 @@ inline constexpr ::std::size_t cstr_len(char_type const *cstr) noexcept template <::std::integral char_type> inline constexpr ::std::size_t cstr_nlen(char_type const *cstr, ::std::size_t n) noexcept { -#ifdef __cpp_if_consteval +#if __cpp_if_consteval >= 202106L if consteval { return details::dummy_cstr_nlen(cstr, n); diff --git a/include/fast_io_core_impl/freestanding/noexcept_call.h b/include/fast_io_core_impl/freestanding/noexcept_call.h index d1bec42d5..22571ae4c 100644 --- a/include/fast_io_core_impl/freestanding/noexcept_call.h +++ b/include/fast_io_core_impl/freestanding/noexcept_call.h @@ -66,7 +66,7 @@ inline } #else #if __cpp_lib_is_constant_evaluated >= 201811 - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return f(::std::forward(args)...); // EH unwinding does not matter here } diff --git a/include/fast_io_core_impl/intrinsics.h b/include/fast_io_core_impl/intrinsics.h index 896a843f2..b37b439c6 100644 --- a/include/fast_io_core_impl/intrinsics.h +++ b/include/fast_io_core_impl/intrinsics.h @@ -209,7 +209,7 @@ inline constexpr bool add_carry(bool carry, T a, T b, T &out) noexcept } else #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return add_carry_naive(carry, a, b, out); } @@ -402,7 +402,7 @@ inline constexpr bool sub_borrow(bool borrow, T a, T b, T &out) noexcept return sub_borrow_naive(borrow, a, b, out); } #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return sub_borrow_naive(borrow, a, b, out); } @@ -631,7 +631,7 @@ inline } else #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { __uint128_t res{static_cast<__uint128_t>(a) * b}; high = static_cast<::std::uint_least64_t>(res >> 64u); @@ -687,7 +687,7 @@ inline } else #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return umul_least_64_emulated(a, b, high); } @@ -750,7 +750,7 @@ inline } else #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return umul_least64_high_emulated(a, b); } @@ -768,7 +768,7 @@ inline constexpr ::std::size_t add_or_overflow_die(::std::size_t a, ::std::size_ { #if defined(_MSC_VER) && !defined(__clang__) #if __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { #if defined(_M_X64) ::std::size_t res; @@ -955,7 +955,7 @@ template inline constexpr U shiftright(U low_part, U high_part, ::std::uint_least8_t shift) noexcept { #if __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return shiftright_naive(low_part, high_part, shift); } diff --git a/include/fast_io_core_impl/io_lockable.h b/include/fast_io_core_impl/io_lockable.h index 2019f6110..e75c5d702 100644 --- a/include/fast_io_core_impl/io_lockable.h +++ b/include/fast_io_core_impl/io_lockable.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once namespace fast_io { diff --git a/include/fast_io_core_impl/local_new_array_ptr.h b/include/fast_io_core_impl/local_new_array_ptr.h index 3e467ab76..32af660f9 100644 --- a/include/fast_io_core_impl/local_new_array_ptr.h +++ b/include/fast_io_core_impl/local_new_array_ptr.h @@ -10,7 +10,7 @@ inline constexpr char_type *allocate_iobuf_space(::std::size_t buffer_size) noex #if __cpp_if_consteval >= 202106L if consteval #else - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { return new char_type[buffer_size]; @@ -47,7 +47,7 @@ inline constexpr void deallocate_iobuf_space(char_type *ptr, [[maybe_unused]] :: #if __cpp_if_consteval >= 202106L if consteval #else - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { delete[] ptr; diff --git a/include/fast_io_core_impl/operations/writeimpl/scatterp.h b/include/fast_io_core_impl/operations/writeimpl/scatterp.h index 54fa42332..8af7682c3 100644 --- a/include/fast_io_core_impl/operations/writeimpl/scatterp.h +++ b/include/fast_io_core_impl/operations/writeimpl/scatterp.h @@ -55,12 +55,13 @@ scatter_pwrite_some_cold_impl(outstmtype outsm, ::fast_io::details::scatter_pwrite_all_bytes_cold_impl(outsm, pscatters, n, off); return {n, 0}; } - else if constexpr ((::fast_io::operations::decay::defines::has_pwrite_all_bytes_overflow_define || - ::fast_io::operations::decay::defines::has_scatter_pwrite_all_bytes_overflow_define< - outstmtype> || - ::fast_io::operations::decay::defines::has_pwrite_some_bytes_overflow_define || - ::fast_io::operations::decay::defines::has_scatter_pwrite_some_bytes_overflow_define< - outstmtype>)) + else +#if 0 + if constexpr ((::fast_io::operations::decay::defines::has_pwrite_all_bytes_overflow_define || +#endif + /* + * The implementation of synthesizing pwrite through write+seek is missing + */ { if constexpr (sizeof(char_type) == 1) { @@ -178,12 +179,18 @@ scatter_pwrite_all_cold_impl(outstmtype outsm, off = ::fast_io::fposoffadd_nonegative(off, len); } } - else if constexpr ((::fast_io::operations::decay::defines::has_pwrite_all_bytes_overflow_define || + else +#if 0 +if constexpr ((::fast_io::operations::decay::defines::has_pwrite_all_bytes_overflow_define || ::fast_io::operations::decay::defines::has_scatter_pwrite_all_bytes_overflow_define< outstmtype> || ::fast_io::operations::decay::defines::has_pwrite_some_bytes_overflow_define || ::fast_io::operations::decay::defines::has_scatter_pwrite_some_bytes_overflow_define< outstmtype>)) +#endif + /* + * The implementation of synthesizing pwrite through write+seek is missing + */ { using char_type = typename outstmtype::output_char_type; if constexpr (sizeof(char_type) == 1) diff --git a/include/fast_io_core_impl/random_access_transmit.h b/include/fast_io_core_impl/random_access_transmit.h index 12d13b4d1..1061ed873 100644 --- a/include/fast_io_core_impl/random_access_transmit.h +++ b/include/fast_io_core_impl/random_access_transmit.h @@ -45,7 +45,7 @@ inline constexpr auto random_access_transmit_impl(output &outp, input &inp, ::st else { #ifdef __cpp_lib_is_constant_evaluated - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { seek(inp, offset); return bufferred_transmit_impl(outp, inp, ::std::forward(args)...); diff --git a/include/fast_io_core_impl/simd/is_all_zeros.h b/include/fast_io_core_impl/simd/is_all_zeros.h index 51e67ca1a..93a4955e6 100644 --- a/include/fast_io_core_impl/simd/is_all_zeros.h +++ b/include/fast_io_core_impl/simd/is_all_zeros.h @@ -81,7 +81,7 @@ inline #if __cpp_if_consteval >= 202106L if !consteval #elif __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) #endif { if constexpr (sizeof(::fast_io::intrinsics::simd_vector) == 16) diff --git a/include/fast_io_core_impl/simd/mask_countr.h b/include/fast_io_core_impl/simd/mask_countr.h index a2dd5af7b..d0165713b 100644 --- a/include/fast_io_core_impl/simd/mask_countr.h +++ b/include/fast_io_core_impl/simd/mask_countr.h @@ -101,7 +101,7 @@ inline #if __cpp_if_consteval >= 202106L if consteval #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { return vector_mask_countr_common_no_intrinsics_impl(vec); @@ -140,7 +140,7 @@ inline if constexpr (::fast_io::details::cpu_flags::sse2_supported) { __m128i a = __builtin_bit_cast(__m128i, vec); - ::std::uint_least16_t const value{static_cast<::std::uint_least16_t>(_mm_movemask_epi8(a, a))}; + ::std::uint_least16_t const value{static_cast<::std::uint_least16_t>(_mm_movemask_epi8(a))}; if constexpr (ctzero) { d = static_cast(::std::countr_zero(value)); @@ -172,7 +172,7 @@ inline if constexpr (::fast_io::details::cpu_flags::avx2_supported) { __m256i a = __builtin_bit_cast(__m256i, vec); - ::std::uint_least32_t const value{static_cast<::std::uint_least32_t>(_mm256_movemask_epi8(a, a))}; + ::std::uint_least32_t const value{static_cast<::std::uint_least32_t>(_mm256_movemask_epi8(a))}; if constexpr (ctzero) { d = static_cast(::std::countr_zero(value)); @@ -239,4 +239,4 @@ inline constexpr auto vector_mask_countr_zero(simd_vector const &vec) noex } // namespace intrinsics -} // namespace fast_io \ No newline at end of file +} // namespace fast_io diff --git a/include/fast_io_core_impl/simd_find.h b/include/fast_io_core_impl/simd_find.h index 604c25786..3db9d3393 100644 --- a/include/fast_io_core_impl/simd_find.h +++ b/include/fast_io_core_impl/simd_find.h @@ -365,7 +365,7 @@ inline constexpr char unsigned const *find_characters_musl(char unsigned const * #if __cpp_if_consteval >= 202106L if !consteval #else - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) #endif { constexpr ::std::size_t diff{sizeof(::std::size_t)}; @@ -426,7 +426,7 @@ inline constexpr char_type const *find_simd_constant_common_cold_impl(char_type #if __cpp_if_consteval >= 202106L if !consteval #else - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) #endif { constexpr bool use_builtin_memchr{ @@ -576,7 +576,7 @@ inline constexpr char_type const *find_space_common_cold_impl(char_type const *f #if __cpp_if_consteval >= 202106L if !consteval #else - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) #endif { if constexpr (::fast_io::details::optimal_simd_vector_run_with_cpu_instruction_size) diff --git a/include/fast_io_core_impl/utils.h b/include/fast_io_core_impl/utils.h index ae7107203..5f87f19b0 100644 --- a/include/fast_io_core_impl/utils.h +++ b/include/fast_io_core_impl/utils.h @@ -164,19 +164,19 @@ concept my_floating_point = ::std::floating_point || ::std::same_as<::std::remove_cv_t, __float128> #endif #ifdef __STDCPP_BFLOAT16_T__ - || ::std::same_as<::std::remove_cv_t, decltype(0.0bf16)> + || ::std::same_as<::std::remove_cv_t, decltype(0.0bf16)> #endif #ifdef __STDCPP_FLOAT16_T__ - || ::std::same_as<::std::remove_cv_t, _Float16> + || ::std::same_as<::std::remove_cv_t, _Float16> #endif #ifdef __STDCPP_FLOAT32_T__ - || ::std::same_as<::std::remove_cv_t, _Float32> + || ::std::same_as<::std::remove_cv_t, _Float32> #endif #ifdef __STDCPP_FLOAT64_T__ - || ::std::same_as<::std::remove_cv_t, _Float64> + || ::std::same_as<::std::remove_cv_t, _Float64> #endif #ifdef __STDCPP_FLOAT128_T__ - || ::std::same_as<::std::remove_cv_t, _Float128> + || ::std::same_as<::std::remove_cv_t, _Float128> #endif ; @@ -271,7 +271,7 @@ inline constexpr U byte_swap(U a) noexcept #else #if __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { return details::byte_swap_naive_impl(a); } diff --git a/include/fast_io_crypto/hash/crc32.h b/include/fast_io_crypto/hash/crc32.h index 15725fd97..478040d64 100644 --- a/include/fast_io_crypto/hash/crc32.h +++ b/include/fast_io_crypto/hash/crc32.h @@ -23,7 +23,7 @@ inline constexpr void crc32_to_byte_ptr_commom_impl(::std::uint_least32_t crc, : #if __cpp_if_consteval >= 202106L if consteval #elif __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { auto a{::std::bit_cast<::fast_io::freestanding::array<::std::byte, sizeof(::std::uint_least32_t)>>(crc)}; diff --git a/include/fast_io_crypto/hash/sha1.h b/include/fast_io_crypto/hash/sha1.h index a64db7875..548cc6f78 100644 --- a/include/fast_io_crypto/hash/sha1.h +++ b/include/fast_io_crypto/hash/sha1.h @@ -66,7 +66,7 @@ inline for (::std::byte const *data(blocks_start), *ed(blocks_start + blocks_bytes); data != ed; data += block_size) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { for (::std::size_t j{}; j != 16; ++j) { diff --git a/include/fast_io_crypto/hash/sha256.h b/include/fast_io_crypto/hash/sha256.h index be4045539..1846cd25d 100644 --- a/include/fast_io_crypto/hash/sha256.h +++ b/include/fast_io_crypto/hash/sha256.h @@ -84,7 +84,7 @@ inline for (; i < 16; ++i) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { X[i] = B2U32(data[0], 24) | B2U32(data[1], 16) | B2U32(data[2], 8) | B2U32(data[3], 0); } diff --git a/include/fast_io_crypto/streamcipher/chacha/scalar.h b/include/fast_io_crypto/streamcipher/chacha/scalar.h index 761b69225..24a717716 100644 --- a/include/fast_io_crypto/streamcipher/chacha/scalar.h +++ b/include/fast_io_crypto/streamcipher/chacha/scalar.h @@ -43,7 +43,7 @@ inline #if __cpp_if_consteval >= 202106L if consteval #else - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { for (::std::size_t i{}; i != n; ++i) @@ -83,7 +83,7 @@ inline #if __cpp_if_consteval >= 202106L if consteval #else - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { auto v{::std::bit_cast<::fast_io::freestanding::array<::std::byte, sizeof(::std::uint_least32_t)>>(res)}; diff --git a/include/fast_io_driver/boost/uuid.h b/include/fast_io_driver/boost/uuid.h index b9c278604..9c9a20f6b 100644 --- a/include/fast_io_driver/boost/uuid.h +++ b/include/fast_io_driver/boost/uuid.h @@ -25,7 +25,7 @@ inline constexpr char_type *pr_rsv_boost_uuid(char_type *iter, boost::uuids::uui #if __cpp_if_consteval >= 202106L if consteval #else - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) #endif { ::std::byte buffer[16]; diff --git a/include/fast_io_driver/linux_kernel_impl/kpr.h b/include/fast_io_driver/linux_kernel_impl/kpr.h index 6748fb314..312211107 100644 --- a/include/fast_io_driver/linux_kernel_impl/kpr.h +++ b/include/fast_io_driver/linux_kernel_impl/kpr.h @@ -342,6 +342,31 @@ inline void write_all_bytes_overflow_define(basic_kpr kpr, ::std::byt { ::fast_io::details::linux_kpr_raw_write(kpr.level, first, last); } +#endif + +template <::std::integral ch_type> +inline constexpr basic_kpr io_stream_ref_define(basic_kpr other) noexcept +{ + return other; +} + +template <::std::integral ch_type> +inline constexpr basic_kpr io_bytes_stream_ref_define(basic_kpr other) noexcept +{ + return other; +} + +template <::std::integral ch_type> +inline constexpr void write_all_bytes_overflow_define(basic_kpr d, ::std::byte const *first, ::std::byte const *last) noexcept +{ + details::linux_kpr_raw_write(kpr.level, first, last); +} + +template <::std::integral ch_type> +inline constexpr void pwrite_all_bytes_overflow_define(basic_kpr d, ::std::byte const *first, ::std::byte const *last) noexcept +{ + details::linux_kpr_raw_write(kpr.level, first, last); +} template <::std::integral ch_type> inline constexpr basic_kpr output_stream_ref_define(basic_kpr linuxkpr) noexcept diff --git a/include/fast_io_driver/nt_kernel_impl/driver_func.h b/include/fast_io_driver/nt_kernel_impl/driver_func.h new file mode 100644 index 000000000..6b24be051 --- /dev/null +++ b/include/fast_io_driver/nt_kernel_impl/driver_func.h @@ -0,0 +1,141 @@ +#pragma once + +namespace fast_io::win32::nt +{ +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + IoDeleteSymbolicLink(::fast_io::win32::nt::unicode_string *SymbolicLinkName) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("IoDeleteSymbolicLink@4") +#else + __asm__("_IoDeleteSymbolicLink@4") +#endif +#else + __asm__("IoDeleteSymbolicLink") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + IoDeleteDevice(::fast_io::win32::nt::device_object *DeviceObject) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("IoDeleteDevice@4") +#else + __asm__("_IoDeleteDevice@4") +#endif +#else + __asm__("IoDeleteDevice") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__fastcall__) && !defined(__WINE__)) +[[__gnu__::__fastcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__fastcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __fastcall +#endif + IofCompleteRequest(::fast_io::win32::nt::irp *Irp, char PriorityBoost) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("IofCompleteRequest@8") +#else + __asm__("_IofCompleteRequest@8") +#endif +#else + __asm__("IofCompleteRequest") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + IoCreateDevice(::fast_io::win32::nt::driver_object *DriverObject, + ::std::uint_least32_t DeviceExtensionSize, + ::fast_io::win32::nt::unicode_string *DeviceName, + ::std::uint_least32_t DeviceType, + ::std::uint_least32_t DeviceCharacteristics, + ::std::uint_least8_t Exclusive, + ::fast_io::win32::nt::device_object **DeviceObject) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("IoCreateDevice@28") +#else + __asm__("_IoCreateDevice@28") +#endif +#else + __asm__("IoCreateDevice") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + IoCreateSymbolicLink(::fast_io::win32::nt::unicode_string *SymbolicLinkName, ::fast_io::win32::nt::unicode_string *DeviceName) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("IoCreateSymbolicLink@8") +#else + __asm__("_IoCreateSymbolicLink@8") +#endif +#else + __asm__("IoCreateSymbolicLink") +#endif +#endif + ; + +} // namespace fast_io::win32::nt diff --git a/include/fast_io_driver/nt_kernel_impl/driver_object.h b/include/fast_io_driver/nt_kernel_impl/driver_object.h index 107a943b6..e0b380642 100644 --- a/include/fast_io_driver/nt_kernel_impl/driver_object.h +++ b/include/fast_io_driver/nt_kernel_impl/driver_object.h @@ -2,23 +2,671 @@ namespace fast_io::win32::nt { +struct driver_object; +struct device_object; -struct driver_object +struct list_entry +{ + list_entry *Flink; + list_entry *Blink; +}; + +struct single_list_entry +{ + single_list_entry *Next; +}; + +struct kdevice_queue { ::std::int_least16_t Type; ::std::int_least16_t Size; - driver_object *DeviceObject; + list_entry DeviceListHead; + ::std::size_t Lock; + +#if defined(__x86_64__) || defined(_M_AMD64) + + union + { + ::std::uint_least8_t Busy; + + struct + { + ::std::int_least64_t Reserved : 8; + ::std::int_least64_t Hint : 56; + }; + }; + +#else + + ::std::uint_least8_t Busy; + +#endif +}; + +struct kdevice_queue_entry +{ + list_entry DeviceListEntry; + ::std::uint_least32_t SortKey; + ::std::uint_least8_t Inserted; +}; + +enum class io_allocation_action +{ + KeepObject = 1, + DeallocateObject, + DeallocateObjectKeepRegisters +}; + +struct dispatcher_header +{ + union + { + union + { + ::std::int_least32_t volatile Lock; + ::std::int_least32_t LockNV; + } DUMMYUNIONNAME; + + struct + { + // Events, Semaphores, Gates, etc. + ::std::uint_least8_t Type; // All (accessible via KOBJECT_TYPE) + ::std::uint_least8_t Signalling; + ::std::uint_least8_t Size; + ::std::uint_least8_t Reserved1; + } DUMMYSTRUCTNAME; + + struct + { + // Timer + ::std::uint_least8_t TimerType; + + union + { + ::std::uint_least8_t TimerControlFlags; + + struct + { + ::std::uint_least8_t Absolute : 1; + ::std::uint_least8_t Wake : 1; + ::std::uint_least8_t EncodedTolerableDelay : 6; + } DUMMYSTRUCTNAME; + }; + + ::std::uint_least8_t Hand; + + union + { + ::std::uint_least8_t TimerMiscFlags; + + struct + { + +#if !defined(KENCODED_TIMER_PROCESSOR) + + ::std::uint_least8_t Index : 6; + +#else + + ::std::uint_least8_t Index : 1; + ::std::uint_least8_t Processor : 5; + +#endif + + ::std::uint_least8_t Inserted : 1; + ::std::uint_least8_t volatile Expired : 1; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + } DUMMYSTRUCTNAME2; + + struct + { // Timer2 + ::std::uint_least8_t Timer2Type; + + union + { + ::std::uint_least8_t Timer2Flags; + + struct + { + ::std::uint_least8_t Timer2Inserted : 1; + ::std::uint_least8_t Timer2Expiring : 1; + ::std::uint_least8_t Timer2CancelPending : 1; + ::std::uint_least8_t Timer2SetPending : 1; + ::std::uint_least8_t Timer2Running : 1; + ::std::uint_least8_t Timer2Disabled : 1; + ::std::uint_least8_t Timer2ReservedFlags : 2; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + ::std::uint_least8_t Timer2ComponentId; + ::std::uint_least8_t Timer2RelativeId; + } DUMMYSTRUCTNAME3; + + struct + { // Queue + ::std::uint_least8_t QueueType; + + union + { + ::std::uint_least8_t QueueControlFlags; + + struct + { + ::std::uint_least8_t Abandoned : 1; + ::std::uint_least8_t DisableIncrement : 1; + ::std::uint_least8_t QueueReservedControlFlags : 6; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + ::std::uint_least8_t QueueSize; + ::std::uint_least8_t QueueReserved; + } DUMMYSTRUCTNAME4; + + struct + { // Thread + ::std::uint_least8_t ThreadType; + ::std::uint_least8_t ThreadReserved; + + union + { + ::std::uint_least8_t ThreadControlFlags; + + struct + { + ::std::uint_least8_t CycleProfiling : 1; + ::std::uint_least8_t CounterProfiling : 1; + ::std::uint_least8_t GroupScheduling : 1; + ::std::uint_least8_t AffinitySet : 1; + ::std::uint_least8_t Tagged : 1; + ::std::uint_least8_t EnergyProfiling : 1; + ::std::uint_least8_t SchedulerAssist : 1; + +#if !defined(_X86_) + + ::std::uint_least8_t ThreadReservedControlFlags : 1; + +#else + + ::std::uint_least8_t Instrumented : 1; + +#endif + + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + union + { + ::std::uint_least8_t DebugActive; + +#if !defined(_X86_) + + struct + { + ::std::uint_least8_t ActiveDR7 : 1; + ::std::uint_least8_t Instrumented : 1; + ::std::uint_least8_t Minimal : 1; + ::std::uint_least8_t Reserved4 : 2; + ::std::uint_least8_t AltSyscall : 1; + ::std::uint_least8_t Emulation : 1; + ::std::uint_least8_t Reserved5 : 1; + } DUMMYSTRUCTNAME; + +#endif + + } DUMMYUNIONNAME2; + } DUMMYSTRUCTNAME5; + + struct + { // Mutant + ::std::uint_least8_t MutantType; + ::std::uint_least8_t MutantSize; + ::std::uint_least8_t DpcActive; + ::std::uint_least8_t MutantReserved; + } DUMMYSTRUCTNAME6; + } DUMMYUNIONNAME; + + ::std::int_least32_t SignalState; // Object lock + list_entry WaitListHead; // Object lock +}; + +struct kevent +{ + dispatcher_header Header; +}; + +struct mdl +{ + mdl *Next; + ::std::int_least16_t Size; + ::std::int_least16_t MdlFlags; + + struct eprocess *Process; + void *MappedSystemVa; /* see creators for field size annotations. */ + void *StartVa; /* see creators for validity; could be address 0. */ + ::std::uint_least32_t ByteCount; + ::std::uint_least32_t ByteOffset; +}; + +using pdriver_control = io_allocation_action (*)(struct device_object *DeviceObject, struct irp *Irp, void *MapRegisterBase, void *Context); + +using pkdeferred_routine = void (*)(struct kdpc *Dpc, void *DeferredContext, void *SystemArgument1, void *SystemArgument2); + +using pdriver_cancel = void (*)(struct device_object *Dpc, struct irp *Irp); + +struct kapc +{ + ::std::uint_least8_t Type; + ::std::uint_least8_t AllFlags; + ::std::uint_least8_t Size; + ::std::uint_least8_t SpareByte1; + ::std::uint_least32_t SpareLong0; + struct _KTHREAD *Thread; + list_entry ApcListEntry; + void *Reserved[3]; + void *NormalContext; + void *SystemArgument1; + void *SystemArgument2; + char ApcStateIndex; + char ApcMode; + ::std::uint_least8_t Inserted; +}; + +struct irp +{ + ::std::int_least16_t Type; + ::std::uint_least16_t Size; + + // + // Define the common fields used to control the IRP. + // + + // + // Define a pointer to the Memory Descriptor List (MDL) for this I/O + // request. This field is only used if the I/O is "direct I/O". + // + + mdl *MdlAddress; + + // + // Flags word - used to remember various flags. + // + + ::std::uint_least32_t Flags; + + // + // The following union is used for one of three purposes: + // + // 1. This IRP is an associated IRP. The field is a pointer to a master + // IRP. + // + // 2. This is the master IRP. The field is the count of the number of + // IRPs which must complete (associated IRPs) before the master can + // complete. + // + // 3. This operation is being buffered and the field is the address of + // the system space buffer. + // + + union + { + irp *MasterIrp; + ::std::int_least32_t IrpCount; + void *SystemBuffer; + } AssociatedIrp; + + // + // Thread list entry - allows queuing the IRP to the thread pending I/O + // request packet list. + // + + list_entry ThreadListEntry; + + // + // I/O status - final status of operation. + // + + io_status_block IoStatus; + + // + // Requester mode - mode of the original requester of this operation. + // + + char RequestorMode; + + // + // Pending returned - TRUE if pending was initially returned as the + // status for this packet. + // + + ::std::uint_least8_t PendingReturned; + + // + // Stack state information. + // + + char StackCount; + char CurrentLocation; + + // + // Cancel - packet has been canceled. + // + + ::std::uint_least8_t Cancel; + + // + // Cancel Irql - Irql at which the cancel spinlock was acquired. + // + + ::std::uint_least8_t CancelIrql; + + // + // ApcEnvironment - Used to save the APC environment at the time that the + // packet was initialized. + // + + char ApcEnvironment; + + // + // Allocation control flags. + // + + ::std::uint_least8_t AllocationFlags; + + // + // User parameters. + // + + union + { + io_status_block *UserIosb; + + // + // Context used when the Irp is managed by IoRing and is used by IoRing. + // UserIosb is used to cancel an Irp, so sharing space with UserIosb + // let IoRing cancel an Irp based on its context. + // + + void *IoRingContext; + }; + + kevent *UserEvent; + + union + { + struct + { + union + { + pio_apc_routine UserApcRoutine; + void *IssuingProcess; + }; + + union + { + void *UserApcContext; + + // + // IoRing object that rolled this Irp, if any. The completion + // is processed through this IoRing object. UserApcRoutine and + // UserApcContext is not supported when issuing IOs through an + // IoRing so we union this with UserApcContext. We did not use + // UserApcRoutine because IssuingProcess use the same location + // and is used when an Irp is queued to FileObject and when the + // Irp is managed by IoRing it is queued to the FileObject. + // + + struct _IORING_OBJECT *IoRing; + }; + } AsynchronousParameters; + + large_integer AllocationSize; + } Overlay; + + // + // CancelRoutine - Used to contain the address of a cancel routine supplied + // by a device driver when the IRP is in a cancelable state. + // + + pdriver_cancel CancelRoutine; + + // + // Note that the UserBuffer parameter is outside of the stack so that I/O + // completion can copy data back into the user's address space without + // having to know exactly which service was being invoked. The length + // of the copy is stored in the second half of the I/O status block. If + // the UserBuffer field is NULL, then no copy is performed. + // + + void *UserBuffer; + + // + // Kernel structures + // + // The following section contains kernel structures which the IRP needs + // in order to place various work information in kernel controller system + // queues. Because the size and alignment cannot be controlled, they are + // placed here at the end so they just hang off and do not affect the + // alignment of other fields in the IRP. + // + + union + { + + struct + { + + union + { + + // + // DeviceQueueEntry - The device queue entry field is used to + // queue the IRP to the device driver device queue. + // + + kdevice_queue_entry DeviceQueueEntry; + + struct + { + + // + // The following are available to the driver to use in + // whatever manner is desired, while the driver owns the + // packet. + // + + void *DriverContext[4]; + }; + }; + + // + // Thread - pointer to caller's Thread Control Block. + // + + struct ethread *Thread; + + // + // Auxiliary buffer - pointer to any auxiliary buffer that is + // required to pass information to a driver that is not contained + // in a normal buffer. + // + + char *AuxiliaryBuffer; + + // + // The following unnamed structure must be exactly identical + // to the unnamed structure used in the minipacket header used + // for completion queue entries. + // + + struct + { + + // + // List entry - used to queue the packet to completion queue, among + // others. + // + + list_entry ListEntry; + + union + { + + // + // Current stack location - contains a pointer to the current + // IO_STACK_LOCATION structure in the IRP stack. This field + // should never be directly accessed by drivers. They should + // use the standard functions. + // + + struct _IO_STACK_LOCATION *CurrentStackLocation; + + // + // Minipacket type. + // + + ::std::uint_least32_t PacketType; + }; + }; + + // + // Original file object - pointer to the original file object + // that was used to open the file. This field is owned by the + // I/O system and should not be used by any other drivers. + // + + struct file_object *OriginalFileObject; + + } Overlay; + + // + // APC - This APC control block is used for the special kernel APC as + // well as for the caller's APC, if one was specified in the original + // argument list. If so, then the APC is reused for the normal APC for + // whatever mode the caller was in and the "special" routine that is + // invoked before the APC gets control simply deallocates the IRP. + // + + kapc Apc; + + // + // CompletionKey - This is the key that is used to distinguish + // individual I/O operations initiated on a single file handle. + // + + void *CompletionKey; + + } Tail; +}; + +struct kdpc +{ + union + { + ::std::uint_least32_t TargetInfoAsUlong; + + struct + { + ::std::uint_least8_t Type; + ::std::uint_least8_t Importance; + ::std::uint_least16_t volatile Number; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + single_list_entry DpcListEntry; + ::std::size_t ProcessorHistory; + pkdeferred_routine DeferredRoutine; + void *DeferredContext; + void *SystemArgument1; + void *SystemArgument2; + void *DpcData; +}; + +struct wait_context_block +{ + union + { + kdevice_queue_entry WaitQueueEntry; + + struct + { + list_entry DmaWaitEntry; + ::std::uint_least32_t NumberOfChannels; + ::std::uint_least32_t SyncCallback : 1; + ::std::uint_least32_t DmaContext : 1; + ::std::uint_least32_t ZeroMapRegisters : 1; + ::std::uint_least32_t Reserved : 9; + ::std::uint_least32_t NumberOfRemapPages : 20; + }; + }; + + pdriver_control DeviceRoutine; + void *DeviceContext; + ::std::uint_least32_t NumberOfMapRegisters; + void *DeviceObject; + void *CurrentIrp; + kdpc *BufferChainingDpc; +}; + +struct device_object +{ + ::std::int_least16_t Type; + ::std::uint_least16_t Size; + ::std::int_least32_t ReferenceCount; + driver_object *DriverObject; + device_object *NextDevice; + device_object *AttachedDevice; + struct irp *CurrentIrp; + struct io_timer *Timer; + ::std::uint_least32_t Flags; + ::std::uint_least32_t Characteristics; + struct vpb *Vpb; + void *DeviceExtension; + ::std::uint_least32_t DeviceType; + char StackSize; + + union + { + list_entry ListEntry; + wait_context_block Wcb; + } Queue; + + ::std::uint_least32_t AlignmentRequirement; + kdevice_queue DeviceQueue; + kdpc Dpc; + ::std::uint_least32_t ActiveThreadCount; + void *SecurityDescriptor; + kevent DeviceLock; + ::std::uint_least16_t SectorSize; + ::std::uint_least16_t Spare1; + struct devobj_extension *DeviceObjectExtension; + void *Reserved; +}; + +struct device_extension +{ + device_object *pDevice; + ::fast_io::win32::nt::unicode_string ustrDeviceName; + ::fast_io::win32::nt::unicode_string ustrSymLinkName; +}; + +struct driver_object +{ + ::std::int_least16_t Type; + ::std::uint_least16_t Size; + device_object *DeviceObject; ::std::uint_least32_t Flags; void *DriverStart; ::std::uint_least32_t DriverSize; void *DriverSection; void *DriverExtension; - utf16_string DriverName; - utf16_string *HardwareDatabase; + ::fast_io::win32::nt::unicode_string DriverName; + ::fast_io::win32::nt::unicode_string *HardwareDatabase; void *FastIoDispatch; void *DriverInit; void *DriverStartIo; void *DriverUnload; void *MajorFunction[28]; }; + } // namespace fast_io::win32::nt diff --git a/include/fast_io_driver/openssl_driver/bio.h b/include/fast_io_driver/openssl_driver/bio.h index e6c3e4a0d..f94ddda0d 100644 --- a/include/fast_io_driver/openssl_driver/bio.h +++ b/include/fast_io_driver/openssl_driver/bio.h @@ -481,13 +481,13 @@ inline ::std::byte const *write_some_bytes_overflow_define(basic_bio_io_observer return ::fast_io::details::bio_write_impl(iob.bio, first, last); } -#if __cpp_lib_three_way_comparison >= 201907L template <::std::integral ch_type> inline constexpr bool operator==(basic_bio_io_observer a, basic_bio_io_observer b) noexcept { return a.bio == b.bio; } +#if __cpp_lib_three_way_comparison >= 201907L template <::std::integral ch_type> inline constexpr auto operator<=>(basic_bio_io_observer a, basic_bio_io_observer b) noexcept { diff --git a/include/fast_io_driver/stvl2.h b/include/fast_io_driver/stvl2.h index a4192350b..36cad05df 100644 --- a/include/fast_io_driver/stvl2.h +++ b/include/fast_io_driver/stvl2.h @@ -621,7 +621,7 @@ inline constexpr char_type *print_reserve_define_impl_for_stvl2_firmware_flags(c inline constexpr ::std::size_t constexpr_stvl2_u8strlen(char8_t const *strlen) noexcept { - if (::std::is_constant_evaluated()) + if (__builtin_is_constant_evaluated()) { ::std::size_t len{}; for (; strlen[len]; ++len) diff --git a/include/fast_io_driver/timer.h b/include/fast_io_driver/timer.h index ea6726792..fc32522fb 100644 --- a/include/fast_io_driver/timer.h +++ b/include/fast_io_driver/timer.h @@ -1,6 +1,6 @@ #pragma once -#include -#include +#include "../fast_io.h" +#include "../fast_io_dsal/string_view.h" namespace fast_io { diff --git a/include/fast_io_dsal/impl/array.h b/include/fast_io_dsal/impl/array.h index 0285098ce..2813650ce 100644 --- a/include/fast_io_dsal/impl/array.h +++ b/include/fast_io_dsal/impl/array.h @@ -506,7 +506,7 @@ constexpr bool operator==(::fast_io::containers::array const &a, ::fast_i } } -#if defined(__cpp_lib_three_way_comparison) +#if __cpp_lib_three_way_comparison >= 201907L template requires ::std::three_way_comparable diff --git a/include/fast_io_dsal/impl/cstring_view.h b/include/fast_io_dsal/impl/cstring_view.h index 6bc9ed30b..c77c43ed8 100644 --- a/include/fast_io_dsal/impl/cstring_view.h +++ b/include/fast_io_dsal/impl/cstring_view.h @@ -42,6 +42,7 @@ class basic_cstring_view : private ::fast_io::containers::basic_string_view constexpr basic_cstring_view(char_type const (&buffer)[N]) noexcept : string_view_type(buffer) @@ -202,7 +203,7 @@ constexpr bool operator==(::fast_io::containers::basic_string_view a, return b == a; } -#ifdef __cpp_lib_three_way_comparison +#if __cpp_lib_three_way_comparison >= 201907L template <::std::integral char_type> constexpr auto operator<=>(::fast_io::containers::basic_cstring_view a, ::fast_io::containers::basic_cstring_view b) noexcept { diff --git a/include/fast_io_dsal/impl/index_span.h b/include/fast_io_dsal/impl/index_span.h index 6b26b37ef..c43eb3453 100644 --- a/include/fast_io_dsal/impl/index_span.h +++ b/include/fast_io_dsal/impl/index_span.h @@ -383,7 +383,7 @@ constexpr bool operator==(::fast_io::containers::index_span a, ::fast_io: } } -#ifdef __cpp_lib_three_way_comparison +#if __cpp_lib_three_way_comparison >= 201907L template requires ::std::three_way_comparable constexpr auto operator<=>(::fast_io::containers::index_span a, ::fast_io::containers::index_span b) diff --git a/include/fast_io_dsal/impl/list.h b/include/fast_io_dsal/impl/list.h index d99f2507c..841a9001c 100644 --- a/include/fast_io_dsal/impl/list.h +++ b/include/fast_io_dsal/impl/list.h @@ -1033,7 +1033,7 @@ constexpr bool operator==(list const &lhs, list co return ::std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend()); } -#if defined(__cpp_lib_three_way_comparison) +#if __cpp_lib_three_way_comparison >= 201907L template requires ::std::three_way_comparable diff --git a/include/fast_io_dsal/impl/span.h b/include/fast_io_dsal/impl/span.h index c7409fd3e..43d79a264 100644 --- a/include/fast_io_dsal/impl/span.h +++ b/include/fast_io_dsal/impl/span.h @@ -344,7 +344,7 @@ constexpr bool operator==(::fast_io::containers::span a, ::fast_io::container return ::std::equal(a.ptr, a.ptr + a.n, b.ptr, b.ptr + b.n); } -#ifdef __cpp_lib_three_way_comparison +#if __cpp_lib_three_way_comparison >= 201907L template requires ::std::three_way_comparable constexpr auto operator<=>(::fast_io::containers::span a, ::fast_io::containers::span b) diff --git a/include/fast_io_dsal/impl/string.h b/include/fast_io_dsal/impl/string.h index bbe5eca73..326ee865c 100644 --- a/include/fast_io_dsal/impl/string.h +++ b/include/fast_io_dsal/impl/string.h @@ -188,6 +188,11 @@ class } public: + explicit constexpr basic_string(char_type const *f, char_type const *e) noexcept + { + this->construct_impl(f, static_cast(e - f)); + } + explicit constexpr basic_string(string_view_type othervw) noexcept { this->construct_impl(othervw.data(), othervw.size()); diff --git a/include/fast_io_dsal/impl/string_view.h b/include/fast_io_dsal/impl/string_view.h index 9146cc280..74cfd483d 100644 --- a/include/fast_io_dsal/impl/string_view.h +++ b/include/fast_io_dsal/impl/string_view.h @@ -645,7 +645,7 @@ constexpr bool operator==(char_type const (&buffer)[n], ::fast_io::containers::b return ::std::equal(buffer, buffer + nm1, a.ptr, a.ptr + a.n); } -#ifdef __cpp_lib_three_way_comparison +#if __cpp_lib_three_way_comparison >= 201907L template <::std::integral char_type> constexpr auto operator<=>(::fast_io::containers::basic_string_view a, ::fast_io::containers::basic_string_view b) noexcept { diff --git a/include/fast_io_dsal/impl/vector.h b/include/fast_io_dsal/impl/vector.h index 8037396b8..892831304 100644 --- a/include/fast_io_dsal/impl/vector.h +++ b/include/fast_io_dsal/impl/vector.h @@ -451,7 +451,7 @@ class vector { this->destroy(); this->imp = vec.imp; - vec.imp = nullptr; + vec.imp = {}; return *this; } constexpr ~vector() @@ -980,7 +980,7 @@ class vector auto lastele{imp.curr_ptr}; if constexpr (!::std::is_trivially_destructible_v) { - ::std::destroy_at(it); + ::std::destroy_at(it); } ::fast_io::freestanding::uninitialized_relocate(it + 1, lastele, it); imp.curr_ptr = lastele; @@ -1027,6 +1027,14 @@ class vector this->erase_common(beginptr + idx); } + constexpr void erase_index_unchecked(size_type idx) noexcept + { + auto beginptr{imp.begin_ptr}; + auto currptr{imp.curr_ptr}; + size_type sz{static_cast(currptr - beginptr)}; + this->erase_common(beginptr + idx); + } + constexpr iterator erase(const_iterator first, const_iterator last) noexcept { #ifdef __cpp_if_consteval @@ -1054,6 +1062,14 @@ class vector } this->erase_iters_common(beginptr + firstidx, beginptr + lastidx); } + + constexpr void erase_index_unchecked(size_type firstidx, size_type lastidx) noexcept + { + auto beginptr{imp.begin_ptr}; + auto currptr{imp.curr_ptr}; + size_type sz{static_cast(currptr - beginptr)}; + this->erase_iters_common(beginptr + firstidx, beginptr + lastidx); + } }; template @@ -1063,7 +1079,7 @@ constexpr bool operator==(vector const &lhs, vector= 201907L template requires ::std::three_way_comparable constexpr auto operator<=>(vector const &lhs, vector const &rhs) noexcept diff --git a/include/fast_io_hosted/dbg/nt_dbg.h b/include/fast_io_hosted/dbg/nt_dbg.h index 8280b9844..fc8f10dbd 100644 --- a/include/fast_io_hosted/dbg/nt_dbg.h +++ b/include/fast_io_hosted/dbg/nt_dbg.h @@ -7,6 +7,8 @@ template <::std::integral ch_type> struct basic_nt_dbg { using char_type = ch_type; + using output_char_type = char_type; + ::std::uint_least32_t component_id{UINT_LEAST32_MAX}; ::std::uint_least32_t level{}; static inline constexpr ::std::size_t output_buffer_alignment_size{512u}; @@ -132,7 +134,7 @@ template #endif inline void nt_dbg_scatter_constant_write_impl(nt_dbg_carrier carr, io_scatter_t const *scatters) noexcept { - if constexpr (n == 0) + if constexpr (n == 0) { return; } @@ -144,6 +146,37 @@ inline void nt_dbg_scatter_constant_write_impl(nt_dbg_carrier carr, io_scatter_t } // namespace details +template <::std::integral ch_type> +inline constexpr basic_nt_dbg io_stream_ref_define(basic_nt_dbg other) noexcept +{ + return other; +} + +template <::std::integral ch_type> +inline constexpr basic_nt_dbg io_bytes_stream_ref_define(basic_nt_dbg other) noexcept +{ + return other; +} + +template <::std::integral ch_type> +inline constexpr void write_all_bytes_overflow_define(basic_nt_dbg d, ::std::byte const* first, ::std::byte const* last) noexcept +{ + constexpr bool is_wide{sizeof(ch_type) == 2}; + ::fast_io::details::nt_dbg_write_impl(details::nt_dbg_carrier{d.component_id, d.level}, + reinterpret_cast(first), + reinterpret_cast(last)); +} + +template <::std::integral ch_type> +inline constexpr void pwrite_all_bytes_overflow_define(basic_nt_dbg d, ::std::byte const* first, ::std::byte const* last) noexcept +{ + constexpr bool is_wide{sizeof(ch_type) == 2}; + ::fast_io::details::nt_dbg_write_impl(details::nt_dbg_carrier{d.component_id, d.level}, + reinterpret_cast(first), + reinterpret_cast(last)); +} + +#if 0 template <::std::integral ch_type, ::std::contiguous_iterator Iter> inline void write(basic_nt_dbg d, Iter first, Iter last) noexcept { @@ -159,6 +192,7 @@ inline void scatter_constant_write(basic_nt_dbg d, io_scatter_t const * constexpr bool is_wide{sizeof(ch_type) == 2}; ::fast_io::details::nt_dbg_scatter_constant_write_impl({d.component_id, d.level}, pscatters); } +#endif #if !defined(_WIN32_WINDOWS) inline auto dbg(::std::uint_least32_t component_id = UINT_LEAST32_MAX, ::std::uint_least32_t level = 0) noexcept diff --git a/include/fast_io_hosted/filesystem/dos.h b/include/fast_io_hosted/filesystem/dos.h index b44045477..8d5ee7968 100644 --- a/include/fast_io_hosted/filesystem/dos.h +++ b/include/fast_io_hosted/filesystem/dos.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include diff --git a/include/fast_io_hosted/filesystem/dos_at.h b/include/fast_io_hosted/filesystem/dos_at.h index 73b4b8665..6f70f09be 100644 --- a/include/fast_io_hosted/filesystem/dos_at.h +++ b/include/fast_io_hosted/filesystem/dos_at.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/include/fast_io_hosted/filesystem/nt.h b/include/fast_io_hosted/filesystem/nt.h index c217889a2..75075a3ee 100644 --- a/include/fast_io_hosted/filesystem/nt.h +++ b/include/fast_io_hosted/filesystem/nt.h @@ -21,6 +21,7 @@ struct nt_dirent { void *d_handle{}; file_type d_type{}; + ::std::uint_least64_t d_ino{}; char16_t native_d_name[0x2001]; ::std::size_t native_d_namlen{}; char8_t u8d_name[0x8004]; @@ -126,11 +127,14 @@ inline nt_dirent *set_nt_dirent(nt_dirent *entry, bool start) } throw_nt_error(status); } - auto ful_dir_info{d_info.FullDirInfo}; - entry->native_d_namlen = ful_dir_info->FileNameLength / sizeof(char16_t); + auto id_ful_dir_info{d_info.IdFullDirInfo}; - ::fast_io::freestanding::nonoverlapped_bytes_copy_n(reinterpret_cast<::std::byte const *>(ful_dir_info->FileName), - ful_dir_info->FileNameLength, + entry->d_ino = static_cast<::std::uint_least64_t>(id_ful_dir_info->FileId.QuadPart); + + entry->native_d_namlen = id_ful_dir_info->FileNameLength / sizeof(char16_t); + + ::fast_io::freestanding::nonoverlapped_bytes_copy_n(reinterpret_cast<::std::byte const *>(id_ful_dir_info->FileName), + id_ful_dir_info->FileNameLength, reinterpret_cast<::std::byte *>(entry->native_d_name)); entry->native_d_name[entry->native_d_namlen] = 0; @@ -149,7 +153,7 @@ inline nt_dirent *set_nt_dirent(nt_dirent *entry, bool start) = DT_DIR; else data->entries[data->index].d_type = DT_REG; */ - ::std::uint_least32_t attribute{ful_dir_info->FileAttributes}; + ::std::uint_least32_t attribute{id_ful_dir_info->FileAttributes}; if (attribute & 0x400) { entry->d_type = file_type::symlink; diff --git a/include/fast_io_hosted/filesystem/posix.h b/include/fast_io_hosted/filesystem/posix.h index 1a670750f..ae92e2c2c 100644 --- a/include/fast_io_hosted/filesystem/posix.h +++ b/include/fast_io_hosted/filesystem/posix.h @@ -562,4 +562,4 @@ inline cross_code_cvt_t print_alias_define(io_alias_t, posix_directory_ using native_directory_entry = posix_directory_entry; -} // namespace fast_io \ No newline at end of file +} // namespace fast_io diff --git a/include/fast_io_hosted/filesystem/win9x.h b/include/fast_io_hosted/filesystem/win9x.h index 73b4b8665..6f70f09be 100644 --- a/include/fast_io_hosted/filesystem/win9x.h +++ b/include/fast_io_hosted/filesystem/win9x.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/include/fast_io_hosted/filesystem/win9x_at.h b/include/fast_io_hosted/filesystem/win9x_at.h index 73b4b8665..6f70f09be 100644 --- a/include/fast_io_hosted/filesystem/win9x_at.h +++ b/include/fast_io_hosted/filesystem/win9x_at.h @@ -1 +1 @@ -#pragma once +#pragma once diff --git a/include/fast_io_hosted/platforms/native_base.h b/include/fast_io_hosted/platforms/native_base.h index 0e940ab84..0b7a88a18 100644 --- a/include/fast_io_hosted/platforms/native_base.h +++ b/include/fast_io_hosted/platforms/native_base.h @@ -33,18 +33,24 @@ inline constexpr ::std::uint_least32_t win32_stderr_number(static_cast<::std::ui namespace fast_io { -#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WINE__) +#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WINE__) && !defined(__BIONIC__) using native_at_entry = nt_at_entry; using native_fs_dirent = nt_fs_dirent; +#if defined(_WIN32_WINDOWS) template <::std::integral ch_type> using basic_native_io_observer = basic_win32_io_observer; template <::std::integral ch_type> using basic_native_file = basic_win32_file; -using native_process_io = win32_process_io; - +#else +template <::std::integral ch_type> +using basic_native_io_observer = basic_nt_io_observer; +template <::std::integral ch_type> +using basic_native_file = basic_nt_file; +#endif template <::std::integral ch_type> using basic_native_pipe = basic_win32_pipe; +using native_process_io = win32_process_io; #else diff --git a/include/fast_io_hosted/platforms/nt.h b/include/fast_io_hosted/platforms/nt.h index 310a4a189..bcdafbc40 100644 --- a/include/fast_io_hosted/platforms/nt.h +++ b/include/fast_io_hosted/platforms/nt.h @@ -690,8 +690,6 @@ inline ::std::byte const *pwrite_some_bytes_overflow_define(basic_nt_family_io_o return ::fast_io::win32::nt::details::nt_pwrite_some_bytes_impl(niob.handle, first, last, off); } -#if __cpp_lib_three_way_comparison >= 201907L - template inline constexpr bool operator==(basic_nt_family_io_observer a, basic_nt_family_io_observer b) noexcept @@ -699,6 +697,8 @@ inline constexpr bool operator==(basic_nt_family_io_observer a, return a.handle == b.handle; } +#if __cpp_lib_three_way_comparison >= 201907L + template inline constexpr auto operator<=>(basic_nt_family_io_observer a, basic_nt_family_io_observer b) noexcept @@ -1323,7 +1323,7 @@ inline basic_zw_io_observer zw_stderr() noexcept return {::fast_io::details::nt_get_stdhandle<2>()}; } -#if !defined(_WIN32_WINDOWS) && 0 +#if !defined(__WINE__) && !defined(__CYGWIN__) && !defined(__BIONIC__) && !defined(_WIN32_WINDOWS) template <::std::integral char_type = char> inline basic_nt_io_observer native_stdin() noexcept { diff --git a/include/fast_io_hosted/platforms/nt/nt_definitions.h b/include/fast_io_hosted/platforms/nt/nt_definitions.h index 2e39c4454..51b65ee57 100644 --- a/include/fast_io_hosted/platforms/nt/nt_definitions.h +++ b/include/fast_io_hosted/platforms/nt/nt_definitions.h @@ -29,7 +29,7 @@ struct object_attributes struct io_status_block { - union + union dummyunion { ::std::uint_least32_t Status; void *Pointer; @@ -165,6 +165,23 @@ struct file_full_dir_information char16_t FileName[1]; }; +struct file_id_full_dir_information +{ + ::std::uint_least32_t NextEntryOffset; + ::std::uint_least32_t FileIndex; + ::std::int_least64_t CreationTime; + ::std::int_least64_t LastAccessTime; + ::std::int_least64_t LastWriteTime; + ::std::int_least64_t ChangeTime; + ::std::int_least64_t EndOfFile; + ::std::int_least64_t AllocationSize; + ::std::uint_least32_t FileAttributes; + ::std::uint_least32_t FileNameLength; + ::std::uint_least32_t EaSize; + large_integer FileId; + char16_t FileName[1]; +}; + struct file_both_dir_information { ::std::uint_least32_t NextEntryOffset; @@ -183,11 +200,32 @@ struct file_both_dir_information char16_t FileName[1]; }; +struct file_id_both_dir_information +{ + ::std::uint_least32_t NextEntryOffset; + ::std::uint_least32_t FileIndex; + ::std::int_least64_t CreationTime; + ::std::int_least64_t LastAccessTime; + ::std::int_least64_t LastWriteTime; + ::std::int_least64_t ChangeTime; + ::std::int_least64_t EndOfFile; + ::std::int_least64_t AllocationSize; + ::std::uint_least32_t FileAttributes; + ::std::uint_least32_t FileNameLength; + ::std::uint_least32_t EaSize; + char ShortNameLength; + char16_t ShortName[12]; + large_integer FileId; + char16_t FileName[1]; +}; + union dir_information { void *DirInfo; file_full_dir_information *FullDirInfo; + file_id_full_dir_information *IdFullDirInfo; file_both_dir_information *BothDirInfo; + file_id_both_dir_information *IdBothDirInfo; }; struct file_standard_information @@ -661,6 +699,71 @@ struct rtl_unicode_string_buffer char16_t MinimumStaticBufferForTerminalNul; }; +enum class system_information_class +{ + SystemBasicInformation, + SystemProcessorInformation, + SystemPerformanceInformation, + SystemTimeOfDayInformation, + SystemPathInformation, + SystemProcessInformation, + SystemCallCountInformation, + SystemDeviceInformation, + SystemProcessorPerformanceInformation, + SystemFlagsInformation, + SystemCallTimeInformation, + SystemModuleInformation, + SystemLocksInformation, + SystemStackTraceInformation, + SystemPagedPoolInformation, + SystemNonPagedPoolInformation, + SystemHandleInformation, + SystemObjectInformation, + SystemPageFileInformation, + SystemVdmInstemulInformation, + SystemVdmBopInformation, + SystemFileCacheInformation, + SystemPoolTagInformation, + SystemInterruptInformation, + SystemDpcBehaviorInformation, + SystemFullMemoryInformation, + SystemLoadGdiDriverInformation, + SystemUnloadGdiDriverInformation, + SystemTimeAdjustmentInformation, + SystemSummaryMemoryInformation, + SystemNextEventIdInformation, + SystemEventIdsInformation, + SystemCrashDumpInformation, + SystemExceptionInformation, + SystemCrashDumpStateInformation, + SystemKernelDebuggerInformation, + SystemContextSwitchInformation, + SystemRegistryQuotaInformation, + SystemExtendServiceTableInformation, + SystemPrioritySeperation, + SystemPlugPlayBusInformation, + SystemDockInformation, + SystemPowerInformation, + SystemProcessorSpeedInformation, + SystemCurrentTimeZoneInformation, + SystemLookasideInformation +}; + +struct system_basic_information +{ + ::std::uint_least32_t Reserved; + ::std::uint_least32_t TimerResolution; + ::std::uint_least32_t PageSize; + ::std::uint_least32_t NumberOfPhysicalPages; + ::std::uint_least32_t LowestPhysicalPageNumber; + ::std::uint_least32_t HighestPhysicalPageNumber; + ::std::uint_least32_t AllocationGranularity; + ::std::size_t MinimumUserModeAddress; + ::std::size_t MaximumUserModeAddress; + ::std::size_t ActiveProcessorsAffinityMask; + char NumberOfProcessors; +}; + struct rtl_srwlock { void *Ptr; diff --git a/include/fast_io_hosted/platforms/nt/nt_linker.h b/include/fast_io_hosted/platforms/nt/nt_linker.h index cc4274bde..dc7a6df0a 100644 --- a/include/fast_io_hosted/platforms/nt/nt_linker.h +++ b/include/fast_io_hosted/platforms/nt/nt_linker.h @@ -2252,6 +2252,72 @@ inline ::std::uint_least32_t nt_allocate_virtual_memory(Args... args) noexcept } } +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + NtFreeVirtualMemory(void *, void **, ::std::size_t *, ::std::uint_least32_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("NtFreeVirtualMemory@16") +#else + __asm__("_NtFreeVirtualMemory@16") +#endif +#else + __asm__("NtFreeVirtualMemory") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + ZwFreeVirtualMemory(void *, void **, ::std::size_t *, ::std::uint_least32_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("ZwFreeVirtualMemory@16") +#else + __asm__("_ZwFreeVirtualMemory@16") +#endif +#else + __asm__("ZwFreeVirtualMemory") +#endif +#endif + ; + +template + requires(sizeof...(Args) == 4) +inline ::std::uint_least32_t nt_free_virtual_memory(Args... args) noexcept +{ + if constexpr (zw) + { + return ZwFreeVirtualMemory(args...); + } + else + { + return NtFreeVirtualMemory(args...); + } +} + #if defined(_MSC_VER) && !defined(__clang__) __declspec(dllimport) #elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) @@ -2304,6 +2370,72 @@ extern ::std::uint_least32_t #endif ; +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + NtQuerySystemInformation(system_information_class, void *, ::std::uint_least32_t, ::std::uint_least32_t *) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("NtQuerySystemInformation@16") +#else + __asm__("_NtQuerySystemInformation@16") +#endif +#else + __asm__("NtQuerySystemInformation") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern ::std::uint_least32_t +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + ZwQuerySystemInformation(system_information_class, void *, ::std::uint_least32_t, ::std::uint_least32_t *) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("ZwQuerySystemInformation@16") +#else + __asm__("_ZwQuerySystemInformation@16") +#endif +#else + __asm__("ZwQuerySystemInformation") +#endif +#endif + ; + +template + requires(sizeof...(Args) == 4) +inline ::std::uint_least32_t nt_query_system_information(Args... args) noexcept +{ + if constexpr (zw) + { + return ZwQuerySystemInformation(args...); + } + else + { + return NtQuerySystemInformation(args...); + } +} + #if defined(_MSC_VER) && !defined(__clang__) __declspec(dllimport) #elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) diff --git a/include/fast_io_hosted/platforms/nt_mapping.h b/include/fast_io_hosted/platforms/nt_mapping.h index 6300521a4..5365e34e7 100644 --- a/include/fast_io_hosted/platforms/nt_mapping.h +++ b/include/fast_io_hosted/platforms/nt_mapping.h @@ -271,4 +271,8 @@ class nt_family_memory_map_file using nt_memory_map_file = nt_family_memory_map_file; using zw_memory_map_file = nt_family_memory_map_file; +#if defined(_WIN32) && !defined(__WINE__) && !defined(__CYGWIN__) && !defined(__BIONIC__) && !defined(_WIN32_WINDOWS) +using native_memory_map_file = nt_memory_map_file; +#endif + } // namespace fast_io diff --git a/include/fast_io_hosted/platforms/posix.h b/include/fast_io_hosted/platforms/posix.h index f14ef5799..6fb5c3f77 100644 --- a/include/fast_io_hosted/platforms/posix.h +++ b/include/fast_io_hosted/platforms/posix.h @@ -477,14 +477,14 @@ class basic_posix_family_io_observer } }; -#ifdef __cpp_lib_three_way_comparison - template <::fast_io::posix_family family, ::std::integral ch_type> inline constexpr bool operator==(basic_posix_family_io_observer a, basic_posix_family_io_observer b) noexcept { return a.fd == b.fd; } +#if __cpp_lib_three_way_comparison >= 201907L + template <::fast_io::posix_family family, ::std::integral ch_type> inline constexpr auto operator<=>(basic_posix_family_io_observer a, basic_posix_family_io_observer b) noexcept { @@ -523,10 +523,19 @@ inline constexpr posix_at_entry at_fdcwd() noexcept { return posix_at_entry(AT_FDCWD); } +#elif defined(__MSDOS__) || defined(__DJGPP__) + +inline constexpr posix_at_entry posix_at_fdcwd() noexcept +{ + return posix_at_entry(-100); +} +inline constexpr posix_at_entry at_fdcwd() noexcept +{ + return posix_at_entry(-100); +} #endif -#if (!defined(__NEWLIB__) || defined(__CYGWIN__)) && (!defined(_WIN32) || defined(__WINE__)) namespace details { @@ -712,19 +721,20 @@ inline posix_file_status fstat_impl(int fd) #else struct stat st; #endif - if ( + if (::fast_io::noexcept_call( #if (defined(_WIN32) && !defined(__WINE__) && !defined(__BIONIC__)) && !defined(__CYGWIN__) #if (!defined(__MINGW32__) || __has_include(<_mingw_stat64.h>)) - _fstat64 + _fstat64 #else - _fstati64 + _fstati64 #endif #elif defined(__linux__) && defined(__USE_LARGEFILE64) - fstat64 + fstat64 #else - fstat + fstat #endif - (fd, __builtin_addressof(st)) < 0) + , + fd, __builtin_addressof(st)) < 0) throw_posix_error(); return struct_stat_to_posix_file_status(st); } @@ -741,8 +751,6 @@ inline posix_file_status status(basic_posix_family_io_observer #endif } -#endif - #if (defined(_WIN32) && !defined(__WINE__) && !defined(__BIONIC__)) && !defined(__CYGWIN__) template <::fast_io::posix_family family, ::std::integral ch_type> inline auto redirect_handle(basic_posix_family_io_observer h) noexcept @@ -815,11 +823,54 @@ inline int open_fd_from_handle(void *handle, open_mode md) template inline int my_posix_openat(int dirfd, char const *pathname, int flags, mode_t mode) { - auto pathname_cstr{::fast_io::noexcept_call(::__get_fd_name, dirfd)}; - ::fast_io::tlc::string pn{::fast_io::tlc::concat_fast_io_tlc(::fast_io::mnp::os_c_str(pathname_cstr), "\\", ::fast_io::mnp::os_c_str(pathname))}; - int fd{::open(pn.c_str(), flags, mode)}; - system_call_throw_error(fd); - return fd; + if (pathname == nullptr) [[unlikely]] + { + system_call_throw_error(-1); + return -1; + } + + if (dirfd == -100) + { + int fd(::open(pathname, flags, mode)); + system_call_throw_error(fd); + return fd; + } + else + { + auto pathname_cstr{::fast_io::noexcept_call(::__get_fd_name, dirfd)}; + if (pathname_cstr == nullptr) [[unlikely]] + { + system_call_throw_error(-1); + return -1; + } + + // check vaildity + ::fast_io::cstring_view para_pathname{::fast_io::mnp::os_c_str(pathname)}; + if (auto const sz{para_pathname.size()}; sz == 0 || sz > 255) [[unlikely]] + { + return -1; + } + + if (auto const fc{para_pathname.front_unchecked()}; fc == '+' || fc == '-' || fc == '.') [[unlikely]] + { + return -1; + } + + for (auto const fc : para_pathname) + { + if (fc == '/' || fc == '\\' || fc == '\t' || fc == '\b' || fc == '@' || fc == '#' || fc == '$' || fc == '%' || fc == '^' || fc == '&' || + fc == '*' || fc == '(' || fc == ')' || fc == '[' || fc == ']') [[unlikely]] + { + return -1; + } + } + + // concat + ::fast_io::tlc::string pn{::fast_io::tlc::concat_fast_io_tlc(::fast_io::mnp::os_c_str(pathname_cstr), "\\", para_pathname)}; + int fd{::open(pn.c_str(), flags, mode)}; + system_call_throw_error(fd); + return fd; + } } #elif defined(__NEWLIB__) || defined(_PICOLIBC__) @@ -837,14 +888,17 @@ inline int my_posix_openat(int, char const *, int, mode_t) } } #else + +extern int my_posix_openat_noexcept(int fd, const char *path, int aflag, ... /*mode_t mode*/) noexcept __asm__("openat"); + template inline int my_posix_openat(int dirfd, char const *pathname, int flags, mode_t mode) { int fd{ -#if defined(__linux__) +#if defined(__linux__) && defined(__NR_openat) system_call<__NR_openat, int> #else - ::openat + my_posix_openat_noexcept #endif (dirfd, pathname, flags, mode)}; system_call_throw_error(fd); @@ -911,6 +965,8 @@ inline int my_posix_open(char const *pathname, int flags, mode_t mode) { #if 0 + // MSDOS + /* Referenced from https://dl.acm.org/doi/pdf/10.1145/70931.70935?casa_token=rWDy5JyhhkMAAAAA:BdkF0zbbWgurns3mU3yEJI2HnHXWhe6wyYGtKxjRewlEgLg6lk-cGGNLZTTdr3vUjtFg6Cnia2b4 @@ -944,12 +1000,12 @@ inline int my_posix_open(char const *pathname, int flags, throw_posix_error(); } } - int md{O_TEXT}; + int dos_mode{O_TEXT}; if ((static_cast(flags) & static_cast(O_BINARY)) == static_cast(O_BINARY)) { - md = O_BINARY; + dos_mode = O_BINARY; } - if (::fast_io::details::my_dos_setmode(fd, md) == -1) + if (::fast_io::details::my_dos_setmode(fd, dos_mode) == -1) { ::fast_io::details::my_dos_close(fd); if constexpr (always_terminate) @@ -963,6 +1019,7 @@ inline int my_posix_open(char const *pathname, int flags, } return fd; #endif + #if defined(__MSDOS__) || (defined(__NEWLIB__) && !defined(AT_FDCWD)) || defined(_PICOLIBC__) int fd{::open(pathname, flags, mode)}; system_call_throw_error(fd); @@ -1340,7 +1397,7 @@ class basic_posix_family_pipe #else int a2[2]{-1, -1}; #if (defined(_WIN32) && !defined(__WINE__) && !defined(__BIONIC__)) && !defined(__CYGWIN__) - if (noexcept_call(_pipe, a2, 131072u, _O_BINARY) == -1) + if (noexcept_call(::_pipe, a2, 131072u, _O_BINARY) == -1) #elif (defined(__MSDOS__) || defined(__DJGPP__)) || (defined(__APPLE__) || defined(__DARWIN_C_LEVEL)) if (noexcept_call(::pipe, a2) == -1) #else diff --git a/include/fast_io_hosted/platforms/posix/common.h b/include/fast_io_hosted/platforms/posix/common.h index 2f77ee34d..bc9880b2f 100644 --- a/include/fast_io_hosted/platforms/posix/common.h +++ b/include/fast_io_hosted/platforms/posix/common.h @@ -51,6 +51,7 @@ inline ::std::byte const *posix_write_bytes_impl(int fd, ::std::byte const *firs } #ifdef __MSDOS__ + extern unsigned my_dos_read(int, void *, unsigned, unsigned *) noexcept __asm__("__dos_read"); extern unsigned my_dos_write(int, void const *, unsigned, unsigned *) noexcept __asm__("__dos_write"); diff --git a/include/fast_io_hosted/platforms/posix_mapping.h b/include/fast_io_hosted/platforms/posix_mapping.h index 155a8c431..0cb5e016d 100644 --- a/include/fast_io_hosted/platforms/posix_mapping.h +++ b/include/fast_io_hosted/platforms/posix_mapping.h @@ -8,7 +8,7 @@ namespace fast_io namespace details { -inline ::std::byte *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, ::std::uintmax_t offset) +inline ::std::byte *sys_mmap(void *addr, ::std::size_t len, int prot, int flags, int fd, ::std::uintmax_t offset) { #if defined(__linux__) && defined(__NR_mmap) && !defined(__NR_mmap2) if constexpr (sizeof(::std::uintmax_t) > sizeof(off_t)) @@ -44,7 +44,7 @@ inline ::std::byte *sys_mmap(void *addr, size_t len, int prot, int flags, int fd } } auto ret{reinterpret_cast<::std::byte *>( - mmap(addr, len, prot, flags, fd, static_cast(static_cast>(offset))))}; + ::mmap(addr, len, prot, flags, fd, static_cast(static_cast>(offset))))}; if (ret == MAP_FAILED) { throw_posix_error(); @@ -53,13 +53,29 @@ inline ::std::byte *sys_mmap(void *addr, size_t len, int prot, int flags, int fd #endif } -inline int sys_munmap(void *addr, size_t len) +inline int sys_mprotect(void *start, ::std::size_t len, int prot) +{ + auto const result{ +#if defined(__linux__) && defined(__NR_mprotect) + system_call<__NR_mprotect, int>(start, len, prot) +#else + ::mprotect(start, len, prot) +#endif + }; + if (result) [[unlikely]] + { + throw_posix_error(); + } + return result; +} + +inline int sys_munmap(void *addr, ::std::size_t len) { return #if defined(__linux__) && defined(__NR_munmap) system_call<__NR_munmap, int>(addr, len); #else - munmap(addr, len); + ::munmap(addr, len); #endif } diff --git a/include/fast_io_hosted/platforms/systemcall_details.h b/include/fast_io_hosted/platforms/systemcall_details.h index 905167c97..f960b70b4 100644 --- a/include/fast_io_hosted/platforms/systemcall_details.h +++ b/include/fast_io_hosted/platforms/systemcall_details.h @@ -8,8 +8,15 @@ extern int dup(int) noexcept __asm__("_dup"); extern int dup2(int, int) noexcept __asm__("_dup2"); extern int _close(int) noexcept __asm__("_close"); #elif defined(__wasi__) -extern int dup(int) noexcept __asm__("dup"); -extern int dup2(int, int) noexcept __asm__("dup2"); +inline int dup(int) noexcept +{ + return -1; +} + +inline int dup2(int old_fd, int new_fd) noexcept +{ + return ::fast_io::noexcept_call(__wasi_fd_renumber, old_fd, new_fd); +} #endif inline int sys_dup(int old_fd) diff --git a/include/fast_io_hosted/platforms/win32.h b/include/fast_io_hosted/platforms/win32.h index 2bdf0fa37..fd387c0da 100644 --- a/include/fast_io_hosted/platforms/win32.h +++ b/include/fast_io_hosted/platforms/win32.h @@ -608,8 +608,6 @@ class basic_win32_family_io_observer } }; -#if __cpp_lib_three_way_comparison >= 201907L - template inline constexpr bool operator==(basic_win32_family_io_observer a, basic_win32_family_io_observer b) noexcept @@ -617,6 +615,8 @@ inline constexpr bool operator==(basic_win32_family_io_observer return a.handle == b.handle; } +#if __cpp_lib_three_way_comparison >= 201907L + template inline constexpr auto operator<=>(basic_win32_family_io_observer a, basic_win32_family_io_observer b) noexcept @@ -1431,7 +1431,7 @@ inline basic_win32_io_observer win32_stderr() noexcept return {::fast_io::win32::GetStdHandle(win32_stderr_number)}; } -#if !defined(__CYGWIN__) && !defined(__WINE__) +#if !defined(__CYGWIN__) && !defined(__WINE__) && !defined(__BIONIC__) && defined(_WIN32_WINDOWS) template <::std::integral char_type = char> inline basic_win32_io_observer native_stdin() noexcept { diff --git a/include/fast_io_hosted/platforms/win32/apis.h b/include/fast_io_hosted/platforms/win32/apis.h index 602e1f02d..0d44e7051 100644 --- a/include/fast_io_hosted/platforms/win32/apis.h +++ b/include/fast_io_hosted/platforms/win32/apis.h @@ -951,6 +951,7 @@ extern int #endif #endif ; + #if defined(_MSC_VER) && !defined(__clang__) __declspec(dllimport) #elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) @@ -2938,6 +2939,84 @@ extern ::std::uint_least32_t #endif ; +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern void +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + GetSystemInfo(::fast_io::win32::system_info *) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("GetSystemInfo@4") +#else + __asm__("_GetSystemInfo@4") +#endif +#else + __asm__("GetSystemInfo") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern int +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + SetFileInformationByHandle(void *, file_info_by_handle_class, void *, ::std::uint_least32_t) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("SetFileInformationByHandle@16") +#else + __asm__("_SetFileInformationByHandle@16") +#endif +#else + __asm__("SetFileInformationByHandle") +#endif +#endif + ; + +#if defined(_MSC_VER) && !defined(__clang__) +__declspec(dllimport) +#elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) +[[__gnu__::__dllimport__]] +#endif +#if (__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) +[[__gnu__::__stdcall__]] +#endif +extern int +#if (!__has_cpp_attribute(__gnu__::__stdcall__) && !defined(__WINE__)) && defined(_MSC_VER) + __stdcall +#endif + SetFileTime(void *, filetime const *, filetime const *, filetime const *) noexcept +#if defined(__clang__) || defined(__GNUC__) +#if SIZE_MAX <= UINT_LEAST32_MAX && (defined(__x86__) || defined(_M_IX86) || defined(__i386__)) +#if !defined(__clang__) + __asm__("SetFileTime@16") +#else + __asm__("_SetFileTime@16") +#endif +#else + __asm__("SetFileTime") +#endif +#endif + ; + #if defined(_MSC_VER) && !defined(__clang__) __declspec(dllimport) #elif (__has_cpp_attribute(__gnu__::__dllimport__) && !defined(__WINE__)) diff --git a/include/fast_io_hosted/platforms/win32/msvc_linker_32.h b/include/fast_io_hosted/platforms/win32/msvc_linker_32.h index 56e1d08f5..66edba58e 100644 --- a/include/fast_io_hosted/platforms/win32/msvc_linker_32.h +++ b/include/fast_io_hosted/platforms/win32/msvc_linker_32.h @@ -1,6 +1,7 @@ #pragma once // clang-format off +// WIN32 #pragma comment(linker,"/alternatename:__imp_?GetLastError@win32@fast_io@@YAIXZ=__imp_GetLastError") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryA@win32@fast_io@@YAPAXPBD@Z=__imp_LoadLibraryA") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryW@win32@fast_io@@YAPAXPB_S@Z=__imp_LoadLibraryW") @@ -116,6 +117,10 @@ #pragma comment(linker,"/alternatename:__imp_?AcquireSRWLockExclusive@win32@fast_io@@YAXPAX@Z=__imp_AcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?TryAcquireSRWLockExclusive@win32@fast_io@@YAIPAX@Z=__imp_TryAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?ReleaseSRWLockExclusive@win32@fast_io@@YAXPAX@Z=__imp_ReleaseSRWLockExclusive") +#pragma comment(linker,"/alternatename:__imp_?GetSystemInfo@win32@fast_io@@YAXPAUsystem_info@12@@Z=__imp_GetSystemInfo") +#pragma comment(linker,"/alternatename:__imp_?SetFileInformationByHandle@win32@fast_io@@YAHPAXW4file_info_by_handle_class@12@0I@Z?=__imp_SetFileInformationByHandle") +#pragma comment(linker,"/alternatename:__imp_?SetFileTime@win32@fast_io@@YAHPAXPBUfiletime@12@11@Z=__imp_SetFileTime") +// NT #pragma comment(linker,"/alternatename:__imp_?rtl_nt_status_to_dos_error@nt@win32@fast_io@@YAII@Z=__imp_RtlNtStatusToDosError") #pragma comment(linker,"/alternatename:__imp_?NtClose@nt@win32@fast_io@@YAIPAX@Z=__imp_NtClose") #pragma comment(linker,"/alternatename:__imp_?ZwClose@nt@win32@fast_io@@YAIPAX@Z=__imp_ZwClose") @@ -189,6 +194,13 @@ #pragma comment(linker,"/alternatename:__imp_?RtlAcquireSRWLockExclusive@nt@win32@fast_io@@YAXPAX@Z=__imp_RtlAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?RtlTryAcquireSRWLockExclusive@nt@win32@fast_io@@YAIPAX@Z=__imp_RtlTryAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?RtlReleaseSRWLockExclusive@nt@win32@fast_io@@YAXPAX@Z=__imp_RtlReleaseSRWLockExclusive") +#pragma comment(linker,"/alternatename:__imp_?NtQueryObject@nt@win32@fast_io@@YAIPAXW4object_information_class@123@0IPAI@Z=__imp_NtQueryObject") +#pragma comment(linker,"/alternatename:__imp_?ZwQueryObject@nt@win32@fast_io@@YAIPAXW4object_information_class@123@0IPAI@Z=__imp_ZwQueryObject") +#pragma comment(linker,"/alternatename:__imp_?NtQuerySystemInformation@nt@win32@fast_io@@YAIW4system_information_class@123@PAXIPAI@Z=__imp_NtQuerySystemInformation") +#pragma comment(linker,"/alternatename:__imp_?ZwQuerySystemInformation@nt@win32@fast_io@@YAIW4system_information_class@123@PAXIPAI@Z=__imp_ZwQuerySystemInformation") +#pragma comment(linker,"/alternatename:__imp_?NtFreeVirtualMemory@nt@win32@fast_io@@YAIPAXPAPAXPAII@Z=__imp_NtFreeVirtualMemory") +#pragma comment(linker,"/alternatename:__imp_?ZwFreeVirtualMemory@nt@win32@fast_io@@YAIPAXPAPAXPAII@Z=__imp_ZwFreeVirtualMemory") +//msvc #pragma comment(linker,"/alternatename:__imp_?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=__imp___RTtypeid") #pragma comment(linker,"/alternatename:?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=__RTtypeid") // clang-format on diff --git a/include/fast_io_hosted/platforms/win32/msvc_linker_32_i686.h b/include/fast_io_hosted/platforms/win32/msvc_linker_32_i686.h index 89a553ad0..f0bb3b31f 100644 --- a/include/fast_io_hosted/platforms/win32/msvc_linker_32_i686.h +++ b/include/fast_io_hosted/platforms/win32/msvc_linker_32_i686.h @@ -1,6 +1,7 @@ #pragma once // clang-format off +// WIN32 #pragma comment(linker,"/alternatename:__imp_?GetLastError@win32@fast_io@@YGIXZ=__imp__GetLastError@0") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryA@win32@fast_io@@YGPAXPBD@Z=__imp__LoadLibraryA@4") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryW@win32@fast_io@@YGPAXPB_S@Z=__imp__LoadLibraryW@4") @@ -116,6 +117,10 @@ #pragma comment(linker,"/alternatename:__imp_?AcquireSRWLockExclusive@win32@fast_io@@YGXPAX@Z=__imp__AcquireSRWLockExclusive@4") #pragma comment(linker,"/alternatename:__imp_?TryAcquireSRWLockExclusive@win32@fast_io@@YGIPAX@Z=__imp__TryAcquireSRWLockExclusive@4") #pragma comment(linker,"/alternatename:__imp_?ReleaseSRWLockExclusive@win32@fast_io@@YGXPAX@Z=__imp__ReleaseSRWLockExclusive@4") +#pragma comment(linker,"/alternatename:__imp_?GetSystemInfo@win32@fast_io@@YGXPAUsystem_info@12@@Z=__imp__GetSystemInfo@4") +#pragma comment(linker,"/alternatename:__imp_?SetFileInformationByHandle@win32@fast_io@@YGHPAXW4file_info_by_handle_class@12@0I@Z=__imp__SetFileInformationByHandle@16") +#pragma comment(linker,"/alternatename:__imp_?SetFileTime@win32@fast_io@@YGHPAXPBUfiletime@12@11@Z=__imp__SetFileTime@16") +// NT #pragma comment(linker,"/alternatename:__imp_?rtl_nt_status_to_dos_error@nt@win32@fast_io@@YGII@Z=__imp__RtlNtStatusToDosError@4") #pragma comment(linker,"/alternatename:__imp_?NtClose@nt@win32@fast_io@@YGIPAX@Z=__imp__NtClose@4") #pragma comment(linker,"/alternatename:__imp_?ZwClose@nt@win32@fast_io@@YGIPAX@Z=__imp__ZwClose@4") @@ -189,6 +194,13 @@ #pragma comment(linker,"/alternatename:__imp_?RtlAcquireSRWLockExclusive@nt@win32@fast_io@@YGXPAX@Z=__imp__RtlAcquireSRWLockExclusive@4") #pragma comment(linker,"/alternatename:__imp_?RtlTryAcquireSRWLockExclusive@nt@win32@fast_io@@YGIPAX@Z=__imp__RtlTryAcquireSRWLockExclusive@4") #pragma comment(linker,"/alternatename:__imp_?RtlReleaseSRWLockExclusive@nt@win32@fast_io@@YGXPAX@Z=__imp__RtlReleaseSRWLockExclusive@4") +#pragma comment(linker,"/alternatename:__imp_?NtQueryObject@nt@win32@fast_io@@YGIPAXW4object_information_class@123@0IPAI@Z=__imp__NtQueryObject@20") +#pragma comment(linker,"/alternatename:__imp_?ZwQueryObject@nt@win32@fast_io@@YGIPAXW4object_information_class@123@0IPAI@Z=__imp__ZwQueryObject@20") +#pragma comment(linker,"/alternatename:__imp_?NtQuerySystemInformation@nt@win32@fast_io@@YGIW4system_information_class@123@PAXIPAI@Z=__imp__NtQuerySystemInformation@16") +#pragma comment(linker,"/alternatename:__imp_?ZwQuerySystemInformation@nt@win32@fast_io@@YGIW4system_information_class@123@PAXIPAI@Z=__imp__ZwQuerySystemInformation@16") +#pragma comment(linker,"/alternatename:__imp_?NtFreeVirtualMemory@nt@win32@fast_io@@YGIPAXPAPAXPAII@Z=__imp__NtFreeVirtualMemory@16") +#pragma comment(linker,"/alternatename:__imp_?ZwFreeVirtualMemory@nt@win32@fast_io@@YGIPAXPAPAXPAII@Z=__imp__ZwFreeVirtualMemory@16") +// msvc #pragma comment(linker,"/alternatename:__imp_?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=__imp____RTtypeid") #pragma comment(linker,"/alternatename:?msvc__RTtypeid@msvc@fast_io@@YAPAXPAX@Z=___RTtypeid") // clang-format on diff --git a/include/fast_io_hosted/platforms/win32/msvc_linker_64.h b/include/fast_io_hosted/platforms/win32/msvc_linker_64.h index 01d1f598d..1040890f6 100644 --- a/include/fast_io_hosted/platforms/win32/msvc_linker_64.h +++ b/include/fast_io_hosted/platforms/win32/msvc_linker_64.h @@ -1,6 +1,7 @@ #pragma once // clang-format off +// WIN32 #pragma comment(linker,"/alternatename:__imp_?GetLastError@win32@fast_io@@YAIXZ=__imp_GetLastError") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryA@win32@fast_io@@YAPEAXPEBD@Z=__imp_LoadLibraryA") #pragma comment(linker,"/alternatename:__imp_?LoadLibraryW@win32@fast_io@@YAPEAXPEB_S@Z=__imp_LoadLibraryW") @@ -116,6 +117,10 @@ #pragma comment(linker,"/alternatename:__imp_?AcquireSRWLockExclusive@win32@fast_io@@YAXPEAX@Z=__imp_AcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?TryAcquireSRWLockExclusive@win32@fast_io@@YAIPEAX@Z=__imp_TryAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?ReleaseSRWLockExclusive@win32@fast_io@@YAXPEAX@Z=__imp_ReleaseSRWLockExclusive") +#pragma comment(linker,"/alternatename:__imp_?GetSystemInfo@win32@fast_io@@YAXPEAUsystem_info@12@@Z=__imp_GetSystemInfo") +#pragma comment(linker,"/alternatename:__imp_?SetFileInformationByHandle@win32@fast_io@@YAHPEAXW4file_info_by_handle_class@12@0I@Z=__imp_SetFileInformationByHandle") +#pragma comment(linker,"/alternatename:__imp_?SetFileTime@win32@fast_io@@YAHPEAXPEBUfiletime@12@11@Z=__imp_SetFileTime") +// NT #pragma comment(linker,"/alternatename:__imp_?rtl_nt_status_to_dos_error@nt@win32@fast_io@@YAII@Z=__imp_RtlNtStatusToDosError") #pragma comment(linker,"/alternatename:__imp_?NtClose@nt@win32@fast_io@@YAIPEAX@Z=__imp_NtClose") #pragma comment(linker,"/alternatename:__imp_?ZwClose@nt@win32@fast_io@@YAIPEAX@Z=__imp_ZwClose") @@ -189,6 +194,12 @@ #pragma comment(linker,"/alternatename:__imp_?RtlAcquireSRWLockExclusive@nt@win32@fast_io@@YAXPEAX@Z=__imp_RtlAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?RtlTryAcquireSRWLockExclusive@nt@win32@fast_io@@YAIPEAX@Z=__imp_RtlTryAcquireSRWLockExclusive") #pragma comment(linker,"/alternatename:__imp_?RtlReleaseSRWLockExclusive@nt@win32@fast_io@@YAXPEAX@Z=__imp_RtlReleaseSRWLockExclusive") +#pragma comment(linker,"/alternatename:__imp_?NtQueryObject@nt@win32@fast_io@@YAIPEAXW4object_information_class@123@0IPEAI@Z=__imp_NtQueryObject") +#pragma comment(linker,"/alternatename:__imp_?ZwQueryObject@nt@win32@fast_io@@YAIPEAXW4object_information_class@123@0IPEAI@Z=__imp_ZwQueryObject") +#pragma comment(linker,"/alternatename:__imp_?NtQuerySystemInformation@nt@win32@fast_io@@YAIW4system_information_class@123@PEAXIPEAI@Z=__imp_NtQuerySystemInformation") +#pragma comment(linker,"/alternatename:__imp_?NtFreeVirtualMemory@nt@win32@fast_io@@YAIPEAXPEAPEAXPEA_KI@Z=__imp_NtFreeVirtualMemory") +#pragma comment(linker,"/alternatename:__imp_?ZwFreeVirtualMemory@nt@win32@fast_io@@YAIPEAXPEAPEAXPEA_KI@Z=__imp_ZwFreeVirtualMemory") +// msvc #pragma comment(linker,"/alternatename:__imp_?msvc__RTtypeid@msvc@fast_io@@YAPEAXPEAX@Z=__imp___RTtypeid") #pragma comment(linker,"/alternatename:?msvc__RTtypeid@msvc@fast_io@@YAPEAXPEAX@Z=__RTtypeid") // clang-format on diff --git a/include/fast_io_hosted/platforms/win32/win32_definitions.h b/include/fast_io_hosted/platforms/win32/win32_definitions.h index 90716cda9..762b8202c 100644 --- a/include/fast_io_hosted/platforms/win32/win32_definitions.h +++ b/include/fast_io_hosted/platforms/win32/win32_definitions.h @@ -325,4 +325,54 @@ struct time_zone_information ::std::int_least32_t DaylightBias; }; +struct system_info +{ + union + { + ::std::uint_least32_t dwOemId; // Obsolete field...do not use + + struct + { + ::std::uint_least16_t wProcessorArchitecture; + ::std::uint_least16_t wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + ::std::uint_least32_t dwPageSize; + void *lpMinimumApplicationAddress; + void *lpMaximumApplicationAddress; + ::std::size_t dwActiveProcessorMask; + ::std::uint_least32_t dwNumberOfProcessors; + ::std::uint_least32_t dwProcessorType; + ::std::uint_least32_t dwAllocationGranularity; + ::std::uint_least16_t wProcessorLevel; + ::std::uint_least16_t wProcessorRevision; +}; + +union large_integer +{ + struct + { + ::std::uint_least32_t LowPart; + ::std::int_least32_t HighPart; + }; + + struct + { + ::std::uint_least32_t LowPart; + ::std::int_least32_t HighPart; + } u; + + ::std::int_least64_t QuadPart; +}; + +struct file_basic_info +{ + large_integer CreationTime; + large_integer LastAccessTime; + large_integer LastWriteTime; + large_integer ChangeTime; + ::std::uint_least32_t FileAttributes; +}; + } // namespace fast_io::win32 diff --git a/include/fast_io_hosted/platforms/win32_mapping.h b/include/fast_io_hosted/platforms/win32_mapping.h index 938fac4ee..ad9514066 100644 --- a/include/fast_io_hosted/platforms/win32_mapping.h +++ b/include/fast_io_hosted/platforms/win32_mapping.h @@ -267,7 +267,7 @@ using win32_memory_map_file_9xa = win32_family_memory_map_file; using win32_memory_map_file = win32_family_memory_map_file; -#if !defined(__CYGWIN__) && !defined(__WINE__) +#if defined(_WIN32) && !defined(__WINE__) && !defined(__CYGWIN__) && !defined(__BIONIC__) && defined(_WIN32_WINDOWS) using native_memory_map_file = win32_memory_map_file; #endif diff --git a/include/fast_io_hosted/timeutil/time.h b/include/fast_io_hosted/timeutil/time.h index 1b1eb82d7..9898a2596 100644 --- a/include/fast_io_hosted/timeutil/time.h +++ b/include/fast_io_hosted/timeutil/time.h @@ -277,7 +277,7 @@ namespace win32::details inline unix_timestamp win32_posix_clock_gettime_tai_impl() noexcept { ::fast_io::win32::filetime ftm; -#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602) && !defined(_WIN32_WINDOWS) +#if (!defined(_WIN32_WINNT) || _WIN32_WINNT >= 0x0602) && !defined(_WIN32_WINDOWS) ::fast_io::win32::GetSystemTimePreciseAsFileTime(__builtin_addressof(ftm)); #else ::fast_io::win32::GetSystemTimeAsFileTime(__builtin_addressof(ftm)); diff --git a/include/fast_io_legacy_impl/filebuf/rtti_hack/impl.h b/include/fast_io_legacy_impl/filebuf/rtti_hack/impl.h index b85af9be0..2fd9ac227 100644 --- a/include/fast_io_legacy_impl/filebuf/rtti_hack/impl.h +++ b/include/fast_io_legacy_impl/filebuf/rtti_hack/impl.h @@ -69,7 +69,11 @@ inline constexpr bool symbol_cmp_equal_commom(char8_t const *sym, char const *st { if (N == len) { - if (__builtin_is_constant_evaluated()) +#if __cpp_if_consteval >= 202106L + if !consteval +#else + if(!__builtin_is_constant_evaluated()) +#endif { for (::std::size_t i{}; i != len; ++i) { diff --git a/include/fast_io_legacy_impl/filebuf/streambuf_io_observer.h b/include/fast_io_legacy_impl/filebuf/streambuf_io_observer.h index 8dc5aa600..4fb9a88ea 100644 --- a/include/fast_io_legacy_impl/filebuf/streambuf_io_observer.h +++ b/include/fast_io_legacy_impl/filebuf/streambuf_io_observer.h @@ -63,7 +63,6 @@ class basic_general_streambuf_io_observer #endif }; -#ifdef __cpp_lib_three_way_comparison template inline constexpr bool operator==(basic_general_streambuf_io_observer a, @@ -72,6 +71,7 @@ inline constexpr bool operator==(basic_general_streambuf_io_observer a, return a.fb == b.fb; } +#if __cpp_lib_three_way_comparison >= 201907L template inline constexpr auto operator<=>(basic_general_streambuf_io_observer a, basic_general_streambuf_io_observer b) noexcept diff --git a/include/fast_io_unit/gb18030.h b/include/fast_io_unit/gb18030.h index e9dd92e58..5c6342d56 100644 --- a/include/fast_io_unit/gb18030.h +++ b/include/fast_io_unit/gb18030.h @@ -72,7 +72,7 @@ inline constexpr ::std::size_t lookup_uni_to_gb18030(char32_t cdpt, T *p_dst) no ::std::endian::native == ::std::endian::big)) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { if constexpr (::std::endian::native == ::std::endian::big) { @@ -98,7 +98,7 @@ inline constexpr ::std::size_t lookup_uni_to_gb18030(char32_t cdpt, T *p_dst) no ::std::endian::native == ::std::endian::big)) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { if constexpr (::std::endian::native == ::std::endian::big) { @@ -182,7 +182,7 @@ inline constexpr ::std::size_t lookup_uni_to_gb18030_pdsz(char32_t cdpt, T *p_ds ::std::endian::native == ::std::endian::big)) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { if constexpr (::std::endian::native == ::std::endian::big) { @@ -212,7 +212,7 @@ inline constexpr ::std::size_t lookup_uni_to_gb18030_pdsz(char32_t cdpt, T *p_ds ::std::endian::native == ::std::endian::big)) { #if __cpp_lib_is_constant_evaluated >= 201811L - if (!::std::is_constant_evaluated()) + if (!__builtin_is_constant_evaluated()) { if constexpr (::std::endian::native == ::std::endian::big) {