boostライブラリについて
-----
#contents
-----
*ライブラリ [#a989aab7]
**[[boost::bind:http://boost.cppll.jp/HEAD/libs/bind/bind.html]] [#v451c6c9]
個人的には一番よく使うのがboost::bind.
STLのbind1st, bind2stの汎用版である.任意の引数をbindして,固定値にしたり,メンバ関数へのポインタもサポートする.
#include <boost/bind.hpp>
boost::bindは関数オブジェクトを作成することができるのだが,関数の引数をある値に固定することができる.
例えば,
#code(C){{
int func2(int x, int y)
{
return x+y;
}
int func3(int x, int y, int z)
{
return x+y+z;
}
void main(void)
{
boost::function<int (int, int)> func;
func = func2;
cout << func(1, 2) << endl;
func = boost::bind(func3, _1, _2, 0);
cout << func(1, 2) << endl;
}
}}
のように,3引数を取る関数の最後の引数に渡す値を0に固定した関数の関数オブジェクトを簡単に作れる.
また,下のboost::functionでも述べているが,メンバ関数についても下記のmem_fnと同様にできる.
#code(C){{
Class1 *obj = new Class1;
boost::function<int (int)> func = boost::bind(&Class1::Func1, boost::ref(obj), _1);
}}
**[[boost::mem_fn:http://boost.cppll.jp/HEAD/libs/bind/mem_fn.html]] [#i98ec359]
#include<boost/mem_fn.hpp>
メンバ関数を関数オブジェクトとして扱えるようにする.std::mem_fun,std::mem_fun_ref の一般化バージョンで引数の数は2個以上でも可能.std::for_eachにメンバ関数を渡したいときなどに便利.
class MemClass
{
public:
MemClass(int x) : a(x){}
void Print(){ cout << a << endl; }
private:
int a;
};
void main(void)
{
vector<MemClass> v;
v.push_back(MemClass(1));
v.push_back(MemClass(2));
v.push_back(MemClass(3));
for_each(v.begin(), v.end(), boost::mem_fn(&MemClass::Print));
}
**[[boost::lexical_cast:http://boost.cppll.jp/HEAD/libs/conversion/lexical_cast.htm]] [#p7255647]
#include<boost/lexical_cast.hpp>
文字列と値の変換を行う.C言語のitoaとかと同じ.
double x = 0.0;
std::string str;
str = boost::lexical_cast<std::string>(x);
x = boost::lexical_cast<double>(str);
**[[boost::format:http://boost.cppll.jp/HEAD/libs/format/doc/format.html]] [#r2099d1c]
#include<boost/format.hpp>
printfに似たような感じの書式化処理をする.
cout << boost::format("i : %1% - x=%2%, str=%3%") % 1 % 15.0 % "rml";
formatではformatオブジェクト(フォーマッタ)にオペレータ"%" で変数を食わせるため,
boost::format frmt("i : %1% - x=%2%, str=%3%");
frmt % 1;
frmt % 15.0;
frmt % "rml";
でも可.std::stringではき出したい場合は,メンバ関数str()かboost::ioのstr(const format&)を用いる.
std::string str;
str = frmt.str();
str = boost::io::str(frmt);
フォーマッタに別の変数を食わせる場合は,そのまま,
frmt % 2;
frmt % 20.0;
frmt % "rml2";
と続ける.
書式指定に%1%,%2%・・・を用いる場合は並べ替えが可能.
cout << boost::format("%2%, %1%, %3%, %1%") % 1 % 2 % 3;
出力は 2, 1, 3, 1 となる.並び替えが必要でないなら従来のprintf通りの書式指定を用いることもできる.
cout << boost::format("%d, %s, %3.1f") % 1 % "2" % 3.0;
出力は 1, 2, 3.0 .
**[[boost::function:http://boost.cppll.jp/HEAD/doc/html/function.html]] [#wa1babb8]
#include<boost/function.hpp>
汎用関数オブジェクト.関数ポインタも関数オブジェクトも両方とも格納できる.
class FuncClass
{
public:
FuncClass(int i, int j) : a(i), b(j) {}
double Dot(int x, int y){ return sqrt((double)(a*x+b*y)); }
int a, b;
};
struct FuncObject
{
double operator()(int x, int y){ return sqrt((double)(x*x+y*y)); }
};
double Func(int x, int y)
{
return sqrt((double)(x*x+y*y));
}
とあった場合,関数ポインタ(Func(int x, int y))では,
boost::function<double (int, int)> length = &Func;
cout << boost::format("length = %f\n") % length(1, 2);
で出力は,length = 2.236068 となる.function<double (int, int)>でdoubleが返値,(int, int)が引数を表している.コンパイラによっては,function2<double, int, int> と書かなければならないかも.
関数オブジェクト(FuncObject)は,
length = FuncObject();
cout << boost::format("length = %f\n") % length(2, 3);
出力は,length = 3.605551 となる.
クラスのメンバ関数を渡すときは,std::mem_fun と std::bind1st あたりを用いることができるが,ここでは2変数をとっているので boost::bind を用いる.
FuncClass obj(3, 4);
length = boost::bind(&FuncClass::Dot, boost::ref(obj), _1, _2);
cout << boost::format("length = %f\n") % length(3, 4);
出力は,length = 5.000000 となる.
**[[boost::xpressive:http://www.boost.org/doc/libs/1_46_1/doc/html/xpressive.html]] [#p558cb31]
#include <boost/xpressive/xpressive.hpp>
正規表現クラス.boost::regexと違ってlibファイルは必要ない.
#code(C){{
/*!
* 正規表現に文字列がマッチするかどうかテスト
* @param[in] str 文字列
* @param[in] reg_str 正規表現
* @return マッチしたらtrue
*/
static bool Match(const string &str, const string ®_str)
{
using namespace boost::xpressive;
sregex reg = sregex::compile(reg_str);
smatch m;
if(regex_search(str, m, reg)){
return (m.str() == str);
}
else{
return false;
}
}
/*!
* 正規表現に文字列がマッチするかどうかテスト
* @param[in] str 文字列
* @param[in] reg_str 正規表現
* @param[out] mch マッチした部分文字列
* @return マッチしたらtrue
*/
static bool Match2(const string &str, const string ®_str, vector<string> &mch)
{
using namespace boost::xpressive;
sregex reg = sregex::compile(reg_str);
smatch m;
if(regex_search(str, m, reg)){
mch.resize(m.size());
for(int i = 0; i < (int)mch.size(); ++i){
mch[i] = m[i];
}
return (m.str() == str);
}
else{
return false;
}
}
}}
**[[boost::random:http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html]] [#z7d4f86e]
#include <boost/random.hpp>
様々な乱数を生成する.以下は[[メルセンヌツイスタ:http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.html]]で正規乱数,定分布乱数を生成するジェネレータの例.
#code(C){{
typedef boost::variate_generator< boost::mt19937, boost::uniform_real<> > rxRandMtUni;
typedef boost::variate_generator< boost::mt19937, boost::normal_distribution<> > rxRandMtGen;
/*!
* 「メルセンヌツイスター」(Seed=現在時刻) で「正規乱数」を生成するジェネレータを返す
* @param[in] _min 乱数の最小値
* @param[in] _max 乱数の最大値
* @return 「メルセンヌツイスター」(Seed=現在時刻) で「正規乱数」を生成するジェネレータ
*/
inline rxRandMtGen GenRandomGenerator(const double &_min, const double &_max)
{
boost::mt19937 gen0(static_cast<unsigned long>(time(0)));
//boost::uniform_real<> dst0(_min, _max);
boost::normal_distribution<> dst0(0, 0.01);
rxRandMtGen rand0(gen0, dst0);
return rand0;
}
/*!
* 「メルセンヌツイスター」(Seed=現在時刻) で「定分布乱数」を生成するジェネレータを返す
* @param[in] _min 乱数の最小値
* @param[in] _max 乱数の最大値
* @return 「メルセンヌツイスター」(Seed=現在時刻) で乱数を生成するジェネレータ
*/
inline rxRandMtUni GenRandomGeneratorMtUni(const double &_min, const double &_max)
{
boost::mt19937 gen0(static_cast<unsigned long>(time(0)));
boost::uniform_real<> dst0(_min, _max);
rxRandMtUni rand0(gen0, dst0);
return rand0;
}
}}
使うときは,
rxRandMtGen rand = GenRandomGenerator(0.0, 1.0);
for(int i = 0; i < 100; ++i){
cout << rand() << endl;
}
など.
**[[boost::iostreams:http://www.boost.org/doc/libs/1_46_1/libs/iostreams/doc/index.html]] [#kd91bd0d]
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/operations.hpp>
など.
オリジナルのストリームを作成することができる.
#code(C){{
//! テキストストリーム - コマンドプロンプトに表示すると共にログファイルにも保存
class rxCout : public boost::iostreams::sink
{
string m_strLog;
public:
rxCout(string fn)
{
m_strLog = fn;
}
std::streamsize write(const char* s, std::streamsize n)
{
string str;//=s;
str.resize(n);
for(int i = 0; i < n; ++i){
str[i] = s[i];
}
cout << str;
boost::algorithm::replace_all(str, "\n", "");
static std::ofstream fsOut(m_strLog, std::ios::out);
fsOut << str << endl;
return n;
}
};
static boost::iostreams::stream<rxCout> RXCOUT("test.log");
//#define RXCOUT std::cout
//! ファイルへのテキストストリーム
class rxCoutFile : public boost::iostreams::sink
{
//std::ofstream m_fsOut0;
public:
rxCoutFile(bool enable)
{
//m_fsOut.open("log/sph.log", std::ios::out);
}
std::streamsize write(const char* s, std::streamsize n)
{
string str;//=s;
str.resize(n);
for(int i = 0; i < n; ++i){
str[i] = s[i];
}
boost::algorithm::replace_all(str, "\n", "");
static std::ofstream fsOut("log/sph.log", std::ios::out);
fsOut << str << endl;
return n;
}
};
static boost::iostreams::stream<rxCoutFile> RXFOUT(true);
}}
例のRXCOUTをcoutの代わりに使うことで出力内容を画面に表示すると共にファイルにも保存することができる.
**boost::filesystem [#rc01b152]
***v3での変更点 [#t6e4843c]
-1バイト文字のpathと2バイト文字のwpathを,一つのクラスpathに統合.
-pathクラスの新しいメンバ関数
--[[has_stem():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-has_stem]] :
ファイル名の最初から最後の"."までを抜き出したもの([[stem():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-stem]]参照)がempty()ならfalseを返す.
--[[has_extension():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-has_extension]] :
ファイル名に拡張子があればtrue, なければfalseを返す.
--[[is_absolute():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-is_absolute]] :
絶対パスならtrue, 相対パスならfalseを返す.(同じ機能であったis_complete()は廃止)
--[[is_relative():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-is_relative]] :
is_absolute()の逆.
--[[make_preferred():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#path-make_preferred]] :
パス文字列を使用している環境でのネイティブフォーマットに変換したものを返す.
Windowsなら"/"(スラッシュ)はすべて"\"(バックスラッシュ or 円マーク)に置き換えられる.
-boost::filesytem関数の変更,新規追加
--[[absolute():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#absolute]] :
絶対パスに変換.complete()を置き換える関数.
--[[create_symlink():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#create_symlink]] :
シンボリックリンクを生成する関数.POSIXとWindows両方をサポートするようになった.
--[[read_symlink():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#read_symlink]] :
新規追加関数.シンボリックリンクの本体のパスを返す.
--[[resize_file():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#resize_file]] :
新規追加関数.ファイルサイズ変更.
--[[unique_path():http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#unique_path]] :
新規追加関数.一時ファイル用のランダムなファイル名を生成する.
たとえば,引数にpath("%%%%-%%%%")と指定すると"c463-8e59"のような0-9,a-fで構成されたファイル名が生成される.
詳しくは[[Boost Filesystem Version 3 - Introduction:http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/v3.html]].
*Visual C++でのインストール [#n289f7ea]
#include(build_boost,notitle)
*リンク [#te9e6f40]
-[[Boost C++ Libraries:http://boost.cppll.jp/HEAD/]]
-[[Let's Boost:http://www.kmonos.net/alang/boost/]]