From patchwork Fri Jan 4 23:23:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1020930 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-493419-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="EwUNhteS"; 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 43WgpC2sN5z9s4s for ; Sat, 5 Jan 2019 10:23:45 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=QnlIMnHGHWEv9lr8tnjyuLEvNAOMz6HDyXhZaLSAI/qtfv58a3rc/ jcs+2oL8gsD6ul9p8lgQSB7CgviLlOpOmbOrqrnZQeSuk5xR9noKgS4jZcMHLvaL n8zV7ELm4KYEaZuDx/TxgdXwQqgk6Bjm8fRhCwhRB565ImZkJDyb+8= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=PxUf05HehojW9JjgW/z1U7vLAi8=; b=EwUNhteSHGq8NXhQ4aIB vkkSG7CWTFLk4t4ZrQDhJQPbF+LyQXhRD4Im+ulFHZ8i7W0O2jGXu3SzIYt1NMtb c9iC5zerHFfUYnCvDOJTsr8thc/CnAMC9KfwBtEuDXykhNNYMpEmi9bw/T/SD0lB yciGndBCu3YJZeYy/zA+0Wc= Received: (qmail 88531 invoked by alias); 4 Jan 2019 23:23: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 88513 invoked by uid 89); 4 Jan 2019 23:23:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=li, lt X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 04 Jan 2019 23:23:33 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 819622BE87; Fri, 4 Jan 2019 23:23:32 +0000 (UTC) Received: from localhost (unknown [10.33.36.12]) by smtp.corp.redhat.com (Postfix) with ESMTP id 200F45C1A1; Fri, 4 Jan 2019 23:23:31 +0000 (UTC) Date: Fri, 4 Jan 2019 23:23:31 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] Add allocator-extended copy/move ctors to COW string Message-ID: <20190104232331.GA21282@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.10.1 (2018-07-13) Add these constructors from C++11 which were missing from the COW basic_string. Additionally simplify the definitions of the basic_string::reference and basic_string::const_reference types as required by C++11. This allows filesystem::path::string() to be simplified, so that the same code is used for both basic_string implementations. * config/abi/pre/gnu.ver (GLIBCXX_3.4.26): Export allocator-extended copy/move constructors for old std::basic_string. * include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI] (basic_string::reference, basic_string::const_reference): Define as plain references for C++11 and later. (basic_string::basic_string()): Put constructor body outside preprocessor conditional groups. (basic_string::basic_string(basic_string&&)): Move _Alloc_hider instead of copying it. (basic_string::basic_string(const basic_string&, const _Alloc&)): Define. (basic_string::basic_string(basic_string&&, const _Alloc&)): Define. * include/bits/fs_path.h [!_GLIBCXX_USE_CXX11_ABI]: Remove special cases for old basic_string. * testsuite/21_strings/basic_string/cons/char/8.cc: Test allocator-extended constructors unconditionally. Add extra members to allocator type when using old string ABI. * testsuite/21_strings/basic_string/allocator/71964.cc: Enable test for old string ABI. * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: Likewise. Tested powerpc64-linux, committed to trunk. There are still more new symbols that I plan to add to the library, so don't regenerate baseline_symbols.txt files yet. commit d8b09a24301736d69db0d041b4fb313b185c635d Author: Jonathan Wakely Date: Thu Oct 25 22:39:53 2018 +0100 Add allocator-extended copy/move ctors to COW string Add these constructors from C++11 which were missing from the COW basic_string. Additionally simplify the definitions of the basic_string::reference and basic_string::const_reference types as required by C++11. This allows filesystem::path::string() to be simplified, so that the same code is used for both basic_string implementations. * config/abi/pre/gnu.ver (GLIBCXX_3.4.26): Export allocator-extended copy/move constructors for old std::basic_string. * include/bits/basic_string.h [!_GLIBCXX_USE_CXX11_ABI] (basic_string::reference, basic_string::const_reference): Define as plain references for C++11 and later. (basic_string::basic_string()): Put constructor body outside preprocessor conditional groups. (basic_string::basic_string(basic_string&&)): Move _Alloc_hider instead of copying it. (basic_string::basic_string(const basic_string&, const _Alloc&)): Define. (basic_string::basic_string(basic_string&&, const _Alloc&)): Define. * include/bits/fs_path.h [!_GLIBCXX_USE_CXX11_ABI]: Remove special cases for old basic_string. * testsuite/21_strings/basic_string/cons/char/8.cc: Test allocator-extended constructors unconditionally. Add extra members to allocator type when using old string ABI. * testsuite/21_strings/basic_string/allocator/71964.cc: Enable test for old string ABI. * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: Likewise. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index de3c87abf15..1d157288fcf 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2072,6 +2072,11 @@ GLIBCXX_3.4.26 { _ZNSt14collate_bynameI[cw]EC[12]ERKSs[jmy]; _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc; + _ZNSsC[12]ERKSsRKSaIcE; + _ZNSsC[12]EOSsRKSaIcE; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_RKS1_; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]EOS2_RKS1_; + } GLIBCXX_3.4.25; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index e96d93fca34..43460df5d1f 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -3145,8 +3145,13 @@ _GLIBCXX_END_NAMESPACE_CXX11 typedef _Alloc allocator_type; typedef typename _CharT_alloc_type::size_type size_type; typedef typename _CharT_alloc_type::difference_type difference_type; +#if __cplusplus < 201103L typedef typename _CharT_alloc_type::reference reference; typedef typename _CharT_alloc_type::const_reference const_reference; +#else + typedef value_type& reference; + typedef const value_type& const_reference; +#endif typedef typename _CharT_alloc_type::pointer pointer; typedef typename _CharT_alloc_type::const_pointer const_pointer; typedef __gnu_cxx::__normal_iterator iterator; @@ -3526,10 +3531,11 @@ _GLIBCXX_END_NAMESPACE_CXX11 basic_string() #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 _GLIBCXX_NOEXCEPT - : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { } + : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) #else - : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()){ } + : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) #endif + { } /** * @brief Construct an empty string using allocator @a a. @@ -3610,7 +3616,7 @@ _GLIBCXX_END_NAMESPACE_CXX11 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 noexcept // FIXME C++11: should always be noexcept. #endif - : _M_dataplus(__str._M_dataplus) + : _M_dataplus(std::move(__str._M_dataplus)) { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 __str._M_data(_S_empty_rep()._M_refdata()); @@ -3625,6 +3631,25 @@ _GLIBCXX_END_NAMESPACE_CXX11 * @param __a Allocator to use (default is default allocator). */ basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()); + + basic_string(const basic_string& __str, const _Alloc& __a) + : _M_dataplus(__str._M_rep()->_M_grab(__a, __str.get_allocator()), __a) + { } + + basic_string(basic_string&& __str, const _Alloc& __a) + : _M_dataplus(__str._M_data(), __a) + { + if (__a == __str.get_allocator()) + { +#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 + __str._M_data(_S_empty_rep()._M_refdata()); +#else + __str._M_data(_S_construct(size_type(), _CharT(), __a)); +#endif + } + else + _M_dataplus._M_p = _S_construct(__str.begin(), __str.end(), __a); + } #endif // C++11 /** diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 34a5d324ce0..37dcfc16703 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -965,16 +965,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path::string(const _Allocator& __a) const { if constexpr (is_same_v<_CharT, value_type>) - { -#if _GLIBCXX_USE_CXX11_ABI - return { _M_pathname, __a }; -#else - if constexpr (is_same_v<_Allocator, string_type::allocator_type>) - return _M_pathname; - else - return { _M_pathname, string_type::size_type(0), __a }; -#endif - } + return { _M_pathname, __a }; else return _S_str_convert<_CharT, _Traits>(_M_pathname, __a); } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/71964.cc b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/71964.cc index 1d52738cfc2..2bebb232d41 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/71964.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/71964.cc @@ -16,8 +16,6 @@ // . // { dg-do run { target c++11 } } -// COW strings don't support C++11 allocators: -// { dg-require-effective-target cxx11-abi } #include #include @@ -47,6 +45,17 @@ template bool moved_to; bool moved_from; + +#if ! _GLIBCXX_USE_CXX11_ABI + // COW string doesn't use allocator_traits, requires C++03 allocator API. + using pointer = T*; + using const_pointer = const T*; + using difference_type = int; + template struct rebind { using other = mv_allocator; }; + void construct(pointer p, const T& val) { ::new(p) T(val); } + void destroy(pointer p) { p->~T(); } + size_type max_size() const { return std::allocator().max_size(); } +#endif }; template diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc index 28cdb938624..d99fb732722 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc @@ -70,10 +70,8 @@ test01() VERIFY( construct( lvalue.begin(), lvalue.end(), alloc ) == 6 ); VERIFY( construct( list{ 'l' , 'i' , 's', 't' } ) == 4 ); VERIFY( construct( list{ 'l', 'i', 's', 't' }, alloc ) == 4 ); -#if _GLIBCXX_USE_CXX11_ABI VERIFY( construct( lvalue, alloc ) == 6 ); VERIFY( construct( string{"rvalue"}, alloc ) == 6 ); -#endif } int diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc index f5fc9d6af78..8c330e38aea 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc @@ -70,10 +70,8 @@ test01() VERIFY( construct( lvalue.begin(), lvalue.end(), alloc ) == 6 ); VERIFY( construct( list{ L'l' , L'i' , L's', L't' } ) == 4 ); VERIFY( construct( list{ L'l', L'i', L's', L't' }, alloc ) == 4 ); -#if _GLIBCXX_USE_CXX11_ABI VERIFY( construct( lvalue, alloc ) == 6 ); VERIFY( construct( string{L"rvalue"}, alloc ) == 6 ); -#endif } int