diff mbox

Add std::string constructor for substring of string_view (LWG 2742)

Message ID 20161115143349.GG3145@redhat.com
State Accepted
Commit bf56b0b8384cfcc5142f24eeb8f837cc974f8119
Headers show

Commit Message

Jonathan Wakely Nov. 15, 2016, 2:33 p.m. UTC
This is another issue resolution for C++17 features that was approved
at the recent meeting. I think this resolution is wrong too, but in
this case the fix is obvious so I've gone ahead and done it.

	* doc/xml/manual/intro.xml: Document LWG 2742 status.
	* doc/html/*: Regenerate.
	* include/bits/basic_string.h
	(basic_string(const T&, size_type, size_type, const Allocator&)): Add
	constructor for substring of basic_string_view, as per LWG 2742 but
	with additional constraint to fix ambiguity.
	* testsuite/21_strings/basic_string/cons/char/9.cc: New test.
	* testsuite/21_strings/basic_string/cons/wchar_t/9.cc: New test.

Tested powerpc64le-linux, comitted to trunk.
diff mbox

Patch

commit d8d7a6fba221a205f28212a8bb6288aa724d5c63
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Nov 15 12:52:42 2016 +0000

    Add std::string constructor for substring of string_view (LWG 2742)
    
    	* doc/xml/manual/intro.xml: Document LWG 2742 status.
    	* doc/html/*: Regenerate.
    	* include/bits/basic_string.h
    	(basic_string(const T&, size_type, size_type, const Allocator&)): Add
    	constructor for substring of basic_string_view, as per LWG 2742 but
    	with additional constraint to fix ambiguity.
    	* testsuite/21_strings/basic_string/cons/char/9.cc: New test.
    	* testsuite/21_strings/basic_string/cons/wchar_t/9.cc: New test.

diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml
index 0df24bb..7f2586d 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -1107,6 +1107,14 @@  requirements of the license of GCC.
     <listitem><para>Define the <code>value_compare</code> typedef.
     </para></listitem></varlistentry>
 
+    <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2742">2742</link>:
+       <emphasis>Inconsistent <code>string</code> interface taking <code>string_view</code>
+       </emphasis>
+    </term>
+    <listitem><para>Add the new constructor and additionally constrain it
+      to avoid ambiguities with non-const <code>charT*</code>.
+    </para></listitem></varlistentry>
+
     <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2748">2748</link>:
        <emphasis>swappable traits for optionals
        </emphasis>
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index b80e270..943e88d 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -586,12 +586,27 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
 
 #if __cplusplus > 201402L
       /**
+       *  @brief  Construct string from a substring of a string_view.
+       *  @param  __t   Source string view.
+       *  @param  __pos The index of the first character to copy from __t.
+       *  @param  __n   The number of characters to copy from __t.
+       *  @param  __a   Allocator to use.
+       */
+      template<typename _Tp, typename =
+	       _Require<is_convertible<_Tp, __sv_type>,
+			__not_<is_convertible<const _Tp&, const _CharT*>>>>
+	basic_string(const _Tp& __t, size_type __pos, size_type __n,
+		     const _Alloc& __a = _Alloc())
+	: basic_string(__sv_type(__t).substr(__pos, __n), __a) { }
+
+      /**
        *  @brief  Construct string from a string_view.
        *  @param  __sv  Source string view.
        *  @param  __a  Allocator to use (default is default allocator).
        */
-      explicit basic_string(__sv_type __sv, const _Alloc& __a = _Alloc())
-	: basic_string(__sv.data(), __sv.size(), __a) {}
+      explicit
+      basic_string(__sv_type __sv, const _Alloc& __a = _Alloc())
+      : basic_string(__sv.data(), __sv.size(), __a) { }
 #endif // C++17
 
       /**
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/9.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/9.cc
new file mode 100644
index 0000000..0024ffc
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/9.cc
@@ -0,0 +1,46 @@ 
+// 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  using C = char;
+  using string_type = std::basic_string<C>;
+  using view_type = std::basic_string_view<C>;
+
+  std::allocator<C> alloc;
+  VERIFY( string_type(view_type("string")) == "string" );
+  VERIFY( string_type(view_type("string"), alloc) == "string" );
+
+  // LWG 2742
+  VERIFY( string_type("substring", 3, 6) == "string" );
+  VERIFY( string_type("substring", 3, 6, alloc) == "string" );
+  VERIFY( string_type(view_type("substring"), 3, 6) == "string" );
+  VERIFY( string_type(view_type("substring"), 3, 6, alloc) == "string" );
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/9.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/9.cc
new file mode 100644
index 0000000..bf4b440
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/9.cc
@@ -0,0 +1,46 @@ 
+// 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++1z } }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  using C = wchar_t;
+  using string_type = std::basic_string<C>;
+  using view_type = std::basic_string_view<C>;
+
+  std::allocator<C> alloc;
+  VERIFY( string_type(view_type(L"string")) == L"string" );
+  VERIFY( string_type(view_type(L"string"), alloc) == L"string" );
+
+  // LWG 2742
+  VERIFY( string_type(L"substring", 3, 6) == L"string" );
+  VERIFY( string_type(L"substring", 3, 6, alloc) == L"string" );
+  VERIFY( string_type(view_type(L"substring"), 3, 6) == L"string" );
+  VERIFY( string_type(view_type(L"substring"), 3, 6, alloc) == L"string" );
+}
+
+int
+main()
+{
+  test01();
+}