[libcxx-commits] [libcxx] dce5fc5 - [libc++] Implement file_clock::{to, from}_sys

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 11 11:17:23 PST 2021


Author: Louis Dionne
Date: 2021-11-11T14:17:02-05:00
New Revision: dce5fc56b6191ec63fd1d2bed7d3c815bacc49b7

URL: https://github.com/llvm/llvm-project/commit/dce5fc56b6191ec63fd1d2bed7d3c815bacc49b7
DIFF: https://github.com/llvm/llvm-project/commit/dce5fc56b6191ec63fd1d2bed7d3c815bacc49b7.diff

LOG: [libc++] Implement file_clock::{to,from}_sys

This is part of https://wg21.link/P0355R7. I am adding these methods
to provide an alternative for the {from,to}_time_t methods that were
removed in https://llvm.org/D113027.

Differential Revision: https://reviews.llvm.org/D113430

Added: 
    libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/include/chrono

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 9ccb211c5abbb..62e5a0ca89f58 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -80,7 +80,9 @@ API Changes
 
 - Removed the nonstandard methods ``std::chrono::file_clock::to_time_t`` and
   ``std::chrono::file_clock::from_time_t``; neither libstdc++ nor MSVC STL
-  had such methods.
+  had such methods. Instead, in C++20, you can use ``std::chrono::file_clock::from_sys``
+  and ``std::chrono::file_clock::to_sys``, which are specified in the Standard.
+  If you are not using C++20, you should move to it.
 
 - The declarations of functions ``declare_reachable``, ``undeclare_reachable``, ``declare_no_pointers``,
   ``undeclare_no_pointers``, and ``get_pointer_safety`` have been removed not only from C++2b but

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index ec510a99b5831..f703d6cf0dc3f 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -276,7 +276,23 @@ template <class Duration>
 using sys_seconds = sys_time<seconds>;                  // C++20
 using sys_days    = sys_time<days>;                     // C++20
 
-class file_clock;                                       // C++20
+class file_clock                                        // C++20
+{
+public:
+    typedef see-below                      rep;
+    typedef nano                           period;
+    typedef chrono::duration<rep, period>  duration;
+    typedef chrono::time_point<file_clock> time_point;
+    static constexpr bool is_steady =      false;
+
+    static time_point now() noexcept;
+
+    template<class Duration>
+    static sys_time<see-below> to_sys(const file_time<Duration>&);
+
+    template<class Duration>
+    static file_time<see-below> from_sys(const sys_time<Duration>&);
+};
 
 template<class Duration>
   using file_time = time_point<file_clock, Duration>;   // C++20
@@ -2798,6 +2814,20 @@ struct _FilesystemClock {
   static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
 
   _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept;
+
+#if _LIBCPP_STD_VER > 17
+  template <class _Duration>
+  _LIBCPP_HIDE_FROM_ABI
+  static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) {
+    return chrono::sys_time<_Duration>(__t.time_since_epoch());
+  }
+
+  template <class _Duration>
+  _LIBCPP_HIDE_FROM_ABI
+  static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) {
+    return chrono::file_time<_Duration>(__t.time_since_epoch());
+  }
+#endif // _LIBCPP_STD_VER > 17
 };
 _LIBCPP_END_NAMESPACE_FILESYSTEM
 #endif // !_LIBCPP_CXX03_LANG

diff  --git a/libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp b/libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp
new file mode 100644
index 0000000000000..d8fecd93d731c
--- /dev/null
+++ b/libcxx/test/std/utilities/time/time.clock/time.clock.file/to_from_sys.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-has-no-filesystem-library
+
+// Filesystem is supported on Apple platforms starting with macosx10.15.
+// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14}}
+
+// TODO(ldionne): This test fails on Ubuntu Focal on our CI nodes (and only there), in 32 bit mode.
+// UNSUPPORTED: linux && 32bits-on-64bits
+
+// <chrono>
+//
+// file_clock
+//
+// template<class Duration>
+// static sys_time<see-below> to_sys(const file_time<Duration>&);
+//
+// template<class Duration>
+// static file_time<see-below> from_sys(const sys_time<Duration>&);
+
+#include <chrono>
+#include <cassert>
+
+int main(int, char**) {
+  // Test round-trip through the system clock, starting from file_clock::now()
+  {
+    std::chrono::file_clock::time_point const ft = std::chrono::file_clock::now();
+    auto st = std::chrono::file_clock::to_sys(ft);
+    assert(ft == std::chrono::file_clock::from_sys(st));
+  }
+
+  // Test round-trip through the system clock, starting from system_clock::now()
+  {
+    std::chrono::system_clock::time_point const st = std::chrono::system_clock::now();
+    auto ft = std::chrono::file_clock::from_sys(st);
+    assert(st == std::chrono::file_clock::to_sys(ft));
+  }
+
+  // Make sure the value we get is in the ballpark of something reasonable
+  {
+    std::chrono::file_clock::time_point const file_now = std::chrono::file_clock::now();
+    std::chrono::system_clock::time_point const sys_now = std::chrono::system_clock::now();
+    {
+      auto 
diff  = sys_now - std::chrono::file_clock::to_sys(file_now);
+      assert(std::chrono::milliseconds(-500) < 
diff  && 
diff  < std::chrono::milliseconds(500));
+    }
+    {
+      auto 
diff  = std::chrono::file_clock::from_sys(sys_now) - file_now;
+      assert(std::chrono::milliseconds(-500) < 
diff  && 
diff  < std::chrono::milliseconds(500));
+    }
+  }
+
+  // Make sure to_sys and from_sys are consistent with each other
+  {
+    std::chrono::file_clock::time_point const ft = std::chrono::file_clock::now();
+    std::chrono::system_clock::time_point const st = std::chrono::system_clock::now();
+    auto sys_
diff  = std::chrono::file_clock::to_sys(ft) - st;
+    auto file_
diff  = ft - std::chrono::file_clock::from_sys(st);
+    assert(sys_
diff  == file_
diff );
+  }
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list