From patchwork Fri Sep 27 22:55:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 98089 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3CACE385DDD1 for ; Fri, 27 Sep 2024 22:57:28 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 655313858C48 for ; Fri, 27 Sep 2024 22:56:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 655313858C48 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 655313858C48 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727477807; cv=none; b=xPOO9JdK4OlSVHAGAGFu8OUh1LgtWtkOlxtCoA63H6hfstDOcBNMfQ663+caIiKYyupJ82QbqISwzhOs33szzXHgQJe0jcPdyu0vhDSTeUeMBMLqRV3xW9JEhV+g3lgOZ8OryWyd8Fp5p/gh1H7JWN846ld2YdSacAKsihZhQuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1727477807; c=relaxed/simple; bh=J9tAChn8wgyUOsiAQHkzOX76DBJNz9Cy52bvKLA0Ks0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Hy4JDZPelN4pRKI5RpJOVVQms4IsSNqF0ieLFmmhrcfQxDjLKTubk/5bPURhoUtP8GNAlPCb5ceX3tR+Q/31jn3NzvuHbBmbYOWcDpZsc5rshT7FmG2dxwko8DrquVFZGKx7GXTGD4ZQkGfpnuRDsYBmj6redWBvgTWCG+gNqdo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1727477805; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=hmqMDDqeoHNFFi4dmvG7B23sK2EM0ATut5RzlRmj+fQ=; b=DL9uDPvqvfIlKPvLYUbWG968X4Rzfxgei9Hd9mf010q2tP1RYdvn9kh4+F59/R0fMJVPxm jpOqaQVqNRS7ZBglRWWbZdaniHZK6tako9hvYz9UHyJhYOjDkc4SGCT1FSXW9Dx+RLOk4A +Duelusb7/zqorKgJZArHGGOHtknR+4= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-426-9zmMRAwmM9K2f4F9MoRWuA-1; Fri, 27 Sep 2024 18:56:43 -0400 X-MC-Unique: 9zmMRAwmM9K2f4F9MoRWuA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (unknown [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AE8401943CD2; Fri, 27 Sep 2024 22:56:42 +0000 (UTC) Received: from localhost (unknown [10.42.28.136]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 46BFC19560A3; Fri, 27 Sep 2024 22:56:42 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Refactor experimental::filesystem::path string conversions Date: Fri, 27 Sep 2024 23:55:56 +0100 Message-ID: <20240927225641.2380561-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org Tested x86_64-linux and x86_64-w64-mingw32 (just the experimental::filesystem parts though). Pushed to trunk. -- >8 -- I noticed a -Wc++17-extensions warning due to use of if-constexpr in std::experimental::filesystem::path, which was not protected by diagnostic pragmas to disable the warning. While adding the pragmas I noticed that other places in the same file use tag dispatching and multiple overloads instead of if-constexpr. Since we're already using it in that file, we might as well just use it everywhere. libstdc++-v3/ChangeLog: * include/experimental/bits/fs_path.h (path::_Cvt): Refactor to use if-constexpr. (path::string(const Allocator&)): Likewise. --- .../include/experimental/bits/fs_path.h | 139 +++++++----------- 1 file changed, 54 insertions(+), 85 deletions(-) diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 5008e26af8d..a504aa2492c 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -775,60 +775,38 @@ namespace __detail __codecvt_utf8_to_wchar, __codecvt_utf8_to_utfNN>; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr + static string_type + _S_convert(const _CharT* __f, const _CharT* __l) + { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS -#ifdef _GLIBCXX_USE_CHAR8_T - static string_type - _S_wconvert(const char8_t* __f, const char8_t* __l, const char8_t*) - { - const char* __f2 = (const char*)__f; - const char* __l2 = (const char*)__l; - std::wstring __wstr; - std::codecvt_utf8_utf16 __wcvt; - if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt)) - return __wstr; - } -#endif - - static string_type - _S_wconvert(const char* __f, const char* __l, const char*) - { - std::codecvt_utf8_utf16 __cvt; - std::wstring __wstr; - if (__str_codecvt_in_all(__f, __l, __wstr, __cvt)) - return __wstr; - _GLIBCXX_THROW_OR_ABORT(filesystem_error( - "Cannot convert character sequence", - std::make_error_code(errc::illegal_byte_sequence))); - } - - static string_type - _S_wconvert(const _CharT* __f, const _CharT* __l, const void*) - { - __codecvt_utf8_to_wide __cvt; - std::string __str; - if (__str_codecvt_out_all(__f, __l, __str, __cvt)) + if constexpr (is_same<_CharT, char>::value) { - const char* __f2 = __str.data(); - const char* __l2 = __f2 + __str.size(); - std::codecvt_utf8_utf16 __wcvt; + std::codecvt_utf8_utf16 __cvt; std::wstring __wstr; - if (__str_codecvt_in_all(__f2, __l2, __wstr, __wcvt)) + // Convert char (assumed to be UTF-8) to wchar_t (UTF-16). + if (__str_codecvt_in_all(__f, __l, __wstr, __cvt)) return __wstr; } +#ifdef _GLIBCXX_USE_CHAR8_T + else if constexpr (is_same<_CharT, char8_t>::value) + return _S_convert((const char*)__f, (const char*)__l); +#endif + else + { + // Convert from _CharT to char first: + __codecvt_utf8_to_utfNN __cvt; + std::string __str; + if (__str_codecvt_out_all(__f, __l, __str, __cvt)) + // Then convert char to wchar_t: + return _S_convert(__str.c_str(), __str.c_str() + __str.size()); + } _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); - } - - static string_type - _S_convert(const _CharT* __f, const _CharT* __l) - { - return _S_wconvert(__f, __l, (const _CharT*)nullptr); - } -#else - static string_type - _S_convert(const _CharT* __f, const _CharT* __l) - { +#else // ! WINDOWS #ifdef _GLIBCXX_USE_CHAR8_T if constexpr (is_same<_CharT, char8_t>::value) return string_type(__f, __l); @@ -843,8 +821,9 @@ namespace __detail "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } +#endif // ! WINDOWS } -#endif +#pragma GCC diagnostic pop static string_type _S_convert(_CharT* __f, _CharT* __l) @@ -1038,66 +1017,55 @@ namespace __detail std::swap(_M_type, __rhs._M_type); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr template inline std::basic_string<_CharT, _Traits, _Allocator> path::string(const _Allocator& __a) const { - if _GLIBCXX17_CONSTEXPR (is_same<_CharT, value_type>::value) - return { _M_pathname.begin(), _M_pathname.end(), __a }; - using _WString = basic_string<_CharT, _Traits, _Allocator>; const value_type* __first = _M_pathname.data(); const value_type* __last = __first + _M_pathname.size(); + if constexpr (is_same<_CharT, value_type>::value) + return _WString(__first, __last, __a); #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - using _CharAlloc = __alloc_rebind<_Allocator, char>; - using _String = basic_string, _CharAlloc>; - - // First convert native string from UTF-16 to to UTF-8. - // XXX This assumes that the execution wide-character set is UTF-16. - codecvt_utf8_utf16 __cvt; - _String __u8str{_CharAlloc{__a}}; - if (__str_codecvt_out_all(__first, __last, __u8str, __cvt)) + else { - struct - { - const _String* - operator()(const _String& __from, _String&, true_type) - { return std::__addressof(__from); } + using _CharAlloc = __alloc_rebind<_Allocator, char>; + using _String = basic_string, _CharAlloc>; - _WString* - operator()(const _String& __from, _WString& __to, false_type) + // First convert native string from UTF-16 to to UTF-8. + // XXX This assumes that the execution wide-character set is UTF-16. + codecvt_utf8_utf16 __cvt; + _String __u8str{_CharAlloc{__a}}; + if (__str_codecvt_out_all(__first, __last, __u8str, __cvt)) { + if constexpr (is_same<_CharT, char>::value) + return __u8str; #ifdef _GLIBCXX_USE_CHAR8_T - if constexpr (is_same<_CharT, char8_t>::value) - { - __to.assign(__from.begin(), __from.end()); - return std::__addressof(__to); - } - else + else if constexpr (is_same<_CharT, char8_t>::value) + return _WString(__u8str.begin(), __u8str.end(), __a); #endif - { + else + { + _WString __wstr(__a); // Convert UTF-8 to char16_t or char32_t string. typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt; - const char* __f = __from.data(); - const char* __l = __f + __from.size(); - if (__str_codecvt_in_all(__f, __l, __to, __cvt)) - return std::__addressof(__to); - } - return nullptr; + const char* __f = __u8str.data(); + const char* __l = __f + __u8str.size(); + if (__str_codecvt_in_all(__f, __l, __wstr, __cvt)) + return __wstr; + } } - } __dispatch; - _WString __wstr(__a); - if (auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{})) - return *__p; } #else // ! Windows #ifdef _GLIBCXX_USE_CHAR8_T - if constexpr (is_same<_CharT, char8_t>::value) - return _WString(__first, __last, __a); - else + else if constexpr (is_same<_CharT, char8_t>::value) + return _WString(__first, __last, __a); #endif + else { typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt; _WString __wstr(__a); @@ -1109,6 +1077,7 @@ namespace __detail "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); } +#pragma GCC diagnostic pop inline std::string path::string() const { return string(); }