diff --git a/include/fast_io_driver/qt_impl/qiodevice.h b/include/fast_io_driver/qt_impl/qiodevice.h index 5b520a71b..aa72aae58 100644 --- a/include/fast_io_driver/qt_impl/qiodevice.h +++ b/include/fast_io_driver/qt_impl/qiodevice.h @@ -112,7 +112,7 @@ inline Iter read(basic_general_qdevice_io_observer qiob, Iter begin, template <::std::integral ch_type, typename T> requires(sizeof(ch_type) == 1) -inline ::std::pair try_get(basic_general_qdevice_io_observer qiob) +inline ::fast_io::try_get_result try_get(basic_general_qdevice_io_observer qiob) { char ch; bool ef{qiob.qdevice->getChar(&ch)}; diff --git a/include/fast_io_legacy_impl/c/done.h b/include/fast_io_legacy_impl/c/done.h index f4b823995..00bbf6755 100644 --- a/include/fast_io_legacy_impl/c/done.h +++ b/include/fast_io_legacy_impl/c/done.h @@ -55,33 +55,78 @@ inline ::std::size_t c_fwrite_unlocked_impl(void const *__restrict begin, ::std: throw_posix_error(rent._errno); } #else - ::std::size_t written_count{ -#if defined(__CYGWIN__) - my_cygwin_fwrite_unlocked(begin, type_size, count, fp) -#elif (defined(__USE_MISC) || defined(__BSD_VISIBLE)) && (!defined(__BIONIC__) || (defined(__USE_BSD))) -#if !defined(fwrite_unlocked) && defined(__has_builtin) + +#pragma push_macro("FAST_IO_FWRITE_UNLOCKED") +#pragma push_macro("FAST_IO_FWRITE") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED") +#pragma push_macro("FAST_IO_FWRITE_UNLOCKED_IMPL") + +#undef FAST_IO_FWRITE_UNLOCKED +#undef FAST_IO_FWRITE +#undef FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED +#undef FAST_IO_FWRITE_UNLOCKED_IMPL + +#ifdef __has_builtin #if __has_builtin(__builtin_fwrite_unlocked) - __builtin_fwrite_unlocked(begin, type_size, count, fp) -#else - fwrite_unlocked(begin, type_size, count, fp) +#define FAST_IO_FWRITE_UNLOCKED(...) __builtin_fwrite_unlocked(__VA_ARGS__) #endif +#endif +#ifndef FAST_IO_FWRITE_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FWRITE_UNLOCKED(...) ::fwrite_unlocked(__VA_ARGS__) +#elif defined(fwrite_unlocked) +#define FAST_IO_FWRITE_UNLOCKED(...) fwrite_unlocked(__VA_ARGS__) #else - fwrite_unlocked(begin, type_size, count, fp) +#define FAST_IO_FWRITE_UNLOCKED(...) ::fast_io::noexcept_call(::fwrite_unlocked, __VA_ARGS__) +#endif #endif -#elif !defined(fwrite) && defined(__has_builtin) + +#ifdef __has_builtin #if __has_builtin(__builtin_fwrite) - __builtin_fwrite(begin, type_size, count, fp) +#define FAST_IO_FWRITE(...) __builtin_fwrite(__VA_ARGS__) +#endif +#endif +#ifndef FAST_IO_FWRITE +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FWRITE(...) ::fwrite(__VA_ARGS__) +#elif defined(fwrite) +#define FAST_IO_FWRITE(...) fwrite(__VA_ARGS__) #else - fwrite(begin, type_size, count, fp) +#define FAST_IO_FWRITE(...) ::fast_io::noexcept_call(::fwrite, __VA_ARGS__) +#endif +#endif + +#if defined(__BIONIC__) +#if defined(__BIONIC_AVAILABILITY_GUARD) +#if __BIONIC_AVAILABILITY_GUARD(28) +#define FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED 1 +#endif #endif +#elif defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED 1 +#elif defined(__USE_MISC) || defined(__BSD_VISIBLE) +#define FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED 1 +#endif + +#if defined(__CYGWIN__) +#define FAST_IO_FWRITE_UNLOCKED_IMPL(...) my_cygwin_fwrite_unlocked(__VA_ARGS__) +#elif defined(FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED) +#define FAST_IO_FWRITE_UNLOCKED_IMPL(...) FAST_IO_FWRITE_UNLOCKED(__VA_ARGS__) #else - fwrite(begin, type_size, count, fp) +#define FAST_IO_FWRITE_UNLOCKED_IMPL(...) FAST_IO_FWRITE(__VA_ARGS__) #endif - }; + + ::std::size_t const written_count{FAST_IO_FWRITE_UNLOCKED_IMPL(begin, type_size, count, fp)}; + +#pragma pop_macro("FAST_IO_FWRITE_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_FWRITE_UNLOCKED") +#pragma pop_macro("FAST_IO_FWRITE") +#pragma pop_macro("FAST_IO_FWRITE_UNLOCKED") if (!written_count) [[unlikely]] { throw_posix_error(); } + #endif return written_count; } @@ -110,29 +155,77 @@ inline ::std::size_t c_fread_unlocked_impl(void *__restrict begin, ::std::size_t } } #else - ::std::size_t read_count{ -#if defined(__CYGWIN__) - my_cygwin_fread_unlocked(begin, type_size, count, fp) -#elif (defined(__USE_MISC) || defined(__BSD_VISIBLE)) && (!defined(__BIONIC__) || (defined(__USE_BSD))) -#if !defined(fread_unlocked) && defined(__has_builtin) + +#pragma push_macro("FAST_IO_FREAD_UNLOCKED") +#pragma push_macro("FAST_IO_FREAD") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED") +#pragma push_macro("FAST_IO_FREAD_UNLOCKED_IMPL") + +#undef FAST_IO_FREAD_UNLOCKED +#undef FAST_IO_FREAD +#undef FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED +#undef FAST_IO_FREAD_UNLOCKED_IMPL + +// Define FAST_IO_FREAD_UNLOCKED +#ifdef __has_builtin #if __has_builtin(__builtin_fread_unlocked) - __builtin_fread_unlocked(begin, type_size, count, fp) -#else - fread_unlocked(begin, type_size, count, fp) +#define FAST_IO_FREAD_UNLOCKED(...) __builtin_fread_unlocked(__VA_ARGS__) +#endif #endif +#ifndef FAST_IO_FREAD_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FREAD_UNLOCKED(...) ::fread_unlocked(__VA_ARGS__) +#elif defined(fread_unlocked) +#define FAST_IO_FREAD_UNLOCKED(...) fread_unlocked(__VA_ARGS__) #else - fread_unlocked(begin, type_size, count, fp) +#define FAST_IO_FREAD_UNLOCKED(...) ::fast_io::noexcept_call(::fread_unlocked, __VA_ARGS__) #endif -#elif !defined(fread) && defined(__has_builtin) +#endif + +// Define FAST_IO_FREAD +#ifdef __has_builtin #if __has_builtin(__builtin_fread) - __builtin_fread(begin, type_size, count, fp) +#define FAST_IO_FREAD(...) __builtin_fread(__VA_ARGS__) +#endif +#endif +#ifndef FAST_IO_FREAD +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FREAD(...) ::fread(__VA_ARGS__) +#elif defined(fread) +#define FAST_IO_FREAD(...) fread(__VA_ARGS__) #else - fread(begin, type_size, count, fp) +#define FAST_IO_FREAD(...) ::fast_io::noexcept_call(::fread, __VA_ARGS__) +#endif +#endif + +// Detect whether platform supports fread_unlocked +#if defined(__BIONIC__) +#if defined(__BIONIC_AVAILABILITY_GUARD) +#if __BIONIC_AVAILABILITY_GUARD(28) +#define FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED 1 +#endif #endif +#elif defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED 1 +#elif defined(__USE_MISC) || defined(__BSD_VISIBLE) +#define FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED 1 +#endif + +// Define the unified dispatch macro +#if defined(__CYGWIN__) +#define FAST_IO_FREAD_UNLOCKED_IMPL(...) my_cygwin_fread_unlocked(__VA_ARGS__) +#elif defined(FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED) +#define FAST_IO_FREAD_UNLOCKED_IMPL(...) FAST_IO_FREAD_UNLOCKED(__VA_ARGS__) #else - fread(begin, type_size, count, fp) +#define FAST_IO_FREAD_UNLOCKED_IMPL(...) FAST_IO_FREAD(__VA_ARGS__) #endif - }; + + ::std::size_t const read_count{FAST_IO_FREAD_UNLOCKED_IMPL(begin, type_size, count, fp)}; + +#pragma pop_macro("FAST_IO_FREAD_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_FREAD_UNLOCKED") +#pragma pop_macro("FAST_IO_FREAD") +#pragma pop_macro("FAST_IO_FREAD_UNLOCKED") if (read_count == 0) [[unlikely]] { if ( @@ -179,18 +272,27 @@ inline ::std::size_t c_fwrite_impl(void const *__restrict begin, ::std::size_t t throw_posix_error(rent._errno); } #else +#pragma push_macro("FAST_IO_FWRITE") +#undef FAST_IO_FWRITE - ::std::size_t written_count{ -#if !defined(fwrite) && defined(__has_builtin) +#ifdef __has_builtin #if __has_builtin(__builtin_fwrite) - __builtin_fwrite(begin, type_size, count, fp) -#else - fwrite(begin, type_size, count, fp) +#define FAST_IO_FWRITE(...) __builtin_fwrite(__VA_ARGS__) +#endif #endif +#ifndef FAST_IO_FWRITE +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FWRITE(...) ::fwrite(__VA_ARGS__) +#elif defined(fwrite) +#define FAST_IO_FWRITE(...) fwrite(__VA_ARGS__) #else - fwrite(begin, type_size, count, fp) +#define FAST_IO_FWRITE(...) ::fast_io::noexcept_call(::fwrite, __VA_ARGS__) #endif - }; +#endif + + ::std::size_t const written_count{FAST_IO_FWRITE(begin, type_size, count, fp)}; + +#pragma pop_macro("FAST_IO_FWRITE") if (!written_count) [[unlikely]] { throw_posix_error(); @@ -217,17 +319,27 @@ inline ::std::size_t c_fread_impl(void *__restrict begin, ::std::size_t type_siz } } #else - ::std::size_t read_count{ -#if !defined(fread) && defined(__has_builtin) +#pragma push_macro("FAST_IO_FREAD") +#undef FAST_IO_FREAD + +#ifdef __has_builtin #if __has_builtin(__builtin_fread) - __builtin_fread(begin, type_size, count, fp) -#else - fread(begin, type_size, count, fp) +#define FAST_IO_FREAD(...) __builtin_fread(__VA_ARGS__) #endif +#endif +#ifndef FAST_IO_FREAD +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FREAD(...) ::fread(__VA_ARGS__) +#elif defined(fread) +#define FAST_IO_FREAD(...) fread(__VA_ARGS__) #else - fread(begin, type_size, count, fp) +#define FAST_IO_FREAD(...) ::fast_io::noexcept_call(::fread, __VA_ARGS__) #endif - }; +#endif + + ::std::size_t const read_count{FAST_IO_FREAD(begin, type_size, count, fp)}; + +#pragma pop_macro("FAST_IO_FREAD") if (read_count == 0) [[unlikely]] { if ( diff --git a/include/fast_io_legacy_impl/c/general.h b/include/fast_io_legacy_impl/c/general.h index 7fd22b04b..3f0b0ce20 100644 --- a/include/fast_io_legacy_impl/c/general.h +++ b/include/fast_io_legacy_impl/c/general.h @@ -23,29 +23,153 @@ inline auto fgetc_unlocked_impl(FILE *fp) noexcept { if constexpr (::std::same_as || ::std::same_as) { + +#pragma push_macro("FAST_IO_FGETC_UNLOCKED") +#pragma push_macro("FAST_IO_FGETC") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED") +#pragma push_macro("FAST_IO_FGETC_UNLOCKED_IMPL") + +#undef FAST_IO_FGETC_UNLOCKED +#undef FAST_IO_FGETC +#undef FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED +#undef FAST_IO_FGETC_UNLOCKED_IMPL + #if (defined(_WIN32) && !defined(__WINE__)) - return _fgetc_nolock(fp); -#elif (defined(__NEWLIB__) && __GNU_VISIBLE) || \ - (!defined(__NEWLIB__) && \ - (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE)) - return fgetc_unlocked(fp); +#ifdef _fgetc_nolock +#define FAST_IO_FGETC_UNLOCKED(...) ::_fgetc_nolock(__VA_ARGS__) #else - return fgetc(fp); +#define FAST_IO_FGETC_UNLOCKED(...) ::fast_io::noexcept_call(::_fgetc_nolock, __VA_ARGS__) #endif +#elif defined(__BIONIC__) +#define FAST_IO_FGETC_UNLOCKED(...) ::fast_io::noexcept_call(::getc_unlocked, __VA_ARGS__) +#endif + +#ifndef FAST_IO_FGETC_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FGETC_UNLOCKED(...) ::fgetc_unlocked(__VA_ARGS__) +#elif defined(fgetc_unlocked) +#define FAST_IO_FGETC_UNLOCKED(...) fgetc_unlocked(__VA_ARGS__) +#else +#define FAST_IO_FGETC_UNLOCKED(...) ::fast_io::noexcept_call(::fgetc_unlocked, __VA_ARGS__) +#endif +#endif + + +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FGETC(...) ::fgetc(__VA_ARGS__) +#elif defined(fgetc_unlocked) +#define FAST_IO_FGETC(...) fgetc(__VA_ARGS__) +#else +#define FAST_IO_FGETC(...) ::fast_io::noexcept_call(::fgetc, __VA_ARGS__) +#endif + +#if defined(__BIONIC__) +#define FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED 1 +#elif defined(_WIN32) && !defined(__WINE__) +#define FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED 1 +#elif defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED 1 +#elif defined(__NEWLIB__) +#if __GNU_VISIBLE +#define FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED 1 +#endif +#elif _POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE +#define FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED 1 +#endif + +#if defined(FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED) +#define FAST_IO_FGETC_UNLOCKED_IMPL(...) FAST_IO_FGETC_UNLOCKED(__VA_ARGS__) +#else +#define FAST_IO_FGETC_UNLOCKED_IMPL(...) FAST_IO_FGETC(__VA_ARGS__) +#endif + + return FAST_IO_FGETC_UNLOCKED_IMPL(fp); + +#pragma pop_macro("FAST_IO_FGETC_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_FGETC_UNLOCKED") +#pragma pop_macro("FAST_IO_FGETC") +#pragma pop_macro("FAST_IO_FGETC_UNLOCKED") } else { +#pragma push_macro("FAST_IO_FGETWC_UNLOCKED") +#pragma push_macro("FAST_IO_FGETWC") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED") +#pragma push_macro("FAST_IO_PLATFORM_NOT_SUPPORTS_FGETWC") +#pragma push_macro("FAST_IO_FGETWC_UNLOCKED_IMPL") + +#undef FAST_IO_FGETWC_UNLOCKED +#undef FAST_IO_FGETWC +#undef FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED +#undef FAST_IO_PLATFORM_NOT_SUPPORTS_FGETWC +#undef FAST_IO_FGETWC_UNLOCKED_IMPL + +#if (defined(_WIN32) && !defined(__WINE__)) +#ifdef _fgetwc_nolock +#define FAST_IO_FGETWC_UNLOCKED(...) _fgetwc_nolock(__VA_ARGS__) +#else +#define FAST_IO_FGETWC_UNLOCKED(...) ::fast_io::noexcept_call(::_fgetwc_nolock, __VA_ARGS__) +#endif +#elif defined(__BIONIC__) +#define FAST_IO_FGETWC_UNLOCKED(...) ::fast_io::noexcept_call(::getc_unlocked, __VA_ARGS__) +#endif + +#ifndef FAST_IO_FGETWC_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FGETWC_UNLOCKED(...) ::fgetwc_unlocked(__VA_ARGS__) +#elif defined(fgetwc_unlocked) +#define FAST_IO_FGETWC_UNLOCKED(...) fgetwc_unlocked(__VA_ARGS__) +#else +#define FAST_IO_FGETWC_UNLOCKED(...) ::fast_io::noexcept_call(::fgetwc_unlocked, __VA_ARGS__) +#endif +#endif + + +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_FGETWC(...) ::fgetwc(__VA_ARGS__) +#elif defined(fgetwc_unlocked) +#define FAST_IO_FGETWC(...) fgetwc(__VA_ARGS__) +#else +#define FAST_IO_FGETWC(...) ::fast_io::noexcept_call(::fgetwc, __VA_ARGS__) +#endif + +#if defined(__serenity__) +#define FAST_IO_PLATFORM_NOT_SUPPORTS_FGETWC 1 +#elif defined(__BIONIC__) +#if defined(__BIONIC_AVAILABILITY_GUARD) +#if __BIONIC_AVAILABILITY_GUARD(28) +#define FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED 1 +#endif +#endif +#elif defined(_WIN32) && !defined(__WINE__) #if defined(_MSC_VER) || defined(_UCRT) || __MSVCRT_VERSION__ >= 0x800 - return _fgetwc_nolock(fp); -#elif (defined(__NEWLIB__) && __GNU_VISIBLE) || \ - (!defined(__NEWLIB__) && \ - (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE)) - return fgetwc_unlocked(fp); -#elif defined(__serenity__) - return EOF; +#define FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED 1 +#endif +#elif defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED 1 +#elif defined(__NEWLIB__) +#if __GNU_VISIBLE +#define FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED 1 +#endif +#elif _POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE +#define FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED 1 +#endif + +#if defined(FAST_IO_PLATFORM_NOT_SUPPORTS_FGETWC) +#define FAST_IO_FGETWC_UNLOCKED_IMPL(...) EOF +#elif defined(FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED) +#define FAST_IO_FGETWC_UNLOCKED_IMPL(...) FAST_IO_FGETWC_UNLOCKED(__VA_ARGS__) #else - return fgetwc(fp); +#define FAST_IO_FGETWC_UNLOCKED_IMPL(...) FAST_IO_FGETWC(__VA_ARGS__) #endif + + return FAST_IO_FGETWC_UNLOCKED_IMPL(fp); + +#pragma pop_macro("FAST_IO_FGETWC_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_NOT_SUPPORTS_FGETWC") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_FGETWC_UNLOCKED") +#pragma pop_macro("FAST_IO_FGETWC") +#pragma pop_macro("FAST_IO_FGETWC_UNLOCKED") } } @@ -67,29 +191,125 @@ inline constexpr bool equals_to_eof_macro(int_type inv) noexcept template <::std::integral char_type> inline auto ungetc_unlocked_impl(char_type ch, FILE *fp) noexcept { + + if constexpr (::std::same_as || ::std::same_as) { -#if defined(_MSC_VER) - return _ungetc_nolock(ch, fp); -#elif (defined(__NEWLIB__) && __GNU_VISIBLE) || \ - (!defined(__NEWLIB__) && \ - (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE)) - return ungetc_unlocked(ch, fp); + +#pragma push_macro("FAST_IO_UNGETC_UNLOCKED") +#pragma push_macro("FAST_IO_UNGETC") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_UNGETC_UNLOCKED") +#pragma push_macro("FAST_IO_UNGETC_UNLOCKED_IMPL") + +#undef FAST_IO_UNGETC_UNLOCKED +#undef FAST_IO_UNGETC +#undef FAST_IO_PLATFORM_SUPPORTS_UNGETC_UNLOCKED +#undef FAST_IO_UNGETC_UNLOCKED_IMPL + +#if (defined(_WIN32) && !defined(__WINE__)) +#ifdef _ungetc_nolock +#define FAST_IO_UNGETC_UNLOCKED(...) _ungetc_nolock(__VA_ARGS__) +#else +#define FAST_IO_UNGETC_UNLOCKED(...) ::fast_io::noexcept_call(::_ungetc_nolock, __VA_ARGS__) +#endif +#endif + +#ifndef FAST_IO_UNGETC_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_UNGETC_UNLOCKED(...) ::ungetc_unlocked(__VA_ARGS__) +#elif defined(ungetc_unlocked) +#define FAST_IO_UNGETC_UNLOCKED(...) ungetc_unlocked(__VA_ARGS__) +#else +#define FAST_IO_UNGETC_UNLOCKED(...) ::fast_io::noexcept_call(::ungetc_unlocked, __VA_ARGS__) +#endif +#endif + + +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_UNGETC(...) ::ungetc(__VA_ARGS__) +#elif defined(ungetc) +#define FAST_IO_UNGETC(...) ungetc(__VA_ARGS__) +#else +#define FAST_IO_UNGETC(...) ::fast_io::noexcept_call(::ungetc, __VA_ARGS__) +#endif + +#if !defined(__BIONIC__) && defined(_MSC_VER) +#define FAST_IO_PLATFORM_SUPPORTS_UNGETC_UNLOCKED 1 +#endif + +#if defined(FAST_IO_PLATFORM_SUPPORTS_UNGETC_UNLOCKED) +#define FAST_IO_UNGETC_UNLOCKED_IMPL(...) FAST_IO_UNGETC_UNLOCKED(__VA_ARGS__) #else - return ungetc(ch, fp); +#define FAST_IO_UNGETC_UNLOCKED_IMPL(...) FAST_IO_UNGETC(__VA_ARGS__) #endif + + return FAST_IO_UNGETC_UNLOCKED_IMPL(ch, fp); + +#pragma pop_macro("FAST_IO_UNGETC_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_UNGETC_UNLOCKED") +#pragma pop_macro("FAST_IO_UNGETC") +#pragma pop_macro("FAST_IO_UNGETC_UNLOCKED") } else { -#if defined(_MSC_VER) - return _ungetwc_nolock(ch, fp); -#elif (defined(__NEWLIB__) && __GNU_VISIBLE) || \ - (!defined(__NEWLIB__) && \ - (_POSIX_C_SOURCE >= 199309L || _XOPEN_SOURCE || _POSIX_SOURCE || _BSD_SOURCE || _SVID_SOURCE)) - return ungetwc_unlocked(ch, fp); +#pragma push_macro("FAST_IO_UNGETWC_UNLOCKED") +#pragma push_macro("FAST_IO_UNGETWC") +#pragma push_macro("FAST_IO_PLATFORM_SUPPORTS_UNGETWC_UNLOCKED") +#pragma push_macro("FAST_IO_PLATFORM_NOT_SUPPORTS_UNGETWC") +#pragma push_macro("FAST_IO_UNGETWC_UNLOCKED_IMPL") + +#undef FAST_IO_UNGETWC_UNLOCKED +#undef FAST_IO_UNGETWC +#undef FAST_IO_PLATFORM_SUPPORTS_UNGETWC_UNLOCKED +#undef FAST_IO_PLATFORM_NOT_SUPPORTS_UNGETWC +#undef FAST_IO_UNGETWC_UNLOCKED_IMPL + +#if (defined(_WIN32) && !defined(__WINE__)) +#ifdef _ungetwc_nolock +#define FAST_IO_UNGETWC_UNLOCKED(...) ::_ungetwc_nolock(__VA_ARGS__) #else - return ungetwc(ch, fp); +#define FAST_IO_UNGETWC_UNLOCKED(...) ::fast_io::noexcept_call(::_ungetwc_nolock, __VA_ARGS__) +#endif #endif + +#ifndef FAST_IO_UNGETWC_UNLOCKED +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_UNGETWC_UNLOCKED(...) ::ungetwc_unlocked(__VA_ARGS__) +#elif defined(ungetwc_unlocked) +#define FAST_IO_UNGETWC_UNLOCKED(...) ungetwc_unlocked(__VA_ARGS__) +#else +#define FAST_IO_UNGETWC_UNLOCKED(...) ::fast_io::noexcept_call(::ungetwc_unlocked, __VA_ARGS__) +#endif +#endif + + +#if defined(__GLIBC__) || defined(__LLVM_LIBC_TYPES_FILE_H__) +#define FAST_IO_UNGETWC(...) ::ungetwc(__VA_ARGS__) +#elif defined(ungetwc_unlocked) +#define FAST_IO_UNGETWC(...) ungetwc(__VA_ARGS__) +#else +#define FAST_IO_UNGETWC(...) ::fast_io::noexcept_call(::ungetwc, __VA_ARGS__) +#endif + +#if !defined(__BIONIC__) && defined(_MSC_VER) +#define FAST_IO_PLATFORM_SUPPORTS_UNGETWC_UNLOCKED 1 +#endif + +#if defined(FAST_IO_PLATFORM_NOT_SUPPORTS_UNGETWC) +#define FAST_IO_UNGETWC_UNLOCKED_IMPL(...) WEOF +#elif defined(FAST_IO_PLATFORM_SUPPORTS_UNGETWC_UNLOCKED) +#define FAST_IO_UNGETWC_UNLOCKED_IMPL(...) FAST_IO_UNGETWC_UNLOCKED(__VA_ARGS__) +#else +#define FAST_IO_UNGETWC_UNLOCKED_IMPL(...) FAST_IO_UNGETWC(__VA_ARGS__) +#endif + + return FAST_IO_UNGETWC_UNLOCKED_IMPL(ch, fp); + +#pragma pop_macro("FAST_IO_UNGETWC_UNLOCKED_IMPL") +#pragma pop_macro("FAST_IO_PLATFORM_NOT_SUPPORTS_UNGETWC") +#pragma pop_macro("FAST_IO_PLATFORM_SUPPORTS_UNGETWC_UNLOCKED") +#pragma pop_macro("FAST_IO_UNGETWC") +#pragma pop_macro("FAST_IO_UNGETWC_UNLOCKED") } } inline void ferror_throw_ex_impl(FILE *fp) @@ -112,12 +332,12 @@ template <::std::integral char_type> || ::std::same_as #endif || ::std::same_as) -inline ::std::pair try_get(basic_c_io_observer_unlocked ciob) +inline ::fast_io::try_get_result try_get(::fast_io::basic_c_io_observer_unlocked ciob) { - auto ret{details::fgetc_unlocked_impl(ciob.fp)}; - if (details::equals_to_eof_macro(ret)) + auto ret{::fast_io::details::fgetc_unlocked_impl(ciob.fp)}; + if (::fast_io::details::equals_to_eof_macro(ret)) { - details::ferror_throw_ex_impl(ciob.fp); + ::fast_io::details::ferror_throw_ex_impl(ciob.fp); return {0, false}; } return {static_cast(ret), true}; @@ -126,9 +346,9 @@ inline ::std::pair try_get(basic_c_io_observer_unlocked requires(::std::same_as || ::std::same_as || ::std::same_as) -inline void try_unget(basic_c_io_observer_unlocked ciob, char_type ch) noexcept +inline void try_unget(::fast_io::basic_c_io_observer_unlocked ciob, char_type ch) noexcept { - details::ungetc_unlocked_impl(ch, ciob.fp); + ::fast_io::details::ungetc_unlocked_impl(ch, ciob.fp); } } // namespace fast_io