From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-2.mimecast.com [207.211.31.81]) by sourceware.org (Postfix) with ESMTP id 9DF233851C0C for ; Sat, 23 May 2020 08:42:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9DF233851C0C Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-365-S2HdHyaSP4Olj3g-TalLig-1; Sat, 23 May 2020 04:42:09 -0400 X-MC-Unique: S2HdHyaSP4Olj3g-TalLig-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 26EE7107ACCA; Sat, 23 May 2020 08:42:08 +0000 (UTC) Received: from localhost (unknown [10.33.36.10]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E75519C4F; Sat, 23 May 2020 08:42:07 +0000 (UTC) Date: Sat, 23 May 2020 09:42:06 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed 1/3] libstdc++: Simplify filesystem::path SFINAE constraints Message-ID: <20200523084206.GR2678@redhat.com> References: <20200523084043.GQ2678@redhat.com> MIME-Version: 1.0 In-Reply-To: <20200523084043.GQ2678@redhat.com> X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="zq44+AAfm4giZpo5" Content-Disposition: inline X-Spam-Status: No, score=-18.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 May 2020 08:42:15 -0000 --zq44+AAfm4giZpo5 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline This replaces the filesystem::__detail::_Path SFINAE helper with two separate helpers, _Path and _Path2. This avoids having one helper which tries to check two different sets of requirements. The _Path helper now uses variable templates instead of a set of overloaded functions to detect specializations of basic_string or basic_string_view. The __not_> check is not necessary in C++20 because iterator_traits is now empty. For C++17 replace that check with a __safe_iterator_traits helper with partial specializations for void pointers. Finally, the __is_encoded_char check no longer uses remove_const_t, which means that iterators with a const value_type will no longer be accepted as arguments for path creation. Such iterators resulted in undefined behaviour anyway, so it's still conforming to reject them in the constraint checks. * include/bits/fs_path.h (filesystem::__detail::__is_encoded_char): Replace alias template with variable template. Don't remove const. (filesystem::__detail::__is_path_src): Replace overloaded function template with variable template and specializations. (filesystem::__detail::__is_path_iter_src): Replace alias template with class template. (filesystem::__detail::_Path): Use __is_path_src. Remove support for iterator pairs. (filesystem::__detail::_Path2): New alias template for checking InputIterator requirements. (filesystem::__detail::__constructible_from): Remove. (filesystem::path): Replace _Path with _Path2. * testsuite/27_io/filesystem/path/construct/80762.cc: Check with two constructor arguments of void and void* types. Tested powerpc64le-linux, committed to master. --zq44+AAfm4giZpo5 Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 988b853f9c829742907ae22ac66de56facfc7bc5 Author: Jonathan Wakely Date: Sat May 23 07:28:40 2020 +0100 libstdc++: Simplify filesystem::path SFINAE constraints This replaces the filesystem::__detail::_Path SFINAE helper with two separate helpers, _Path and _Path2. This avoids having one helper which tries to check two different sets of requirements. The _Path helper now uses variable templates instead of a set of overloaded functions to detect specializations of basic_string or basic_string_view. The __not_> check is not necessary in C++20 because iterator_traits is now empty. For C++17 replace that check with a __safe_iterator_traits helper with partial specializations for void pointers. Finally, the __is_encoded_char check no longer uses remove_const_t, which means that iterators with a const value_type will no longer be accepted as arguments for path creation. Such iterators resulted in undefined behaviour anyway, so it's still conforming to reject them in the constraint checks. * include/bits/fs_path.h (filesystem::__detail::__is_encoded_char): Replace alias template with variable template. Don't remove const. (filesystem::__detail::__is_path_src): Replace overloaded function template with variable template and specializations. (filesystem::__detail::__is_path_iter_src): Replace alias template with class template. (filesystem::__detail::_Path): Use __is_path_src. Remove support for iterator pairs. (filesystem::__detail::_Path2): New alias template for checking InputIterator requirements. (filesystem::__detail::__constructible_from): Remove. (filesystem::path): Replace _Path with _Path2. * testsuite/27_io/filesystem/path/construct/80762.cc: Check with two constructor arguments of void and void* types. diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index ee6ab15cc4c..5a998284a99 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -73,58 +73,87 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __detail { template - using __is_encoded_char = __is_one_of, - char, + inline constexpr bool __is_encoded_char = false; + template<> + inline constexpr bool __is_encoded_char = true; #ifdef _GLIBCXX_USE_CHAR8_T - char8_t, + template<> + inline constexpr bool __is_encoded_char = true; #endif #if _GLIBCXX_USE_WCHAR_T - wchar_t, + template<> + inline constexpr bool __is_encoded_char = true; #endif - char16_t, char32_t>; - - template> - using __is_path_iter_src - = __and_<__is_encoded_char, - std::is_base_of>; + template<> + inline constexpr bool __is_encoded_char = true; + template<> + inline constexpr bool __is_encoded_char = true; +#if __cpp_concepts >= 201907L 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 std::false_type - __is_path_src(const _Unknown&, ...); - - template - struct __constructible_from; - + using __safe_iterator_traits = std::iterator_traits<_Iter>; +#else template - struct __constructible_from<_Iter, _Iter> - : __is_path_iter_src<_Iter> + struct __safe_iterator_traits : std::iterator_traits<_Iter> + { }; + + // Protect against ill-formed iterator_traits specializations in C++17 + template<> struct __safe_iterator_traits { }; + template<> struct __safe_iterator_traits { }; + template<> struct __safe_iterator_traits { }; + template<> struct __safe_iterator_traits { }; +#endif + + template + struct __is_path_iter_src + : false_type + { }; + + template + struct __is_path_iter_src<_Iter_traits, + void_t> + : bool_constant<__is_encoded_char> { }; template - struct __constructible_from<_Source, void> - : decltype(__is_path_src(std::declval<_Source>(), 0)) - { }; + inline constexpr bool __is_path_src + = __is_path_iter_src>>::value; - template - using _Path = typename - std::enable_if<__and_<__not_, path>>, - __not_>>, - __constructible_from<_Tp1, _Tp2>>::value, - path>::type; + template<> + inline constexpr bool __is_path_src = false; + + template<> + inline constexpr bool __is_path_src = false; + + template<> + inline constexpr bool __is_path_src = false; + + template<> + inline constexpr bool __is_path_src = false; + + template<> + inline constexpr bool __is_path_src = false; + + template<> + inline constexpr bool __is_path_src = false; + + template + inline constexpr bool + __is_path_src> + = __is_encoded_char<_CharT>; + + template + inline constexpr bool + __is_path_src> + = __is_encoded_char<_CharT>; + + // SFINAE constraint for Source parameters as required by [fs.path.req]. + template + using _Path = enable_if_t<__is_path_src<_Tp>, path>; + + // SFINAE constraint for InputIterator parameters as required by [fs.req]. + template> + using _Path2 = enable_if_t<__is_path_iter_src<_Tr>::value, path>; template static _Source @@ -227,7 +256,7 @@ namespace __detail { _M_split_cmpts(); } template> + typename _Require = __detail::_Path2<_InputIterator>> path(_InputIterator __first, _InputIterator __last, format = auto_format) : _M_pathname(_S_convert(__first, __last)) { _M_split_cmpts(); } @@ -241,8 +270,8 @@ namespace __detail { _M_split_cmpts(); } template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> + typename _Require = __detail::_Path2<_InputIterator>, + typename _Req2 = __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)) @@ -268,7 +297,7 @@ namespace __detail { return *this = path(__source); } template - __detail::_Path<_InputIterator, _InputIterator>& + __detail::_Path2<_InputIterator>& assign(_InputIterator __first, _InputIterator __last) { return *this = path(__first, __last); } @@ -295,7 +324,7 @@ namespace __detail } template - __detail::_Path<_InputIterator, _InputIterator>& + __detail::_Path2<_InputIterator>& append(_InputIterator __first, _InputIterator __last) { _M_append(_S_convert(__first, __last)); @@ -315,7 +344,7 @@ namespace __detail operator+=(_Source const& __x) { return concat(__x); } template - __detail::_Path<_CharT*, _CharT*>& + __detail::_Path2<_CharT*>& operator+=(_CharT __x); template @@ -328,7 +357,7 @@ namespace __detail } template - __detail::_Path<_InputIterator, _InputIterator>& + __detail::_Path2<_InputIterator>& concat(_InputIterator __first, _InputIterator __last) { _M_concat(_S_convert(__first, __last)); @@ -695,7 +724,7 @@ namespace __detail * @relates std::filesystem::path */ template, + typename _Require = __detail::_Path2<_InputIterator>, typename _CharT = __detail::__value_type_is_char_or_char8_t<_InputIterator>> inline path @@ -1000,7 +1029,7 @@ namespace __detail } template - inline __detail::_Path<_CharT*, _CharT*>& + inline __detail::_Path2<_CharT*>& path::operator+=(_CharT __x) { auto* __addr = std::__addressof(__x); diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/80762.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/80762.cc index bfc1e125e0c..2f37b663f26 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/80762.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/80762.cc @@ -37,3 +37,9 @@ static_assert( !std::is_constructible_v ); static_assert( !std::is_constructible_v ); static_assert( !std::is_constructible_v ); static_assert( !std::is_constructible_v ); + +static_assert( !std::is_constructible_v ); +static_assert( !std::is_constructible_v ); +static_assert( !std::is_constructible_v ); +static_assert( !std::is_constructible_v ); +static_assert( !std::is_constructible_v ); --zq44+AAfm4giZpo5--