Subject: [Boost-bugs] [Boost C++ Libraries] #6092: input from non integral durations makes the compiler fail
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-11-03 22:53:01
#6092: input from non integral durations makes the compiler fail
------------------------------+---------------------------------------------
Reporter: viboes | Owner: viboes
Type: Bugs | Status: new
Milestone: To Be Determined | Component: chrono
Version: Boost 1.47.0 | Severity: Problem
Keywords: |
------------------------------+---------------------------------------------
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;
}
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/6092> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:07 UTC