Как преобразовать std :: chrono :: system_clock :: duration в структуру timeval

Название говорит само за себя.

Мне нужно реализовать функцию, которая получает значение std :: chrono :: system_clock :: duration и которая должна преобразовать его в sruct timeval, чтобы я мог передать его какой-то системной функции.


person chmike    schedule 01.07.2013    source источник


Ответы (2)


Более общая реализация.

template<typename Duration>
void to_timeval(Duration&& d, struct timeval & tv) {
    std::chrono::seconds const sec = std::chrono::duration_cast<std::chrono::seconds>(d);

    tv.tv_sec  = sec.count();
    tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(d - sec).count();
}

ОБНОВИТЬ:

Отдельные методы вроде to_timeval() не слишком удобны. Где перегрузка? Мы только что жестко ввели тип timeval в имя функции to_timeval(). Это не способ C ++. Я хочу передать struct timeval, например, std::chrono::duration_cast() и получить свой chrono-результат и наоборот.

Итак, мы можем продлить std::chrono::duration_cast (конечно, на ваш страх и риск). Наслаждаться.

namespace std {
namespace chrono {
namespace detail {

template<typename From, typename To>
struct posix_duration_cast;

// chrono -> timeval caster
template<typename Rep, typename Period>
struct posix_duration_cast< std::chrono::duration<Rep, Period>, struct timeval > {

    static struct timeval cast(std::chrono::duration<Rep, Period> const& d) {
        struct timeval tv;

        std::chrono::seconds const sec = std::chrono::duration_cast<std::chrono::seconds>(d);

        tv.tv_sec  = sec.count();
        tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(d - sec).count();

        return std::move(tv);
    }

};

// timeval -> chrono caster
template<typename Rep, typename Period>
struct posix_duration_cast< struct timeval, std::chrono::duration<Rep, Period> > {

    static std::chrono::duration<Rep, Period> cast(struct timeval const & tv) {
        return std::chrono::duration_cast< std::chrono::duration<Rep, Period> >(
                    std::chrono::seconds(tv.tv_sec) + std::chrono::microseconds(tv.tv_usec)
                    );
    }

};

}

// chrono -> timeval    
template<typename T, typename Rep, typename Period>
auto duration_cast(std::chrono::duration<Rep, Period> const& d)
-> std::enable_if_t< std::is_same<T, struct timeval>::value, struct timeval >
{
    return detail::posix_duration_cast< std::chrono::duration<Rep, Period>, timeval >::cast(d);
}

// timeval -> chrono
template<typename Duration>
Duration duration_cast(struct timeval const& tv) {
    return detail::posix_duration_cast< struct timeval, Duration >::cast(tv);
}

} // chrono
} // std

Это просто пример. В качестве альтернативы мы можем реализовать собственный duration_cast() и в некоторых случаях пересылать его в std::chrono::duration_cast().

И мы помним про struct timespec.

person Nevermore    schedule 24.09.2015
comment
Отличный ответ! (Для других читателей) Причина, по которой этот ответ лучше, в том, что в нем нет коэффициентов ручного преобразования. Он использует библиотеку chrono для преобразования. - person Howard Hinnant; 24.09.2015

Пусть d будет значением входной длительности, а tv - выходной временной структурой, заполненной функцией convert. Примечание: функция устанавливает значение 0, если длительность отрицательная.

void convert( const std::chrono::system_clock::duration &d, timeval &tv )
{
  chrono::microseconds usec = chrono::duration_cast<chrono::microseconds>(d);
  if( usec <= chrono::microseconds(0) )
    tv.tv_sec = tv.tv_usec = 0;
  else
  {
    tv.tv_sec = usec.count()/1000000;
    tv.tv_usec = usec.count()%1000000;
  }
}
person chmike    schedule 02.07.2013