Skip to content

fix #1181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2025
Merged

fix #1181

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/fast_io_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <bit>
#include <limits>
#include <cstdint>
#include <version>

#if __cpp_lib_three_way_comparison >= 201907L
#include <compare>
Expand Down
2 changes: 1 addition & 1 deletion include/fast_io_core_impl/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ inline constexpr T compile_pow2{::fast_io::details::compile_pow_n<T, 2, pow>};


inline constexpr bool is_wasi_environment{
#if __wasi__
#ifdef __wasi__
true
#endif
};
Expand Down
12 changes: 6 additions & 6 deletions include/fast_io_freestanding_impl/serializations/lebe.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ inline constexpr auto iec559_lebe_put(T t)
}
else
{
#if __STDCPP_FLOAT32_T__
#ifdef __STDCPP_FLOAT32_T__
return ::fast_io::manipulators::lebe_put<en, 32>(
::std::bit_cast<::std::uint_least32_t>(static_cast<_Float32>(t)));
#else
Expand All @@ -198,7 +198,7 @@ inline constexpr auto iec559_lebe_put(T t)
}
else
{
#if __STDCPP_FLOAT64_T__
#ifdef __STDCPP_FLOAT64_T__
return ::fast_io::manipulators::lebe_put<en, 64>(
::std::bit_cast<::std::uint_least64_t>(static_cast<_Float64>(t)));
#else
Expand All @@ -208,7 +208,7 @@ inline constexpr auto iec559_lebe_put(T t)
}
else if constexpr (::std::same_as<nocvref, long double>)
{
#if __STDCPP_FLOAT128_T__
#ifdef __STDCPP_FLOAT128_T__
using proxy_type = ::fast_io::details::pesudo_int128type;
return ::fast_io::manipulators::basic_lebe_get_put<en, basic_lebe_put_integral<128, proxy_type>>{
{::std::bit_cast<::fast_io::details::pesudo_int128type>(static_cast<_Float128>(t))}};
Expand Down Expand Up @@ -480,7 +480,7 @@ scan_precise_reserve_define_lebe_float_get_impl(char_type const *iter, flttypef
}
else
{
#if __STDCPP_FLOAT32_T__
#ifdef __STDCPP_FLOAT32_T__
t = static_cast<flttypef>(::std::bit_cast<_Float32>(temp));
#else
static_assert(isiec559, "float is not iec60559");
Expand All @@ -495,7 +495,7 @@ scan_precise_reserve_define_lebe_float_get_impl(char_type const *iter, flttypef
}
else
{
#if __STDCPP_FLOAT64_T__
#ifdef __STDCPP_FLOAT64_T__
t = static_cast<flttypef>(::std::bit_cast<_Float64>(temp));
#else
static_assert(isiec559, "double is not iec60559");
Expand All @@ -504,7 +504,7 @@ scan_precise_reserve_define_lebe_float_get_impl(char_type const *iter, flttypef
}
else if constexpr (::std::same_as<flttype, long double>)
{
#if __STDCPP_FLOAT128_T__
#ifdef __STDCPP_FLOAT128_T__
t = static_cast<flttypef>(::std::bit_cast<_Float128>(temp));
#else
static_assert(sizeof(double) != sizeof(long) && isiec559,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class basic_transcoder_file : public transcoder_io_observer
other.transhandle = nullptr;
return *this;
}
inline constexpr void close() noexcept
inline constexpr void close()
{
this->transhandle->destroy();
this->transhandle = nullptr;
Expand Down
73 changes: 12 additions & 61 deletions include/fast_io_hosted/filesystem/dos_at.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,65 +111,16 @@ inline constexpr dos_at_flags &operator^=(dos_at_flags &x, dos_at_flags y) noexc
namespace details
{

struct my_dos_concat_path_common_result
{
bool failed{};
::fast_io::tlc::string path = ::fast_io::tlc::string();
};

inline my_dos_concat_path_common_result my_dos_concat_path_common(int dirfd, char const *pathname) noexcept
{
if (dirfd == -100)
{
return {false, ::fast_io::tlc::string(::fast_io::mnp::os_c_str(pathname))};
}
else
{
auto pathname_cstr{::fast_io::noexcept_call(::__get_fd_name, dirfd)};
if (pathname_cstr == nullptr) [[unlikely]]
{
return {true};
}

// check vaildity
auto const sz{::fast_io::cstr_len(pathname)};

if (sz > 255) [[unlikely]]
{
return {true};
}

if (::fast_io::details::is_invalid_dos_filename_with_size(pathname, sz)) [[unlikely]]
{
return {true};
}

// concat
return {false, ::fast_io::tlc::concat_fast_io_tlc(::fast_io::mnp::os_c_str(pathname_cstr), ::fast_io::mnp::chvw(u8'\\'), para_pathname)};
}
}

template <bool always_terminate = true>
inline ::fast_io::tlc::string my_dos_concat_path(int dirfd, char const *pathname) noexcept(always_terminate)
{
auto [failed, path] = ::fast_io::details::my_dos_concat_path_common(dirfd, pathname);
if (failed) [[unlikely]]
{
::fast_io::system_call_throw_error<always_terminate>(-1);
}
return ::std::move(path);
}

inline void dos_renameat_impl(int olddirfd, char const *oldpath, int newdirfd, char const *newpath)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_rename(::fast_io::details::my_dos_concat_path(olddirfd, oldpath).c_str(),
::fast_io::details::my_dos_concat_path(newdirfd, newpath).c_str()));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_rename(::fast_io::details::my_dos_concat_tlc_path(olddirfd, oldpath).c_str(),
::fast_io::details::my_dos_concat_tlc_path(newdirfd, newpath).c_str()));
}

inline void dos_linkat_impl(int olddirfd, char const *oldpath, int newdirfd, char const *newpath)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_link(::fast_io::details::my_dos_concat_path(olddirfd, oldpath).c_str(),
::fast_io::details::my_dos_concat_path(newdirfd, newpath).c_str()));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_link(::fast_io::details::my_dos_concat_tlc_path(olddirfd, oldpath).c_str(),
::fast_io::details::my_dos_concat_tlc_path(newdirfd, newpath).c_str()));
}

