public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ibm/heads/gcc-9-branch)] libstdc++: Fix experimental::path::generic_string (PR 93245)
@ 2020-09-04 19:27 Peter Bergner
  0 siblings, 0 replies; only message in thread
From: Peter Bergner @ 2020-09-04 19:27 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:88f2b72e77fea11803b761f4fb569d83266e1d9e

commit 88f2b72e77fea11803b761f4fb569d83266e1d9e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Mar 21 22:11:44 2020 +0000

    libstdc++: Fix experimental::path::generic_string (PR 93245)
    
    This function was unimplemented, simply returning the native format
    string instead.
    
            PR libstdc++/93245
            * include/experimental/bits/fs_path.h (path::generic_string<C,T,A>()):
            Return the generic format path, not the native one.
            * testsuite/experimental/filesystem/path/generic/generic_string.cc:
            Improve test coverage.
    
    (cherry picked from commit a577c0c26931090e7c25e56ef5ffc807627961ec)

Diff:
---
 libstdc++-v3/include/experimental/bits/fs_path.h   | 40 ++++++++++++++-----
 .../filesystem/path/generic/generic_string.cc      | 46 +++++++++++++++++-----
 2 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h
index 64089b432eb..64329e36b54 100644
--- a/libstdc++-v3/include/experimental/bits/fs_path.h
+++ b/libstdc++-v3/include/experimental/bits/fs_path.h
@@ -996,34 +996,56 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
   inline std::u32string
   path::u32string() const { return string<char32_t>(); }
 
-#ifndef _GLIBCXX_FILESYSTEM_IS_WINDOWS
   template<typename _CharT, typename _Traits, typename _Allocator>
     inline std::basic_string<_CharT, _Traits, _Allocator>
     path::generic_string(const _Allocator& __a) const
-    { return string<_CharT, _Traits, _Allocator>(__a); }
+    {
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+      const _CharT __slash = is_same<_CharT, wchar_t>::value
+	? _CharT(L'/')
+	: _CharT('/'); // Assume value is correct for the encoding.
+#else
+      const _CharT __slash = _CharT('/');
+#endif
+      basic_string<_CharT, _Traits, _Allocator> __str(__a);
+      __str.reserve(_M_pathname.size());
+      bool __add_slash = false;
+      for (auto& __elem : *this)
+	{
+	  if (__elem._M_type == _Type::_Root_dir)
+	    {
+	      __str += __slash;
+	      continue;
+	    }
+	  if (__add_slash)
+	    __str += __slash;
+	  __str += __elem.string<_CharT, _Traits, _Allocator>(__a);
+	  __add_slash = __elem._M_type == _Type::_Filename;
+	}
+      return __str;
+    }
 
   inline std::string
-  path::generic_string() const { return string(); }
+  path::generic_string() const { return generic_string<char>(); }
 
 #if _GLIBCXX_USE_WCHAR_T
   inline std::wstring
-  path::generic_wstring() const { return wstring(); }
+  path::generic_wstring() const { return generic_string<wchar_t>(); }
 #endif
 
 #ifdef _GLIBCXX_USE_CHAR8_T
   inline std::u8string
-  path::generic_u8string() const { return u8string(); }
+  path::generic_u8string() const { return generic_string<char8_t>(); }
 #else
   inline std::string
-  path::generic_u8string() const { return u8string(); }
+  path::generic_u8string() const { return generic_string<char>(); }
 #endif
 
   inline std::u16string
-  path::generic_u16string() const { return u16string(); }
+  path::generic_u16string() const { return generic_string<char16_t>(); }
 
   inline std::u32string
-  path::generic_u32string() const { return u32string(); }
-#endif
+  path::generic_u32string() const { return generic_string<char32_t>(); }
 
   inline int
   path::compare(const string_type& __s) const { return compare(path(__s)); }
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/generic/generic_string.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/generic/generic_string.cc
index 2788ebd3082..efaa452a586 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/generic/generic_string.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/generic/generic_string.cc
@@ -23,27 +23,55 @@
 
 #include <experimental/filesystem>
 #include <testsuite_fs.h>
-#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
 
 using std::experimental::filesystem::path;
 
 void
 test01()
 {
-  for (const path& p : __gnu_test::test_paths)
+  __gnu_test::compare_paths( path("///a//b///").generic_string(), "/a/b/." );
+  __gnu_test::compare_paths( path("///a//b").generic_u16string(), "/a/b" );
+  __gnu_test::compare_paths( path("//a//b").generic_u16string(), "//a/b" );
+}
+
+using __gnu_test::SimpleAllocator;
+
+void
+test02()
+{
+  path p = "//foo//bar//.";
+  using C = char16_t;
+  auto g = p.generic_string<C, std::char_traits<C>, SimpleAllocator<C>>();
+  VERIFY( g == u"//foo/bar/." );
+}
+
+
+void
+test03()
+{
+  for (path p : { "/a///b//c", "///a//b//c", "a:b//c", "a://b///c" })
   {
-    path p2(p), p3;
-    p2.swap(p3);
-    VERIFY( p2 == path() );
-    VERIFY( p3 == p );
-    p2.swap(p3);
-    VERIFY( p2 == p );
-    VERIFY( p3 == path() );
+    // A path constructed from the generic format string should compare equal
+    // to the original, because they represent the same path.
+    VERIFY( path(p.generic_string()) == p );
+    VERIFY( path(p.generic_wstring()) == p );
+    VERIFY( path(p.generic_u8string()) == p );
+    VERIFY( path(p.generic_u16string()) == p );
+    VERIFY( path(p.generic_u32string()) == p );
   }
+
+  // Except when the original consists entirely of a root-directory with
+  // multiple slashes, because path("///").native() is "///" but the
+  // generic format string is "/". In the Filesystem TS path::compare just
+  // compares native strings, so path("///") != path("/").
+  VERIFY( path("///").generic_string() == "/" );
 }
 
 int
 main()
 {
   test01();
+  test02();
+  test03();
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-04 19:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-04 19:27 [gcc(refs/vendors/ibm/heads/gcc-9-branch)] libstdc++: Fix experimental::path::generic_string (PR 93245) Peter Bergner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).