For Development HEAD DRAFTSearch (procedure/syntax/module):

6.13 ベクタの仲間

ベクタは固定長でO(1)アクセス可能な値の並びです。 Schemeは伝統的に、任意の値を格納できるベクタを提供してきました。 これはベクタで説明されます。

R7RS-largeでは、均質な数値型だけを効率よく格納できるベクタ(uvector)も定義されています。 ユニフォームベクタを見てください。

Gaucheはまた、ビット列を格納するビットベクタも提供します。 ビットベクタで説明します。

最後に、weakベクタは任意の要素をweakポインタを使って格納できるベクタです。 Weakベクタ参照。


6.13.1 ベクタ

Builtin Class: <vector>

ベクタはSchemeオブジェクトの単純な一次元配列です。 インデックスを用いて定数時間でその要素にアクセスできます。 一度作成されたベクタはその大きさを変えることはできません。

<vector>クラスはまた<sequence>クラスを継承し、 mapfoldなど様々な総称関数を使うことができます。 gauche.collection - コレクションフレームワークgauche.sequence - シーケンスフレームワーク を参照して下さい。

数値しか要素に持たないベクタを使う場合、 ユニフォームベクタも使えるかもしれません (ユニフォームベクタ参照)。

R7RSはバイトベクタを定義しています。Gaucheではそれは単に gauche.uvectorモジュールのu8vectorです (R7RSモジュールは別名を定義しています。scheme.base - R7RS基本ライブラリ参照。)

より多くのベクタに対する操作がscheme.vector - R7RSベクタで提供されています。

Function: vector? obj

[R7RS base] objがベクタなら#tを、そうでなければ#fを返します。

Function: make-vector k :optional fill

[R7RS base] 長さkのベクタを作成して返します。 省略可能な引数fillが与えられていれば、ベクタの各要素はその値で 初期化されます。そうでなければベクタの各要素の値は不定です。

Function: vector obj …

[R7RS base] 要素がobj …であるようなベクタを作成して返します。

Function: vector-tabulate len proc

長さlenのベクタを作成し、0以上len未満のiについて i番目の要素を(proc i)の値で初期化します。

(vector-tabulate 5 (^x (* x x)))
  ⇒ #(0 1 4 9 16)
Function: vector-length vector

[R7RS base] ベクタvectorの長さを返します。

gauche.collectionモジュールをロードしていれば、 メソッドsize-ofも同じ目的で使えます。

Function: vector-ref vector k :optional fallback

[R7RS+ base] ベクタvectork番目の要素を返します。

vector-refkが負の値であったりベクタの長さより 大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback が与えられている場合はその値が返されます。これはGaucheの拡張です。

gauche.sequenceモジュールをロードしていれば、 メソッドrefも同じ目的で使えます。

Function: vector-set! vector k obj

[R7RS base] ベクタvectork番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。

gauche.sequenceモジュールをロードしていれば、 メソッドrefのsetterメソッドも使えます。

Function: vector->list vector :optional start end
Function: list->vector list :optional start end

[R7RS+ base] ベクタをリストに変換したり、その逆を行う手続きです。

省略可能な引数startendを与えることにより、 値を取り出す範囲を制限することができます。 (R7RSのlist->vectorstartend引数を規定していません。)

