From: Jonathan Wakely Date: Fri, 28 Oct 2016 18:48:43 +0000 (+0100) Subject: Make filesystem::path work with basic_string_view (P0392R0) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0414b973f9b399bd726605943fbca39dea8ef77;p=gcc.git Make filesystem::path work with basic_string_view (P0392R0) * include/experimental/bits/fs_path.h (__is_path_src) (_S_range_begin, _S_range_end): Overload to treat string_view as a Source object. (path::operator+=, path::compare): Overload for basic_string_view. * testsuite/experimental/filesystem/path/construct/string_view.cc: New test. * testsuite/experimental/filesystem/path/construct/ string_view_cxx17.cc: New test. From-SVN: r241658 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 37f745547fb..71ef4cfa269 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,14 @@ 2016-10-28 Jonathan Wakely + * include/experimental/bits/fs_path.h (__is_path_src) + (_S_range_begin, _S_range_end): Overload to treat string_view as a + Source object. + (path::operator+=, path::compare): Overload for basic_string_view. + * testsuite/experimental/filesystem/path/construct/string_view.cc: + New test. + * testsuite/experimental/filesystem/path/construct/ + string_view_cxx17.cc: New test. + * include/experimental/bits/fs_path.h (path::_S_convert<_Iter>(_Iter, _Iter)): Remove cv-qualifiers from iterator's value_type. diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index f6a290d5f47..70a5445dfa8 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -44,6 +44,9 @@ #include #include #include +#if __cplusplus == 201402L +# include +#endif #if defined(_WIN32) && !defined(__CYGWIN__) # define _GLIBCXX_FILESYSTEM_IS_WINDOWS 1 @@ -61,6 +64,12 @@ inline namespace v1 _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_CXX11 +#if __cplusplus == 201402L + using std::experimental::basic_string_view; +#elif __cplusplus > 201402L + using std::basic_string_view; +#endif + /** * @ingroup filesystem * @{ @@ -87,6 +96,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 static __is_encoded_char<_CharT> __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int); +#if __cplusplus >= 201402L + template + static __is_encoded_char<_CharT> + __is_path_src(const basic_string_view<_CharT, _Traits>&, int); +#endif + template static std::false_type __is_path_src(const _Unknown&, ...); @@ -130,6 +145,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _S_range_end(const basic_string<_CharT, _Traits, _Alloc>& __str) { return __str.data() + __str.size(); } +#if __cplusplus >= 201402L + template + static const _CharT* + _S_range_begin(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data(); } + + template + static const _CharT* + _S_range_end(const basic_string_view<_CharT, _Traits>& __str) + { return __str.data() + __str.size(); } +#endif + template())), typename _Val = typename std::iterator_traits<_Iter>::value_type> @@ -243,6 +270,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 path& operator+=(const string_type& __x); path& operator+=(const value_type* __x); path& operator+=(value_type __x); +#if __cplusplus >= 201402L + path& operator+=(basic_string_view __x); +#endif template _Path<_Source>& @@ -311,6 +341,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 int compare(const path& __p) const noexcept; int compare(const string_type& __s) const; int compare(const value_type* __s) const; +#if __cplusplus >= 201402L + int compare(const basic_string_view __s) const; +#endif // decomposition @@ -768,6 +801,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 return *this; } +#if __cplusplus >= 201402L + inline path& + path::operator+=(basic_string_view __x) + { + _M_pathname.append(__x.data(), __x.size()); + _M_split_cmpts(); + return *this; + } +#endif + template inline path::_Path<_CharT*, _CharT*>& path::operator+=(_CharT __x) @@ -909,6 +952,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 inline int path::compare(const value_type* __s) const { return compare(path(__s)); } +#if __cplusplus >= 201402L + inline int + path::compare(basic_string_view __s) const + { return compare(path(__s)); } +#endif + inline path path::filename() const { return empty() ? path() : *--end(); } diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc new file mode 100644 index 00000000000..13ebaaa905a --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/string_view.cc @@ -0,0 +1,56 @@ +// { dg-options "-lstdc++fs -std=gnu++1z" } +// { dg-do run { target c++1z } } +// { dg-require-filesystem-ts "" } + +// 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 +// . + +// 8.4.1 path constructors [path.construct] + +#include +#include +#include +#include + +using std::experimental::filesystem::path; +using __gnu_test::compare_paths; + +void +test01() +{ + for (std::string s : __gnu_test::test_paths) + { + path p1 = s; + std::string_view sv(s); + path p2 = sv; + compare_paths(p1, p2); + +#if _GLIBCXX_USE_WCHAR_T + std::wstring ws(s.begin(), s.end()); + path p3 = ws; + std::wstring_view wsv(ws); + path p4 = wsv; + compare_paths(p1, p4); +#endif + } +} + +int +main() +{ + test01(); +}