boost 的 integer 与 chrono

boost 提供了一个 integer traits 库,方便一些对 integer 特殊的需求。

  • integral_traits 包括 is_integral、const_min 和 const_max,后两者其实与 std::numeric_limits 接近
  • 通过类似 uint_t<N> 这些定义了对应的 exact、fast 和 least 版本的实现,这样就能很好的控制使用的类型(比如最大是 8 可以自动选择 uchar 之类的);
  • 通过 high_bits_mask 和 low_bits_mask 实现一些基本的 mask;
  • static_log_2 能在编译时计算 \log_2

boost 的 chrono 提供了一些计时的功能,主要通过 chrono 模板提供了满足各种尺度需求的容器以及转换:

  • boost::chrono::duration<container, ratio>,这里常用的 container 有 long,而 ratio 可以使用 boost::ratio 表示大于 1s 的,如小时、分钟的概念,也可以使用一些定义好的,如 boost::micro;chrono 自己定义了不少 duration,对应 ostream&<< 也进行了重载;
  • 可以用 duration_cast 完成不同 scale 之间的转换;
  • 可以用 round<>、floor<> 和 ceil<> 表示 duration 的取整(发生运算的时候比较常用);
  • 实现了几个 clock (system_clock、steady_clock、high_resolution_clock、process_cpu_clock 和 thread_clock),clock 提供对应的 duration、time_point 和 now() 方法。

正因为如此,chrono 并不是一个完全头文件组成的 lib,使用 clock 需要链接到 libboost_chrono。下面是一个简单的例子展示如何将视频的帧数对应到播放时间。

#include <boost/chrono.hpp>
#include <boost/integer.hpp>
#include <iostream>

namespace chrono = boost::chrono ;

template <class CharT, class Traits, class Rep, class Period> void
display(std::basic_ostream<CharT, Traits>& os,
        chrono::duration<Rep, Period> d) {
  typedef chrono::duration<long long, boost::centi> centiseconds;
  // round d to nearest centiseconds, to even on tie
  centiseconds cs = chrono::duration_cast<centiseconds>(d);
  if (d - cs > chrono::milliseconds(5)
      || (d - cs == chrono::milliseconds(5) && cs.count() & 1))
    ++cs;
  // separate seconds from centiseconds
  chrono::seconds s = chrono::duration_cast<chrono::seconds>(cs);
  cs -= s;
  // separate minutes from seconds
  chrono::minutes m = chrono::duration_cast<chrono::minutes>(s);
  s -= m;
  // separate hours from minutes
  chrono::hours h = chrono::duration_cast<chrono::hours>(m);
  m -= h;
  // print d/hh:mm:ss.cc
  if (h < chrono::hours(10))
    os << '0';
  os << h.count() << ':';
  if (m < chrono::minutes(10))
    os << '0';
  os << m.count() << ':';
  if (s < chrono::seconds(10))
    os << '0';
  os << s.count() << '.';
  if (cs < centiseconds(10))
    os << '0';
  os << cs.count();
}

typedef boost::int_t<32>::fast fint ;
typedef chrono::duration<fint, boost::ratio<1, 24> > frame ;

int
main (int, char**) {
  chrono::high_resolution_clock::time_point
    start = chrono::high_resolution_clock::now();
  frame five_seconds = boost::chrono::seconds (5) ;
  for (frame i (0) ; i < frame (10000); ++ i) {
    std::cout << i
              <<
      (i.count() % five_seconds.count () == 0
       ? '\n' : '\r') ;
  }

  chrono::duration<double>
    sec = chrono::high_resolution_clock::now() - start;

  std::cout << "took " ;
  display (std::cout, sec) ;
  std::cout << std::endl ;
  return 0 ;
}

主要注意的是应该与 chrono 和 system 两个进行连接。很 ws 的是似乎不能 include ratio.hpp,难道这个地方也有跟 spirit 类似的地方?

——————
This is my covenant, which you shall keep, between me and you and your seed after you; Every man child among you shall be circumcised.

Advertisements
boost 的 integer 与 chrono

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s