I have an application that uses asio deadline timers. The rest of the application uses std::chrono
constructs for its time values, and it feels awkward to use boost::posix_time
for only the stuff that touches asio. I'd like to use std::chrono
throughout the application if I can, for consistency, readability, etc.
It seems to me that the answer would involve using the timer's template:
typedef boost::asio::basic_deadline_timer<std::chrono::system_clock::time_point>
my_deadline_timer_type;
my_deadline_timer_type a_timer(io_service);
Except this blows up badly at compile time...many lines of error, most of which are similar to this:
/opt/arm/include/boost/asio/deadline_timer_service.hpp:51:43: error: invalid use of incomplete type 'boost::asio::deadline_timer_service > >, boost::asio::time_traits > > > >::traits_type {aka struct boost::asio::time_traits > > >}'
So, it looks like I may need to create a new traits_type
and declare a deadline_timer_service
using it, but I'm not sure how/where. I have to believe this problem has been solved. I'm using g++ 4.7.3 with -std=c++11 on linux, cross-compiling to arm.
If you are using boost 1.49 or later, ASIO introduced the basic_waitable_timer, which uses C++11 compatible clocks, either from std::chrono
or boost::chrono
. They also provided pre-defined typedefs for the boost versions of steady_clock
, system_clock
, and high_resolution_clock
. Its functionality is the same as deadline_timer
, but uses the C++11 clock mechanisms instead of the boost::posix_time
structures.
For earlier versions, you're going to have to pass a traits structure to handle conversion to the type expected by deadline_timer
. See the ASIO TimeTraits requirements. Most are trivial, the last is not. So, for example
template<typename Clock>
struct CXX11Traits
{
typedef typename Clock::time_point time_type;
typedef typename Clock::duration duration_type;
static time_type now()
{
return Clock::now();
}
static time_type add(time_type t, duration_type d)
{
return t + d;
}
static duration subtract(time_type t1, time_type t2)
{
return t1-t2;
}
static bool less_than(time_type t1, time_type t2)
{
return t1 < t2;
}
static boost::posix_time::time_duration
to_posix_duration(duration_type d1)
{
using std::chrono::duration_cast;
auto in_sec = duration_cast<std::chrono::seconds>(d1);
auto in_usec = duration_cast<std::chrono::microseconds>(d1 - in_sec);
boost::posix_time::time_duration result =
boost::posix_time::seconds(in_sec.count()) +
boost::posix_time::microseconds(in_usec.count());
return result;
}
};
You would then create deadline timers for each C++11 clock you want to use. The example here is for std::system_clock
. You would use this deadline timer as normal.
typedef boost::asio::basic_deadline_timer<
std::system_clock,
CXX11Traits<std::system_clock>> my_system_clock_deadline_timer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With