Boost C++ライブラリ
Boost (ブースト)とは、C++の開発者のコミュニティ、およびそのコミュニティによって公開されているオープンソースのソフトウェアライブラリのことを指す。 概要コミュニティとしてのBoostはC++標準化委員会の委員により設立されており、現在でもその多くが構成員として留まっている。このような経緯もあり、BoostコミュニティはC++の標準化において大きな影響力を有している。実際に標準化委員会が発表した「TR1」の2/3以上がBoostライブラリを基にしている。Random, Regex, ThreadなどはいずれもC++11規格の標準ライブラリとして正式に導入・標準化されている。その後もOptionalやAnyなどがC++17規格で導入されており、影響を与え続けている。このことから、Boostは考案された新機能を標準化させる前の試験運用の場であるとも言える。 Boostで公開されるライブラリはコミュニティの公開レビューによって精選されている。Boostを使用して作成したプログラムは、商用、非商用を問わず無償のBoost Software Licenseの下でライセンスされる。 Boostはテンプレートなどを活用して積極的にメタプログラミングやジェネリックプログラミングの技法を取り入れて行く傾向がある。そのためBoostライブラリの利用者にはC++の現代的な記述に慣れていることを要求される。 内容Boostには次のような分野のライブラリが含まれている。ヘッダーをインクルードするだけで使えるクラステンプレートや関数テンプレートが多いが、ライブラリの一部はビルドが必要。
線型代数Boostには、BLASのレベル1、2、3の各演算を実装したuBLASという線型代数 (linear algebra) ライブラリがある。
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace boost::numeric::ublas;
/* "y = Ax" example */
int main()
{
vector<double> x(2);
x(0) = 1; x(1) = 2;
matrix<double> A(2,2);
A(0,0) = 0; A(0,1) = 1;
A(1,0) = 2; A(1,1) = 3;
vector<double> y = prod(A, x);
std::cout << y << std::endl;
return 0;
}
乱数生成Boost.Random - 分布(ディストリビューション)非依存の擬似乱数生成器 (PRNG) と、具体的な生成器を構築するために組み合わせる疑似乱数に依存しない確率分布を提供する。
#include <boost/random.hpp>
#include <boost/random/random_device.hpp>
double SampleNormal(double mean, double sigma)
{
// 非決定論的な乱数生成器をシードに使用。
boost::random::random_device seed_gen;
// メルセンヌ・ツイスタ乱数生成器の作成。
typedef boost::random::mt19937 MyGenerator;
MyGenerator rand_gen(seed_gen);
// ガウス確率分布を選択。
typedef boost::random::normal_distribution<double> MyDistribution;
MyDistribution dist(mean, sigma);
// 関数の形で乱数生成器を分布にバインドする。
boost::random::variate_generator<MyGenerator&, MyDistribution> sampler(rand_gen, dist);
// 分布からサンプルする。
return sampler();
}
詳細はBoost Random Number Libraryを参照。 Boost.RandomのサブセットがC++11の標準ライブラリとして取り込まれた。 テキストのパースBoost.Spirit - バッカス・ナウア記法に出来るだけ近いC++のプログラム形式で直接パーサを記述するという、Boostにおける最も複雑なライブラリのひとつ。
#include <boost/spirit/core.hpp>
#include <boost/spirit/actor/push_back_actor.hpp>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
using namespace boost::spirit;
// Parser comma-separated numbers
bool parse_numbers(const char* str, vector<double>& v)
{
return parse(str,
// Start grammar
(
real_p[push_back_a(v)] >> *(',' >> real_p[push_back_a(v)])
)
,
// End grammar
space_p).full;
}
詳細は Spirit User's Guide を参照。 正規表現の利用Boost.Regex - 正規表現を利用するライブラリ。フィルタ・検索・パース・テキスト処理に必要な各種関数を持っている。 正規表現の種類としてPCRE、POSIX基本正規表現とPOSIX拡張正規表現が利用可能である。
#include <boost/regex.hpp>
#include <vector>
#include <string>
// Example program parsing the URL
int main(int argc, char** argv)
{
// Check the number of parameters
if (argc < 2) return 0;
// container for the values
std::vector<std::string> values;
// Expression to parse
boost::regex expression(
// proto host port
"^(\?:([^:/\?#]+)://)\?(\\w+[^/\?#:]*)(\?::(\\d+))\?"
// path file parameters
"(/\?(\?:[^\?#/]*/)*)\?([^\?#]*)\?(\\\?(.*))\?"
);
// The formation of the source string to parse (taken from command-line)
std::string src(argv[1]);
// Parse and filling the container
if (boost::regex_split(std::back_inserter(values), src, expression)) {
// Output the result
const char* names[] = {"Protocol", "Host", "Port", "Path", "File", "Parameters", NULL};
for (int i = 0; names[i]; i++)
printf("%s: %s\n", names[i], values[i].c_str());
}
return 0;
}
詳細は Boost.Regex を参照。 Boost.RegexのサブセットがC++11の標準ライブラリとして取り込まれた。 動的な正規表現と静的な正規表現Boost.Xpressiveは、動的な正規表現と静的な正規表現を提供する。 以下のプログラムは「私は2052/10/30に生まれた。」という文字列に対し、年月日を抽出する正規表現である。どちらも出力結果は同じである。 動的な正規表現#include <iostream>
#include <string>
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
int main()
{
// 従来の char[] 型の文字列リテラルの内部表現は処理系依存であり、Shift_JIS の 0x5c など、場合によっては問題を引き起こす可能性があるため、UTF-8 文字列リテラルを使用するべき。
// しかし C++20 以降は UTF-8 文字列リテラルの型が char8_t[] 型になるため、明示的なキャストが必要。
// また、Microsoft Visual C++ 環境ではデフォルトで UTF-8 文字列をコンソールに出力できない。
std::string str = "私は2052/10/30に生まれた。";
sregex rx = sregex::compile(R"((\d{1,4})/(\d{1,2})/(\d{1,2}))");
smatch m;
if (regex_search(str, m, rx)) {
// ここでは range-based for 構文を使っているので、C++11 以降に対応したコンパイラが必要。
for (const auto& e : m) {
std::cout << e << std::endl;
}
}
}
静的な正規表現#include <iostream>
#include <string>
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
int main()
{
std::string str = "私は2052/10/30に生まれた。";
mark_tag years(1), month(2), days(3);
sregex rx =
(years = repeat<1, 4>(_d)) >> '/' >>
(month = repeat<1, 2>(_d)) >> '/' >>
(days = repeat<1, 2>(_d));
smatch m;
if (regex_search(str, m, rx)) {
std::cout << m[0] << std::endl;
std::cout << m[years] << std::endl;
std::cout << m[month] << std::endl;
std::cout << m[days] << std::endl;
}
}
グラフのアルゴリズムBoost.Graph - グラフ理論の複数の視点および多数のアルゴリズムの形で、グラフ概念の柔軟かつ効果的な実装を提供する。
#include <iostream>
#include <list>
#include <algorithm>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <iterator>
#include <utility>
int main()
{
using namespace boost;
// Type of graph
typedef adjacency_list<vecS, vecS, directedS,
property<vertex_color_t, default_color_type> > Graph;
// Handle vertices
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
// Container for the chain of vertices
typedef std::vector<Vertex> container;
// Type of representation of arcs
typedef std::pair<std::size_t,std::size_t> Pair;
// Edges of the graph
Pair edges[6] = {
Pair(0,1), Pair(2,4),
Pair(2,5),
Pair(0,3), Pair(1,4),
Pair(4,3)
};
// Count
Graph G(edges, edges + 6, 6);
// Dictionary to get a handle on the numbers of vertices vertices
boost::property_map<Graph, vertex_index_t>::type id = get(vertex_index, G);
// Container for storing the sorted vertices
container c;
// Execute algorithm
topological_sort(G, std::back_inserter(c));
// Output results: sorting descriptors of the graph in the container,
// Get the serial number of vertices
std::cout << "Topological check:";
for (container::reverse_iterator ii = c.rbegin(); ii != c.rend(); ++ii)
std::cout << id[*ii] << " ";
std::cout << std::endl;
return 0;
}
詳細は The Boost Graph Library を参照。 マルチスレッドBoost.Thread - プラットフォームに依存しないスレッドの抽象化を提供する。APIはPOSIXスレッドをベースにオブジェクト指向化したものとなっている。
#include <boost/thread/thread.hpp>
#include <iostream>
void hello_world()
{
std::cout << "Hello world, I'm a thread!" << std::endl;
}
int main()
{
// hello_world関数を呼び出す新しいスレッドを起動する。
boost::thread my_thread(&hello_world);
// スレッドが終了するまで待つ。
my_thread.join();
return 0;
}
Boost.ThreadのサブセットがC++11の標準ライブラリとして取り込まれた。
脚注
外部リンク
|
Portal di Ensiklopedia Dunia