From patchwork Sun Sep 15 19:39:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Honermann X-Patchwork-Id: 1162521 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-509025-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=honermann.net Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="cmWyJeL2"; dkim=pass (1024-bit key; unprotected) header.d=honermann.net header.i=@honermann.net header.b="IoKDkkP1"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Wfq14C3Mz9sN1 for ; Mon, 16 Sep 2019 05:40:13 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=yRZ7qzxAOehVnH0t5ym517Vke2ElR1bkKa9fLDZF/9pfhlf1fQplX zvkV/3HE0/jfLTy4mjE7EEbsZLjUgiE11Qh3tIXUM2eMKlsp99McO4RN5lN68NKz ZyX5LQG08E4G4r7JChRdPWqD8lQ08nI6gTEWHnecpMS8eRFfe0dAsI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=ykgqaDdDhpBdHng3UUz7Ir2ycr0=; b=cmWyJeL2Ex4UUOeMzR83 tsFS5966J+pvXwdtphAs8CLcCGTvj5eU2zhxLclp+XhpV6t4ab4DMhAxy+RNfO8/ ExEV+g07l9hYknnTMBhJoP9zIiKHTPTp3QUR8WY0lUaUA58Y/N6ALpiGdLGBbbnG zagD6n7nUia4bL1n9RQqFNE= Received: (qmail 2786 invoked by alias); 15 Sep 2019 19:39:37 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 2649 invoked by uid 89); 15 Sep 2019 19:39:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-13.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=XXX, implementations, viewing X-HELO: smtp64.iad3b.emailsrvr.com Received: from smtp64.iad3b.emailsrvr.com (HELO smtp64.iad3b.emailsrvr.com) (146.20.161.64) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 15 Sep 2019 19:39:31 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568576369; bh=avdOEkAPizejlEGJj8taJXMnFZM4X+6edKLjYShEqLc=; h=From:Subject:To:Date:From; b=IoKDkkP1IrMksAtCbVM8RoQzdgyfAudpeSprqGDi5emvbFXj/C+tYEgxNjDKTcuTN l1WgD7J60bHRtcive9N8z0ueYAgleyfp4KqP3VWy0dUL8hmqWj5D3G3F/98+f1jUDE qJoyjbfW5J0v8gMp0jYxz9SKAY2/gEXw6HhtqK1E= X-Auth-ID: tom@honermann.net Received: by smtp17.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 363EEA00C7; Sun, 15 Sep 2019 15:39:29 -0400 (EDT) X-Sender-Id: tom@honermann.net Received: from [192.168.1.20] (pool-72-84-244-119.rcmdva.fios.verizon.net [72.84.244.119]) (using TLSv1.2 with cipher AES128-SHA) by 0.0.0.0:25 (trex/5.7.12); Sun, 15 Sep 2019 15:39:29 -0400 From: Tom Honermann Subject: [PATCH 1/4]: C++ P1423R3 char8_t remediation: Decouple constraints for u8path from path constructors To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <467e09c6-62e9-14aa-9239-1cdd2be346b1@honermann.net> Date: Sun, 15 Sep 2019 15:39:28 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch moves helper classes and functions for std::filesystem::path out of the class definition to a detail namespace so that they are available to the implementations of std::filesystem::u8path. Prior to this patch, the SFINAE constraints for those implementations were specified via delegation to the overloads of path constructors with a std::locale parameter; it just so happened that those overloads had the same constraints. As of P1423R3, u8path and those overloads no longer have the same constraints, so this dependency must be broken. This patch also updates the experimental implementation of the filesystem TS to add SFINAE constraints to its implementations of u8path. These functions were previously unconstrained and marked with a TODO comment. This patch does not provide any intentional behavioral changes other than the added constraints to the experimental filesystem TS implementation of u8path. I recommend applying the patch and viewing the diff with white space ignored when reviewing; there will be many fewer differences this way. Alternatives to this refactoring would have been to make the u8path overloads friends of class path, or to make the helpers public members. Both of those approaches struck me as less desirable than this approach, though this approach does require more code changes and will affect implementation detail portions of mangled names for path constructors and inline member functions (mostly function template specializations). libstdc++-v3/ChangeLog: 2019-09-15 Tom Honermann * include/bits/fs_path.h: Moved helper utilities out of std::filesystem::path into a detail namespace to make them available for use by u8path. * include/experimental/bits/fs_path.h: Moved helper utilities out of std::experimental::filesystem::v1::path into a detail namespace to make them available for use by u8path. Tom. diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index e1083acf30f..71354515403 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -59,103 +59,114 @@ namespace filesystem { _GLIBCXX_BEGIN_NAMESPACE_CXX11 - /** @addtogroup filesystem + class path; + +namespace __detail +{ + /** @addtogroup filesystem-detail * @{ */ - /// A filesystem path. - class path - { - template - using __is_encoded_char = __is_one_of, - char, + template + using __is_encoded_char = __is_one_of, + char, #ifdef _GLIBCXX_USE_CHAR8_T - char8_t, + char8_t, #endif #if _GLIBCXX_USE_WCHAR_T - wchar_t, + wchar_t, #endif - char16_t, char32_t>; + char16_t, char32_t>; - template> - using __is_path_iter_src - = __and_<__is_encoded_char, - std::is_base_of>; + template> + using __is_path_iter_src + = __and_<__is_encoded_char, + std::is_base_of>; - template - static __is_path_iter_src<_Iter> - __is_path_src(_Iter, int); - - template - static __is_encoded_char<_CharT> - __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); - - template - static __is_encoded_char<_CharT> - __is_path_src(const basic_string_view<_CharT, _Traits>&, int); + template + static __is_path_iter_src<_Iter> + __is_path_src(_Iter, int); - template - static std::false_type - __is_path_src(const _Unknown&, ...); - - template - struct __constructible_from; - - template - struct __constructible_from<_Iter, _Iter> - : __is_path_iter_src<_Iter> - { }; + template + static __is_encoded_char<_CharT> + __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); - template - struct __constructible_from<_Source, void> - : decltype(__is_path_src(std::declval<_Source>(), 0)) - { }; + template + static __is_encoded_char<_CharT> + __is_path_src(const basic_string_view<_CharT, _Traits>&, int); - template - using _Path = typename - std::enable_if<__and_<__not_, path>>, - __not_>>, - __constructible_from<_Tp1, _Tp2>>::value, - path>::type; + template + static std::false_type + __is_path_src(const _Unknown&, ...); - template - static _Source - _S_range_begin(_Source __begin) { return __begin; } + template + struct __constructible_from; - struct __null_terminated { }; + template + struct __constructible_from<_Iter, _Iter> + : __is_path_iter_src<_Iter> + { }; - template - static __null_terminated - _S_range_end(_Source) { return {}; } + template + struct __constructible_from<_Source, void> + : decltype(__is_path_src(std::declval<_Source>(), 0)) + { }; - template - static const _CharT* - _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str) - { return __str.data(); } + template + using _Path = typename + std::enable_if<__and_<__not_, path>>, + __not_>>, + __constructible_from<_Tp1, _Tp2>>::value, + path>::type; - template - static const _CharT* - _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) - { return __str.data() + __str.size(); } + template + static _Source + _S_range_begin(_Source __begin) { return __begin; } - template - static const _CharT* - _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) - { return __str.data(); } + struct __null_terminated { }; - template - static const _CharT* - _S_range_end(const basic_string_view<_CharT, _Traits>& __str) - { return __str.data() + __str.size(); } + template + static __null_terminated + _S_range_end(_Source) { return {}; } + + template + static const _CharT* + _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str) + { return __str.data(); } + + template + static const _CharT* + _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) + { return __str.data() + __str.size(); } + + template + static const _CharT* + _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data(); } + + template + static const _CharT* + _S_range_end(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data() + __str.size(); } + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type> + using __value_type_is_char + = std::enable_if_t, char>>; + + // @} group filesystem-detail +} // namespace __detail - template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> - using __value_type_is_char - = std::enable_if_t, char>>; + /** @addtogroup filesystem + * @{ + */ + /// A filesystem path. + class path + { public: #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS using value_type = wchar_t; @@ -193,29 +204,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_split_cmpts(); } template> + typename _Require = __detail::_Path<_Source>> path(_Source const& __source, format = auto_format) - : _M_pathname(_S_convert(_S_range_begin(__source), - _S_range_end(__source))) + : _M_pathname(_S_convert(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source))) { _M_split_cmpts(); } template> + typename _Require = __detail::_Path<_InputIterator, _InputIterator>> path(_InputIterator __first, _InputIterator __last, format = auto_format) : _M_pathname(_S_convert(__first, __last)) { _M_split_cmpts(); } template, - typename _Require2 = __value_type_is_char<_Source>> + typename _Require = __detail::_Path<_Source>, + typename _Require2 = __detail::__value_type_is_char<_Source>> path(_Source const& __source, const locale& __loc, format = auto_format) - : _M_pathname(_S_convert_loc(_S_range_begin(__source), - _S_range_end(__source), __loc)) + : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source), __loc)) { _M_split_cmpts(); } template, - typename _Require2 = __value_type_is_char<_InputIterator>> + typename _Require = __detail::_Path<_InputIterator, _InputIterator>, + typename _Require2 = __detail::__value_type_is_char<_InputIterator>> path(_InputIterator __first, _InputIterator __last, const locale& __loc, format = auto_format) : _M_pathname(_S_convert_loc(__first, __last, __loc)) @@ -231,17 +242,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& assign(string_type&& __source); template - _Path<_Source>& + __detail::_Path<_Source>& operator=(_Source const& __source) { return *this = path(__source); } template - _Path<_Source>& + __detail::_Path<_Source>& assign(_Source const& __source) { return *this = path(__source); } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& assign(_InputIterator __first, _InputIterator __last) { return *this = path(__first, __last); } @@ -250,23 +261,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& operator/=(const path& __p); template - _Path<_Source>& + __detail::_Path<_Source>& operator/=(_Source const& __source) { - _M_append(_S_convert(_S_range_begin(__source), _S_range_end(__source))); + _M_append(_S_convert(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source))); return *this; } template - _Path<_Source>& + __detail::_Path<_Source>& append(_Source const& __source) { - _M_append(_S_convert(_S_range_begin(__source), _S_range_end(__source))); + _M_append(_S_convert(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source))); return *this; } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& append(_InputIterator __first, _InputIterator __last) { _M_append(_S_convert(__first, __last)); @@ -282,23 +295,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& operator+=(basic_string_view __x); template - _Path<_Source>& + __detail::_Path<_Source>& operator+=(_Source const& __x) { return concat(__x); } template - _Path<_CharT*, _CharT*>& + __detail::_Path<_CharT*, _CharT*>& operator+=(_CharT __x); template - _Path<_Source>& + __detail::_Path<_Source>& concat(_Source const& __x) { - _M_concat(_S_convert(_S_range_begin(__x), _S_range_end(__x))); + _M_concat(_S_convert(__detail::_S_range_begin(__x), + __detail::_S_range_end(__x))); return *this; } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& concat(_InputIterator __first, _InputIterator __last) { _M_concat(_S_convert(__first, __last)); @@ -496,11 +510,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct _Cvt; static basic_string_view - _S_convert(value_type* __src, __null_terminated) + _S_convert(value_type* __src, __detail::__null_terminated) { return __src; } static basic_string_view - _S_convert(const value_type* __src, __null_terminated) + _S_convert(const value_type* __src, __detail::__null_terminated) { return __src; } static basic_string_view @@ -522,7 +536,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template static string_type - _S_convert(_InputIterator __src, __null_terminated) + _S_convert(_InputIterator __src, __detail::__null_terminated) { // Read from iterator into basic_string until a null value is seen: auto __s = _S_string_from_iter(__src); @@ -544,7 +558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template static string_type - _S_convert_loc(_InputIterator __src, __null_terminated, + _S_convert_loc(_InputIterator __src, __detail::__null_terminated, const std::locale& __loc) { const std::string __s = _S_string_from_iter(__src); @@ -623,10 +637,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 size_t hash_value(const path& __p) noexcept; /// Create a path from a UTF-8-encoded sequence of char - template - inline auto + template, + typename _Require2 = __detail::__value_type_is_char<_InputIterator>> + inline path u8path(_InputIterator __first, _InputIterator __last) - -> decltype(filesystem::path(__first, __last, std::locale::classic())) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS // XXX This assumes native wide encoding is UTF-16. @@ -654,10 +669,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } /// Create a path from a UTF-8-encoded sequence of char - template - inline auto + template, + typename _Require2 = __detail::__value_type_is_char<_Source>> + inline path u8path(const _Source& __source) - -> decltype(filesystem::path(__source, std::locale::classic())) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS if constexpr (is_convertible_v) @@ -944,7 +960,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } template - inline path::_Path<_CharT*, _CharT*>& + inline __detail::_Path<_CharT*, _CharT*>& path::operator+=(_CharT __x) { auto* __addr = std::__addressof(__x); diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index a3655f616f2..3f9a69514a1 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -71,111 +71,120 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 using std::basic_string_view; #endif - /** - * @addtogroup filesystem-ts - * @{ +namespace __detail +{ + /** @addtogroup filesystem-ts-detail + * @{ */ - /// A filesystem path. - class path - { - template::type> - using __is_encoded_char - = __or_, - is_same<_Ch, wchar_t>, + template::type> + using __is_encoded_char + = __or_, + is_same<_Ch, wchar_t>, #ifdef _GLIBCXX_USE_CHAR8_T - is_same<_Ch, char8_t>, + is_same<_Ch, char8_t>, #endif - is_same<_Ch, char16_t>, - is_same<_Ch, char32_t>>; + is_same<_Ch, char16_t>, + is_same<_Ch, char32_t>>; - template> - using __is_path_iter_src - = __and_<__is_encoded_char, - std::is_base_of>; + template> + using __is_path_iter_src + = __and_<__is_encoded_char, + std::is_base_of>; - template - static __is_path_iter_src<_Iter> - __is_path_src(_Iter, int); + template + static __is_path_iter_src<_Iter> + __is_path_src(_Iter, int); - template - static __is_encoded_char<_CharT> - __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); + template + static __is_encoded_char<_CharT> + __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); #if __cplusplus >= 201402L - template - static __is_encoded_char<_CharT> - __is_path_src(const basic_string_view<_CharT, _Traits>&, int); + template + static __is_encoded_char<_CharT> + __is_path_src(const basic_string_view<_CharT, _Traits>&, int); #endif - template - static std::false_type - __is_path_src(const _Unknown&, ...); + template + static std::false_type + __is_path_src(const _Unknown&, ...); - template - struct __constructible_from; + template + struct __constructible_from; - template - struct __constructible_from<_Iter, _Iter> - : __is_path_iter_src<_Iter> - { }; + template + struct __constructible_from<_Iter, _Iter> + : __is_path_iter_src<_Iter> + { }; - template - struct __constructible_from<_Source, void> - : decltype(__is_path_src(std::declval<_Source>(), 0)) - { }; - - template::type, - typename _Tp1_noptr = typename remove_pointer<_Tp1>::type> - using _Path = typename - std::enable_if<__and_<__not_>, - __not_>, - __constructible_from<_Tp1, _Tp2>>::value, - path>::type; + template + struct __constructible_from<_Source, void> + : decltype(__is_path_src(std::declval<_Source>(), 0)) + { }; + + template::type, + typename _Tp1_noptr = typename remove_pointer<_Tp1>::type> + using _Path = typename + std::enable_if<__and_<__not_>, + __not_>, + __constructible_from<_Tp1, _Tp2>>::value, + path>::type; - template - static _Source - _S_range_begin(_Source __begin) { return __begin; } + template + static _Source + _S_range_begin(_Source __begin) { return __begin; } - struct __null_terminated { }; + struct __null_terminated { }; - template - static __null_terminated - _S_range_end(_Source) { return {}; } + template + static __null_terminated + _S_range_end(_Source) { return {}; } - template - static const _CharT* - _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str) - { return __str.data(); } + template + static const _CharT* + _S_range_begin(const basic_string<_CharT, _Traits, _Alloc>& __str) + { return __str.data(); } - template - static const _CharT* - _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) - { return __str.data() + __str.size(); } + template + static const _CharT* + _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) + { return __str.data() + __str.size(); } #if __cplusplus >= 201402L - template - static const _CharT* - _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) - { return __str.data(); } - - template - static const _CharT* - _S_range_end(const basic_string_view<_CharT, _Traits>& __str) - { return __str.data() + __str.size(); } + template + static const _CharT* + _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data(); } + + template + static const _CharT* + _S_range_end(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data() + __str.size(); } #endif - template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> - using __value_type_is_char = typename std::enable_if< - std::is_same::type, char>::value - >::type; + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type> + using __value_type_is_char = typename std::enable_if< + std::is_same::type, char>::value + >::type; + + // @} group filesystem-ts-detail +} // namespace __detail + /** + * @addtogroup filesystem-ts + * @{ + */ + + /// A filesystem path. + class path + { public: #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS typedef wchar_t value_type; @@ -205,29 +214,29 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 { _M_split_cmpts(); } template> + typename _Require = __detail::_Path<_Source>> path(_Source const& __source) - : _M_pathname(_S_convert(_S_range_begin(__source), - _S_range_end(__source))) + : _M_pathname(_S_convert(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source))) { _M_split_cmpts(); } template> + typename _Require = __detail::_Path<_InputIterator, _InputIterator>> path(_InputIterator __first, _InputIterator __last) : _M_pathname(_S_convert(__first, __last)) { _M_split_cmpts(); } template, - typename _Require2 = __value_type_is_char<_Source>> + typename _Require = __detail::_Path<_Source>, + typename _Require2 = __detail::__value_type_is_char<_Source>> path(_Source const& __source, const locale& __loc) - : _M_pathname(_S_convert_loc(_S_range_begin(__source), - _S_range_end(__source), __loc)) + : _M_pathname(_S_convert_loc(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source), __loc)) { _M_split_cmpts(); } template, - typename _Require2 = __value_type_is_char<_InputIterator>> + typename _Require = __detail::_Path<_InputIterator, _InputIterator>, + typename _Require2 = __detail::__value_type_is_char<_InputIterator>> path(_InputIterator __first, _InputIterator __last, const locale& __loc) : _M_pathname(_S_convert_loc(__first, __last, __loc)) { _M_split_cmpts(); } @@ -242,17 +251,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& assign(string_type&& __source); template - _Path<_Source>& + __detail::_Path<_Source>& operator=(_Source const& __source) { return *this = path(__source); } template - _Path<_Source>& + __detail::_Path<_Source>& assign(_Source const& __source) { return *this = path(__source); } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& assign(_InputIterator __first, _InputIterator __last) { return *this = path(__first, __last); } @@ -261,20 +270,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& operator/=(const path& __p) { return _M_append(__p._M_pathname); } template - _Path<_Source>& + __detail::_Path<_Source>& operator/=(_Source const& __source) { return append(__source); } template - _Path<_Source>& + __detail::_Path<_Source>& append(_Source const& __source) { - return _M_append(_S_convert(_S_range_begin(__source), - _S_range_end(__source))); + return _M_append(_S_convert(__detail::_S_range_begin(__source), + __detail::_S_range_end(__source))); } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& append(_InputIterator __first, _InputIterator __last) { return _M_append(_S_convert(__first, __last)); } @@ -289,20 +298,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #endif template - _Path<_Source>& + __detail::_Path<_Source>& operator+=(_Source const& __x) { return concat(__x); } template - _Path<_CharT*, _CharT*>& + __detail::_Path<_CharT*, _CharT*>& operator+=(_CharT __x); template - _Path<_Source>& + __detail::_Path<_Source>& concat(_Source const& __x) - { return *this += _S_convert(_S_range_begin(__x), _S_range_end(__x)); } + { + return *this += _S_convert(__detail::_S_range_begin(__x), + __detail::_S_range_end(__x)); + } template - _Path<_InputIterator, _InputIterator>& + __detail::_Path<_InputIterator, _InputIterator>& concat(_InputIterator __first, _InputIterator __last) { return *this += _S_convert(__first, __last); } @@ -446,11 +458,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 struct _Cvt; static string_type - _S_convert(value_type* __src, __null_terminated) + _S_convert(value_type* __src, __detail::__null_terminated) { return string_type(__src); } static string_type - _S_convert(const value_type* __src, __null_terminated) + _S_convert(const value_type* __src, __detail::__null_terminated) { return string_type(__src); } template @@ -464,7 +476,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template static string_type - _S_convert(_InputIterator __src, __null_terminated) + _S_convert(_InputIterator __src, __detail::__null_terminated) { auto __s = _S_string_from_iter(__src); return _S_convert(__s.c_str(), __s.c_str() + __s.size()); @@ -484,7 +496,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template static string_type - _S_convert_loc(_InputIterator __src, __null_terminated, + _S_convert_loc(_InputIterator __src, __detail::__null_terminated, const std::locale& __loc) { const std::string __s = _S_string_from_iter(__src); @@ -580,8 +592,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } /// Create a path from a UTF-8-encoded sequence of char - // TODO constrain with _Path and __value_type_is_char - template + template, + typename _Require2 = __detail::__value_type_is_char<_InputIterator>> inline path u8path(_InputIterator __first, _InputIterator __last) { @@ -602,8 +615,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } /// Create a path from a UTF-8-encoded sequence of char - // TODO constrain with _Path and __value_type_is_char - template + template, + typename _Require2 = __detail::__value_type_is_char<_Source>> inline path u8path(const _Source& __source) { @@ -872,7 +886,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 #endif template - inline path::_Path<_CharT*, _CharT*>& + inline __detail::_Path<_CharT*, _CharT*>& path::operator+=(_CharT __x) { auto* __addr = std::__addressof(__x); From patchwork Sun Sep 15 19:39:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Honermann X-Patchwork-Id: 1162523 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-509026-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=honermann.net Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yxm2U34L"; dkim=pass (1024-bit key; unprotected) header.d=honermann.net header.i=@honermann.net header.b="XszNMrkH"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46WfqL4v2Pz9sN1 for ; Mon, 16 Sep 2019 05:40:30 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=edFZuHsi53L6eB6PHLpq0V/YfUP4ultV4yBc4lNM+6RP+NhsWq0NP KaNHQT5DWTV7D9OAAr6NWH8DpRHCSRiQAtGIfAfo3xV5dgtWAim1TsRsbWN4FKEJ ZJcr1i1gVbWGjB+R53e2usRhu9gJlwVxftH5ELELMJ2F7MMRaNaYg8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=8bOLwKlWGnWWRhnP6bQeDplTZ7Q=; b=yxm2U34LBWbZLg4d9Yj/ ABl+sY2FQKDBCjBo7LNys9xje1mrYgAZM74vd5qkjtEv9R7R2cjeGYbp6QP70bqo +OJQ8CSVdZHNbNKC9jiimbLcvNZg5+k1YlnAz06HRXISdyYo9wQZyblN5xOHB7fj 8YoTuqsXOqE0IZR8pyRuoZ0= Received: (qmail 4099 invoked by alias); 15 Sep 2019 19:39:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4022 invoked by uid 89); 15 Sep 2019 19:39:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=increments X-HELO: smtp117.iad3b.emailsrvr.com Received: from smtp117.iad3b.emailsrvr.com (HELO smtp117.iad3b.emailsrvr.com) (146.20.161.117) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 15 Sep 2019 19:39:45 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568576383; bh=+Kva1kBkSOJpmQYiylbRZNFlOzU7/+9M5fRucL32ffs=; h=From:Subject:To:Date:From; b=XszNMrkHlIL4bety1G6J16fIPBI7Cbaicz8A9CSPKZsuspzwKVUoQc4M/38P8MYPp I7ctCM0SLVf8Jn9qTdQTljHLYasvXOIfGqN+HGM0MwwfLjTtC/x/N3/1bVCWH0+xL4 D7bAz5lHjAJcZR3x/8GTNpdD0yeSu4H5L9elhJkM= X-Auth-ID: tom@honermann.net Received: by smtp15.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 99EE0C00BB; Sun, 15 Sep 2019 15:39:43 -0400 (EDT) X-Sender-Id: tom@honermann.net Received: from [192.168.1.20] (pool-72-84-244-119.rcmdva.fios.verizon.net [72.84.244.119]) (using TLSv1.2 with cipher AES128-SHA) by 0.0.0.0:25 (trex/5.7.12); Sun, 15 Sep 2019 15:39:43 -0400 From: Tom Honermann Subject: [PATCH 2/4]: C++ P1423R3 char8_t remediation: Update feature test macro, add deleted operators, update u8path To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <05f9b7ab-b89a-4348-e758-e7ef9077261a@honermann.net> Date: Sun, 15 Sep 2019 15:39:41 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch increments the __cpp_lib_char8_t feature test macro, adds deleted operator<< overloads for basic_ostream, and modifies u8path to accept sequences of char8_t for both the C++17 implementation of std::filesystem, and the filesystem TS implementation. The implementation mechanism used for u8path differs between the C++17 and filesystem TS implementations. The changes to the former take advantage of C++17 'if constexpr'. The changes to the latter retain C++11 compatibility and rely on tag dispatching. libstdc++-v3/ChangeLog: 2019-09-15 Tom Honermann * libstdc++-v3/include/bits/c++config: Bumped the value of the __cpp_lib_char8_t feature test macro. * libstdc++-v3/include/bits/fs_path.h (u8path): Modified u8path to accept sequences of char8_t. * libstdc++-v3/include/experimental/bits/fs_path.h (u8path): Modified u8path to accept sequences of char8_t. * libstdc++-v3/include/std/ostream: Added deleted overloads of wchar_t, char8_t, char16_t, and char32_t for ordinary and wide formatted character and string inserters. Tom. diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index c8e099aaadd..5bcf32d95ef 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -620,7 +620,7 @@ namespace std # endif #endif #ifdef _GLIBCXX_USE_CHAR8_T -# define __cpp_lib_char8_t 201811L +# define __cpp_lib_char8_t 201907L #endif /* Define if __float128 is supported on this host. */ diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 71354515403..f3f539412fc 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -153,9 +153,24 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> using __value_type_is_char - = std::enable_if_t, char>>; + = std::enable_if_t, + _UnqualVal>; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> + using __value_type_is_char_or_char8_t + = std::enable_if_t<__or_v< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >, + _UnqualVal>; // @} group filesystem-detail } // namespace __detail @@ -639,29 +654,41 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> inline path u8path(_InputIterator __first, _InputIterator __last) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - // XXX This assumes native wide encoding is UTF-16. - std::codecvt_utf8_utf16 __cvt; - path::string_type __tmp; - if constexpr (is_pointer_v<_InputIterator>) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) - return path{ __tmp }; + return path{ __first, __last }; } else { - const std::string __u8str{__first, __last}; - const char* const __ptr = __u8str.data(); - if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) - return path{ __tmp }; +#endif + // XXX This assumes native wide encoding is UTF-16. + std::codecvt_utf8_utf16 __cvt; + path::string_type __tmp; + if constexpr (is_pointer_v<_InputIterator>) + { + if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) + return path{ __tmp }; + } + else + { + const std::string __u8str{__first, __last}; + const char* const __ptr = __u8str.data(); + if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) + return path{ __tmp }; + } + _GLIBCXX_THROW_OR_ABORT(filesystem_error( + "Cannot convert character sequence", + std::make_error_code(errc::illegal_byte_sequence))); +#ifdef _GLIBCXX_USE_CHAR8_T } - _GLIBCXX_THROW_OR_ABORT(filesystem_error( - "Cannot convert character sequence", - std::make_error_code(errc::illegal_byte_sequence))); +#endif #else // This assumes native normal encoding is UTF-8. return path{ __first, __last }; @@ -671,21 +698,32 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - if constexpr (is_convertible_v) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - const std::string_view __s = __source; - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return path{ __source }; } else { - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); +#endif + if constexpr (is_convertible_v) + { + const std::string_view __s = __source; + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + else + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } +#ifdef _GLIBCXX_USE_CHAR8_T } +#endif #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 3f9a69514a1..7a8cd8d20de 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -169,10 +169,23 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> using __value_type_is_char = typename std::enable_if< - std::is_same::type, char>::value - >::type; + std::is_same<_UnqualVal, char>::value, + _UnqualVal>::type; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> + using __value_type_is_char_or_char8_t = typename std::enable_if< + __or_< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >::value, _UnqualVal>::type; // @} group filesystem-ts-detail } // namespace __detail @@ -592,13 +605,11 @@ namespace __detail } /// Create a path from a UTF-8-encoded sequence of char - template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template inline path - u8path(_InputIterator __first, _InputIterator __last) + __u8path(_InputIterator __first, _InputIterator __last, char) { -#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS // XXX This assumes native wide encoding is UTF-16. std::codecvt_utf8_utf16 __cvt; path::string_type __tmp; @@ -609,21 +620,61 @@ namespace __detail _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(_InputIterator __first, _InputIterator __last, char8_t) + { + return path{ __first, __last }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + + template, + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> + inline path + u8path(_InputIterator __first, _InputIterator __last) + { +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + return __u8path(__first, __last, _CharT{}); #else return path{ __first, __last }; #endif } /// Create a path from a UTF-8-encoded sequence of char +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template + inline path + __u8path(const _Source& __source, char) + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(const _Source& __source, char8_t) + { + return path{ __source }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return __u8path(__source, _CharT{}); #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 2541d978886..94308d5de04 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -527,6 +527,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream& operator<<(basic_ostream& __out, unsigned char __c) { return (__out << static_cast(__c)); } + +#ifdef _GLIBCXX_USE_CHAR8_T + // The following deleted overloads prevent formatting character values as + // numeric values. + + template + basic_ostream& + operator<<(basic_ostream&, wchar_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; +#endif // _GLIBCXX_USE_CHAR8_T //@} //@{ @@ -582,6 +615,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream & operator<<(basic_ostream& __out, const unsigned char* __s) { return (__out << reinterpret_cast(__s)); } + +#ifdef _GLIBCXX_USE_CHAR8_T + // The following deleted overloads prevent formatting strings as + // pointer values. + + template + basic_ostream& + operator<<(basic_ostream&, const wchar_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; +#endif // _GLIBCXX_USE_CHAR8_T //@} // Standard basic_ostream manipulators From patchwork Sun Sep 15 19:39:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Honermann X-Patchwork-Id: 1162525 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-509027-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=honermann.net Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="eyiDd6lB"; dkim=pass (1024-bit key; unprotected) header.d=honermann.net header.i=@honermann.net header.b="GNMhTfFU"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Wfqp6G5Vz9sN1 for ; Mon, 16 Sep 2019 05:40:54 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=Vh9Ws1RvZ7OFQtBptNoAdtLmva0/2AamwFJgm1Lc+w3bGi5J8kFUB uF7RBK+/MfHU7FEXy3i18cdJ89M9wrAUwuwuAm03ydBNd2nwJsNT/vqNRDTA/v2G mMD0ik996rAyJKTEoOscbArqV0VmhdRWXRYcMRt9I0ao0ZBiyFRW0E= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=KO2Ahw6AGH/Z6uSSU9doVkUS3oM=; b=eyiDd6lBUv5rfsV2/MnK 29hkjih1Z9kn+mtFu+5VXQF7wj89MTyie7h+w8JA0UGVo0lEVExbKqIro+qBDaux P98wOMU27Fw4RKyMCQyVCrtDg4g7TrSXr/UktTUPFRFbkinc+UxrBDa7J1/3qu9z eQeGs3YZ2FMmY/jEq+4W7nc= Received: (qmail 5053 invoked by alias); 15 Sep 2019 19:39:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4993 invoked by uid 89); 15 Sep 2019 19:39:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=VERIFY, exercise, thereof X-HELO: smtp69.iad3b.emailsrvr.com Received: from smtp69.iad3b.emailsrvr.com (HELO smtp69.iad3b.emailsrvr.com) (146.20.161.69) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 15 Sep 2019 19:39:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568576395; bh=T2Bl3YPf2RZ2GzWy1Vn/+a6JMER94KyfPkLcKvmuU/g=; h=From:Subject:To:Date:From; b=GNMhTfFUA2ys0+DU61omKgWtCZSft+bsejttlHs/8P8lAYXCPPS4qGcKzSq6Uj1n6 M1q8wAsLVNAeuVAZdJr5m2DmLGCOglfoJKK1A3sUZzS9s1unxjeOy0xcIkK1bUv5qN T8elSv6YTQpK5FmucgwXN3EY93e9dNnP2daPmUTs= X-Auth-ID: tom@honermann.net Received: by smtp9.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 14DDF200B8; Sun, 15 Sep 2019 15:39:55 -0400 (EDT) X-Sender-Id: tom@honermann.net Received: from [192.168.1.20] (pool-72-84-244-119.rcmdva.fios.verizon.net [72.84.244.119]) (using TLSv1.2 with cipher AES128-SHA) by 0.0.0.0:25 (trex/5.7.12); Sun, 15 Sep 2019 15:39:55 -0400 From: Tom Honermann Subject: [PATCH 3/4]: C++ P1423R3 char8_t remediation: Updates to existing tests To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: Date: Sun, 15 Sep 2019 15:39:54 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch updates existing tests to validate the new value for the __cpp_lib_char8_t feature test macros and to exercise u8path factory function invocations with std::string, std::string_view, and interator pair arguments. libstdc++-v3/ChangeLog: 2019-09-15 Tom Honermann * libstdc++-v3/testsuite/experimental/feat-char8_t.cc: Updated the expected __cpp_lib_char8_t feature test macro value. * libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc: Added testing of u8path invocation with std::string, std::string_view, and iterators thereof. * libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc: Added testing of u8path invocation with std::string, std::string_view, and iterators thereof. Tom. diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc index aff722b5867..fb337ce1284 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path.cc @@ -19,6 +19,7 @@ // { dg-do run { target c++17 } } #include +#include #include namespace fs = std::filesystem; @@ -34,6 +35,22 @@ test01() p = fs::u8path("\xf0\x9d\x84\x9e"); VERIFY( p.u8string() == u8"\U0001D11E" ); + + std::string s1 = "filename2"; + p = fs::u8path(s1); + VERIFY( p.u8string() == u8"filename2" ); + + std::string s2 = "filename3"; + p = fs::u8path(s2.begin(), s2.end()); + VERIFY( p.u8string() == u8"filename3" ); + + std::string_view sv1{ s1 }; + p = fs::u8path(sv1); + VERIFY( p.u8string() == u8"filename2" ); + + std::string_view sv2{ s2 }; + p = fs::u8path(sv2.begin(), sv2.end()); + VERIFY( p.u8string() == u8"filename3" ); } void diff --git a/libstdc++-v3/testsuite/experimental/feat-char8_t.cc b/libstdc++-v3/testsuite/experimental/feat-char8_t.cc index e843604266c..c9b277a4626 100644 --- a/libstdc++-v3/testsuite/experimental/feat-char8_t.cc +++ b/libstdc++-v3/testsuite/experimental/feat-char8_t.cc @@ -12,6 +12,6 @@ #ifndef __cpp_lib_char8_t # error "__cpp_lib_char8_t" -#elif __cpp_lib_char8_t != 201811L -# error "__cpp_lib_char8_t != 201811L" +#elif __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t != 201907L" #endif diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc index bdeb3946a15..83219b7ddda 100644 --- a/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc +++ b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path.cc @@ -35,6 +35,14 @@ test01() p = fs::u8path("\xf0\x9d\x84\x9e"); VERIFY( p.u8string() == u8"\U0001D11E" ); + + std::string s1 = "filename2"; + p = fs::u8path(s1); + VERIFY( p.u8string() == u8"filename2" ); + + std::string s2 = "filename3"; + p = fs::u8path(s2.begin(), s2.end()); + VERIFY( p.u8string() == u8"filename3" ); } void From patchwork Sun Sep 15 19:40:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Honermann X-Patchwork-Id: 1162526 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-509028-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=honermann.net Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="aSXUSRVw"; dkim=pass (1024-bit key; unprotected) header.d=honermann.net header.i=@honermann.net header.b="g8xFQL1T"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Wfr91tdCz9sNx for ; Mon, 16 Sep 2019 05:41:13 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=GEXY2MZ9G4QTOT+W0rXVXjD4jMHlnPY0LOdZqb35L8z6dhTiOPajv yf1dGzCzk6p3kb4AvEj5S/qZkWsaZO+pNm77M6QWpGqgNNENWExVoUoe3zZgl341 sbtdai/7xZkexokblkjVh63Ktb+Uxe9fzq3h3TakqyFvfDUdjS2tF8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=LoyOWxgwgsSfV0lbyeNHX68Vvto=; b=aSXUSRVwYDz/VDC2Ya1e XohBdOeN5IDnZOoE9vohT7q3KV8WCOZaLNl+lFxmHxYXJPIYfDFWsVBNZ+YEO+tN glQmMJmLTkQX2xeGdZg7KQJa3pvsuvAjsBvMCiX4qYN03X9MUAsInnUuDAEpBQUW rEj141rpcClUKOAuyR01OTI= Received: (qmail 6473 invoked by alias); 15 Sep 2019 19:40:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 6367 invoked by uid 89); 15 Sep 2019 19:40:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=lx, Lx X-HELO: smtp104.iad3b.emailsrvr.com Received: from smtp104.iad3b.emailsrvr.com (HELO smtp104.iad3b.emailsrvr.com) (146.20.161.104) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 15 Sep 2019 19:40:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568576408; bh=CJk60bYjXq3ZZmirAWwwAzac0CLWSnnspFcC/ErnsS8=; h=From:Subject:To:Date:From; b=g8xFQL1Te4P/eA17GSRfE29jyRtFGTZn2EZYHqdPRtnK87S0nJcUBzxmwIBLgg/QR iERiwNmzklf19CSamcPM9i8QY+gSTYiN0RQFcUKApZvA1XiSIDQlItSRzTaY5yTxpX bLHHNtIODOifiIz/dlJ8mRDCU0b3nevAgZqJ26lw= X-Auth-ID: tom@honermann.net Received: by smtp14.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 7EE2BE00E1; Sun, 15 Sep 2019 15:40:08 -0400 (EDT) X-Sender-Id: tom@honermann.net Received: from [192.168.1.20] (pool-72-84-244-119.rcmdva.fios.verizon.net [72.84.244.119]) (using TLSv1.2 with cipher AES128-SHA) by 0.0.0.0:25 (trex/5.7.12); Sun, 15 Sep 2019 15:40:08 -0400 From: Tom Honermann Subject: [PATCH 4/4]: C++ P1423R3 char8_t remediation: New tests To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <23ef4bc4-bae7-662e-d6e7-07a60df053d4@honermann.net> Date: Sun, 15 Sep 2019 15:40:07 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch adds new tests to validate new deleted overloads of wchar_t, char8_t, char16_t, and char32_t for ordinary and wide formatted character and string ostream inserters. Additionally, new tests are added to validate invocations of u8path with sequences of char8_t for both the C++17 and filesystem TS implementations. libstdc++-v3/ChangeLog: 2019-09-15 Tom Honermann * libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc: New test to validate deleted overloads of character and string inserters for narrow ostreams. * libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc: New test to validate deleted overloads of character and string inserters for wide ostreams. * libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc: New test to validate u8path invocations with sequences of char8_t. * libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc New test to validate u8path invocations with sequences of char8_t. Tom. diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc new file mode 100644 index 00000000000..87afb295086 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/char/deleted.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.7.2 Header synopsys; deleted character inserters. + +// Test character inserters defined as deleted by P1423. + +// { dg-options "-std=gnu++17 -fchar8_t" } +// { dg-do compile { target c++17 } } + +#include + +void test_character_inserters(std::ostream &os) +{ + os << 'x'; // ok. + os << L'x'; // { dg-error "use of deleted function" } + os << u8'x'; // { dg-error "use of deleted function" } + os << u'x'; // { dg-error "use of deleted function" } + os << U'x'; // { dg-error "use of deleted function" } +} + +void test_string_inserters(std::ostream &os) +{ + os << "text"; // ok. + os << L"text"; // { dg-error "use of deleted function" } + os << u8"text"; // { dg-error "use of deleted function" } + os << u"text"; // { dg-error "use of deleted function" } + os << U"text"; // { dg-error "use of deleted function" } +} diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc new file mode 100644 index 00000000000..701de16822b --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_character/wchar_t/deleted.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// 29.7.2 Header synopsys; deleted character inserters. + +// Test wide character inserters defined as deleted by P1423. + +// { dg-options "-std=gnu++17 -fchar8_t" } +// { dg-do compile { target c++17 } } + +#include + +void test_character_inserters(std::wostream &os) +{ + os << 'x'; // ok. + os << L'x'; // ok. + os << u8'x'; // { dg-error "use of deleted function" } + os << u'x'; // { dg-error "use of deleted function" } + os << U'x'; // { dg-error "use of deleted function" } +} + +void test_string_inserters(std::wostream &os) +{ + os << "text"; // ok. + os << L"text"; // ok. + os << u8"text"; // { dg-error "use of deleted function" } + os << u"text"; // { dg-error "use of deleted function" } + os << U"text"; // { dg-error "use of deleted function" } +} diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc new file mode 100644 index 00000000000..867ee5b3856 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/factory/u8path-char8_t.cc @@ -0,0 +1,60 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17 -fchar8_t" } +// { dg-do run { target c++17 } } + +#include +#include +#include + +namespace fs = std::filesystem; + +void +test01() +{ + fs::path p = fs::u8path(u8""); + VERIFY( p.empty() ); + + p = fs::u8path(u8"filename1"); + VERIFY( p.u8string() == u8"filename1" ); + + p = fs::u8path(u8"\xf0\x9d\x84\x9e"); + VERIFY( p.u8string() == u8"\U0001D11E" ); + + std::u8string s1 = u8"filename2"; + p = fs::u8path(s1); + VERIFY( p.u8string() == u8"filename2" ); + + std::u8string s2 = u8"filename3"; + p = fs::u8path(s2.begin(), s2.end()); + VERIFY( p.u8string() == u8"filename3" ); + + std::u8string_view sv1{ s1 }; + p = fs::u8path(sv1); + VERIFY( p.u8string() == u8"filename2" ); + + std::u8string_view sv2{ s2 }; + p = fs::u8path(sv2.begin(), sv2.end()); + VERIFY( p.u8string() == u8"filename3" ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc new file mode 100644 index 00000000000..dc509c3f912 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/path/factory/u8path-char8_t.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-lstdc++fs -fchar8_t" } +// { dg-do run { target c++11 } } +// { dg-require-filesystem-ts "" } + +#include +#include + +namespace fs = std::experimental::filesystem; + +void +test01() +{ + fs::path p = fs::u8path(u8""); + VERIFY( p.empty() ); + + p = fs::u8path(u8"filename1"); + VERIFY( p.u8string() == u8"filename1" ); + + p = fs::u8path(u8"\xf0\x9d\x84\x9e"); + VERIFY( p.u8string() == u8"\U0001D11E" ); + + std::u8string s1 = u8"filename2"; + p = fs::u8path(s1); + VERIFY( p.u8string() == u8"filename2" ); + + std::u8string s2 = u8"filename3"; + p = fs::u8path(s2.begin(), s2.end()); + VERIFY( p.u8string() == u8"filename3" ); +} + +int +main() +{ + test01(); +}