Skip to content

Commit 3f638e3

Browse files
Implement LWG-3090 What is [time.duration.cons]/4's "no overflow is induced in the conversion" intended to mean? (#6050)
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
1 parent 793b6f2 commit 3f638e3

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

stl/inc/__msvc_chrono.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@ namespace chrono {
129129
: _MyRep(static_cast<_Rep>(_Val)) {}
130130

131131
template <class _Rep2, class _Period2,
132-
enable_if_t<treat_as_floating_point_v<_Rep>
133-
|| (_Ratio_divide_sfinae<_Period2, _Period>::den == 1 && !treat_as_floating_point_v<_Rep2>),
132+
enable_if_t<is_convertible_v<const _Rep2&, _Rep>
133+
&& (treat_as_floating_point_v<_Rep>
134+
|| (_Ratio_divide_sfinae<_Period2, _Period>::den == 1
135+
&& !treat_as_floating_point_v<_Rep2>) ),
134136
int> = 0>
135137
constexpr duration(const duration<_Rep2, _Period2>& _Dur)
136138
noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened

tests/std/tests/P0092R1_polishing_chrono/test.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
// Tests the new functions added as part of P0092R1, "Polishing Chrono"
66
//
77

8+
#include <__msvc_int128.hpp> // an integer-class type should emulate an arithmetic type, see also GH-1909
89
#include <cassert>
910
#include <chrono>
1011
#include <cstdint>
1112
#include <ratio>
13+
#include <type_traits>
1214

1315
using namespace std;
1416
using namespace std::chrono;
@@ -188,6 +190,75 @@ STATIC_ASSERT(floor<seconds>(tp1).time_since_epoch().count() == 1);
188190
STATIC_ASSERT(ceil<seconds>(tp1).time_since_epoch().count() == 2);
189191
STATIC_ASSERT(round<seconds>(tp1).time_since_epoch().count() == 2);
190192

193+
// Test LWG-3090 "What is [time.duration.cons]/4's "no overflow is induced in the conversion" intended to mean?"
194+
constexpr bool test_lwg_3090() {
195+
STATIC_ASSERT(is_constructible_v<duration<_Signed128>, seconds>);
196+
STATIC_ASSERT(is_constructible_v<duration<_Signed128>, const seconds&>);
197+
STATIC_ASSERT(is_convertible_v<seconds, duration<_Signed128>>);
198+
STATIC_ASSERT(is_convertible_v<const seconds&, duration<_Signed128>>);
199+
200+
STATIC_ASSERT(!is_constructible_v<seconds, duration<_Signed128>>);
201+
STATIC_ASSERT(!is_constructible_v<seconds, const duration<_Signed128>&>);
202+
STATIC_ASSERT(!is_convertible_v<duration<_Signed128>, seconds>);
203+
STATIC_ASSERT(!is_convertible_v<const duration<_Signed128>&, seconds>);
204+
205+
STATIC_ASSERT(is_constructible_v<duration<_Signed128>, minutes>);
206+
STATIC_ASSERT(is_constructible_v<duration<_Signed128>, const minutes&>);
207+
STATIC_ASSERT(is_convertible_v<minutes, duration<_Signed128>>);
208+
STATIC_ASSERT(is_convertible_v<const minutes&, duration<_Signed128>>);
209+
210+
STATIC_ASSERT(!is_constructible_v<minutes, duration<_Signed128>>);
211+
STATIC_ASSERT(!is_constructible_v<minutes, const duration<_Signed128>&>);
212+
STATIC_ASSERT(!is_convertible_v<duration<_Signed128>, minutes>);
213+
STATIC_ASSERT(!is_convertible_v<const duration<_Signed128>&, minutes>);
214+
215+
STATIC_ASSERT(!is_constructible_v<duration<_Signed128>, milliseconds>);
216+
STATIC_ASSERT(!is_constructible_v<duration<_Signed128>, const milliseconds&>);
217+
STATIC_ASSERT(!is_convertible_v<milliseconds, duration<_Signed128>>);
218+
STATIC_ASSERT(!is_convertible_v<const milliseconds&, duration<_Signed128>>);
219+
220+
STATIC_ASSERT(!is_constructible_v<milliseconds, duration<_Signed128>>);
221+
STATIC_ASSERT(!is_constructible_v<milliseconds, const duration<_Signed128>&>);
222+
STATIC_ASSERT(!is_convertible_v<duration<_Signed128>, milliseconds>);
223+
STATIC_ASSERT(!is_convertible_v<const duration<_Signed128>&, milliseconds>);
224+
225+
STATIC_ASSERT(is_constructible_v<duration<_Unsigned128>, seconds>);
226+
STATIC_ASSERT(is_constructible_v<duration<_Unsigned128>, const seconds&>);
227+
STATIC_ASSERT(is_convertible_v<seconds, duration<_Unsigned128>>);
228+
STATIC_ASSERT(is_convertible_v<const seconds&, duration<_Unsigned128>>);
229+
230+
STATIC_ASSERT(!is_constructible_v<seconds, duration<_Unsigned128>>);
231+
STATIC_ASSERT(!is_constructible_v<seconds, const duration<_Unsigned128>&>);
232+
STATIC_ASSERT(!is_convertible_v<duration<_Unsigned128>, seconds>);
233+
STATIC_ASSERT(!is_convertible_v<const duration<_Unsigned128>&, seconds>);
234+
235+
STATIC_ASSERT(is_constructible_v<duration<_Unsigned128>, minutes>);
236+
STATIC_ASSERT(is_constructible_v<duration<_Unsigned128>, const minutes&>);
237+
STATIC_ASSERT(is_convertible_v<minutes, duration<_Unsigned128>>);
238+
STATIC_ASSERT(is_convertible_v<const minutes&, duration<_Unsigned128>>);
239+
240+
STATIC_ASSERT(!is_constructible_v<minutes, duration<_Unsigned128>>);
241+
STATIC_ASSERT(!is_constructible_v<minutes, const duration<_Unsigned128>&>);
242+
STATIC_ASSERT(!is_convertible_v<duration<_Unsigned128>, minutes>);
243+
STATIC_ASSERT(!is_convertible_v<const duration<_Unsigned128>&, minutes>);
244+
245+
STATIC_ASSERT(!is_constructible_v<duration<_Unsigned128>, milliseconds>);
246+
STATIC_ASSERT(!is_constructible_v<duration<_Unsigned128>, const milliseconds&>);
247+
STATIC_ASSERT(!is_convertible_v<milliseconds, duration<_Unsigned128>>);
248+
STATIC_ASSERT(!is_convertible_v<const milliseconds&, duration<_Unsigned128>>);
249+
250+
STATIC_ASSERT(!is_constructible_v<milliseconds, duration<_Unsigned128>>);
251+
STATIC_ASSERT(!is_constructible_v<milliseconds, const duration<_Unsigned128>&>);
252+
STATIC_ASSERT(!is_convertible_v<duration<_Unsigned128>, milliseconds>);
253+
STATIC_ASSERT(!is_convertible_v<const duration<_Unsigned128>&, milliseconds>);
254+
255+
assert(duration<_Signed128>{seconds{1}}.count() == 1);
256+
assert(duration<_Signed128>{minutes{12}}.count() == 720);
257+
assert(duration<_Unsigned128>{seconds{123}}.count() == 123);
258+
assert(duration<_Unsigned128>{minutes{1234}}.count() == 74040);
259+
260+
return true;
261+
}
191262

192263
int overloaded(milliseconds) {
193264
return 11;
@@ -222,4 +293,7 @@ int main() {
222293
assert(overloaded(40ms) == 11);
223294
assert(overloaded(50s) == 22);
224295
assert(overloaded(duration<int, exa>(60)) == 33);
296+
297+
STATIC_ASSERT(test_lwg_3090());
298+
test_lwg_3090();
225299
}

0 commit comments

Comments
 (0)