[Boost-bugs] [Boost C++ Libraries] #6092: input from non integral durations makes the compiler fail

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