diff --git a/include/fast_io_core_impl/char_category/char_category.h b/include/fast_io_core_impl/char_category/char_category.h index e704f91b..db94a543 100644 --- a/include/fast_io_core_impl/char_category/char_category.h +++ b/include/fast_io_core_impl/char_category/char_category.h @@ -1578,268 +1578,6 @@ inline constexpr char32_t to_c_lower_ascii_impl(char32_t ch) noexcept } // namespace details -template <::std::integral char_type> -inline constexpr char_type to_c_lower(char_type ch) noexcept -{ - using unsigned_char_type = ::std::make_unsigned_t; - if constexpr (!::fast_io::details::is_ebcdic) - { - return static_cast( - static_cast(details::to_c_lower_ascii_impl(static_cast(ch)))); - } - else if constexpr (::std::same_as) - { - switch (ch) - { - case 'A': - return 'a'; - case 'B': - return 'b'; - case 'C': - return 'c'; - case 'D': - return 'd'; - case 'E': - return 'e'; - case 'F': - return 'f'; - case 'G': - return 'g'; - case 'H': - return 'h'; - case 'I': - return 'i'; - case 'J': - return 'j'; - case 'K': - return 'k'; - case 'L': - return 'l'; - case 'M': - return 'm'; - case 'N': - return 'n'; - case 'O': - return 'o'; - case 'P': - return 'p'; - case 'Q': - return 'q'; - case 'R': - return 'r'; - case 'S': - return 's'; - case 'T': - return 't'; - case 'U': - return 'u'; - case 'V': - return 'v'; - case 'W': - return 'w'; - case 'X': - return 'x'; - case 'Y': - return 'y'; - case 'Z': - return 'z'; - default: - return ch; - } - } - else if constexpr (::std::same_as) - { - switch (ch) - { - case L'A': - return L'a'; - case L'B': - return L'b'; - case L'C': - return L'c'; - case L'D': - return L'd'; - case L'E': - return L'e'; - case L'F': - return L'f'; - case L'G': - return L'g'; - case L'H': - return L'h'; - case L'I': - return L'i'; - case L'J': - return L'j'; - case L'K': - return L'k'; - case L'L': - return L'l'; - case L'M': - return L'm'; - case L'N': - return L'n'; - case L'O': - return L'o'; - case L'P': - return L'p'; - case L'Q': - return L'q'; - case L'R': - return L'r'; - case L'S': - return L's'; - case L'T': - return L't'; - case L'U': - return L'u'; - case L'V': - return L'v'; - case L'W': - return L'w'; - case L'X': - return L'x'; - case L'Y': - return L'y'; - case L'Z': - return L'z'; - default: - return ch; - } - } -} - -template <::std::integral char_type> -inline constexpr char_type to_c_upper(char_type ch) noexcept -{ - using unsigned_char_type = ::std::make_unsigned_t; - if constexpr (!::fast_io::details::is_ebcdic) - { - return static_cast( - static_cast(details::to_c_upper_ascii_impl(static_cast(ch)))); - } - else if constexpr (::std::same_as) - { - switch (ch) - { - case 'a': - return 'A'; - case 'b': - return 'B'; - case 'c': - return 'C'; - case 'd': - return 'D'; - case 'e': - return 'E'; - case 'f': - return 'F'; - case 'g': - return 'G'; - case 'h': - return 'H'; - case 'i': - return 'I'; - case 'j': - return 'J'; - case 'k': - return 'K'; - case 'l': - return 'L'; - case 'm': - return 'M'; - case 'n': - return 'N'; - case 'o': - return 'O'; - case 'p': - return 'P'; - case 'q': - return 'Q'; - case 'r': - return 'R'; - case 's': - return 'S'; - case 't': - return 'T'; - case 'u': - return 'U'; - case 'v': - return 'V'; - case 'w': - return 'W'; - case 'x': - return 'X'; - case 'y': - return 'Y'; - case 'z': - return 'Z'; - default: - return ch; - } - } - else if constexpr (::std::same_as) - { - switch (ch) - { - case L'a': - return L'A'; - case L'b': - return L'B'; - case L'c': - return L'C'; - case L'd': - return L'D'; - case L'e': - return L'E'; - case L'f': - return L'F'; - case L'g': - return L'G'; - case L'h': - return L'H'; - case L'i': - return L'I'; - case L'j': - return L'J'; - case L'k': - return L'K'; - case L'l': - return L'L'; - case L'm': - return L'M'; - case L'n': - return L'N'; - case L'o': - return L'O'; - case L'p': - return L'P'; - case L'q': - return L'Q'; - case L'r': - return L'R'; - case L's': - return L'S'; - case L't': - return L'T'; - case L'u': - return L'U'; - case L'v': - return L'V'; - case L'w': - return L'W'; - case L'x': - return L'X'; - case L'y': - return L'Y'; - case L'z': - return L'Z'; - default: - return ch; - } - } -} - /* All Ascii based charset, only 6 character is supported space (0x20, ' ') @@ -2183,50 +1921,6 @@ inline constexpr bool is_c_fullwidth(char_type ch) noexcept To do: to_c_fullwidth */ -template <::std::integral char_type> -inline constexpr char_type to_c_halfwidth(char_type ch) noexcept -{ - using unsigned_char_type = ::std::make_unsigned_t; - if constexpr (sizeof(char_type) < sizeof(char32_t)) - { - return ch; - } - else if constexpr (!::std::same_as && sizeof(char_type) == sizeof(char32_t)) - { - return static_cast(to_c_halfwidth(static_cast(ch))); - } - else if constexpr (::std::signed_integral) - { - return static_cast(to_c_halfwidth(static_cast(ch))); - } - else if constexpr (::std::same_as && ::fast_io::details::wide_is_none_utf_endian) - { - constexpr unsigned_char_type fullwidth_exclaimation_mark_val{0xFF01}; - constexpr unsigned_char_type num{94}; - constexpr unsigned_char_type halfwidth_exclaimation_mark_val{u8'!'}; - unsigned_char_type cht{ch}; - cht = ::fast_io::byte_swap(cht); - unsigned_char_type const umav{static_cast(cht - fullwidth_exclaimation_mark_val)}; - if (umav < num) - { - return static_cast(umav + halfwidth_exclaimation_mark_val); - } - return cht; - } - else - { - constexpr unsigned_char_type fullwidth_exclaimation_mark_val{0xFF01}; - constexpr unsigned_char_type num{94}; - constexpr unsigned_char_type halfwidth_exclaimation_mark_val{u8'!'}; - unsigned_char_type const umav{static_cast(ch - fullwidth_exclaimation_mark_val)}; - if (umav < num) - { - return static_cast(umav + halfwidth_exclaimation_mark_val); - } - return ch; - } -} - template <::std::integral T> inline constexpr bool is_dos_path_invalid_character(T ch) noexcept { diff --git a/include/fast_io_core_impl/char_category/char_category_traits.h b/include/fast_io_core_impl/char_category/char_category_traits.h index 761992d0..c3648db5 100644 --- a/include/fast_io_core_impl/char_category/char_category_traits.h +++ b/include/fast_io_core_impl/char_category/char_category_traits.h @@ -172,86 +172,6 @@ class char_category_traits { return find_first_not(first, last) == last; } - - template <::std::integral char_type> - static inline constexpr bool char_to_lower(char_type ch) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_lower) - { - if constexpr (fam == ::fast_io::char_category::char_category_family::c_upper) - { - return ::fast_io::char_category::to_c_lower(ch); - } - else - { - return ch; - } - } - template <::std::integral char_type> - static inline constexpr bool char_to_upper(char_type ch) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_lower) - { - if constexpr (fam == ::fast_io::char_category::char_category_family::c_lower) - { - return ::fast_io::char_category::to_c_upper(ch); - } - else - { - return ch; - } - } - template <::std::forward_iterator Iter> - static inline constexpr Iter to_lower(Iter first, Iter last) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_upper) - { - if constexpr (!negate && fam == ::fast_io::char_category::char_category_family::c_upper) - { - for (; first != last; ++first) - { - *last = ::fast_io::char_category::to_c_lower(first); - } - } - return last; - } - template <::std::forward_iterator Iter> - static inline constexpr Iter to_upper(Iter first, Iter last) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_lower) - { - if constexpr (!negate && fam == ::fast_io::char_category::char_category_family::c_lower) - { - for (; first != last; ++first) - { - *last = ::fast_io::char_category::to_c_upper(first); - } - } - return last; - } - - template <::std::integral char_type> - static inline constexpr bool char_to_halfwidth(char_type ch) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_fullwidth) - { - if constexpr (!negate && fam == ::fast_io::char_category::char_category_family::c_fullwidth) - { - return ::fast_io::char_category::to_c_halfwidth(ch); - } - else - { - return ch; - } - } - template <::std::forward_iterator Iter> - static inline constexpr Iter to_halfwidth(Iter first, Iter last) noexcept - requires(!negate && fam == ::fast_io::char_category::char_category_family::c_fullwidth) - { - if constexpr (!negate && fam == ::fast_io::char_category::char_category_family::c_fullwidth) - { - for (; first != last; ++first) - { - *last = ::fast_io::char_category::to_c_halfwidth(first); - } - } - return last; - } }; using c_alnum = ::fast_io::char_category::char_category_traits<::fast_io::char_category::char_category_family::c_alnum, false>; @@ -289,4 +209,382 @@ using not_c_xdigit = ::fast_io::char_category::char_category_traits<::fast_io::c using not_dos_path_invalid_character = ::fast_io::char_category::char_category_traits<::fast_io::char_category::char_category_family::dos_path_invalid_character, true>; using not_html_whitespace = ::fast_io::char_category::char_category_traits<::fast_io::char_category::char_category_family::html_whitespace, true>; +namespace details +{ +template <::fast_io::char_category::char_category_family fam> +struct to_c_common_fn_impl +{ + template <::std::integral char_type> +#ifdef __cpp_static_call_operator + static +#endif + inline constexpr char_type operator()(char_type ch) +#ifndef __cpp_static_call_operator + const +#endif + noexcept + { + using unsigned_char_type = ::std::make_unsigned_t; + if constexpr (fam == ::fast_io::char_category::char_category_family::c_lower) + { + if constexpr (!::fast_io::details::is_ebcdic) + { + return static_cast( + static_cast(::fast_io::char_category::details::to_c_lower_ascii_impl(static_cast(ch)))); + } + else if constexpr (::std::same_as) + { + switch (ch) + { + case 'A': + return 'a'; + case 'B': + return 'b'; + case 'C': + return 'c'; + case 'D': + return 'd'; + case 'E': + return 'e'; + case 'F': + return 'f'; + case 'G': + return 'g'; + case 'H': + return 'h'; + case 'I': + return 'i'; + case 'J': + return 'j'; + case 'K': + return 'k'; + case 'L': + return 'l'; + case 'M': + return 'm'; + case 'N': + return 'n'; + case 'O': + return 'o'; + case 'P': + return 'p'; + case 'Q': + return 'q'; + case 'R': + return 'r'; + case 'S': + return 's'; + case 'T': + return 't'; + case 'U': + return 'u'; + case 'V': + return 'v'; + case 'W': + return 'w'; + case 'X': + return 'x'; + case 'Y': + return 'y'; + case 'Z': + return 'z'; + default: + return ch; + } + } + else if constexpr (::std::same_as) + { + switch (ch) + { + case L'A': + return L'a'; + case L'B': + return L'b'; + case L'C': + return L'c'; + case L'D': + return L'd'; + case L'E': + return L'e'; + case L'F': + return L'f'; + case L'G': + return L'g'; + case L'H': + return L'h'; + case L'I': + return L'i'; + case L'J': + return L'j'; + case L'K': + return L'k'; + case L'L': + return L'l'; + case L'M': + return L'm'; + case L'N': + return L'n'; + case L'O': + return L'o'; + case L'P': + return L'p'; + case L'Q': + return L'q'; + case L'R': + return L'r'; + case L'S': + return L's'; + case L'T': + return L't'; + case L'U': + return L'u'; + case L'V': + return L'v'; + case L'W': + return L'w'; + case L'X': + return L'x'; + case L'Y': + return L'y'; + case L'Z': + return L'z'; + default: + return ch; + } + } + } + else if constexpr (fam == ::fast_io::char_category::char_category_family::c_upper) + { + if constexpr (!::fast_io::details::is_ebcdic) + { + return static_cast( + static_cast(::fast_io::char_category::details::to_c_upper_ascii_impl(static_cast(ch)))); + } + else if constexpr (::std::same_as) + { + switch (ch) + { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + default: + return ch; + } + } + else if constexpr (::std::same_as) + { + switch (ch) + { + case L'a': + return L'A'; + case L'b': + return L'B'; + case L'c': + return L'C'; + case L'd': + return L'D'; + case L'e': + return L'E'; + case L'f': + return L'F'; + case L'g': + return L'G'; + case L'h': + return L'H'; + case L'i': + return L'I'; + case L'j': + return L'J'; + case L'k': + return L'K'; + case L'l': + return L'L'; + case L'm': + return L'M'; + case L'n': + return L'N'; + case L'o': + return L'O'; + case L'p': + return L'P'; + case L'q': + return L'Q'; + case L'r': + return L'R'; + case L's': + return L'S'; + case L't': + return L'T'; + case L'u': + return L'U'; + case L'v': + return L'V'; + case L'w': + return L'W'; + case L'x': + return L'X'; + case L'y': + return L'Y'; + case L'z': + return L'Z'; + default: + return ch; + } + } + } + else if constexpr (fam == ::fast_io::char_category::char_category_family::c_halfwidth) + { + if constexpr (sizeof(char_type) < sizeof(char32_t)) + { + return ch; + } + else if constexpr (!::std::same_as && sizeof(char_type) == sizeof(char32_t)) + { + return static_cast(operator()(static_cast(ch))); + } + else if constexpr (::std::signed_integral) + { + return static_cast(operator()(static_cast(ch))); + } + else if constexpr (::std::same_as && ::fast_io::details::wide_is_none_utf_endian) + { + constexpr unsigned_char_type fullwidth_exclaimation_mark_val{0xFF01}; + constexpr unsigned_char_type num{94}; + constexpr unsigned_char_type halfwidth_exclaimation_mark_val{u8'!'}; + unsigned_char_type cht{ch}; + cht = ::fast_io::byte_swap(cht); + unsigned_char_type const umav{static_cast(cht - fullwidth_exclaimation_mark_val)}; + if (umav < num) + { + return static_cast(umav + halfwidth_exclaimation_mark_val); + } + return cht; + } + else + { + constexpr unsigned_char_type fullwidth_exclaimation_mark_val{0xFF01}; + constexpr unsigned_char_type num{94}; + constexpr unsigned_char_type halfwidth_exclaimation_mark_val{u8'!'}; + unsigned_char_type const umav{static_cast(ch - fullwidth_exclaimation_mark_val)}; + if (umav < num) + { + return static_cast(umav + halfwidth_exclaimation_mark_val); + } + return ch; + } + } + } +}; + +} // namespace details + +inline constexpr ::fast_io::char_category::details::to_c_common_fn_impl<::fast_io::char_category::char_category_family::c_lower> to_c_lower{}; +inline constexpr ::fast_io::char_category::details::to_c_common_fn_impl<::fast_io::char_category::char_category_family::c_upper> to_c_upper{}; +inline constexpr ::fast_io::char_category::details::to_c_common_fn_impl<::fast_io::char_category::char_category_family::c_halfwidth> to_c_halfwidth{}; + +namespace ranges +{ +namespace details +{ +template <::fast_io::char_category::char_category_family fam> +struct to_c_common_rg_fn +{ + + template <::std::input_iterator Iter, ::std::sentinel_for S, typename Proj = ::std::identity> + requires ::std::integral<::std::iter_value_t> +#ifdef __cpp_static_call_operator + static +#endif + inline constexpr Iter operator()(Iter first, S last, Proj proj = {}) +#ifndef __cpp_static_call_operator + const +#endif + noexcept + { + for (; first != last; ++first) + { + if constexpr (fam == ::fast_io::char_category::char_category_family::c_lower) + { + *first = ::fast_io::char_category::to_c_lower(proj(*first)); + } + else if constexpr (fam == ::fast_io::char_category::char_category_family::c_upper) + { + *first = ::fast_io::char_category::to_c_upper(proj(*first)); + } + else if constexpr (fam == ::fast_io::char_category::char_category_family::c_halfwidth) + { + *first = ::fast_io::char_category::to_c_halfwidth(proj(*first)); + } + } + return first; + } + template <::std::ranges::input_range R, typename Proj = ::std::identity> + requires ::std::integral<::std::ranges::range_value_t> +#ifdef __cpp_static_call_operator + static +#endif + inline constexpr ::std::ranges::borrowed_iterator_t operator()(R &&r, Proj proj = {}) +#ifndef __cpp_static_call_operator + const +#endif + noexcept + { + return operator()(::std::ranges::begin(r), ::std::ranges::end(r), ::std::move(proj)); + } +}; +} // namespace details + +inline constexpr ::fast_io::char_category::ranges::details::to_c_common_rg_fn<::fast_io::char_category::char_category_family::c_lower> to_c_lower{}; +inline constexpr ::fast_io::char_category::ranges::details::to_c_common_rg_fn<::fast_io::char_category::char_category_family::c_upper> to_c_upper{}; +inline constexpr ::fast_io::char_category::ranges::details::to_c_common_rg_fn<::fast_io::char_category::char_category_family::c_halfwidth> to_c_halfwidth{}; +} // namespace ranges } // namespace fast_io::char_category diff --git a/include/fast_io_hosted/process/ipc/win32/alpc_nt.h b/include/fast_io_hosted/process/ipc/win32/alpc_nt.h index 8fe9bd24..d6c310a3 100644 --- a/include/fast_io_hosted/process/ipc/win32/alpc_nt.h +++ b/include/fast_io_hosted/process/ipc/win32/alpc_nt.h @@ -240,24 +240,24 @@ struct nt_alpc_handle FAST_IO_TRIVIALLY_RELOCATABLE_IF_ELIGIBLE { constexpr bool zw{family == nt_family::zw}; - ::std::uint_least32_t status; // No initialization required + ::std::uint_least32_t ntstatus; // No initialization required if (section_handle) { - status = ::fast_io::win32::nt::nt_alpc_disconnect_port(section_handle, 0); - if (status) [[unlikely]] + ntstatus = ::fast_io::win32::nt::nt_alpc_disconnect_port(section_handle, 0); + if (ntstatus) [[unlikely]] { - throw_nt_error(status); + throw_nt_error(ntstatus); } section_handle = nullptr; } if (port_handle) { - status = ::fast_io::win32::nt::nt_alpc_disconnect_port(port_handle, 0); - if (status) [[unlikely]] + ntstatus = ::fast_io::win32::nt::nt_alpc_disconnect_port(port_handle, 0); + if (ntstatus) [[unlikely]] { - throw_nt_error(status); + throw_nt_error(ntstatus); } port_handle = nullptr; } @@ -698,7 +698,7 @@ inline ::fast_io::win32::nt::alpc_message_attributes *nt_family_create_alpc_ipc_ } template -inline void *nt_family_ipc_alpc_client_connect_impl(nt_alpc_char_type const *server_name, ::std::size_t server_name_size, [[maybe_unused]] ::fast_io::ipc_mode mode, +inline void *nt_family_ipc_alpc_client_connect_impl(nt_alpc_char_type const *server_name, ::std::size_t server_name_size, [[maybe_unused]] ::fast_io::ipc_mode mode, ::std::byte const *message_begin, ::std::byte const *message_end, ::fast_io::win32::nt::alpc_message_attributes *__restrict message_attribute, nt_alpc_byte_vector &connect_recv_message) { @@ -904,7 +904,7 @@ inline ::std::byte const *nt_alpc_write_or_pwrite_some_bytes_common_impl(void *_ port_message_p->u1.s1.DataLength = static_cast<::std::uint_least16_t>(message_data_size); port_message_p->u1.s1.TotalLength = static_cast<::std::uint_least16_t>(send_size); - // There is a bug and it cannot be sent. + // There is a bug and it cannot be sent. // At present, the known usage of alpc is only synchronous mode, and the message flow mode has not been found yet // https://github.com/csandker/InterProcessCommunication-Samples/issues/7 diff --git a/tests/0026.container/0004.string/to_c_lower_upper.cc b/tests/0026.container/0004.string/to_c_lower_upper.cc new file mode 100644 index 00000000..98e1c0e4 --- /dev/null +++ b/tests/0026.container/0004.string/to_c_lower_upper.cc @@ -0,0 +1,30 @@ +#include +#include + +int main() +{ + ::fast_io::u8string ustr(u8"abcdefwegeABCDwgwasfsa 325235 fhasdfhsdh"), + ustr_upper(ustr), + ustr_lower(ustr), + numbers(u8"1234567890"), + symbols(u8"!@#$%^&*()"), + empty; + + // Apply transformations + ::fast_io::char_category::ranges::to_c_upper(ustr_upper); + ::fast_io::char_category::ranges::to_c_lower(ustr_lower); + ::fast_io::char_category::ranges::to_c_upper(numbers); + ::fast_io::char_category::ranges::to_c_upper(symbols); + ::fast_io::char_category::ranges::to_c_upper(empty); + + // Print all results in one println + ::fast_io::io::println(::fast_io::u8c_stdout(), + u8"Original: ", ustr, + u8"\nUppercase: ", ustr_upper, + u8"\nLowercase: ", ustr_lower, + u8"\nNumbers (unchanged): ", numbers, + u8"\nSymbols (unchanged): ", symbols, + u8"\nEmpty string: ", empty); + + return 0; +}