Hatena::ブログ(Diary)

C++でゲームプログラミング Twitter

2010-09-09

range の定義

この条件を満たしていれば、基本的に使用できる。

例)

int array[] = {0, 1, 2, 3, 4, 5};   // 配列型なので、OK
int* p = array;                     // ポインタ型なので、NG

std::vector<int> vec;               // 必要なメンバを持っているので、OK
std::pair<
    std::vector<int>::iterator,
    std::vector<int>::iterator
> pair = std::make_pair(vec.begin(), vec.end()); // iterator 型を保持してるので、OK

struct my_array_{
    int array[5];
} my_array;                         // メンバがないので、NG

struct my_array_ex_{
    int array[5];
    typedef int* iterator;
    typedef const int* const_iterator;
    iterator begin(){ return &array[0]; };
    iterator end(){ return &array[5]; };
    const_iterator begin() const{ return &array[0]; };
    const_iterator end() const{ return &array[5]; };
} my_array_ex;                     // 必要なメンバを持っているので、OK

boost::range 機能一覧

使った機能の覚書。

間違いや分かりづらい部分があったらツッコミをお願いします。


[boost]

ver 1.44.0

Chapter 1. Range 2.0


boost::adaptors::transformed

range を走査する際に、操作を行う

#include <boost/range/algorithm/transform.hpp>
int to_double(int n){
    return n + n;
}

int array[] = {0, 1, 2, 3, 4};
array|boost::adaptors::transformed(to_double); // to_doble を返しての値を返す
// こう書くことも出来る
boost::adaptors::transform(array, to_double);

boost::random_shuffle(range)

range の中身をランダムで入れ替える。

#include <boost/range/algorithm/random_shuffle.hpp>

int array[] = {0, 1, 2, 3, 4};
boost::random_shuffle(array); // array == {4, 1, 3, 2, 0}

繰り返し使用する場合は、std::srand で乱数の種を設定する。

#include <ctime>
#include <boost/range/algorithm/random_shuffle.hpp>

std::srand( unsigned (std::time(NULL)) );  // 時間を種とする

int array[] = {0, 1, 2, 3, 4};
boost::random_shuffle(array); // 実行時によって変わる

boost::count(range, value)

range 内の value に等しい数を返す

#include <boost/range/algorithm/count.hpp>

int array[] = {0, 0, 0, 1, 2, 3};
assert(boost::count(array, 0) == 3); // 0 の数を数える

boost::count_if(range, func)

func(value_t) == true の数を返す

#include <boost/range/algorithm/count_if.hpp>

// 偶数の数を計算
int array[] = {0, 1, 2, 3, 4, 5};
assert(boost::count_if(array, [](int n)->bool{return n % 2 == 0;}) == 3);

boost::join(range1, range2)

range1 と range2 を結合した range を返す

int array1[] = {0, 1, 2};
int array2[] = {3, 4, 5};
boost::join(array1, array2); // {0, 1, 2, 3, 4, 5}

boost::adaptors::filter(range, func)

func(value_t) == true の要素だけを抽出した range を返す

#include <boost/range/adaptor/filtered.hpp>

using boost::adaptors::filtered;

// 偶数だけを抽出
int array[] = {0, 1, 2, 3, 4, 5};
filter(array, [](int n)->bool{return n % 2 == 0;});  // {0, 2, 4}
array|filtered([](int n)->bool{return n % 2 == 0;}); // こうも書ける

boost::adaptors::slice(range, n, m)

n 〜 m の間の range を返す。

#include <boost/range/adaptor/sliced.hpp>

int array[] = {0, 1, 2, 3, 4, 5};
boost::adaptors::slice(array, 1, 5);	// {1, 2, 3, 4}
array|boost::adaptors::sliced(1, 5);	// こう書くことも出来る

boost::irange(n, m, step)

基本的に boost::counting_range と同じ。

詳細はこっちを見てね。


boost::counting_range(n, m)

n〜mの間の range を返す

※mは含まれない

boost::irange と同じ動作。

#include <boost/range/counting_range.hpp>

boost::counting_range(0, 5); // {0, 1, 2, 3, 4}

boost::distance(range)

range の長さを返す。

#include <boost/range/as_array.hpp>

int array[] = {0, 1, 2, 3, 4, 5};
assert(boost::distance(array) == 6);

pstade::oven 機能一覧

基本的に、pstade::oven にしかない機能のみ抜粋。


