From: Jonathan Wakely Date: Thu, 26 Mar 2020 14:00:12 +0000 (+0000) Subject: libstdc++: Add some C++20 additions to X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=16948c54b7576fb4b27c59915eac71a0c6bf94f6;p=gcc.git libstdc++: Add some C++20 additions to * include/std/chrono (chrono::days, chrono::weeks, chrono::years) (chrono::months, chrono::sys_days, chrono::local_t) (chrono::local_time, chrono::local_seconds, chrono::local_days): Define for C++20. (chrono::time_point): Add missing static assert. * testsuite/20_util/time_point/requirements/duration_neg.cc: New test. * testsuite/std/time/clock/file/overview.cc: New test. * testsuite/std/time/clock/file/members.cc: New test. * testsuite/std/time/syn_c++20.cc: New test. --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 039eb55939f..2445acb50da 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2020-03-26 Jonathan Wakely + + * include/std/chrono (chrono::days, chrono::weeks, chrono::years) + (chrono::months, chrono::sys_days, chrono::local_t) + (chrono::local_time, chrono::local_seconds, chrono::local_days): + Define for C++20. + (chrono::time_point): Add missing static assert. + * testsuite/20_util/time_point/requirements/duration_neg.cc: New test. + * testsuite/std/time/clock/file/overview.cc: New test. + * testsuite/std/time/clock/file/members.cc: New test. + * testsuite/std/time/syn_c++20.cc: New test. + 2020-03-25 Mike Crowe * testsuite/30_threads/shared_timed_mutex/try_lock_until/1.cc: New diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index b1fa5b83295..514926c5c05 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -709,22 +709,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif /// nanoseconds - typedef duration<_GLIBCXX_CHRONO_INT64_T, nano> nanoseconds; + using nanoseconds = duration<_GLIBCXX_CHRONO_INT64_T, nano>; /// microseconds - typedef duration<_GLIBCXX_CHRONO_INT64_T, micro> microseconds; + using microseconds = duration<_GLIBCXX_CHRONO_INT64_T, micro>; /// milliseconds - typedef duration<_GLIBCXX_CHRONO_INT64_T, milli> milliseconds; + using milliseconds = duration<_GLIBCXX_CHRONO_INT64_T, milli>; /// seconds - typedef duration<_GLIBCXX_CHRONO_INT64_T> seconds; + using seconds = duration<_GLIBCXX_CHRONO_INT64_T>; /// minutes - typedef duration<_GLIBCXX_CHRONO_INT64_T, ratio< 60>> minutes; + using minutes = duration<_GLIBCXX_CHRONO_INT64_T, ratio< 60>>; /// hours - typedef duration<_GLIBCXX_CHRONO_INT64_T, ratio<3600>> hours; + using hours = duration<_GLIBCXX_CHRONO_INT64_T, ratio<3600>>; + +#if __cplusplus > 201703L + /// days + using days = duration<_GLIBCXX_CHRONO_INT64_T, ratio<86400>>; + + /// weeks + using weeks = duration<_GLIBCXX_CHRONO_INT64_T, ratio<604800>>; + + /// years + using years = duration<_GLIBCXX_CHRONO_INT64_T, ratio<31556952>>; + + /// months + using months = duration<_GLIBCXX_CHRONO_INT64_T, ratio<2629746>>; +#endif // C++20 #undef _GLIBCXX_CHRONO_INT64_T @@ -732,9 +746,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct time_point { - typedef _Clock clock; - typedef _Dur duration; - typedef typename duration::rep rep; + static_assert(__is_duration<_Dur>::value, + "duration must be a specialization of std::chrono::duration"); + + typedef _Clock clock; + typedef _Dur duration; + typedef typename duration::rep rep; typedef typename duration::period period; constexpr time_point() : __d(duration::zero()) @@ -790,7 +807,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION time_point<_Clock, _ToDur>>::type time_point_cast(const time_point<_Clock, _Dur>& __t) { - typedef time_point<_Clock, _ToDur> __time_point; + typedef time_point<_Clock, _ToDur> __time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch())); } @@ -837,7 +854,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; - typedef time_point<_Clock, __ct> __time_point; + typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() + __rhs); } @@ -851,7 +868,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef duration<_Rep1, _Period1> __dur1; typedef typename common_type<__dur1,_Dur2>::type __ct; - typedef time_point<_Clock, __ct> __time_point; + typedef time_point<_Clock, __ct> __time_point; return __time_point(__rhs.time_since_epoch() + __lhs); } @@ -865,7 +882,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { typedef duration<_Rep2, _Period2> __dur2; typedef typename common_type<_Dur1,__dur2>::type __ct; - typedef time_point<_Clock, __ct> __time_point; + typedef time_point<_Clock, __ct> __time_point; return __time_point(__lhs.time_since_epoch() -__rhs); } @@ -946,9 +963,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ struct system_clock { - typedef chrono::nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; + typedef chrono::nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; typedef chrono::time_point time_point; static_assert(system_clock::duration::min() @@ -986,10 +1003,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ struct steady_clock { - typedef chrono::nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point time_point; + typedef chrono::nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; static constexpr bool is_steady = true; @@ -1014,6 +1031,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template using sys_time = time_point; using sys_seconds = sys_time; + using sys_days = sys_time; using file_clock = ::std::filesystem::__file_clock; @@ -1027,6 +1045,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<> inline constexpr bool is_clock_v = true; template<> inline constexpr bool is_clock_v = true; template<> inline constexpr bool is_clock_v = true; + + struct local_t { }; + template + using local_time = time_point; + using local_seconds = local_time; + using local_days = local_time; #endif // C++20 // @} diff --git a/libstdc++-v3/testsuite/20_util/time_point/requirements/duration_neg.cc b/libstdc++-v3/testsuite/20_util/time_point/requirements/duration_neg.cc new file mode 100644 index 00000000000..5e3bc7f1a55 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/time_point/requirements/duration_neg.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile { target c++11 } } + +#include + +namespace chrono = std::chrono; + +// A duration-like type +struct durayshun : chrono::seconds +{ + using duration::duration; + durayshun(chrono::seconds); +}; + +chrono::time_point t; // { dg-error "here" } +// { dg-error "specialization of std::chrono::duration" "" { target *-*-* } 0 } diff --git a/libstdc++-v3/testsuite/std/time/clock/file/members.cc b/libstdc++-v3/testsuite/std/time/clock/file/members.cc new file mode 100644 index 00000000000..44ae717a6ee --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/clock/file/members.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include + +void +test01() +{ + auto sys_now = std::chrono::system_clock::now(); + auto file_now = std::chrono::file_clock::now(); + auto d1 = std::chrono::file_clock::to_sys(file_now) - sys_now; + VERIFY( d1 < std::chrono::seconds(1) ); + auto d2 = file_now - std::chrono::file_clock::from_sys(sys_now); + VERIFY( d2 == d1 ); +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/std/time/clock/file/overview.cc b/libstdc++-v3/testsuite/std/time/clock/file/overview.cc new file mode 100644 index 00000000000..3ca530dc249 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/clock/file/overview.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +using std::chrono::file_clock; + +// Cpp17Clock requirements: + +// New type so that is_clock specialization isn't used. +struct C : file_clock { }; +static_assert( std::chrono::is_clock_v ); + +// Cpp17TrivialClock requirements: + +// A trivial clock's rep must be a numeric type, which is true for +// libstdc++ because we use an integral type. +static_assert( std::is_integral_v ); + +// We meet the recursive Cpp17TrivialClock requirement by using the same clock: +static_assert( std::is_same_v ); + +// chrono::file_clock requirements: + +static_assert( std::is_signed_v ); +static_assert( noexcept(file_clock::now()) ); diff --git a/libstdc++-v3/testsuite/std/time/syn_c++20.cc b/libstdc++-v3/testsuite/std/time/syn_c++20.cc new file mode 100644 index 00000000000..5ea7a0f4280 --- /dev/null +++ b/libstdc++-v3/testsuite/std/time/syn_c++20.cc @@ -0,0 +1,199 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include + +#ifndef __cpp_lib_chrono +# error "Feature test macro for chrono is missing in " +// FIXME +// #elif __cpp_lib_chrono < 201907L +// # error "Feature test macro for chrono has wrong value in " +#endif + +namespace __gnu_test +{ + // Check for the new additions to in C++20 + + using std::chrono::is_clock; + using std::chrono::is_clock_v; + + using std::chrono::days; + using std::chrono::weeks; + using std::chrono::years; + using std::chrono::months; + + using std::chrono::sys_time; + using std::chrono::sys_seconds; + using std::chrono::sys_days; + + // FIXME +#if 0 + using std::chrono::utc_clock; + using std::chrono::utc_time; + using std::chrono::utc_seconds; + + using std::chrono::leap_second_info; + using std::chrono::get_leap_second_info; + + using std::chrono::tai_clock; + using std::chrono::tai_time; + using std::chrono::tai_seconds; + + using std::chrono::gps_clock; + using std::chrono::gps_time; + using std::chrono::gps_seconds; +#endif + + using std::chrono::file_clock; + using std::chrono::file_time; + + using std::chrono::local_t; + using std::chrono::local_time; + using std::chrono::local_seconds; + using std::chrono::local_days; + + // FIXME +#if 0 + using std::chrono::clock_time_conversion; + using std::chrono::clock_cast; + + using std::chrono::last_spec; + + using std::chrono::day; + using std::chrono::month; + using std::chrono::year; + using std::chrono::weekday; + using std::chrono::weekday_indexed; + using std::chrono::weekday_last; + using std::chrono::month_day; + using std::chrono::month_day_last; + using std::chrono::month_weekday; + using std::chrono::month_weekday_last; + using std::chrono::year_month; + using std::chrono::year_month_day; + using std::chrono::year_month_day_last; + using std::chrono::year_month_weekday; + using std::chrono::year_month_weekday_last; + using std::chrono::year_month; + using std::chrono::year_month_day; + + using std::chrono::hh_mm_ss; + using std::chrono::is_am; + using std::chrono::is_pm; + using std::chrono::make12; + using std::chrono::make24; + + using std::chrono::tzdb; + using std::chrono::tzdb_list; + using std::chrono::get_tzdb; + using std::chrono::get_tzdb_list; + using std::chrono::locate_zone; + using std::chrono::current_zone; + + using std::chrono::reload_tzdb; + using std::chrono::remote_version; + + using std::chrono::nonexistent_local_time; + using std::chrono::ambiguous_local_time; + + using std::chrono::sys_info; + using std::chrono::local_info; + + using std::chrono::choose; + using std::chrono::time_zone; + + using std::chrono::zoned_traits; + using std::chrono::zoned_time; + using std::chrono::zoned_seconds; + + using std::chrono::leap_second; + + using std::chrono::time_zone_link; + + using std::chrono::local_time_format; + + using std::chrono::parse; + + using std::chrono::last; + using std::chrono::Sunday; + using std::chrono::Monday; + using std::chrono::Tuesday; + using std::chrono::Wednesday; + using std::chrono::Thursday; + using std::chrono::Friday; + using std::chrono::Saturday; + + using std::chrono::January; + using std::chrono::February; + using std::chrono::March; + using std::chrono::April; + using std::chrono::May; + using std::chrono::June; + using std::chrono::July; + using std::chrono::August; + using std::chrono::September; + using std::chrono::October; + using std::chrono::November; + using std::chrono::December; + + using std::chrono_literals::operator""d; + using std::chrono_literals::operator""y; +#endif + + template + constexpr bool is_duration = false; + template + constexpr bool is_duration> = true; + + static_assert( is_duration ); + static_assert( is_duration ); + static_assert( is_duration ); + static_assert( is_duration ); + + template + constexpr bool has_period = std::is_same_v; + + using std::ratio; + using std::ratio_multiply; + using std::ratio_divide; + using std::chrono::hours; + static_assert( has_period, hours::period>> ); + static_assert( has_period, days::period>> ); + static_assert( has_period, days::period>> ); + static_assert( has_period>> ); + + template + constexpr bool is_time_point = false; + template + constexpr bool is_time_point> = true; + + static_assert( is_time_point> ); + static_assert( is_time_point ); + static_assert( is_time_point ); + + static_assert( std::is_class_v ); + static_assert( is_time_point> ); + static_assert( is_time_point ); + static_assert( is_time_point ); + + static_assert( std::is_class_v ); + static_assert( is_time_point> ); +} diff --git a/libstdc++-v3/testsuite/std/time/traits/is_clock.cc b/libstdc++-v3/testsuite/std/time/traits/is_clock.cc index 85f118253c3..f5d449cd42a 100644 --- a/libstdc++-v3/testsuite/std/time/traits/is_clock.cc +++ b/libstdc++-v3/testsuite/std/time/traits/is_clock.cc @@ -35,9 +35,26 @@ static_assert( chrono::is_clock_v ); static_assert(chrono::is_clock::value); static_assert(chrono::is_clock_v); +// Clock will not use the specialization of is_clock +template struct Clock : C { }; + +static_assert( chrono::is_clock>::value ); +static_assert( chrono::is_clock_v> ); + +static_assert( chrono::is_clock>::value ); +static_assert( chrono::is_clock_v> ); + +static_assert( chrono::is_clock>::value ); +static_assert( chrono::is_clock_v> ); + +static_assert(chrono::is_clock>::value); +static_assert(chrono::is_clock_v>); + static_assert( chrono::is_clock<__gnu_test::slow_clock>::value ); static_assert( chrono::is_clock_v<__gnu_test::slow_clock> ); +// Negative tests + static_assert( ! chrono::is_clock::value ); static_assert( ! chrono::is_clock_v );