Implement LWG 3145: file_clock breaks ABI for C++17 implementations.

This patch adds std::chrono::file_clock, but without breaking the
existing ABI for std::filesystem.

llvm-svn: 349883
This commit is contained in:
Eric Fiselier 2018-12-21 03:54:57 +00:00
parent 3eae3c4590
commit 866885e12a
7 changed files with 171 additions and 32 deletions

View File

@ -808,6 +808,9 @@ constexpr chrono::year operator ""y(unsigned lo
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
struct _FilesystemClock;
_LIBCPP_END_NAMESPACE_FILESYSTEM
_LIBCPP_BEGIN_NAMESPACE_STD
@ -1581,10 +1584,14 @@ typedef system_clock high_resolution_clock;
#endif
#if _LIBCPP_STD_VER > 17
// [time.clock.file], type file_clock
using file_clock = _VSTD_FS::_FilesystemClock;
template<class _Duration>
using file_time = time_point<file_clock, _Duration>;
struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; };
class _LIBCPP_TYPE_VIS day {
private:
unsigned char __d;
@ -2689,6 +2696,40 @@ namespace chrono { // hoist the literals into namespace std::chrono
_LIBCPP_END_NAMESPACE_STD
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
struct _FilesystemClock {
#if !defined(_LIBCPP_HAS_NO_INT128)
typedef __int128_t rep;
typedef nano period;
#else
typedef long long rep;
typedef nano period;
#endif
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<_FilesystemClock> time_point;
static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
_LIBCPP_FUNC_VIS static time_point now() noexcept;
_LIBCPP_INLINE_VISIBILITY
static time_t to_time_t(const time_point& __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_t(
chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
}
_LIBCPP_INLINE_VISIBILITY
static time_point from_time_t(time_t __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_point(__secs(__t));
}
};
_LIBCPP_END_NAMESPACE_FILESYSTEM
#endif // !_LIBCPP_CXX03_LANG
_LIBCPP_POP_MACROS
#endif // _LIBCPP_CHRONO

View File

@ -259,36 +259,6 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
struct _FilesystemClock {
#if !defined(_LIBCPP_HAS_NO_INT128)
typedef __int128_t rep;
typedef nano period;
#else
typedef long long rep;
typedef nano period;
#endif
typedef chrono::duration<rep, period> duration;
typedef chrono::time_point<_FilesystemClock> time_point;
static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false;
_LIBCPP_FUNC_VIS static time_point now() noexcept;
_LIBCPP_INLINE_VISIBILITY
static time_t to_time_t(const time_point& __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_t(
chrono::duration_cast<__secs>(__t.time_since_epoch()).count());
}
_LIBCPP_INLINE_VISIBILITY
static time_point from_time_t(time_t __t) noexcept {
typedef chrono::duration<rep> __secs;
return time_point(__secs(__t));
}
};
typedef chrono::time_point<_FilesystemClock> file_time_type;
struct _LIBCPP_TYPE_VIS space_info {

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
//
// TODO: Remove this when filesystem gets integrated into the dylib
// REQUIRES: c++filesystem
// <chrono>
// file_clock
// check clock invariants
#include <chrono>
template <class T>
void test(const T &) {}
int main()
{
typedef std::chrono::system_clock C;
static_assert((std::is_same<C::rep, C::duration::rep>::value), "");
static_assert((std::is_same<C::period, C::duration::period>::value), "");
static_assert((std::is_same<C::duration, C::time_point::duration>::value), "");
static_assert((std::is_same<C::time_point::clock, C>::value), "");
static_assert((C::is_steady || !C::is_steady), "");
test(std::chrono::system_clock::is_steady);
}

View File

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// <chrono>
// file_time
#include <chrono>
#include "test_macros.h"
template <class Dur>
void test() {
ASSERT_SAME_TYPE(std::chrono::file_time<Dur>, std::chrono::time_point<std::chrono::file_clock, Dur>);
}
int main() {
test<std::chrono::nanoseconds>();
test<std::chrono::minutes>();
test<std::chrono::hours>();
}

View File

@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// TODO: Remove this when filesystem gets integrated into the dylib
// REQUIRES: c++filesystem
// <chrono>
// file_clock
// static time_point now() noexcept;
#include <chrono>
#include <cassert>
#include "test_macros.h"
int main()
{
typedef std::chrono::file_clock C;
ASSERT_NOEXCEPT(C::now());
C::time_point t1 = C::now();
assert(t1.time_since_epoch().count() != 0);
assert(C::time_point::min() < t1);
assert(C::time_point::max() > t1);
}

View File

@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
// TODO: Remove this when filesystem gets integrated into the dylib
// REQUIRES: c++filesystem
// <chrono>
// file_clock
// rep should be signed
#include <chrono>
#include <cassert>
int main()
{
static_assert(std::is_signed<std::chrono::file_clock::rep>::value, "");
assert(std::chrono::file_clock::duration::min() <
std::chrono::file_clock::duration::zero());
}

View File

@ -282,7 +282,7 @@
<tr><td><a href="https://wg21.link/LWG3132">3132</a></td><td>Library needs to ban macros named <tt>expects</tt> or <tt>ensures</tt></td><td>San Diego</td><td><i>Nothing to do</i></td></tr>
<tr><td><a href="https://wg21.link/LWG3134">3134</a></td><td>[fund.ts.v3] LFTSv3 contains extraneous [meta] variable templates that should have been deleted by P09961</td><td>San Diego</td><td>Resolved by P1210R0</td></tr>
<tr><td><a href="https://wg21.link/LWG3137">3137</a></td><td>Header for <tt>__cpp_lib_to_chars</tt></td><td>San Diego</td><td><i>We've already made the update; but we don't support all the test macros. When we do, this will be closed</i></td></tr>
<tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG3145">3145</a></td><td><tt>file_clock</tt> breaks ABI for C++17 implementations</td><td>San Diego</td><td>Complete</td></tr>
<tr><td><a href="https://wg21.link/LWG3147">3147</a></td><td>Definitions of "likely" and "unlikely" are likely to cause problems</td><td>San Diego</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG3148">3148</a></td><td><tt>&lt;concepts&gt;</tt> should be freestanding</td><td>San Diego</td><td></td></tr>
<tr><td><a href="https://wg21.link/LWG3153">3153</a></td><td><tt>Common</tt> and <tt>common_type</tt> have too little in common</td><td>San Diego</td><td></td></tr>