10. Any
あらゆる型を保持できる動的型
list<boost::any> ls;
ls.push_back(1); // int
ls.push_back(string("abc")); // string
ls.push_back(3.14); // double
while (!ls.empty()) {
boost::any& a = ls.front();
if (a.type() == typeid(int)) { int i = boost::any_cast<int>(a); }
if (a.type() == typeid(string)) ...
if (a.type() == typeid(double)) ...
ls.pop_front();
}
23. 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);
30. 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
31. 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);
32. 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
46. 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++;
47. Multi Index
複数のソート順、アクセス順序を持たせることのできるコンテナ
using namespace boost::multi_index; #1 入れた順(sequenced)
typedef multi_index_container< C++
std::string, Action Script
indexed_by< Basic
sequenced<>, #2 辞書順(ordered)
ordered_non_unique<identity<std::string> > Action Script
> Basic
> container; C++
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 辞書順
48. 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;
}
49. Operators
関連する演算子の自動生成
class person : boost::less_than_comparable<person> {
int id_;
public:
explicit person(int id) : id_(id) {}
// operator<を定義すれば、>, <=, >=が自動生成される
friend bool operator<(const person& lhs, const person& rhs)
{ return lhs.id_ < rhs.id_; }
};
person a(1);
person b(2);
bool c = a < b;
bool d = a > b;
bool e = a <= b;
bool f = a >= b;
74. Tokenizer
トークン分割
void disp(const string& s) { cout << s << endl; }
string s = "This is a pen";
boost::tokenizer<> tok(s);
for_each(tok.begin(), tok.end(), disp);
This
is
a
pen
77. Typeof
型推論
C++0xの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++0xではこうなる
int a;
// 式の適用結果の型 : int b = a + 2;
decltype(a + 2) b = a + 2;
// 右辺の式から左辺の型を推論 : int c = b + 2;
auto c = b + 2);
78. uBLAS
ベクトルや行列といった線形代数のライブラリ
Expression Templateで組まれているため高速なのが特徴
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)
79. 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^2
85. Xpressive
正規表現
// 文字列中の <ほげほげ> にマッチするものを検索
using namespace boost::xpressive;
std::string str = "The HTML tag <title> means that ...";
sregex rex = sregex::compile(“<[^>]+>”);
smatch result;
if (regex_search(str, result, rex)) {
std::cout << "match : " << result.str() << std::endl;
}
match : <title>