diff options
| author | Howard Hinnant <hhinnant@apple.com> | 2013-08-31 16:51:56 +0000 |
|---|---|---|
| committer | Howard Hinnant <hhinnant@apple.com> | 2013-08-31 16:51:56 +0000 |
| commit | 69bc206547c3b9f413673ef0ebc6e425c6dbd11a (patch) | |
| tree | f12853e0655f113da4ceb11c908f564c2d615748 /libcxx | |
| parent | b5e6300be5cc108df05805299c001b06b71ad0af (diff) | |
| download | bcm5719-llvm-69bc206547c3b9f413673ef0ebc6e425c6dbd11a.tar.gz bcm5719-llvm-69bc206547c3b9f413673ef0ebc6e425c6dbd11a.zip | |
SFINAE out duration converting constructor if the constructor would otherwise cause a ratio compile-time overflow. This fixes LWG 2094.
llvm-svn: 189722
Diffstat (limited to 'libcxx')
| -rw-r--r-- | libcxx/include/chrono | 36 | ||||
| -rw-r--r-- | libcxx/test/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp | 4 | ||||
| -rw-r--r-- | libcxx/www/cxx1y_status.html | 2 |
3 files changed, 39 insertions, 3 deletions
diff --git a/libcxx/include/chrono b/libcxx/include/chrono index 9fb774317da..afc51817007 100644 --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -409,6 +409,37 @@ class _LIBCPP_TYPE_VIS_ONLY duration static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); static_assert(_Period::num > 0, "duration period must be positive"); + + template <class _R1, class _R2> + struct __no_overflow + { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template <intmax_t _Xp, intmax_t _Yp, bool __overflow> + struct __mul // __overflow == false + { + static const intmax_t value = _Xp * _Yp; + }; + + template <intmax_t _Xp, intmax_t _Yp> + struct __mul<_Xp, _Yp, true> + { + static const intmax_t value = 1; + }; + + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, + __mul<__n2, __d1, !value>::value> type; + }; + public: typedef _Rep rep; typedef _Period period; @@ -440,9 +471,10 @@ public: duration(const duration<_Rep2, _Period2>& __d, typename enable_if < + __no_overflow<_Period2, period>::value && ( treat_as_floating_point<rep>::value || - (ratio_divide<_Period2, period>::type::den == 1 && - !treat_as_floating_point<_Rep2>::value) + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)) >::type* = 0) : __rep_(_VSTD::chrono::duration_cast<duration>(__d).count()) {} diff --git a/libcxx/test/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp b/libcxx/test/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp index 04b43672c61..7d7e82ac5e2 100644 --- a/libcxx/test/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp +++ b/libcxx/test/utilities/time/time.point/time.point.cast/time_point_cast.pass.cpp @@ -35,6 +35,8 @@ test(const FromDuration& df, const ToDuration& d) } } +#if _LIBCPP_STD_VER > 11 + template<class FromDuration, long long From, class ToDuration, long long To> void test_constexpr () { @@ -49,6 +51,8 @@ void test_constexpr () } +#endif + int main() { test(std::chrono::milliseconds(7265000), std::chrono::hours(2)); diff --git a/libcxx/www/cxx1y_status.html b/libcxx/www/cxx1y_status.html index c1f61094d22..da920a5b707 100644 --- a/libcxx/www/cxx1y_status.html +++ b/libcxx/www/cxx1y_status.html @@ -140,7 +140,7 @@ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2091">2091</a></td><td>Misplaced effect in m.try_lock_for()</td><td>Bristol</td><td>Complete</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2092">2092</a></td><td>Vague Wording for condition_variable_any</td><td>Bristol</td><td>Complete</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2093">2093</a></td><td>Throws clause of condition_variable::wait with predicate</td><td>Bristol</td><td>Complete</td></tr> - <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2094">2094</a></td><td>duration conversion overflow shouldn't participate in overload resolution</td><td>Bristol</td><td></td></tr> + <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2094">2094</a></td><td>duration conversion overflow shouldn't participate in overload resolution</td><td>Bristol</td><td>Complete</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2122">2122</a></td><td>merge() stability for lists versus forward lists</td><td>Bristol</td><td></td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2128">2128</a></td><td>Absence of global functions cbegin/cend</td><td>Bristol</td><td>Complete</td></tr> <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2145">2145</a></td><td>error_category default constructor</td><td>Bristol</td><td>Complete</td></tr> |