(vector->list '#(1 2 3 4 5))     ⇒ (1 2 3 4 5)
(list->vector '(1 2 3 4 5))      ⇒ #(1 2 3 4 5)
(vector->list '#(1 2 3 4 5) 2 4) ⇒ (3 4)
(list->vector (circular-list 'a 'b 'c) 1 6)
  ⇒ #(b c a b c)

gauche.collectionモジュールをロードしていれば、 (coerce-to <list> vector)(coerce-to <vector> list) も同じ目的で使えます。

Function: reverse-list->vector list :optional start end

[R7RS vector] 省略可能引数が無い場合、 (list->vector (reverse list))と同じ結果を返しますが、 中間リストを作りません。省略可能引数startおよびendが 与えられた場合は、それはlistの範囲を指定します。

(reverse-list->vector '(a b c d e f g) 1 5)
  ⇒ #(e d c b)
Function: vector->string vector :optional start end
Function: string->vector string :optional start end

[R7RS base] 文字のベクタを文字列に変換したり、その逆を行う手続きです。 vector->stringに、文字以外の要素を含むベクタを渡した場合はエラーになります。

省略可能な引数startendを与えることにより、 値を取り出す範囲を制限することができます。

(vector->string '#(#\a #\b #\c #\d #\e))     ⇒ "abcde"
(string->vector "abcde")                     ⇒ #(#\a #\b #\c #\d #\e)
(vector->string '#(#\a #\b #\c #\d #\e) 2 4) ⇒ ("cd")

gauche.collectionモジュールをロードしていれば、 (coerce-to <string> vector)(coerce-to <vector> string) も同じ目的で使えます。

Function: vector-fill! vector fill :optional start end

[R7RS base] ベクタvectorの全ての要素をfillに変更します。

省略可能な引数startendが与えられた場合、 start番目の要素からend-1番目の要素までのみに fillを格納します。startendの既定値は それぞれ0とvectorの大きさです。

Function: vector-copy vector :optional start end fill

[R7RS base] ベクタvectorをコピーします。引数startendを与えることで コピーされる範囲を制限することができます。 startendで指定される範囲が元のvectorの範囲を越えた 場合は、その部分がfillで埋められます。

(vector-copy '#(1 2 3 4 5))     ⇒ #(1 2 3 4 5)
(vector-copy '#(1 2 3 4 5) 2 4) ⇒ #(3 4)
(vector-copy '#(1 2 3 4 5) 3 7 #f) ⇒ #(4 5 #f #f)
Function: vector-copy! target tstart source :optional sstart send

[R7RS base] ベクタsourceの内容をベクタtargetのインデックスtstart以降に コピーします。targetは変更可能でなければなりません。 省略可能なsstartsend引数はコピー元ベクタの範囲を限定します。

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-copy! v 2 '#(1 2)))
  ⇒ #(a b 1 2 e)
(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-copy! v 2 '#(1 2 3 4) 1 3))
  ⇒ #(a b 2 3 e)

コピーされるデータが、コピー先の領域(tstartから末尾まで)より 大きい場合はエラーが報告されます。

targetsourceに同じベクタを渡しても構いません。 コピー元とコピー先の領域に重なりがある場合でもこの手続きは使えます。

Function: vector-append vec …

[R7RS base] ベクタvecを順に継ぎ足した内容を持つベクタを新たに作成して返します。

(vector-append '#(1 2 3) '#(a b)) ⇒ #(1 2 3 a b)
(vector-append) ⇒ #()
Function: vector-map proc vec1 vec2 …

[R7RS base] ベクタvec1 vec2 …の各i番目の要素にprocを 適用したものをi番目の要素とする新たなベクタを作って返します。 結果のベクタの長さは、引数のベクタのうち最も短いものと同じになります。

(vector-map + '#(1 2 3) '#(4 5 6 7))
 ⇒ #(5 7 9)

procが呼ばれる順番は定義されておらず、将来のバージョンで変わるかもしれないので、 procでは順序に影響されるような副作用を起こしてはいけません。

註: gauche.collectionをuseして (map-to <vector> proc vec1 vec2 …) としても同じ機能は得られます。

Function: vector-map-with-index proc vec1 vec2 …

vector-mapと似ていますが、procの第1引数に 現在のインデックスが渡されます。

(vector-map-with-index list '#(a b c d e) '#(A B C))
 ⇒ #((0 a A) (1 b B) (2 c C))

これがSRFI-43でvector-mapと呼ばれている手続きです。 srfi.43 - ベクタライブラリ(旧式)参照。

註: gauche.collectionをuseして (map-to-with-index <vector> proc vec1 vec2 …) としても同じ機能は得られます。

Function: vector-map! proc vec1 vec2 …

[R7RS vector] 各インデックスiについて、ベクタvec1 vec2 …の i番目の要素を引数としてprocを呼び出した結果、vec1i番目の要素にセットします。ベクタの長さが異なる場合は最も短いベクタ の範囲が計算されます。

(rlet1 v (vector 1 2 3)
  (vector-map! ($ + 1 $) v))
  ⇒ #(2 3 4)

(rlet1 v (vector 1 2 3 4)
  (vector-map! + v '#(10 20)))
  ⇒ #(11 22 3 4)
Function: vector-map-with-index! proc vec1 vec2 …

vector-map!と似ていますが、procの第1引数に 現在のインデックスが渡されます。SRFI-43でvector-map! と定義されているものと同じ動作です (srfi.43 - ベクタライブラリ(旧式)参照)。

(rlet1 v (vector 'a 'b 'c)
  (vector-map-with-index! list v))
  ⇒ #((0 a) (1 b) (2 c))
Function: vector-for-each proc vec1 vec2 …

[R7RS base] 0から渡されたベクタのうち一番短いものの最大のインデックスまでのiについて、 vec1 vec2 …のそれぞれi番目の要素を引数に procを呼び出します。

(vector-for-each print '#(a b c))
 ⇒ prints a, b and c.
Function: vector-for-each-with-index proc vec1 vec2 …

vector-for-eachと似ていますが、procの第1引数に 現在のインデックスが渡されます。

この手続きはSRFI-43のvector-for-eachと等価です。 srfi.43 - ベクタライブラリ(旧式)参照。


6.13.2 ユニフォームベクタ

ユニフォームベクタ、あるいは同質な数値ベクタは、 要素として特定の数値型のみを格納する特別なベクタです。 もともとSRFI-4として導入され、SRFI-160で改訂されたのち、 R7RS largeの一部となりました(scheme.vector.@モジュール)。

@の部分は実際には要素の型を示す以下のタグのいずれかです。

u8

8ビット符号無し整数 - 0から255までの正確な整数。

s8

8ビット符号つき整数 - -128から127までの正確な整数。

u16

16ビット符号無し整数 - 0から65535までの正確な整数。

s16

16ビット符号つき整数 - -32768から32767までの正確な整数。

u32

32ビット符号無し整数 - 0から 2^32 - 1 までの正確な整数。

s32

32ビット符号つき整数 - -(2^31) から 2^31 - 1 までの正確な整数。

u64

64ビット符号無し整数 - 0から 2^64 - 1 までの正確な整数。

s64

64ビット符号つき整数 - -(2^63) から 2^63 - 1 までの正確な整数。

f16

16ビット浮動小数点数(仮数部10ビット、指数部5ビット)で表される非正確な実数

f32

IEEE単精度浮動小数点数で表される非正確な実数

f64

IEEE倍精度浮動小数点数で表される非正確な実数

c32

2つの16ビット浮動小数点数で表される非正確な複素数

c64

2つのIEEE単精度浮動小数点数で表される非正確な複素数

c128

2つのIEEE倍精度浮動小数点数で表される非正確な複素数

通常のベクタではなくユニフォームベクタを使うことにより得られる利点がいくつかあります。 まず、ユニフォームベクタは通常のベクタよりもコンパクトです。 いくつかのオペレーション(特に、Gaucheの拡張仕様であるベクタ上の数値演算)では、 型検査と型変換を個々の要素に対して行わなくても良いため、 極めて効率の良い演算が可能です。さらに、 数値の配列を扱う外部のライブラリとのインタフェースが容易です。 例えば、GaucheのOpenGLバインディングではユニフォームベクタを多用しています。

Gaucheは組み込みではごく基本的な手続きしか提供しませんが、 gauche.uvectorモジュールやscheme.vector.@モジュール (R7RSでは(scheme vector @)ライブラリ)では包括的な操作を提供しています。 gauche.uvector - ユニフォームベクタライブラリおよびscheme.vector.@ - R7RSユニフォームベクタ参照。

uvectorクラス

Abstract Class: <uvector>

ユニフォームベクタクラスのベースクラスです。<sequence>を継承します (gauche.sequence - シーケンスフレームワーク参照)。

Builtin Class: <@vector>

{gauche.uvector} @vectorのクラス。@の部分はuvectorタグ (u8s8、…) です。 <uvector>を継承します。

sequenceプロトコル(gauche.sequence - シーケンスフレームワーク参照)を実装しているので、 数値の並びをcoerce-toを使ってuvectorに変換することができます。 ただし各要素はuvectorの要素として有効な範囲の値でなればなりません。

(use gauche.sequence)
(coerce-to <u8vector> '(1 2 3)) ⇒ #u8(1 2 3)

uvectorリテラル

Reader Syntax: #u8(n …)
Reader Syntax: #s8(n …)
Reader Syntax: #u16(n …)
Reader Syntax: #s16(n …)
Reader Syntax: #u32(n …)
Reader Syntax: #s32(n …)
Reader Syntax: #u64(n …)
Reader Syntax: #s64(n …)
Reader Syntax: #f16(n …)
Reader Syntax: #f32(n …)
Reader Syntax: #f64(n …)
Reader Syntax: #c32(n …)
Reader Syntax: #c64(n …)
Reader Syntax: #c128(n …)

リテラルの単一型のベクタを記述します。

(註: R7RSのバイトベクタはu8vectorと同じで、#u8(…)で表記できます。)

#s8(3 -2 4)
#u32(4154 88357 2 323)
#f32(3.14 0.554525 -3.342)

Gaucheはまた、SRFI-207 (文字列表示のバイトベクタ) 形式の バイトベクタリテラルをサポートします。これは、#u8プレフィクスの後に 文字列リテラルが続くものです。ただしその文字列リテラルには、 ASCII文字か\xNN; (Nは十六進数) でエスケープされたオクテットのみが 許されます。この表記で、バイトベクタをバイトストリングとして自然に扱うことができます。 バイトストリングの操作に関してはsrfi.207 - 文字列表示のバイトベクタを参照してください。

#u8"ABC\x00;D" ⇒ #u8(65 66 67 0 68)

uvectorのコンストラクタ

Function: make-s8vector len :optional fill
Function: make-s8vector len :optional fill
Function: make-u8vector len :optional fill
Function: make-s16vector len :optional fill
Function: make-u16vector len :optional fill
Function: make-s32vector len :optional fill
Function: make-u32vector len :optional fill
Function: make-s64vector len :optional fill
Function: make-u64vector len :optional fill
Function: make-f16vector len :optional fill
Function: make-f32vector len :optional fill
Function: make-f64vector len :optional fill
Function: make-c32vector len :optional fill
Function: make-c64vector len :optional fill
Function: make-c128vector len :optional fill

[R7RS vector.@] 長さlenの@vectorを作成して返します。各要素はfillで 初期化されます。正確な整数のベクタに対しては、fillは正確な整数でなければならず、 また有効な範囲内の値でなければなりません。 fillが省略された場合、各要素の初期値は不定です。

(make-u8vector 4 0) ⇒ #u8(0 0 0 0)

uvectorのジェネリックな操作

Function: uvector? obj

objがユニフォームベクタのいずれかなら#tを、 そうでなければ#fを返します。 特定の型のuvectorを検査する述語については後で説明します。

Function: uvector-length uv

uvectoruvの長さ(要素数)を返します。 uvがuvectorでなければエラーを投げます。

特定の型のuvectorの長さを取る手続きは、scheme.vector.@および gauche.uvectorにあります (gauche.uvector - ユニフォームベクタライブラリ参照)。

uvectorの内容がバイナリデータとして占有する大きさを知りたければ、 gauche.uvectoruvector-sizeが使えます。

Function: uvector-ref uv k :optional fallback

汎用的なuvectorのアクセサです。uvector uvk番目の 要素を返します。kが範囲外の場合、fallbackが与えられていればそれが 返され、そうでなければエラーが投げられます。

この手続きは様々な種類のユニフォームベクタに対して動作するような一般的なコードを 書く際にとても便利ですが、それぞれの種類のユニフォームベクタ専用の アクセサに比べると遅いです。Gaucheのコンパイラは@vector-refの 呼び出しを認識して非常に効率の良いコードを出すのに対し、 この手続きは通常の手続き呼び出しになるからです。内部のループ内で呼び出す場合、 これは大きな差になるかもしれません。

型ごと専用のアクセサは下で説明します。

なお、(setter uvector-ref)uvector-set!です。

Function: uvector-set! uv k val :optional clamp

汎用的なuvectorのセッターです。uvector uvk番目の要素を valで置き換えます。 kが範囲外であったり、 uvが変更不可である場合はエラーが投げられます。

省略可能な引数clampが、valが正しい範囲外の数であった場合の動作を指定します。 この引数は#fか、 シンボルlowhighbothのいずれかでなければなりません。 この意味についてはgauche.uvector - ユニフォームベクタライブラリを参照してください。 デフォルトは#fで、範囲外の値についてはエラーを投げます。

uvectorの型ごとの操作

型ごとの述語、アクセサ、セッタはここで提供されます。 他の手続きについてはscheme.vector.@gauche.uvectorを 利用してください (gauche.uvector - ユニフォームベクタライブラリ参照)。

Function: @vector? obj

[R7RS vector.@] objが@vectorなら#tを、そうでなければ#fを返します。 @の部分はuvectorタグ(u8等)です。

Function: @vector-ref vec k :optional fallback

[R7RS vector.@] @vector veck番目の要素を返します。 @の部分はuvectorタグ(u8等)です。

kが有効な範囲外であった場合、通常はエラーが通知されますが、 省略可能な引数fallbackが与えられている場合はそれが返されます。

モジュールgauche.collectionをインポートしていれば、 総称関数refを使うこともできます。

(u16vector-ref '#u16(111 222 333) 1) ⇒ 222

(use gauche.collection)
(ref '#u16(111 222 333) 1) ⇒ 222

@vector-refのsetterは@vector-set!です。

(use gauche.uvector)
(define v (u8vector 1 2 3))
(set! (u8vector-ref v 1) 99)

v ⇒ #u8(1 99 3)
Function: @vector-set! vec k n :optional clamp

[R7RS vector.@] @vector veck番目の要素に数値nをセットします。 @の部分はuvectorタグ(u8等)です。 省略可能な引数clampが、nが正しい範囲外の数であった場合の動作を指定します。 この引数は#fか、 シンボルlowhighbothのいずれかでなければなりません。 この意味についてはgauche.uvector - ユニフォームベクタライブラリを参照してください。 デフォルトは#fで、範囲外の値についてはエラーを投げます。

モジュールgauche.collectionをインポートしていれば、 総称関数refのsetter手続きを使うこともできます。

(let ((v (s32vector -439 852 8933)))
  (s32vector-set! v 1 4)
  v)
 ⇒ #s32vector(-439 4 8933)

(use gauche.collection)
(let ((v (s32vector -439 852 8933)))
  (set! (ref v 1) 4)
  v)
 ⇒ #s32vector(-439 4 8933)

文字列とuvectorの変換

二種類の変換手続きが提供されます。 最初のは、文字列とu8/s8ベクタとを相互に変換するもので、 文字列のマルチバイト表現をバイトベクタとみなします。 もうひとつは文字列とu32/s32ベクタとを相互に変換するもので、 文字列をUnicodeコードポイントの列とみなします。

ポータブルなSchemekコードを書くには、SRFI-181が提供する 文字列とバイトベクタの変換手続きが使えるでしょう。 文字エンコーディングを指定することもできます (符号変換ポート参照)。

Function: string->s8vector string :optional start end immutable?
Function: string->u8vector string :optional start end immutable?

与えられた文字列の内部表現のバイト列と同じバイト列を持つs8vectorもしくは u8vectorを返します。省略可能な範囲引数startendは、 変換される文字列中の文字位置を指定します (バイト位置ではないことに注意)。

デフォルトでは、元の文字列の内容が新たに作られる変更可能なユニフォームベクタへと コピーされ、そのベクタが返されます。しかし、省略可能引数immutable?に 真の値が渡された場合、返されるユニフォームベクタは変更不可能となり、 また文字列本体のコピーが避けられる可能性があります。 (Gaucheでは、文字列本体は変更不可能で、string-set!は新たな 文字列本体を作り出します。したがってstring->u8vectorimmutable?#tを渡してユニフォームベクタを作った後、 元の文字列を変更しても、作られたユニフォームベクタは変更されません。)

これらの手続きは、文字を構成するバイト列をランダムにアクセスしたい場合などに 有用です。

(string->u8vector "abc") ⇒ #u8(97 98 99)

;; 内部コードがEUCの場合
(string->u8vector "いろは") ⇒ #u8(164 164 164 237 164 207)
(string->u8vector "very large string .... " 0 -1 #t)
  ⇒ #u8(...)  ; 変更不可、元の文字列と内容を共有
Function: string->s8vector! target tstart string :optional start end
Function: string->u8vector! target tstart string :optional start end

target は、それぞれ s8vector あるいは u8vector でなければなりません。 target は、変更可能でなければなりません。 string の生バイト表現を target へインデックス tstart からコピーします。

target を返します。

(let ((target (make-u8vector 10 0)))
  (string->u8vector! target 3 "abcde"))
 ⇒ #u8(0 0 0 97 98 99 100 101 0 0)
Function: s8vector->string vec :optional start end terminator
Function: u8vector->string vec :optional start end terminator

与えられたs8vectorもしくはu8vector vecのバイト列と同じ内部バイト列を 持つ文字列を作成して返します。省略可能な範囲引数startendは、 vec中の変換されるべき範囲をバイト位置で指定します。

省略可能引数terminatorは正確な整数か#fでなければなりません (#fがデフォルト)。正確な整数が与えられた場合、vecの中に その数値が現れれば、その直前までが結果の文字列となります。 例えば0を与えることで、バッファからNUL終端された文字列を読むことができます。

(u8vector->string '#u8(65 66 0 67 68) 0 5)   ⇒ "AB\0CD"
(u8vector->string '#u8(65 66 0 67 68) 0 5 0) ⇒ "AB"

vec中のバイト列がutf-8として不正な値を持っていた場合は、 不完全な文字列が返されます。

Function: string->s32vector string :optional start end endian
Function: string->u32vector string :optional start end endian

与えられた文字列stringの各文字の内部コードを値として持つ s32vectorもしくはu32vectorを返します。 省略可能な範囲引数startendは、 変換される文字列中の文字位置を指定します。

省略可能なendian引数は、uvectorにコードポイント値を格納する際の バイトオーダーを指定します。省略された場合や#fの場合は、 プラットフォームのネイティブバイトオーダーが使われます。 シンボルbig-endianbiglittle-endianlittlearm-little-endianで 特定のバイトオーダーを指定できます。 結果のuvectorにアクセスする時にはネイティブバイトオーダーが使われることに注意してください。

これらの手続きは、文字列中の文字をランダムにアクセスする場合に便利です。

Function: string->s32vector! target tstart string :optional start end endian
Function: string->u32vector! target tstart string :optional start end endian

targetは変更可能なs32vectorもしくはu32vectorでなければなりません。 targetの場所tstartから、stringの各文字のコードポイントを 順に埋めてゆきます。targetベクタの終端に達するか、文字が無くなるまで繰り返します。

省略可能な引数startendstring内の文字位置のインデックスで、 考慮するstringの範囲を制限します。

省略可能なendian引数は、uvectorにコードポイント値を格納する際の バイトオーダーを指定します。省略された場合や#fの場合は、 プラットフォームのネイティブバイトオーダーが使われます。 シンボルbig-endianbiglittle-endianlittlearm-little-endianで 特定のバイトオーダーを指定できます。 結果のuvectorにアクセスする時にはネイティブバイトオーダーが使われることに注意してください。

Function: s32vector->string vec :optional start end terminator endian
Function: u32vector->string vec :optional start end terminator endian

startendを考えなければ、 これらの手続きは次のコードのような動作をします:

(lambda (vec) (map-to <string> integer->char vec)))

省略可能な範囲引数startendは、 vec中の変換されるべき範囲を指定します。

省略可能引数terminatorは、正確な整数か#fでなければ なりません (#fがデフォルト)。正確な整数が与えられ、 入力にその数値が見つかった場合は、出力の文字列はその直前で 打ちきられます。

省略可能なendian引数は、uvectorにコードポイント値を格納する際の バイトオーダーを指定します。省略された場合や#fの場合は、 プラットフォームのネイティブバイトオーダーが使われます。 シンボルbig-endianbiglittle-endianlittlearm-little-endianで 特定のバイトオーダーを指定できます。

(u32vector->string '#u32(65 66 0 67 68) 0 5 0) ⇒ "AB"

6.13.3 ビットベクタ

ビットベクタはビットの並びです。各「ビット」は、0/1の数値としても、 #f/#tの論理値としても解釈可能です。 最初の見方では、ビットベクタをユニフォームベクタの一種と考えることもできますが、 インタフェースがそこそこ違っているので、別の型としました。

Gaucheはコアでごく基本的な手続きを提供し、また gauche.bitvectorモジュールで包括的なビットベクタユーティリティを提供します (gauche.bitvector - ビットベクタユーティリティ参照)。 ポータブルなプログラムを書く場合は、SRFI-178がビットベクタライブラリを定義しているので それを使うと良いでしょう。SRFI-178はGaucheの提供するもののサブセットになっています (srfi.178 - ビットベクタライブラリ参照)。

Builtin class: <bitvector>

ビットベクタクラス。<sequence>を継承し、ジェネリックなシーケンス操作も使えます。 (ジェネリックなrefについては、 外部表現との親和性からbitvector-ref/intが使われます)。

Reader Syntax: #*b

[SRFI-178] ビットベクタリテラルは、#*のあとに01が0個以上続いたものです。

#*10010010           ; bitvector of length 8
#*                   ; bitvector of length 0

ビットベクタリテラルはデリミタ文字かEOFで区切られます。

#*10010abc           ; error
#*10001(a b c)       ; a bitvector, followed by a list

註: このルールでは、#*"..."は、 長さゼロのビットベクタと文字列、と解釈されるべきです。"は区切り文字ですから。 しかし、Gaucheでは長らくこの構文を不完全文字列に使っていました。 (長さゼロのビットベクタがあることを見落としてました!) 不完全文字列の外部表記が必要になることは滅多にないので (不完全文字列は現実のデータを扱う際にどうしても「生じてしまう」もので、 積極的に使うべきではありません)、 その表記は0.9.10から#**"..."に変更されました (不完全文字列)。

後方互換性のため、現在のバージョンでは#*"..."は不完全文字列として読まれます。 リーダー字句モードがwarn-legacyであれば、この形のリテラルに対して警告が出されます (リーダー字句モード)。 将来的には#*"..."はビットベクタと文字列として読まれるように徐々に以降する予定です。

Function: bit->integer bit
Function: bit->boolean bit

[SRFI-178] ビットベクタAPIでビットが必要なところには、論理値(#f/#t)あるいは 正確な整数 (0/1)を渡すことができます。これらの手続きは有効なビット値をそれぞれ0/1もしくは #f/#tに揃えます。bitが有効なビット値でなければエラーが投げられます。

Function: bitvector b …

[SRFI-178] 要素がb …であるビットベクタを作って返します。 各引数はビット値でなければなりません (論理値か0か1)。

(bitvector 0 1 0 0 1 0 0 0 1) ⇒ #*010010001
(bitvector) ⇒ #*
Function: make-bitvector len :optional init

[SRFI-178] 長さlenのビットベクタを作って返します。各要素はinitで初期化されます。 initはビット値(論理値か0か1)でなければなりません。

initが省略された場合、ビットベクタの内容は未定義です。 (今のところ0で初期化されますが、それをあてにしてはいけません)。

(make-bitvector 5 #f)  ⇒ #*00000
(make-bitvector 7 1)   ⇒ #*1111111
Function: bitvector? obj

[SRFI-178] objがビットベクタなら#tを、そうでなければ#fを返します。

Function: list->bitvector lis

[SRFI-178] lisはビット値(論理値、0、1)のリストでなければなりません。 それらの値を要素とするビットベクタを作って返します。

(list->bitvector '(#t #f #t #t #f))  ⇒ #*10110
(list->bitvector '(0 1 1 1 0 1 0 1)) ⇒ #*01110101
Function: string->bitvector s

[SRFI-178] sがビットベクタリテラルとして有効な文字列 (#*b...b01) であれば、それで表現されるビットベクタを返します。そうでなければ#fが返されます。

(string->bitvector "#*1010001") ⇒ #*1010001
(string->bitvector "#*1001020") ⇒ #f

これはシーケンスとしての変換ではなく、外部表現からの変換であることに注意してください。

Function: bitvector->string bv

[SRFI-178] ビットベクタbvの外部表現#*b...を文字列として返します。

(bitvector->string #*1001010) ⇒ "#*1001010"

これはシーケンスとしての変換ではなく、外部表現への変換であることに注意してください。

Function: bitvector-ref/int bv k :optional fallback
Function: bitvector-ref/bool bv k :optional fallback

[SRFI-178+] ビットベクタbvk番目の要素を、それぞれ整数0/1か論理値として返します。 kが範囲外だった場合、fallbackが与えられていればそれが返され、 与えられていなければエラーが投げられます。 fallback引数はGaucheの拡張です。

(bitvector-ref/int #*1010001 0)  ⇒ 1
(bitvector-ref/bool #*1010001 0) ⇒ #t

万能アクセサref/~をビットベクタに使った場合は、 整数値が返されます (万能アクセサ)。

(~ #*11001001 1) ⇒ 1
Function: bitvector-set! bv k bit

[SRFI-178] ビットベクタbvk番目の要素にビット値bitをセットします。 bitは0、1、#f#tのいずれかでなければなりません。 kが範囲外ならエラーが投げられます。

この手続きはbitvector-ref/intbitvector-ref/boolのsetterとして 設定されています。また、ビットベクタはシーケンスなので、 (setter ref)/(setter ~)も使えます。

(rlet1 z (make-bitvector 5 0)
  (set! (~ z 2) #t))
  ⇒ #00100
Function: bitvector-copy bv :optional start end

[SRFI-178] ビットベクタbvのコピーを作って返します。 省略可能引数startendでインデックスが与えられた場合は、 その範囲内がコピーされます。startは含まれ、endは含まれません。

(bitvector-copy #*101001000 3)   ⇒ #*001000
(bitvector-copy #*100101000 2 7) ⇒ #*01010
Function: bitvector-copy! target tstart src :optional sstart send

[SRFI-178] ビットベクタsrcの内容を、 変更可能なビットベクタtargettstartインデックス以降にコピーして targetの内容を書き換えます。省略可能なsstartsendsrcのコピーされる範囲を限定します。

(rlet1 v (make-bitvector 10 0)
  (bitvector-copy! v 3 #*101101110 2 6))
  ⇒ #*0001101000
Function: bitvector-any-value? bv bit :optional start end
Function: bitvector-every-value? bv bit :optional start end

それぞれ、ビットベクタbvの少なくともひとつ/全てのビットがbitであるかどうかを 調べます。bitには真偽値もしくは正確な整数0または1を渡すことができます。

省略可能引数start/endは検査する範囲を指定します。

;; See if at least one '1'
(bitvector-any-value? #*000100 1)   ⇒ #t
(bitvector-any-value? #*000000 #t)  ⇒ #f

;; See if at least one '0'
(bitvector-any-value? #*110111 #f)  ⇒ #t
(bitvector-any-value? #*111111 0)   ⇒ #f

;; See if all bits are '1'
(bitvector-every-value? #*11111 #t) ⇒ #t
(bitvector-every-value? #*00000 1)  ⇒ #f

;; See if all bits are '0'
(bitvector-every-value? #*11111 #f) ⇒ #f
(bitvector-every-value? #*00000 0)  ⇒ #t

6.13.4 Weakベクタ

Weak ポインタとは、それが参照しているオブジェクトがガベージコレクトされることを 許すようなポインタです。 Gaucheはweak ベクタオブジェクトによってweak ポインタの機能を提供します。 Weak ベクタは通常のベクタに似ていますが、要素のオブジェクトがweak ベクタ以外から 参照されていない場合、オブジェクトはガベージコレクトされ、weak ベクタの該当するエントリは #fで置き換えられます。

gosh> (define v (make-weak-vector 1))
v
gosh> (weak-vector-ref v 0)
#f
gosh> (weak-vector-set! v 0 (cons 1 1))
#<undef>
gosh> (weak-vector-ref v 0)
(1 . 1)
gosh> (gc)
#<undef>
gosh> (gc)
#<undef>
gosh> (weak-vector-ref v 0)
#f

R7RS-largeでのweakポインタについてはscheme.ephemeron - R7RS Ephemeronを参照してください。

Builtin Class: <weak-vector>

Weak ベクタのクラスです。<sequence><collection>を継承しているので、 gauche.collection (gauche.collection - コレクションフレームワーク参照) と gauche.sequence (gauche.sequence - シーケンスフレームワーク参照) も使えます。

(coerce-to <weak-vector> '(1 2 3 4))
  ⇒ a weak vector with four elements
Function: make-weak-vector size

大きさsizeのweak ベクタを作成して返します。

Function: weak-vector-length wvec

weak ベクタ wvecの大きさを返します。

Function: weak-vector-ref wvec k :optional fallback

weak ベクタ wveck番目の要素を返します。

weak-vector-refkが負の値であったりベクタの長さより 大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback が与えられている場合はその値が返されます。

該当する要素が既にガベージコレクトされていた場合、fallbackが 与えられていればそれが、そうでなければ#fが返されます。

gauche.sequenceモジュールをロードしていれば、 メソッドrefも同じ目的で使えます。

Function: weak-vector-set! wvec k obj

weak ベクタ wveck番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT