Opened 8 years ago
Closed 8 years ago
#11012 closed Bugs (fixed)
chrono_io v2 fail to compile with boost::chrono::duration< boost::rational<int> >
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | Boost 1.58.0 | Component: | chrono |
Version: | Boost 1.57.0 | Severity: | Problem |
Keywords: | Cc: |
Description
When using
boost::chrono::duration< boost::rational<int> >
as duration type, chrono_io v2 fails to build with error
include/boost/chrono/io/duration_units.hpp:136:91: error: invalid static_cast from type ‘boost::chrono::duration<boost::rational<int> >::rep {aka boost::rational<int>}’ to type ‘intmax_t {aka long int}’
while chrono_io v1 builds and works as expected.
Here is the full compilation log for the attached example.
$ gcc --version gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ make g++ -c -g -fPIC -Iinclude -I/home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include -o src/chrono_rational.o src/chrono_rational.cc In file included from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/time_point_put.hpp:16:0, from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/time_point_io.hpp:22, from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/chrono_io.hpp:26, from src/chrono_rational.cc:5: /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp: In instantiation of ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put_value(boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’: /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:128:44: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(const boost::chrono::duration_units<CharT>&, boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&, const CharT*, const CharT*) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:168:81: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_io.hpp:135:15: required from ‘std::basic_ostream<_CharT, _Traits>& boost::chrono::operator<<(std::basic_ostream<_CharT, _Traits>&, const boost::chrono::duration<Rep2, Period2>&) [with CharT = char; Traits = std::char_traits<char>; Rep = boost::rational<int>; Period = boost::ratio<1l>]’ src/chrono_rational.cc:11:18: required from here /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:191:46: error: invalid static_cast from type ‘boost::chrono::duration<boost::rational<int> >::rep {aka boost::rational<int>}’ to type ‘long int’ static_cast<long int> (d.count())); ^ In file included from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:15:0, from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/time_point_put.hpp:16, from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/time_point_io.hpp:22, from /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/chrono_io.hpp:26, from src/chrono_rational.cc:5: /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_units.hpp: In instantiation of ‘boost::chrono::duration_units<CharT>::string_type boost::chrono::duration_units<CharT>::get_unit(boost::chrono::duration_style, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; boost::chrono::duration_units<CharT>::string_type = std::basic_string<char>]’: /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:230:70: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put_unit(const boost::chrono::duration_units<CharT>&, boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:133:56: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(const boost::chrono::duration_units<CharT>&, boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&, const CharT*, const CharT*) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:168:81: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_io.hpp:135:15: required from ‘std::basic_ostream<_CharT, _Traits>& boost::chrono::operator<<(std::basic_ostream<_CharT, _Traits>&, const boost::chrono::duration<Rep2, Period2>&) [with CharT = char; Traits = std::char_traits<char>; Rep = boost::rational<int>; Period = boost::ratio<1l>]’ src/chrono_rational.cc:11:18: required from here /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_units.hpp:127:87: error: invalid static_cast from type ‘boost::chrono::duration<boost::rational<int> >::rep {aka boost::rational<int>}’ to type ‘intmax_t {aka long int}’ return do_get_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count())); ^ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_units.hpp: In instantiation of ‘boost::chrono::duration_units<CharT>::string_type boost::chrono::duration_units<CharT>::get_n_d_unit(boost::chrono::duration_style, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; boost::chrono::duration_units<CharT>::string_type = std::basic_string<char>]’: /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:238:74: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put_unit(const boost::chrono::duration_units<CharT>&, boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:133:56: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(const boost::chrono::duration_units<CharT>&, boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&, const CharT*, const CharT*) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_put.hpp:168:81: required from ‘boost::chrono::duration_put<CharT, OutputIterator>::iter_type boost::chrono::duration_put<CharT, OutputIterator>::put(boost::chrono::duration_put<CharT, OutputIterator>::iter_type, std::ios_base&, boost::chrono::duration_put<CharT, OutputIterator>::char_type, const boost::chrono::duration<Rep2, Period2>&) const [with Rep = boost::rational<int>; Period = boost::ratio<1l>; CharT = char; OutputIterator = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::iter_type = std::ostreambuf_iterator<char, std::char_traits<char> >; boost::chrono::duration_put<CharT, OutputIterator>::char_type = char]’ /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_io.hpp:135:15: required from ‘std::basic_ostream<_CharT, _Traits>& boost::chrono::operator<<(std::basic_ostream<_CharT, _Traits>&, const boost::chrono::duration<Rep2, Period2>&) [with CharT = char; Traits = std::char_traits<char>; Rep = boost::rational<int>; Period = boost::ratio<1l>]’ src/chrono_rational.cc:11:18: required from here /home/sbarthelemy/.local/share/qi/toolchains/linux64/boost/include/boost/chrono/io/duration_units.hpp:136:91: error: invalid static_cast from type ‘boost::chrono::duration<boost::rational<int> >::rep {aka boost::rational<int>}’ to type ‘intmax_t {aka long int}’ return do_get_n_d_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count())); ^ make: *** [src/chrono_rational.o] Error 1
}}}
Attachments (1)
Change History (11)
by , 8 years ago
Attachment: | chrono_rational.tgz added |
---|
follow-up: 2 comment:1 by , 8 years ago
Component: | None → chrono |
---|---|
Owner: | set to |
Status: | new → assigned |
Why do you want the following to compile?
boost::chrono::duration< boost::rational<int> >
duration expects an integral type.
comment:2 by , 8 years ago
Hello Vicente,
thank you for your answer.
Replying to viboes:
Why do you want the following to compile?
boost::chrono::duration< boost::rational<int> >
Well, this specific line does compile, and even the io part did compile under version 1. The compilation only fails with io version 2.
I expected the compilation not to break between versions.
Moreover, the page en.cppreference.com/w/cpp/chrono/duration
documents rep as:
Rep, an arithmetic type representing the number of ticks
I'm not sure what "arithmetic type" precisely means in this context, but using a rational type, which supports the arithmetic operations, seemed legit (and does actually work, except for io version 2).
Note that I just discovered this trait class: en.cppreference.com/w/cpp/types/is_arithmetic
,
maybe there is a precise definition of what an arithmetic type is somewhere in the standard.
Replying to viboes:
duration expects an integral type.
That seems untrue: there is explicit support for floating point numbers.
I guess the crux here is to first understand whether or not std::chrono supports boost::rational-like types as Rep, and then support the same types for the io part.
follow-up: 5 comment:3 by , 8 years ago
My bad. You are right and std::chrono should support boost::rational.
As you mention Boost.Chrono IO V2 doesn't supports it.
V1 needed just that the Rep supports streaming
return os << d.count() << ' ' << f.template name<Period>(d.count());
V2 request num_put facet.
return std::use_facet<std::num_put<CharT, iter_type> >(ios.getloc()).put(s, ios, fill, static_cast<long int> (d.count())); //d.count());
When I comment/uncomment the previous lines I got an ambiguous call to put. This was a bug, and when I replace your example by
typedef boost::chrono::duration< float > RationalSeconds; RationalSeconds d(0.5); std::cout << d << std::endl;
The decimal part is truncated. I get
0 seconds
instead of
0.5 seconds
I have added a trait that promotes int to long int
namespace detail { template <class T> struct propagate { typedef T type; }; template <> struct propagate<boost::int_least32_t> { typedef boost::int_least64_t type; }; }
and used it instead of the cast
static_cast<long int> (d.count()));
as follows
static_cast<typename detail::propagate<Rep>::type> (d.count()));
This will however not take in account boost::rational as a valid representation.
There are other places where I have added more constraints to the representation.
return do_get_unit(style, rt_ratio(Period()), static_cast<intmax_t>(d.count()));
I 'll need to rethink how V2 can take care of IO of Rep not supported by the facets num_get/num_put and many other issues. :(
comment:4 by , 8 years ago
comment:5 by , 8 years ago
Vincente,
many thanks for your work on chrono (I should have said that first)
Replying to viboes:
I 'll need to rethink how V2 can take care of IO of Rep not supported by the facets num_get/num_put and many other issues. :(
yes, good luck for that.
Cheers
follow-ups: 8 8 comment:6 by , 8 years ago
Milestone: | To Be Determined → Boost 1.58.0 |
---|
You are welcome.
I have found a workaround. While not completely satisfactory from the design point of view, it seems to work.
Please, could you take a look at https://github.com/boostorg/chrono/commit/83b881fad4ecb539c63357c3482c95daf2ca7388
comment:7 by , 8 years ago
While the last commit works for stream inserter (<<), I don't have yet a clear idea on how to take care of stream extractor (>>).
comment:8 by , 8 years ago
Thank you for the patch
Replying to viboes:
Please, could you take a look at [...]
I commented there.
comment:8 by , 8 years ago
comment:9 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
I will close this issue, even if the design is not clean.
unbuildable example