diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 56c1199f381..7e8df9db11d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2018-11-19 Jonathan Wakely + + PR libstdc++/88084 - Implement LWG 2777 + * include/std/string_view (basic_string_view::copy): Use traits to + copy. + * testsuite/21_strings/basic_string_view/operations/copy/char/2.cc: + New test. + * testsuite/21_strings/basic_string_view/operations/copy/wchar_t/2.cc: + New test. + 2018-11-18 Michele Pezzutti Edward Smith-Rowland <3dw4rd@verizon.net> diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 9e0f6a723e4..dc2478d8d0e 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -236,9 +236,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_requires_string_len(__str, __n); __pos = _M_check(__pos, "basic_string_view::copy"); const size_type __rlen = std::min(__n, _M_len - __pos); - for (auto __begin = this->_M_str + __pos, - __end = __begin + __rlen; __begin != __end;) - *__str++ = *__begin++; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2777. basic_string_view::copy should use char_traits::copy + traits_type::copy(__str, data() + __pos, __rlen); return __rlen; } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/2.cc new file mode 100644 index 00000000000..b03edf77a4f --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/char/2.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2018 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" } +// { dg-do run { target c++17 } } + +#include +#include + +using char_type = char; + +// PR libstdc++/88084 +// LWG 2777. basic_string_view::copy should use char_traits::copy + +struct traits : std::char_traits +{ + static char_type* + copy(char_type* s, const char_type* p, std::size_t n) + { + while (n--) + *s++ = 'X'; + return s; + } +}; + +void +test01() +{ + std::basic_string_view s = "abc"; + char_type buf[3] = { '1', '2', '3' }; + auto len = s.copy(buf, 3, 1); + VERIFY( len == 2 ); + VERIFY( buf[0] == 'X' ); + VERIFY( buf[1] == 'X' ); + VERIFY( buf[2] == '3' ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/2.cc new file mode 100644 index 00000000000..bf192aa8870 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/operations/copy/wchar_t/2.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2018 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" } +// { dg-do run { target c++17 } } + +#include +#include + +using char_type = wchar_t; + +// PR libstdc++/88084 +// LWG 2777. basic_string_view::copy should use char_traits::copy + +struct traits : std::char_traits +{ + static char_type* + copy(char_type* s, const char_type* p, std::size_t n) + { + while (n--) + *s++ = 'X'; + return s; + } +}; + +void +test01() +{ + std::basic_string_view s = L"abc"; + char_type buf[3] = { L'1', L'2', L'3' }; + auto len = s.copy(buf, 3, 1); + VERIFY( len == 2 ); + VERIFY( buf[0] == L'X' ); + VERIFY( buf[1] == L'X' ); + VERIFY( buf[2] == L'3' ); +} + +int +main() +{ + test01(); +}