Skip to content

Commit 74f494a

Browse files
[libcxx] Implement C++20 std::chrono::is_clock, std::chrono::is_clock_v
1 parent f95aaca commit 74f494a

File tree

7 files changed

+188
-2
lines changed

7 files changed

+188
-2
lines changed

libcxx/docs/ReleaseNotes/22.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Implemented Papers
4141
- P2321R2: ``zip`` (`Github <https://llvm.org/PR105169>`__) (The paper is partially implemented. ``zip_transform_view``
4242
is implemented in this release)
4343
- P3168R2: Give ``std::optional`` Range Support (`Github <https://llvm.org/PR105430>`__)
44+
- P0355R7: ``std::chrono::is_clock`` and ``std::chrono::is_clock_v`` (`Github <https://llvm.org/PR160607>` __)
45+
(The paper is partially implemented. ``is_clock`` and ``is_clock_v`` is implemented in this release)
4446

4547
Improvements and New Features
4648
-----------------------------

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ set(files
262262
__chrono/gps_clock.h
263263
__chrono/hh_mm_ss.h
264264
__chrono/high_resolution_clock.h
265+
__chrono/is_clock.h
265266
__chrono/leap_second.h
266267
__chrono/literals.h
267268
__chrono/local_info.h

libcxx/include/__chrono/is_clock.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___CHRONO_IS_CLOCK_H
11+
#define _LIBCPP___CHRONO_IS_CLOCK_H
12+
13+
#include <__config>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
#if _LIBCPP_STD_VER >= 20
20+
21+
# include <__type_traits/integral_constant.h>
22+
23+
_LIBCPP_BEGIN_NAMESPACE_STD
24+
25+
namespace chrono {
26+
27+
template <class>
28+
struct is_clock : std::false_type {};
29+
30+
template <class _Tp>
31+
requires requires {
32+
typename _Tp::rep;
33+
typename _Tp::period;
34+
typename _Tp::duration;
35+
typename _Tp::time_point;
36+
_Tp::is_steady;
37+
_Tp::now();
38+
}
39+
struct is_clock<_Tp> : std::true_type {};
40+
41+
template <class _Tp>
42+
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_clock_v = is_clock<_Tp>::value;
43+
44+
} // namespace chrono
45+
46+
_LIBCPP_END_NAMESPACE_STD
47+
48+
#endif // _LIBCPP_STD_VER
49+
#endif // _LIBCPP___CHRONO_IS_CLOCK_H

libcxx/include/chrono

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,7 @@ constexpr chrono::year operator ""y(unsigned lo
10571057
# include <__chrono/day.h>
10581058
# include <__chrono/exception.h>
10591059
# include <__chrono/hh_mm_ss.h>
1060+
# include <__chrono/is_clock.h>
10601061
# include <__chrono/literals.h>
10611062
# include <__chrono/local_info.h>
10621063
# include <__chrono/month.h>

libcxx/include/module.modulemap.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,10 @@ module std [system] {
970970
header "__chrono/high_resolution_clock.h"
971971
export *
972972
}
973+
module is_clock {
974+
header "__chrono/is_clock.h"
975+
export std_core.type_traits.integral_constant
976+
}
973977
module leap_second {
974978
header "__chrono/leap_second.h"
975979
}

libcxx/modules/std/chrono.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export namespace std {
2525

2626
using std::chrono::duration_values;
2727

28-
// using std::chrono::is_clock;
29-
// using std::chrono::is_clock_v;
28+
using std::chrono::is_clock;
29+
using std::chrono::is_clock_v;
3030

3131
// [time.duration.nonmember], duration arithmetic
3232
using std::chrono::operator+;
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// REQUIRES: std-at-least-c++20
10+
11+
#include <chrono>
12+
#include <ratio>
13+
14+
struct EmptyStruct {};
15+
16+
// Test structs missing required members
17+
struct MissingRep {
18+
using period = std::ratio<1>;
19+
using duration = std::chrono::seconds;
20+
using time_point = std::chrono::time_point<MissingRep>;
21+
static constexpr bool is_steady = false;
22+
static time_point now();
23+
};
24+
25+
struct MissingPeriod {
26+
using rep = long;
27+
using duration = std::chrono::seconds;
28+
using time_point = std::chrono::time_point<MissingPeriod>;
29+
static constexpr bool is_steady = false;
30+
static time_point now();
31+
};
32+
33+
struct MissingDuration {
34+
using rep = long;
35+
using time_point = long;
36+
static constexpr bool is_steady = false;
37+
static time_point now();
38+
};
39+
40+
struct MissingTimePoint {
41+
using rep = long;
42+
using period = std::ratio<1>;
43+
using duration = std::chrono::seconds;
44+
static constexpr bool is_steady = false;
45+
static std::chrono::time_point<MissingTimePoint> now();
46+
};
47+
48+
struct MissingIsSteady {
49+
using rep = long;
50+
using period = std::ratio<1>;
51+
using duration = std::chrono::seconds;
52+
using time_point = std::chrono::time_point<MissingIsSteady>;
53+
static time_point now();
54+
};
55+
56+
struct MissingNow {
57+
using rep = long;
58+
using period = std::ratio<1>;
59+
using duration = std::chrono::seconds;
60+
using time_point = std::chrono::time_point<MissingNow>;
61+
static constexpr bool is_steady = false;
62+
};
63+
64+
// Valid clock types
65+
struct ValidSteadyClock {
66+
using rep = long long;
67+
using period = std::nano;
68+
using duration = std::chrono::nanoseconds;
69+
using time_point = std::chrono::time_point<ValidSteadyClock>;
70+
static constexpr bool is_steady = true;
71+
static time_point now();
72+
};
73+
74+
struct ValidSystemClock {
75+
using rep = int64_t;
76+
using period = std::micro;
77+
using duration = std::chrono::microseconds;
78+
using time_point = std::chrono::time_point<ValidSystemClock>;
79+
static constexpr bool is_steady = false;
80+
static time_point now();
81+
};
82+
83+
int main(int, char**) {
84+
// Test both is_clock and is_clock_v
85+
static_assert(std::chrono::is_clock<std::chrono::system_clock>::value);
86+
static_assert(std::chrono::is_clock_v<std::chrono::system_clock>);
87+
88+
// Test standard clock types
89+
static_assert(std::chrono::is_clock_v<std::chrono::system_clock>);
90+
static_assert(std::chrono::is_clock_v<std::chrono::steady_clock>);
91+
static_assert(std::chrono::is_clock_v<std::chrono::high_resolution_clock>);
92+
93+
// Test non-clock types
94+
static_assert(!std::chrono::is_clock_v<EmptyStruct>);
95+
static_assert(!std::chrono::is_clock_v<int>);
96+
static_assert(!std::chrono::is_clock_v<void>);
97+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock::time_point>);
98+
static_assert(!std::chrono::is_clock_v<std::chrono::steady_clock::time_point>);
99+
static_assert(!std::chrono::is_clock_v<std::chrono::seconds>);
100+
static_assert(!std::chrono::is_clock_v<std::chrono::milliseconds>);
101+
102+
// Test structs missing required members
103+
static_assert(!std::chrono::is_clock_v<MissingRep>);
104+
static_assert(!std::chrono::is_clock_v<MissingPeriod>);
105+
static_assert(!std::chrono::is_clock_v<MissingDuration>);
106+
static_assert(!std::chrono::is_clock_v<MissingTimePoint>);
107+
static_assert(!std::chrono::is_clock_v<MissingIsSteady>);
108+
static_assert(!std::chrono::is_clock_v<MissingNow>);
109+
110+
// Test valid custom clocks
111+
static_assert(std::chrono::is_clock_v<ValidSteadyClock>);
112+
static_assert(std::chrono::is_clock_v<ValidSystemClock>);
113+
114+
// cv-qualified and reference types
115+
static_assert(std::chrono::is_clock_v<const std::chrono::system_clock>);
116+
static_assert(std::chrono::is_clock_v<volatile std::chrono::system_clock>);
117+
static_assert(std::chrono::is_clock_v<const volatile std::chrono::system_clock>);
118+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock&>);
119+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock&&>);
120+
static_assert(!std::chrono::is_clock_v<const std::chrono::system_clock&>);
121+
122+
// array and pointer types
123+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock[]>);
124+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock[10]>);
125+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock*>);
126+
static_assert(!std::chrono::is_clock_v<std::chrono::system_clock* const>);
127+
128+
return 0;
129+
}

0 commit comments

Comments
 (0)