8.
Algorithm 3/3
アルゴリズム集。文字列検索、C++11/14アルゴリズム、ユーティリティ
が含まれる。
using boost::algorithm::clamp;
!
// xを0~10の範囲に丸める : min(max(a, x), b)
!
int x = 11;
x = clamp(x, 0, 10); // x == 10
!
int y = -1;
y = clamp(y, 0, 10); // x == 0
17.
Chrono
時間処理のためのライブラリ。
C++11標準ライブラリに導入されたものと、その拡張。
// 500ナノ秒遅延する
namespace chrono = boost::chrono;
!
auto go = chrono::steady_clock::now() + chrono::nanoseconds(500);
while (chrono::steady_clock::now() < go)
;
様々な時間の単位と、いくつかの特性をもった時計クラスが提供される。
CPU時間を使う拡張もある。
18.
Circular Buffer
循環バッファ。
バッファがいっぱいになったら上書きしていく。
boost::circular_buffer<int> buff(3);
!
buff.push_back(1); buff.push_back(2); buff.push_back(3);
!
int a = buff[0]; // a : 1
int b = buff[1]; // b : 2
int c = buff[2]; // c : 3
!
buff.push_back(4); buff.push_back(5);
!
a = buff[0]; // a : 3
b = buff[1]; // b : 4
c = buff[2]; // c : 5
19.
Compressed Pair
テンプレート引数のどちらかが空クラスだった場合に
最適化されやすいpair。
struct hoge {}; // empty class
!
boost::compressed_pair<hoge, int> p(hoge(), 1);
!
hoge& h = p.first();
int& i = p.second();
28.
Coroutine
処理の中断と再開を制御する、コルーチンのライブラリ。
using namespace boost::coroutines;
!
void f(asymmetric_coroutine<void>::push_type& yield)
{
for (int i = 0; i < 10; ++i) {
std::cout << "a ";
yield(); // 処理を中断
}
}
!
asymmetric_coroutine<void>::pull_type c(f);
for (int i = 0; i < 10; ++i) {
std::cout << "b ";
c(); // 中断したところから処理を再開
}
a b a b a b …
30.
Date Time
日付・時間ライブラリ
using namespace boost::gregorian;
using namespace boost::posix_time;
!
ptime now = second_clock::local_time();
!
// 日付計算
date today = now.date();
date tomorrow = today + date_duration(1);
!
// 時間計算
ptime t = now + minutes(3);
31.
Dynamic Bitset
大きさを動的に変えられるbitset
boost::dynamic_bitset<> bs(10);
!
// 偶数番目のビットを立てる
for (size_t i = 0; i < bs.size(); ++i) {
if (i % 2 == 0)
bs[i] = 1; // 添字アクセス
}
!
cout << bs << endl; // 0101010101
38.
Format
文字列のフォーマット
// sprintf風のフォーマット
string s1 = (boost::format("this year is %d.") % 2009).str();
cout << s1 << endl; // this year is 2009.
!
// プレースホルダーによるフォーマット
string s2 = (boost::format("next year is %1%.") % 2010).str();
cout << s2 << endl; // next year is 2010
39.
Function
汎用関数オブジェクト。
テンプレート引数は、関数のシグニチャ。
int func(double) { return 1; }
!
struct functor {
typedef int result_type;
int operator()(double) const { return 2; }
};
!
// 関数ポインタ
boost::function<int(double)> f1 = func;
int r1 = f1(3.14);
!
// 関数オブジェクト
boost::function<int(double)> f2 = functor();
int r2 = f2(3.14);
40.
Function Types
関数の型情報を取得するメタ関数
using namespace boost::function_types;
!
// 型が関数ポインタかどうか判別
bool b = is_function_pointer<bool(*)(int)>::value; // == true
!
// 関数(関数ポインタ or 関数オブジェクト)の戻り値の型を取得
typedef result_type<bool(&)(int)>::type result_type; // is bool
56.
Local Function
ローカル関数を定義する。
int main()
{
int sum = 0;
!
void BOOST_LOCAL_FUNCTION(bind& sum, int x) {
sum += x;
} BOOST_LOCAL_FUNCTION_NAME(add);
!
const std::vector<int> v = {1, 2, 3, 4, 5};
boost::for_each(v, add);
!
std::cout << sum << std::endl;
}
15
57.
Lockfree
Boost.Atomicベースの、ロックフリーデータ構造ライブラリ。
キュー、スタック、優先順位付きキューの実装がある。
lockfree::queue<int> que(128);
!
void producer() {
for (int i = 0;; ++i) {
while (!que.push(i)) {}
}
}
!
void consumer() {
for (;;) {
int x = 0;
if (que.pop(x))
std::cout << x << std::endl;
}
}
62.
Meta State Machine (MSM) 2/2
状態マシンライブラリ。状態遷移表を直接記述する。
int main()
{
StopWatch watch;
!
watch.start();
watch.process_event(StartStopEvent()); // stop -> run
watch.process_event(StartStopEvent()); // run -> stop
watch.process_event(StartStopEvent()); // stop -> run
watch.process_event(ResetEvent()); // run -> stop
}
64.
Move
ムーブセマンティクスのC++03実装。
一時オブジェクトのコストを軽減する。
template <class T>
void swap(T& a, T& b)
{
T tmp(boost::move(a));
a = boost::move(b);
b = boost::move(tmp);
}
65.
Multi Array
多次元配列。
typedef boost::multi_array<int, 3> Array;
Array ar(boost::extents[3][4][2]);
!
int value = 0;
for (size_t i = 0; i < ar.size(); ++i)
for (size_t j = 0; j < ar[i].size(); ++j)
for (size_t k = 0; k < ar[i][j].size(); ++k)
ar[i][j][k] = value++;
66.
Multi Index
複数のソート順、アクセス順序を持たせることのできるコンテナ。
using namespace boost::multi_index;
typedef multi_index_container<
std::string,
indexed_by<
sequenced<>,
ordered_non_unique<identity<std::string> >
>
> container;
!
container words;
words.push_back("C++");
words.push_back("Action Script");
words.push_back("Basic");
!
copy(words, ostream_iterator<string>(cout, "n")); // #1 入れた順
!
const container::nth_index<1>::type& c = words.get<1>();
copy(c, ostream_iterator<string>(cout, "n")); // #2 辞書順
#1 入れた順(sequenced)
C++
Action Script
Basic
#2 辞書順(ordered)
Action Script
Basic
C++
67.
Multiprecision
多倍長演算ライブラリ。無限長の整数などを扱える。
// 100の階乗を計算する
cpp_int x = 1;
for(std::size_t i = 1; i <= 100; ++i)
x *= i;
!
std::cout << x << std::endl;
9332621544394415268169923885626670049071596826438162146859296389521759
9993229915608941463976156518286253697920827223758251185210916864000000
000000000000000000
68.
Numeric Conversion
数値型の型変換。
typedef boost::numeric::converter<int, double> DoubleToInt;
!
try {
int x = DoubleToInt::convert(2.0);
assert(x == 2);
!
double m = boost::numeric::bounds<double>::highest();
int y = DoubleToInt::convert(m);
// デフォルトではpositive_overflowを投げる
}
catch (boost::numeric::positive_overflow& ex) {
cout << ex.what() << endl;
}
99.
Test
自動テストのライブラリ
void size_test()
{
std::vector<int> v;
const int size = v.size();
!
v.push_back(3);
BOOST_CHECK_EQUAL(v.size(), size + 1);
!
v.pop_back();
BOOST_CHECK_EQUAL(v.size(), size);
}
!
using namespace boost::unit_test_framework;
test_suite* init_unit_test_suite(int argc, char* argv[])
{
test_suite* test = BOOST_TEST_SUITE("test");
test->add(BOOST_TEST_CASE(&size_test));
return test;
}
Running 1 test case…
!
*** No errors detected
100.
Test v3 (1.59.0)
Boost.Testがバージョン3にメジャーアップデートした。
汎用的なテストマクロBOOST_TESTが追加された(Power Assert)。
パラメタライズドテストに対応した。ドキュメントが読みやすくなった。
BOOST_AUTO_TEST_CASE(equal_test)
{
int a = 1;
int b = 2;
BOOST_TEST(a == b);
}
Running 1 test case...
main.cpp:8: error: in "equal_test": check a == b has failed [1 != 2]
!
*** 1 failure is detected in the test module "example"
102.
Timer
時間計測。
boost::timer::cpu_timer timer; // 時間計測を開始
!
for (long i = 0; i < 100000000; ++i) {
std::sqrt(123.456L); // 時間のかかる処理
}
!
std::string result = timer.format(); // 結果文字列を取得する
std::cout << result << std::endl;
5.636670s wall, 5.600436s user + 0.000000s system = 5.600436s CPU (99.4%)
103.
Tokenizer
トークン分割。
ポリシーによって、さまざまな分割方法を設定できる(たとえばCSV)
string s = "This is a pen";
boost::tokenizer<> tok(s);
!
for_each(tok.begin(), tok.end(), [](const string& t) {
cout << t << endl;
});
This
is
a
pen
104.
Tribool
3値bool。真・偽・不定(NULL相当)の3つの値を持つ。
データベースとのマッピングに使用できる。
using namespace boost::logic;
!
tribool a = true; // 真
a = false; // 偽
a = indeterminate; // 不定
105.
TTI (Type Traits Introspection)
型がどんな情報を持っているかコンパイル時に調べるライブラリ。
// メンバ関数mf()を持っているか判定するメタ関数を生成する
BOOST_TTI_HAS_MEMBER_FUNCTION(mf)
!
struct X {
int mf(int, int);
};
!
型Xが、intを2つ受け取り、intを返すメンバ関数mf()を持っているか
constexpr bool b = has_member_function_mf<
X,
int,
boost::mpl::vector<int, int>
>::value;
109.
Type Index
std::type_info/std::type_indexのBoost版。
RTTIの無効化や、型のデマングル名などに対応している。
using boost::typeindex::type_id;
std::cout << type_id<int>().raw_name() << std::endl;
std::cout << type_id<int>().pretty_name() << std::endl;
i
int
(GCCの場合)
110.
Typeof
型推論。
C++11のautoとdecltypeをエミュレーションする。
int a;
!
// 式の適用結果の型 : int b = a + 2;
BOOST_TYPEOF(a + 2) b = a + 2;
!
// 右辺の式から左辺の型を推論 : int c = b + 2;
BOOST_AUTO(c, b + 2);
C++11では以下のようになる:
int a;
!
// 式の適用結果の型 : int b = a + 2;
decltype(a + 2) b = a + 2;
!
// 右辺の式から左辺の型を推論 : int c = b + 2;
auto c = b + 2;
111.
uBLAS
ベクトルや行列といった、線形代数のライブラリ。
using namespace boost::numeric::ublas;
!
vector<double> a(3);
a[0] = 0;
a[1] = 0;
a[2] = 0;
!
vector<double> b(3);
b[0] = 10;
b[1] = 0;
b[2] = 0;
!
vector<double> v = b - a; // 目的地へのベクトル
v = v / norm_2(v); // 正規化
!
std::cout << v << std::endl; // [3](1,0,0)
112.
Units
単位演算
using namespace boost::units;
using namespace boost::units::si;
!
quantity<length> x(1.5 * meter); // 1.5m
quantity<length> y(120 * centi * meter); // 120cm
cout << x * y << endl; // 面積 : 1.8 m²
Clipping is a handy way to collect and organize the most important slides from a presentation. You can keep your great finds in clipboards organized around topics.
Be the first to comment