diff mbox

Implement std::filesystem for C++17

Message ID 20161028142445.GH2922@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Oct. 28, 2016, 2:24 p.m. UTC
Here's a patch to move std::experimental::filesystem to
std::filesystem, and then add using declarations to pull it all back
into std::experimental::filesystem.

The definitions are still in the separate libstdc++fs.a archive, not
in libstdc++.so, and I plan to keep it that for GCC 7, because there
are some changes likely to happen to the spec that might affect the
API and ABI.

I'll probably commit this in about a week, during the Issaquah
meeting.
diff mbox

Patch

commit a287ae40c1cb242f5b56b0d12eef4464704292d0
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Oct 21 13:57:32 2016 +0100

    std::filesystem

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index a1190bc..a01fa86 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -662,14 +662,13 @@  Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry>Adopt the File System TS for C++17	 </entry>
       <entry>
 	<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0218r1.html">
 	P0218R1
 	</link>
       </entry>
-      <entry align="center"> No </entry>
+      <entry align="center"> 7 </entry>
       <entry><code> __has_include(&lt;filesystem&gt;) </code>,
 	     <code> __cpp_lib_filesystem >= 201603 </code></entry>
     </row>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 15a164e..cfd82bd 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -36,6 +36,7 @@  std_headers = \
 	${std_srcdir}/complex \
 	${std_srcdir}/condition_variable \
 	${std_srcdir}/deque \
+	${std_srcdir}/filesystem \
 	${std_srcdir}/forward_list \
 	${std_srcdir}/fstream \
 	${std_srcdir}/functional \
diff --git a/libstdc++-v3/include/experimental/bits/fs_dir.h b/libstdc++-v3/include/experimental/bits/fs_dir.h
index 70a95eb..b42fec7 100644
--- a/libstdc++-v3/include/experimental/bits/fs_dir.h
+++ b/libstdc++-v3/include/experimental/bits/fs_dir.h
@@ -40,11 +40,9 @@ 
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace experimental
-{
 namespace filesystem
 {
-inline namespace v1
+inline namespace __fs1
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
@@ -353,9 +351,8 @@  _GLIBCXX_END_NAMESPACE_CXX11
 
   // @} group filesystem
 _GLIBCXX_END_NAMESPACE_VERSION
-} // namespace v1
+} // namespace __fs1
 } // namespace filesystem
-} // namespace experimental
 } // namespace std
 
 #endif // C++11
diff --git a/libstdc++-v3/include/experimental/bits/fs_fwd.h b/libstdc++-v3/include/experimental/bits/fs_fwd.h
index fb8521a..ad17465 100644
--- a/libstdc++-v3/include/experimental/bits/fs_fwd.h
+++ b/libstdc++-v3/include/experimental/bits/fs_fwd.h
@@ -40,11 +40,9 @@ 
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace experimental
-{
 namespace filesystem
 {
-inline namespace v1
+inline namespace __fs1
 {
 #if _GLIBCXX_INLINE_VERSION
 inline namespace __7 { }
@@ -283,9 +281,8 @@  _GLIBCXX_END_NAMESPACE_CXX11
 
   // @} group filesystem
 _GLIBCXX_END_NAMESPACE_VERSION
-} // namespace v1
+} // namespace __fs1
 } // namespace filesystem
-} // namespace experimental
 } // namespace std
 
 #endif // C++11
diff --git a/libstdc++-v3/include/experimental/bits/fs_ops.h b/libstdc++-v3/include/experimental/bits/fs_ops.h
index 62a9826..9ff300d 100644
--- a/libstdc++-v3/include/experimental/bits/fs_ops.h
+++ b/libstdc++-v3/include/experimental/bits/fs_ops.h
@@ -38,11 +38,9 @@ 
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace experimental
-{
 namespace filesystem
 {
-inline namespace v1
+inline namespace __fs1
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
@@ -287,9 +285,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // @} group filesystem
 _GLIBCXX_END_NAMESPACE_VERSION
-} // namespace v1
+} // namespace __fs1
 } // namespace filesystem
-} // namespace experimental
 } // namespace std
 
 #endif // C++11
diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h
index 4d7291f..35d39dc 100644
--- a/libstdc++-v3/include/experimental/bits/fs_path.h
+++ b/libstdc++-v3/include/experimental/bits/fs_path.h
@@ -52,11 +52,9 @@ 
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace experimental
-{
 namespace filesystem
 {
-inline namespace v1
+inline namespace __fs1
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_BEGIN_NAMESPACE_CXX11
@@ -337,6 +335,13 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
     bool is_absolute() const;
     bool is_relative() const { return !is_absolute(); }
 
+#if __cplusplus > 201402L
+    // TODO generation
+    path lexically_normal() const;
+    path lexically_relative(const path& __base) const;
+    path lexically_proximate(const path& __base) const;
+#endif
+
     // iterators
     class iterator;
     typedef iterator const_iterator;
@@ -1028,9 +1033,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CXX11
   // @} group filesystem
 _GLIBCXX_END_NAMESPACE_CXX11
 _GLIBCXX_END_NAMESPACE_VERSION
-} // namespace v1
+} // namespace __fs1
 } // namespace filesystem
-} // namespace experimental
 } // namespace std
 
 #endif // C++11