template <posix_api_22 dsp, typename... Args>
Expand All @@ -187,7 +138,7 @@ inline auto dos22_api_dispatcher(int olddirfd, char const *oldpath, int newdirfd

inline void dos_symlinkat_impl(char const *oldpath, int newdirfd, char const *newpath)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_symlink(oldpath, ::fast_io::details::my_dos_concat_path(newdirfd, newpath).c_str()));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_symlink(oldpath, ::fast_io::details::my_dos_concat_tlc_path(newdirfd, newpath).c_str()));
}

template <posix_api_12 dsp, typename... Args>
Expand All @@ -201,37 +152,37 @@ inline auto dos12_api_dispatcher(char const *oldpath, int newdirfd, char const *

inline void dos_faccessat_impl(int dirfd, char const *pathname, int flags)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_access(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(), flags));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_access(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(), flags));
}

inline void dos_fchownat_impl(int dirfd, char const *pathname, uintmax_t owner, uintmax_t group)
{
// chown does nothing under MS-DOS, so just check is_valid filename
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_chown(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(),
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_chown(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(),
static_cast<int>(owner), static_cast<int>(group)));
}

inline void dos_fchmodat_impl(int dirfd, char const *pathname, mode_t mode)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_chmod(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(), mode));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_chmod(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(), mode));
}

inline posix_file_status dos_fstatat_impl(int dirfd, char const *pathname)
{
struct stat buf;

::fast_io::system_call_throw_error(::fast_io::posix::my_dos_stat(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(), __builtin_addressof(buf)));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_stat(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(), __builtin_addressof(buf)));
return ::fast_io::details::struct_stat_to_posix_file_status(buf);
}

inline void dos_mkdirat_impl(int dirfd, char const *pathname, mode_t mode)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_mkdir(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(), mode));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_mkdir(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(), mode));
}

