template<typename _Rep2>
using __is_float = treat_as_floating_point<_Rep2>;
+ static constexpr intmax_t
+ _S_gcd(intmax_t __m, intmax_t __n) noexcept
+ {
+ // Duration only allows positive periods so we don't need to
+ // support negative values here (unlike __static_gcd and std::gcd).
+ return (__m == 0) ? __n : (__n == 0) ? __m : _S_gcd(__n, __m % __n);
+ }
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2094. overflow shouldn't participate in overload resolution
+ // 3090. What is [2094] intended to mean?
+ // This only produces a valid type if no overflow occurs.
+ template<typename _R1, typename _R2,
+ intmax_t __gcd1 = _S_gcd(_R1::num, _R2::num),
+ intmax_t __gcd2 = _S_gcd(_R1::den, _R2::den)>
+ using __divide = ratio<(_R1::num / __gcd1) * (_R2::den / __gcd2),
+ (_R1::den / __gcd2) * (_R2::num / __gcd1)>;
+
// _Period2 is an exact multiple of _Period
template<typename _Period2>
using __is_harmonic
- = __bool_constant<ratio_divide<_Period2, _Period>::den == 1>;
+ = __bool_constant<__divide<_Period2, _Period>::den == 1>;
public:
: __r(static_cast<rep>(__rep)) { }
template<typename _Rep2, typename _Period2, typename = _Require<
+ is_convertible<const _Rep2&, rep>,
__or_<__is_float<rep>,
__and_<__is_harmonic<_Period2>,
__not_<__is_float<_Rep2>>>>>>
--- /dev/null
+// 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <chrono>
+
+void
+test01()
+{
+ using namespace std::chrono;
+ using std::exa;
+
+ // LWG 2094
+ // duration conversion overflow shouldn't participate in overload resolution
+ bool f(milliseconds);
+ void f(seconds);
+ duration<int,exa> r(1);
+ f(r);
+}
+
+void
+test02()
+{
+ struct Number
+ {
+ explicit
+ Number(int t = 0) : i(t)
+ { }
+
+ int i = 0;
+
+ Number& operator+=(Number n) { i += n.i; return *this; }
+ Number& operator-=(Number n) { i -= n.i; return *this; }
+ Number& operator*=(Number n) { i *= n.i; return *this; }
+ Number& operator/=(Number n) { i /= n.i; return *this; }
+ Number& operator%=(Number n) { i %= n.i; return *this; }
+
+ Number operator+(Number n) { return Number{ i + n.i }; }
+ Number operator-(Number n) { return Number{ i - n.i }; }
+ Number operator*(Number n) { return Number{ i * n.i }; }
+ Number operator/(Number n) { return Number{ i / n.i }; }
+ Number operator%(Number n) { return Number{ i % n.i }; }
+ };
+
+ using std::chrono::duration;
+
+ static_assert( ! std::is_constructible<duration<int>, duration<Number>>(),
+ "duration(const duration<R2, P2>&) constrained on R2 -> R conversion" );
+}
Number& operator/=(Number n) { i /= n.i; return *this; }
Number& operator%=(Number n) { i %= n.i; return *this; }
- Number operator+(Number n) { return { i + n.i }; }
- Number operator-(Number n) { return { i - n.i }; }
- Number operator*(Number n) { return { i * n.i }; }
- Number operator/(Number n) { return { i / n.i }; }
- Number operator%(Number n) { return { i % n.i }; }
+ Number operator+(Number n) { return Number{ i + n.i }; }
+ Number operator-(Number n) { return Number{ i - n.i }; }
+ Number operator*(Number n) { return Number{ i * n.i }; }
+ Number operator/(Number n) { return Number{ i / n.i }; }
+ Number operator%(Number n) { return Number{ i % n.i }; }
};
namespace std
// { dg-error "must be a specialization of ratio" "" { target *-*-* } 0 }
// { dg-prune-output "'num' is not a member of 'int'" }
+// { dg-prune-output "'den' is not a member of 'int'" }
// { dg-prune-output "'int' is not a class, struct, or union type" }