diff --git a/libstdc++-v3/include/experimental/filesystem b/libstdc++-v3/include/experimental/filesystem
index e13c428..c12ed4e 100644
--- a/libstdc++-v3/include/experimental/filesystem
+++ b/libstdc++-v3/include/experimental/filesystem
@@ -48,25 +48,69 @@  namespace experimental
 {
 namespace filesystem
 {
-inline namespace v1
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-  /**
-   * @ingroup filesystem
-   */
-    inline std::string filesystem_error::_M_gen_what()
-    {
-      std::string __what = "filesystem error: ";
-      __what += system_error::what();
-      if (!_M_path1.empty())
-	  __what += " [" + _M_path1.string() + ']';
-      if (!_M_path2.empty())
-	  __what += " [" + _M_path2.string() + ']';
-      return __what;
-    }
-
-_GLIBCXX_END_NAMESPACE_VERSION
+inline namespace v1 {
+  using ::std::filesystem::path;
+  using ::std::filesystem::swap;
+  using ::std::filesystem::hash_value;
+  using ::std::filesystem::operator==;
+  using ::std::filesystem::operator!=;
+  using ::std::filesystem::operator<;
+  using ::std::filesystem::operator<=;
+  using ::std::filesystem::operator>;
+  using ::std::filesystem::operator>=;
+  using ::std::filesystem::operator/;
+  using ::std::filesystem::operator<<;
+  using ::std::filesystem::operator>>;
+  using ::std::filesystem::u8path;
+  using ::std::filesystem::filesystem_error;
+  using ::std::filesystem::directory_entry;
+  using ::std::filesystem::directory_iterator;
+  using ::std::filesystem::begin;
+  using ::std::filesystem::end;
+  using ::std::filesystem::recursive_directory_iterator;
+  using ::std::filesystem::file_status;
+  using ::std::filesystem::space_info;
+  using ::std::filesystem::file_type;
+  using ::std::filesystem::perms;
+  using ::std::filesystem::copy_options;
+  using ::std::filesystem::directory_options;
+  using ::std::filesystem::file_time_type;
+  using ::std::filesystem::absolute;
+  using ::std::filesystem::canonical;
+  using ::std::filesystem::copy;
+  using ::std::filesystem::copy_file;
+  using ::std::filesystem::copy_symlink;
+  using ::std::filesystem::create_directories;
+  using ::std::filesystem::create_directory;
+  using ::std::filesystem::create_hard_link;
+  using ::std::filesystem::create_symlink;
+  using ::std::filesystem::current_path;
+  using ::std::filesystem::exists;
+  using ::std::filesystem::equivalent;
+  using ::std::filesystem::file_size;
+  using ::std::filesystem::hard_link_count;
+  using ::std::filesystem::is_block_file;
+  using ::std::filesystem::is_character_file;
+  using ::std::filesystem::is_directory;
+  using ::std::filesystem::is_empty;
+  using ::std::filesystem::is_fifo;
+  using ::std::filesystem::is_other;
+  using ::std::filesystem::is_regular_file;
+  using ::std::filesystem::is_socket;
+  using ::std::filesystem::is_symlink;
+  using ::std::filesystem::last_write_time;
+  using ::std::filesystem::permissions;
+  using ::std::filesystem::read_symlink;
+  using ::std::filesystem::remove;
+  using ::std::filesystem::remove_all;
+  using ::std::filesystem::rename;
+  using ::std::filesystem::resize_file;
+  using ::std::filesystem::space;
+  using ::std::filesystem::status;
+  using ::std::filesystem::status_known;
+  using ::std::filesystem::symlink_status;
+  using ::std::filesystem::system_complete;
+  using ::std::filesystem::temp_directory_path;
 } // namespace v1
 } // namespace filesystem
 } // namespace experimental
diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc
index bcd7dd0..29ec567 100644
--- a/libstdc++-v3/src/filesystem/dir.cc
+++ b/libstdc++-v3/src/filesystem/dir.cc
@@ -45,7 +45,7 @@ 
 # define opendir _wopendir
 #endif
 
-namespace fs = std::experimental::filesystem;
+namespace fs = std::filesystem;
 
 struct fs::_Dir
 {
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 9abcee0..2746054 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -62,7 +62,7 @@ 
 # define chmod _wchmod
 #endif
 
-namespace fs = std::experimental::filesystem;
+namespace fs = std::filesystem;
 
 fs::path
 fs::absolute(const path& p, const path& base)
diff --git a/libstdc++-v3/src/filesystem/path.cc b/libstdc++-v3/src/filesystem/path.cc
index f6505fd..9fc8579 100644
--- a/libstdc++-v3/src/filesystem/path.cc
+++ b/libstdc++-v3/src/filesystem/path.cc
@@ -28,9 +28,21 @@ 
 
 #include <experimental/filesystem>
 
-using std::experimental::filesystem::path;
+namespace fs = std::filesystem;
+using std::filesystem::path;
 
-std::experimental::filesystem::filesystem_error::~filesystem_error() = default;
+fs::filesystem_error::~filesystem_error() = default;
+
+std::string fs::filesystem_error::_M_gen_what()
+{
+  std::string __what = "filesystem error: ";
+  __what += system_error::what();
+  if (!_M_path1.empty())
+      __what += " [" + _M_path1.string() + ']';
+  if (!_M_path2.empty())
+      __what += " [" + _M_path2.string() + ']';
+  return __what;
+}
 
 constexpr path::value_type path::preferred_separator;
 
@@ -461,7 +473,7 @@  path::_S_convert_loc(const char* __first, const char* __last,
 }
 
 std::size_t
-std::experimental::filesystem::hash_value(const path& p) noexcept
+fs::hash_value(const path& p) noexcept
 {
   // [path.non-member]
   // "If for two paths, p1 == p2 then hash_value(p1) == hash_value(p2)."