From 86bbf15b6b87b94c36279a72343c3873b8f20551 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 26 Aug 2016 11:41:37 +0100 Subject: [PATCH] Add new std::basic_string constructor (LWG 2583) * config/abi/pre/gnu.ver (GLIBCXX_3.4, GLIBCXX_3.4.21): Use more precise patterns for basic_string constructors. (GLIBCXX_3.4.23): Export new constructors. * doc/xml/manual/intro.xml: Document LWG 2583 status. * doc/html/*: Regenerate. * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string(const basic_string&, size_type, const Alloc&)): Add new constructor for LWG 2583. (basic_string(const basic_string&, size_type, size_type)): Remove default argument. [!_GLIBCXX_USE_CXX11_ABI]: Likewise. * include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]: Define it. * testsuite/21_strings/basic_string/cons/char/8.cc: New test. * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: New test. From-SVN: r239773 --- libstdc++-v3/ChangeLog | 17 +++++ libstdc++-v3/config/abi/pre/gnu.ver | 34 ++++++++- libstdc++-v3/doc/html/manual/bugs.html | 4 ++ libstdc++-v3/doc/xml/manual/intro.xml | 7 ++ libstdc++-v3/include/bits/basic_string.h | 41 +++++++++-- libstdc++-v3/include/bits/basic_string.tcc | 10 +++ .../21_strings/basic_string/cons/char/8.cc | 70 +++++++++++++++++++ .../21_strings/basic_string/cons/wchar_t/8.cc | 70 +++++++++++++++++++ 8 files changed, 243 insertions(+), 10 deletions(-) create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0d7e8bf7f59..8b552b08cfb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2016-08-26 Jonathan Wakely + + * config/abi/pre/gnu.ver (GLIBCXX_3.4, GLIBCXX_3.4.21): Use more + precise patterns for basic_string constructors. + (GLIBCXX_3.4.23): Export new constructors. + * doc/xml/manual/intro.xml: Document LWG 2583 status. + * doc/html/*: Regenerate. + * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] + (basic_string(const basic_string&, size_type, const Alloc&)): Add + new constructor for LWG 2583. + (basic_string(const basic_string&, size_type, size_type)): Remove + default argument. + [!_GLIBCXX_USE_CXX11_ABI]: Likewise. + * include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]: Define it. + * testsuite/21_strings/basic_string/cons/char/8.cc: New test. + * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: New test. + 2016-08-24 Aditya Kumar * include/bits/algorithmfwd.h: Remove trailing whitespace. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index f51c6f961b0..0ab4bb10b35 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -206,7 +206,14 @@ GLIBCXX_3.4 { # std::string # 'y' here and below represents 'unsigned long long' # where it is used for size_type on LLP64 platforms. - _ZNSsC[12][EI][PRjmvyN]*; + _ZNSsC[12]EPKc*; + _ZNSsC[12]ERKSaIcE; + _ZNSsC[12]ERKSs; +# _ZNSsC[12]ERKSs[jmy]RKSaIcE; + _ZNSsC[12]ERKSs[jmy][jmy]*; + _ZNSsC[12]E[jmy]cRKSaIcE; + _ZNSsC[12]Ev; + _ZNSsC[12]I[PN]*; _ZNSsD*; _ZNSs[0-58-9]a*; _ZNSs5beginEv; @@ -267,7 +274,13 @@ GLIBCXX_3.4 { _ZNKSs4copyEPc[jmy][jmy]; # std::wstring - _ZNSbIwSt11char_traitsIwESaIwEEC[12][EI][PRjmvyN]*; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]EPKw*; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS[12]_; +# _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_mRKS1_; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_[jmy][jmy]*; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]E[jmy]wRKS1_; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]Ev; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]I[PN]*; _ZNSbIwSt11char_traitsIwESaIwEED*; _ZNSbIwSt11char_traitsIwESaIwEE[0-58-9]a*; _ZNSbIwSt11char_traitsIwESaIwEE5beginEv; @@ -1683,7 +1696,17 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE12_M*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[3-9]*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[2-9]*; - _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[CDaip]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EPK*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS[34]_; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_RKS3_; +# _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy]RKS3_; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy][jmy]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt16*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[jmy][cw]RKS3_; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]I[PN]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[Daip]*; _ZNKSt7__cxx1112basic_string*; # operator+ for ABI-tagged std::basic_string @@ -1919,6 +1942,11 @@ GLIBCXX_3.4.23 { # basic_string::_Alloc_hider::_Alloc_hider(C*, A&&) _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE12_Alloc_hiderC[12]EP[cw]OS3_; + # basic_string::basic_string(const basic_string&, size_type, const A&) + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy]RKS3_; + _ZNSsC[12]ERKSs[jmy]RKSaIcE; + _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_mRKS1_; + } GLIBCXX_3.4.22; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/doc/html/manual/bugs.html b/libstdc++-v3/doc/html/manual/bugs.html index c078debaf53..14ba1d2506a 100644 --- a/libstdc++-v3/doc/html/manual/bugs.html +++ b/libstdc++-v3/doc/html/manual/bugs.html @@ -475,6 +475,10 @@ allocator_traits::max_size() default behavior is incorrect

Divide by the object type. +

2583: + There is no way to supply an allocator for basic_string(str, pos) + +

Add new constructor

2684: priority_queue lacking comparator typedef diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index ea4d1c52096..d02306edbf6 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -1058,6 +1058,13 @@ requirements of the license of GCC. Divide by the object type. + 2583: + There is no way to supply an allocator for basic_string(str, pos) + + + Add new constructor + + 2684: priority_queue lacking comparator typedef diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 68cfc994de0..e823f132d4e 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -417,16 +417,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _Alloc_traits::_S_select_on_copy(__str._M_get_allocator())) { _M_construct(__str._M_data(), __str._M_data() + __str.length()); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2583. no way to supply an allocator for basic_string(str, pos) /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. - * @param __n Number of characters to copy (default remainder). + * @param __a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { + const _CharT* __start = __str._M_data() + + __str._M_check(__pos, "basic_string::basic_string"); + _M_construct(__start, __start + __str._M_limit(__pos, npos)); + } + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy. */ - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2402. [this constructor] shouldn't use Allocator() basic_string(const basic_string& __str, size_type __pos, - size_type __n = npos) + size_type __n) : _M_dataplus(_M_local_data()) { const _CharT* __start = __str._M_data() @@ -438,7 +453,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. - * @param __n Number of characters to copy (default remainder). + * @param __n Number of characters to copy. * @param __a Allocator to use. */ basic_string(const basic_string& __str, size_type __pos, @@ -3305,14 +3320,26 @@ _GLIBCXX_END_NAMESPACE_CXX11 * @param __str Source string. */ basic_string(const basic_string& __str); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2583. no way to supply an allocator for basic_string(str, pos) /** * @brief Construct string as copy of a substring. * @param __str Source string. * @param __pos Index of first character to copy from. - * @param __n Number of characters to copy (default remainder). + * @param __a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + const _Alloc& __a = _Alloc()); + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy. */ basic_string(const basic_string& __str, size_type __pos, - size_type __n = npos); + size_type __n); /** * @brief Construct string as copy of a substring. * @param __str Source string. diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 0560b466d73..0080d2b0e2f 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -619,6 +619,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_dataplus(_S_construct(size_type(), _CharT(), __a), __a) { } + template + basic_string<_CharT, _Traits, _Alloc>:: + basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a) + : _M_dataplus(_S_construct(__str._M_data() + + __str._M_check(__pos, + "basic_string::basic_string"), + __str._M_data() + __str._M_limit(__pos, npos) + + __pos, __a), __a) + { } + template basic_string<_CharT, _Traits, _Alloc>:: basic_string(const basic_string& __str, size_type __pos, size_type __n) 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 new file mode 100644 index 00000000000..6534f762a00 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc @@ -0,0 +1,70 @@ +// Copyright (C) 2016 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-do run { target c++11 } } + +#include +#include + +template +std::size_t +construct(Args&&... args) +{ + return std::string( std::forward(args)... ).length(); +} + +void +test01() +{ + bool test __attribute__((unused)) = true; + + using string = std::string; + using list = std::initializer_list; + + const std::string lvalue = "lvalue"; + std::allocator alloc; + + // test all valid combinations of arguments: + VERIFY( construct( ) == 0 ); + VERIFY( construct( alloc ) == 0 ); + VERIFY( construct( lvalue ) == 6 ); + VERIFY( construct( string{"rvalue"} ) == 6 ); + VERIFY( construct( lvalue, 2 ) == 4 ); + VERIFY( construct( lvalue, 2, alloc ) == 4 ); + VERIFY( construct( lvalue, 2, 3 ) == 3 ); + VERIFY( construct( lvalue, 2, 3, alloc ) == 3 ); + VERIFY( construct( "C string", 4 ) == 4 ); + VERIFY( construct( "C string", 4, alloc ) == 4 ); + VERIFY( construct( "C string" ) == 8 ); + VERIFY( construct( "C string and alloc", alloc ) == 18 ); + VERIFY( construct( 5, ' ' ) == 5 ); + VERIFY( construct( 5, ' ', alloc ) == 5 ); + VERIFY( construct( lvalue.begin(), lvalue.end() ) == 6 ); + 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 +main() +{ + test01(); +} 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 new file mode 100644 index 00000000000..9152ad9a8d4 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc @@ -0,0 +1,70 @@ +// Copyright (C) 2016 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-do run { target c++11 } } + +#include +#include + +template +std::size_t +construct(Args&&... args) +{ + return std::wstring( std::forward(args)... ).length(); +} + +void +test01() +{ + bool test __attribute__((unused)) = true; + + using string = std::wstring; + using list = std::initializer_list; + + const std::wstring lvalue = L"lvalue"; + std::allocator alloc; + + // test all valid combinations of arguments: + VERIFY( construct( ) == 0 ); + VERIFY( construct( alloc ) == 0 ); + VERIFY( construct( lvalue ) == 6 ); + VERIFY( construct( string{L"rvalue"} ) == 6 ); + VERIFY( construct( lvalue, 2 ) == 4 ); + VERIFY( construct( lvalue, 2, alloc ) == 4 ); + VERIFY( construct( lvalue, 2, 3 ) == 3 ); + VERIFY( construct( lvalue, 2, 3, alloc ) == 3 ); + VERIFY( construct( L"C string", 4 ) == 4 ); + VERIFY( construct( L"C string", 4, alloc ) == 4 ); + VERIFY( construct( L"C string" ) == 8 ); + VERIFY( construct( L"C string and alloc", alloc ) == 18 ); + VERIFY( construct( 5, L' ' ) == 5 ); + VERIFY( construct( 5, L' ', alloc ) == 5 ); + VERIFY( construct( lvalue.begin(), lvalue.end() ) == 6 ); + 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 +main() +{ + test01(); +} -- 2.30.2