Opened 11 years ago
Closed 11 years ago
#6092 closed Bugs (fixed)
input from non integral durations makes the compiler fail
Reported by: | viboes | Owned by: | viboes |
---|---|---|---|
Milestone: | Boost 1.49.0 | Component: | chrono |
Version: | Boost 1.47.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The following input
1.0 seconds
makes the compiler fails when trying to extract the duration
duration<double,milli> d;
cin >> d;
../../../boost/math/common_factor_rt.hpp: In function ‘RingType boost::math::detail::gcd_euclidean(RingType, RingType) [with RingType = long double]’: ../../../boost/math/common_factor_rt.hpp:122: instantiated from ‘IntegerType boost::math::detail::gcd_integer(const IntegerType&, const IntegerType&) [with IntegerType = long double]’ ../../../boost/math/common_factor_rt.hpp:240: instantiated from ‘T boost::math::detail::gcd_optimal_evaluator_helper_t<T, true, true>::operator()(const T&, const T&) [with T = long double]’ ../../../boost/math/common_factor_rt.hpp:290: instantiated from ‘T boost::math::detail::gcd_optimal_evaluator<T>::operator()(const T&, const T&) [with T = long double]’ ../../../boost/math/common_factor_rt.hpp:442: instantiated from ‘T boost::math::detail::gcd_optimal(const T&, const T&) [with T = long double]’ ../../../boost/math/common_factor_rt.hpp:473: instantiated from ‘typename boost::math::gcd_evaluator<IntegerType>::result_type boost::math::gcd_evaluator<IntegerType>::operator()(const IntegerType&, const IntegerType&) const [with IntegerType = long double]’ ../../../boost/math/common_factor_rt.hpp:505: instantiated from ‘IntegerType boost::math::gcd(const IntegerType&, const IntegerType&) [with IntegerType = long double]’ ../../../boost/chrono/io/duration_get.hpp:239: instantiated from ‘InputIterator boost::chrono::duration_get<CharT, InputIterator>::get(InputIterator, InputIterator, std::ios_base&, std::_Ios_Iostate&, boost::chrono::duration<Rep2, Period2>&, const CharT*, const CharT*) const [with Rep = double, Period = boost::ratio<1l, 1l>, CharT = char, InputIterator = std::istreambuf_iterator<char, std::char_traits<char> >]’ ../../../boost/chrono/io/duration_get.hpp:294: instantiated from ‘InputIterator boost::chrono::duration_get<CharT, InputIterator>::get(InputIterator, InputIterator, std::ios_base&, std::_Ios_Iostate&, boost::chrono::duration<Rep2, Period2>&) const [with Rep = double, Period = boost::ratio<1l, 1l>, CharT = char, InputIterator = std::istreambuf_iterator<char, std::char_traits<char> >]’ ../../../boost/chrono/io/duration_io.hpp:593: instantiated from ‘std::basic_istream<_CharT, _Traits>& boost::chrono::operator>>(std::basic_istream<_CharT, _Traits>&, boost::chrono::duration<Rep2, Period2>&) [with CharT = char, Traits = std::char_traits<char>, Rep = double, Period = boost::ratio<1l, 1l>]’ io/duration_input.cpp:15: instantiated from ‘void test_good(const char*, D) [with D = boost::chrono::duration<double, boost::ratio<1l, 1l> >]’ io/duration_input.cpp:52: instantiated from here ../../../boost/math/common_factor_rt.hpp:102: error: invalid operands of types ‘long double’ and ‘long double’ to binary ‘operator%’ ../../../boost/math/common_factor_rt.hpp:102: error: in evaluation of ‘operator%=(long double, long double)’ ../../../boost/math/common_factor_rt.hpp:106: error: invalid operands of types ‘long double’ and ‘long double’ to binary ‘operator%’ ../../../boost/math/common_factor_rt.hpp:106: error: in evaluation of ‘operator%=(long double, long double)’
This is because the common type is a double and gcd doesn't works for it.
// if (is_integral<intermediate_type>::value) // { // // Reduce r * num / den // common_type_t t = math::gcd<common_type_t>(r, den); // r /= t; // den /= t; // if (den != 1) // { // // Conversion to Period is integral and not exact // is.setstate(is.failbit); // return is; // } // }
This code could be replaced by a template to avoid the bad code to be instantiated.
template <typename intermediate_type> typename enable_if<is_integral<intermediate_type>, bool>::type reduce(intermediate_type& r, unsigned long long& den, std::ios_base::iostate& err) { typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t; // Reduce r * num / den common_type_t t = math::gcd<common_type_t>(common_type_t(r), common_type_t(den)); r /= t; den /= t; if (den != 1) { // Conversion to Period is integral and not exact err |= std::ios_base::failbit; return false; } return true; } template <typename intermediate_type> typename disable_if<is_integral<intermediate_type>, bool>::type reduce(intermediate_type& , unsigned long long& , std::ios_base::iostate& ) { return true; }
Change History (3)
comment:1 by , 11 years ago
Status: | new → assigned |
---|
comment:2 by , 11 years ago
Milestone: | To Be Determined → Boost 1.49.0 |
---|
Note:
See TracTickets
for help on using tickets.
Fixed in trunk r75237.