にゃははー

はへらー

bjam AdC jp 2011 11日目

はいはいーすすめます。

sequenceモジュール

Boost 1.48.0時点でのsequenceモジュールのrule一覧です。

rule filter ( predicate + : sequence * )
rule transform ( function + : sequence * )
rule reverse ( s * )
rule less ( a b )
rule insertion-sort ( s * : ordered * )
rule merge ( s1 * : s2 * : ordered * )
rule join ( s * : joint ? )
rule length ( s * )
rule unique ( list * : stable ? )
rule max-element ( elements + : ordered ? )
rule select-highest-ranked ( elements * : ranks * )

はいー。いろいろあります。名前からして大体理解できると思うので、いくつか例を出せばまぁ他のも使えるでしょう。

そもそもsequenceってなんですか

sequenceとはスペースで区切られた任意の文字列です。文字列リテラルではないです。(多分この説明で合ってるような...

e.g.

hoge fuga piyo

  hoge
  fuga
  piyo
という3要素からなるsequence
"hoge fuga piyo"

  "hoge fuga piyo"
という1要素からなるsequence

間違えないように。

ちなみにruleの引数もsequenceをコロンで区切っているものです。ここらへんに付いては次回説明しましょう!(やったネタできた!

直接sequenceを渡す系

reverse/less/join/length/unique/max-elementは基本的にsequenceを投げると一定の処理をするruleです。内容は名前から解ると思います。lessのみbinary functionなので気をつけてください。

多分uniqueが一番使うんじゃないんでしょうか。こんな感じです

import sequence ;
ECHO [ sequence.unique hoge fuga piyo hoge ] ;

出力が

fuga hoge piyo

でした。unique ruleの場合、stableに何かtrueになるもの渡せばstableなものになるようです。

まぁそんな感じでこいつらは楽です。

高階関数になってるやつ

filter/transform/insertion_sort/mergeは高階関数になっているのでまとめます。

高階関数ということはruleかactionsかクラスか渡すような気がしますが、これはruleを渡すことになります。何か特別な構文があるわけでもなく単にrule名を渡すだけです。transformは変換した値を返すだけで問題ないです。

transform以外はpredicateを要求しています。ところがbjamでpredicateの扱いは面倒です。例えば以下の例

rule always-false1 ( )
{
	return false ;
}

if [ always-false1 ]
{
	ECHO "true !!" ;
}

は多くの人の予想に反して

true !!

と表示されます。

predicateの場合、conditionがfalseになるようなものを返さないといけないのですが、bjamにおいて任意のトークンはすべてtrueとして評価されます。もちろん 0 や no 、大文字であろうとです。
では、どうやってfalseにするかですが、これはruleで何も返さないことでできます。もしくは空の変数を返すことで実現できます。

rule always-false2 ( )
{
}

if [ always-false2 ]
{
	ECHO "true !!" ;
}

rule always-false3 ( )
{
	local false = ;
	return $(false) ;
}

if [ always-false3 ]
{
	ECHO "true !!" ;
}

これらはすべて false として評価されます。

ということでfilterを例にとってみます。

import sequence ;
rule is_hoge ( val )
{
	if $(val) = hoge
	{
		return true ;
	}
}

ECHO [ sequence.filter is_hoge : hoge fuga piyo hoge ] ;

結果は

hoge hoge

となります。

それぞれ渡すruleは、filterはunary predicate、insertion_sort/mergeはbinary predicate、transformはunary functionです。

select-highest-ranked rule

こいつ面倒なんでこれだけで1回分作っていいですか...ネタ無いので...

まとめ

sequenceはbjamでかなり重要なものです。扱えるようになっくといいです。
あ、いい忘れてましたけどsequenceのランダムアクセスは

seq = hoge fuga piyo ;
ECHO $(seq[0]) ; # => hoge
ECHO $(seq[1]) ; # => hoge
ECHO $(seq[2]) ; # => fuga
ECHO $(seq[3]) ; # => piyo
ECHO $(seq[4]) ; # =>

1-origです。存在しないところを参照するとなにも帰ってきません。conditionでfalseになるやつです。
あと

seq = hoge fuga piyo ;
ECHO $(seq[2-]) ; # => fuga piyo
ECHO $(seq[-3]) ; # => hoge
ECHO $(seq[2-3]) ; # => fuga piyo

とかあります。真ん中は範囲ではなく負のindexとして扱われてる点に注意です。

まとめ部分が重要だった気がしましたが気のせいです。今日だけでネタが2つできたので今日は安心して寝れます。