inline void dos_unlinkat_impl(int dirfd, char const *pathname)
{
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_unlink(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str()));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_unlink(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str()));
}

inline constexpr ::std::time_t unix_timestamp_to_time_t(unix_timestamp stmp) noexcept
Expand Down Expand Up @@ -271,7 +222,7 @@ inline void dos_utimensat_impl(int dirfd, char const *pathname, unix_timestamp_o
::fast_io::details::unix_timestamp_to_time_t(last_modification_time),
};

::fast_io::system_call_throw_error(::fast_io::posix::my_dos_utime(::fast_io::details::my_dos_concat_path(dirfd, pathname).c_str(), __builtin_addressof(ts)));
::fast_io::system_call_throw_error(::fast_io::posix::my_dos_utime(::fast_io::details::my_dos_concat_tlc_path(dirfd, pathname).c_str(), __builtin_addressof(ts)));
}

template <posix_api_1x dsp, typename... Args>
Expand Down
80 changes: 77 additions & 3 deletions include/fast_io_hosted/platforms/posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@
namespace fast_io
{

#if ((!defined(_WIN32) || defined(__WINE__)) || defined(__CYGWIN__))
namespace posix
{
#if defined(__DARWIN_C_LEVEL) || defined(__MSDOS__)
extern int libc_ioctl(int fd, unsigned long request, ...) noexcept __asm__("_ioctl");
#else
extern int libc_ioctl(int fd, unsigned long request, ...) noexcept __asm__("ioctl");
#endif
} // namespace posix
#endif

enum class posix_family
{
api,
Expand Down Expand Up @@ -836,13 +847,76 @@ extern int my_posix_open_noexcept(char const *pathname, int flags, mode_t mode)

#if defined(__MSDOS__)

template <bool always_terminate>
inline ::fast_io::tlc::string my_dos_concat_path(int, char const *) noexcept(always_terminate);
using dos_path_tlc_string = ::fast_io::containers::basic_string<char, ::fast_io::native_thread_local_allocator>;

template <typename... Args>
constexpr inline dos_path_tlc_string concat_dos_path_tlc_string(Args &&...args)
{
constexpr bool type_error{::fast_io::operations::defines::print_freestanding_okay<::fast_io::details::dummy_buffer_output_stream<char>, Args...>};
if constexpr (type_error)
{
return ::fast_io::basic_general_concat<false, char, dos_path_tlc_string>(::fast_io::io_print_forward<char>(::fast_io::io_print_alias(args))...);
}
else
{
static_assert(type_error, "some types are not printable, so we cannot concat dos_path_tlc_string");
return {};
}
}

struct my_dos_concat_tlc_path_common_result
{
bool failed{};
dos_path_tlc_string path{};
};

inline constexpr my_dos_concat_tlc_path_common_result my_dos_concat_tlc_path_common(int dirfd, char const *pathname) noexcept
{
if (dirfd == -100)
{
return {false, dos_path_tlc_string{::fast_io::mnp::os_c_str(pathname)}};
}
else
{
auto fd_pathname_cstr{::fast_io::noexcept_call(::__get_fd_name, dirfd)};
if (fd_pathname_cstr == nullptr) [[unlikely]]
{
return {true};
}

// check vaildity
auto const sz{::fast_io::cstr_len(pathname)};

if (sz > 255) [[unlikely]]
{
return {true};
}

if (::fast_io::details::is_invalid_dos_filename_with_size(pathname, sz)) [[unlikely]]
{
return {true};
}

// concat
return {false, concat_dos_path_tlc_string(::fast_io::mnp::os_c_str(fd_pathname_cstr), ::fast_io::mnp::chvw('\\'), ::fast_io::mnp::os_c_str(pathname))};
}
}

template <bool always_terminate = true>
inline constexpr dos_path_tlc_string my_dos_concat_tlc_path(int dirfd, char const *pathname) noexcept(always_terminate)
{
auto [failed, path]{my_dos_concat_tlc_path_common(dirfd, pathname)};
if (failed) [[unlikely]]
{
::fast_io::system_call_throw_error<always_terminate>(-1);
}
return path;
}

template <bool always_terminate = false>
inline int my_posix_openat(int dirfd, char const *pathname, int flags, mode_t mode)
{
int fd{::fast_io::details::my_posix_open_noexcept(::fast_io::details::my_dos_concat_path<always_terminate>(dirfd, pathname).c_str(), flags, mode)};
int fd{::fast_io::details::my_posix_open_noexcept(my_dos_concat_tlc_path<always_terminate>(dirfd, pathname).c_str(), flags, mode)};
system_call_throw_error<always_terminate>(fd);
return fd;
}
Expand Down
2 changes: 1 addition & 1 deletion include/fast_io_hosted/platforms/posix_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ class posix_memory_map_file
{
return address_begin[pos];
}
inline void close() noexcept
inline void close()
{
if (this->address_begin != MAP_FAILED) [[likely]]
{
Expand Down
7 changes: 4 additions & 3 deletions include/fast_io_hosted/platforms/win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -1234,7 +1234,7 @@ class win32_9xa_dir_io_observer
{
return handle;
}
inline explicit operator bool() const noexcept
inline explicit constexpr operator bool() const noexcept
{
return !handle.path.empty();
}
Expand All @@ -1244,6 +1244,7 @@ class win32_9xa_dir_io_observer
return temp;
}
};

inline constexpr bool operator==(win32_9xa_dir_io_observer const &a,
win32_9xa_dir_io_observer const &b) noexcept
{
Expand Down Expand Up @@ -1310,11 +1311,11 @@ class win32_9xa_dir_file : public win32_9xa_dir_io_observer
}
this->handle = ::std::move(newhandle);
}
inline void close() noexcept
inline void close()
{
if (*this) [[likely]]
{
::fast_io::win32::details::close_win32_9xa_dir_handle(this->handle);
::fast_io::win32::details::close_win32_9xa_dir_handle<true>(this->handle);
}
}

Expand Down
4 changes: 2 additions & 2 deletions include/fast_io_hosted/timeutil/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace fast_io
namespace posix
{
#if !defined(_WIN32) && !defined(__AVR__) && !defined(__MSDOS__)
#ifdef __DARWIN_C_LEVEL
#if defined(__DARWIN_C_LEVEL)
extern int libc_clock_getres(clockid_t clk_id, struct timespec *tp) noexcept __asm__("_clock_getres");
extern int libc_clock_settime(clockid_t clk_id, struct timespec const *tp) noexcept __asm__("_clock_settime");
extern int libc_clock_gettime(clockid_t clk_id, struct timespec *tp) noexcept __asm__("_clock_gettime");
#else
#if _REDIR_TIME64
#if defined(_REDIR_TIME64)
extern int libc_clock_getres(clockid_t clk_id, struct timespec *tp) noexcept __asm__("__clock_getres64");
extern int libc_clock_settime(clockid_t clk_id, struct timespec const *tp) noexcept __asm__("__clock_settime64");
extern int libc_clock_gettime(clockid_t clk_id, struct timespec *tp) noexcept __asm__("__clock_gettime64");
Expand Down
2 changes: 1 addition & 1 deletion include/fast_io_hosted/white_hole/white_hole.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ inline int my_random_entropy(int fd) noexcept
return 0;
}
#else
if (::fast_io::posix::ioctl(fd, RNDGETENTCNT, __builtin_addressof(ent)) != 0)
if (::fast_io::posix::libc_ioctl(fd, RNDGETENTCNT, __builtin_addressof(ent)) != 0)
{
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions share/fast_io/fast_io.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export module fast_io;
#include "fast_io_inc/core.inc"
#include "fast_io_inc/core/allocation.inc"
#include "fast_io_inc/freestanding.inc"
#include "fast_io_inc/intrinsics.inc"

#ifndef FAST_IO_FREESTANDING
# include "fast_io_inc/hosted.inc"
Expand Down
Loading
Loading