[pstade]

ver 1.04.3

http://p-stade.sourceforge.net/oven/doc/html/index.html


pstade::oven::steps(n)

iterator を移動する際のステップ数を設定。

#include <pstade/oven/steps.hpp>

int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
array|pstade::oven::steps(2);  // {0, 2, 4, 6, 8}

pstade::oven::concatenated

2次元配列を1次元配列の range にして返す。

#include <pstade/oven/concatenated.hpp>

int array[3][3] = {
    {0, 1, 2},
    {3, 4, 5},
    {6, 7, 8}
};
array|oven::concatenated;  // {0, 1, 2, 3, 4, 5, 6, 7, 8}

pstade::oven::rows(height, width)

pstade::oven::rows(height, width) は、range を2次元配列のような形にして返します。

#include <pstade/oven/matrix.hpp>

int array[] = {
    0, 1, 2,
    3, 4, 5
};
array|oven::rows(2, 3); // { {0, 1, 2}, {3, 4, 5} }

pstade::oven::at(n)

n 番目の要素を返します。

#include <pstade/oven/at.hpp>

int array[] = {0, 1, 2, 3, 4};
assert( (array|oven::at(3)) == array[3] );

pstade::oven::copied

他のコンテナ型へ代入可能な range を返すアダプタです。

#include <pstade/oven/copied.hpp>

int    array[] = {0, 1, 2, 3, 4};

std::vector<int> array2 = array|oven::copied;
std::list<int>     array3 = array|oven::copied;

assert( boost::equal(array2, array3) );

std::string へ代入する方法。


pstade/oven/io.hpp

range の標準出力を行ないます。

#include <pstade/oven/io.hpp>

int array[] = {0, 1, 2, 3, 4};
std::cout << oven::make_iter_range(array) << std::endl;

[出力]

{0,1,2,3,4}

pstade::oven::cycled(n)

range を引数の回数分展開するアダプタです。

#include <pstade/oven/cycled.hpp>
int array[] = {0, 1, 2};
array|oven::cycled(3);    // {0, 1, 2, 0, 1, 2, 0, 1, 2}

pstade::oven::zipped

tuple<range<T1>, range<T2> > を range<tuple<T1, T2> > の様な形に変換を行うアダプタ。

#include <pstade/oven/zipped.hpp>

int  array1[] = {0, 1, 2, 3, 4};
char array2[] = {'a', 'b', 'c', 'd', 'e'};

boost::make_tuple(array1, array2);              // ({0,1,2,3,4} {a,b,c,d,e})
boost::make_tuple(array1, array2)|oven::zipped; // {(0 a),(1 b),(2 c),(3 d),(4 e)}

pstade::oven::any_range

あらゆる range を格納することが出来る範囲型。

#include <pstade/oven/any_range.hpp>

int array[] = {0, 1, 2, 3, 4};

// 保持する値の型と iterator のタイプを指定する
oven::any_range<int, boost::forward_traversal_tag>
    range = array|oven::transformed(lambda::_1 + lambda::_1);
std::cout << range << std::endl;

pstade::oven::initial_values

range の初期化を行います。

#include <pstade/oven/initial_values.hpp>
std::vector<int> array = oven::initial_values(0, 1, 2, 3, 4);
array;    // {0, 1, 2, 3, 4}

pstade::oven::window(n, m)

begin(range)+n〜begin(range)+m の範囲を返すアダプタです。

#include <pstade/oven/window.hpp>

int array[] = {0, 1, 2, 3, 4, 5, 6};
array|oven::window(1, 5);    // {1, 2, 3, 4}

pstade::oven::offset(n, m)

begin(range)+n〜end(range)+m の範囲を返すアダプタです。

#include <pstade/oven/offset.hpp>

int array[] = {0, 1, 2, 3, 4, 5, 6};
array|oven::offset(1, -2);    // {1, 2, 3, 4}

pstade::oven::dropped(n)

pstade::oven::dropped(n) は、range の先頭から n 個分の要素を取り除いた range を返すアダプタです。

#include <pstade/oven/dropped.hpp>

int array[] = {0, 1, 2, 3, 4, 5, 6, 7};
array|pstade::oven::dropped(3);   / {3,4,5,6,7}

pstade::oven::single(x)

pstade::oven::single(x) は、x を range にして返します。

#include <pstade/oven/single.hpp>

boost::equal(oven::single('F'), std::string("F"));