ベクタは固定長でO(1)アクセス可能な値の並びです。 Schemeは伝統的に、任意の値を格納できるベクタを提供してきました。 これはベクタで説明されます。
R7RS-largeでは、均質な数値型だけを効率よく格納できるベクタ(uvector)も定義されています。 ユニフォームベクタを見てください。
Gaucheはまた、ビット列を格納するビットベクタも提供します。 ビットベクタで説明します。
最後に、weakベクタは任意の要素をweakポインタを使って格納できるベクタです。 Weakベクタ参照。
• ベクタ: | ||
• ユニフォームベクタ: | ||
• ビットベクタ: | ||
• Weakベクタ: |
ベクタはSchemeオブジェクトの単純な一次元配列です。 インデックスを用いて定数時間でその要素にアクセスできます。 一度作成されたベクタはその大きさを変えることはできません。
<vector>
クラスはまた<sequence>
クラスを継承し、
map
やfold
など様々な総称関数を使うことができます。
gauche.collection
- コレクションフレームワーク と
gauche.sequence
- シーケンスフレームワーク を参照して下さい。
数値しか要素に持たないベクタを使う場合、 ユニフォームベクタも使えるかもしれません (ユニフォームベクタ参照)。
R7RSはバイトベクタを定義しています。Gaucheではそれは単に
gauche.uvector
モジュールのu8vector
です
(R7RSモジュールは別名を定義しています。scheme.base
- R7RS基本ライブラリ参照。)
より多くのベクタに対する操作がscheme.vector
- R7RSベクタで提供されています。
[R7RS base]
objがベクタなら#t
を、そうでなければ#f
を返します。
[R7RS base] 長さkのベクタを作成して返します。 省略可能な引数fillが与えられていれば、ベクタの各要素はその値で 初期化されます。そうでなければベクタの各要素の値は不定です。
[R7RS base] 要素がobj …であるようなベクタを作成して返します。
長さlenのベクタを作成し、0
以上len未満のiについて
i番目の要素を(proc i)
の値で初期化します。
(vector-tabulate 5 (^x (* x x))) ⇒ #(0 1 4 9 16)
[R7RS base] ベクタvectorの長さを返します。
gauche.collection
モジュールをロードしていれば、
メソッドsize-of
も同じ目的で使えます。
[R7RS+ base] ベクタvectorのk番目の要素を返します。
vector-ref
はkが負の値であったりベクタの長さより
大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback
が与えられている場合はその値が返されます。これはGaucheの拡張です。
gauche.sequence
モジュールをロードしていれば、
メソッドref
も同じ目的で使えます。
[R7RS base] ベクタvectorのk番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。
gauche.sequence
モジュールをロードしていれば、
メソッドref
のsetterメソッドも使えます。
[R7RS+ base] ベクタをリストに変換したり、その逆を行う手続きです。
省略可能な引数startとendを与えることにより、
値を取り出す範囲を制限することができます。
(R7RSのlist->vector
はstartとend引数を規定していません。)
(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)
も同じ目的で使えます。
[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)
[R7RS base]
文字のベクタを文字列に変換したり、その逆を行う手続きです。
vector->string
に、文字以外の要素を含むベクタを渡した場合はエラーになります。
省略可能な引数startとendを与えることにより、 値を取り出す範囲を制限することができます。
(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)
も同じ目的で使えます。
[R7RS base] ベクタvectorの全ての要素をfillに変更します。
省略可能な引数startとendが与えられた場合、 start番目の要素からend-1番目の要素までのみに fillを格納します。startとendの既定値は それぞれ0とvectorの大きさです。
[R7RS base] ベクタvectorをコピーします。引数startとendを与えることで コピーされる範囲を制限することができます。 startとendで指定される範囲が元の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)
[R7RS base] ベクタsourceの内容をベクタtargetのインデックスtstart以降に コピーします。targetは変更可能でなければなりません。 省略可能なsstartとsend引数はコピー元ベクタの範囲を限定します。
(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から末尾まで)より 大きい場合はエラーが報告されます。
targetとsourceに同じベクタを渡しても構いません。 コピー元とコピー先の領域に重なりがある場合でもこの手続きは使えます。
[R7RS base] ベクタvecを順に継ぎ足した内容を持つベクタを新たに作成して返します。
(vector-append '#(1 2 3) '#(a b)) ⇒ #(1 2 3 a b) (vector-append) ⇒ #()
[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 …)
としても同じ機能は得られます。
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 …)
としても同じ機能は得られます。
[R7RS vector] 各インデックスiについて、ベクタvec1 vec2 …の i番目の要素を引数としてprocを呼び出した結果、vec1の i番目の要素にセットします。ベクタの長さが異なる場合は最も短いベクタ の範囲が計算されます。
(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)
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))
[R7RS base] 0から渡されたベクタのうち一番短いものの最大のインデックスまでのiについて、 vec1 vec2 …のそれぞれi番目の要素を引数に procを呼び出します。
(vector-for-each print '#(a b c))
⇒ prints a
, b
and c
.
vector-for-each
と似ていますが、procの第1引数に
現在のインデックスが渡されます。
この手続きはSRFI-43のvector-for-each
と等価です。
srfi.43
- ベクタライブラリ(旧式)参照。
ユニフォームベクタ、あるいは同質な数値ベクタは、
要素として特定の数値型のみを格納する特別なベクタです。
もともと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ユニフォームベクタ参照。
ユニフォームベクタクラスのベースクラスです。<sequence>
を継承します
(gauche.sequence
- シーケンスフレームワーク参照)。
{gauche.uvector
}
@vectorのクラス。@
の部分はuvectorタグ
(u8
、s8
、…) です。
<uvector>
を継承します。
sequenceプロトコル(gauche.sequence
- シーケンスフレームワーク参照)を実装しているので、
数値の並びをcoerce-to
を使ってuvectorに変換することができます。
ただし各要素はuvectorの要素として有効な範囲の値でなればなりません。
(use gauche.sequence) (coerce-to <u8vector> '(1 2 3)) ⇒ #u8(1 2 3)
#u8(n …)
¶#s8(n …)
¶#u16(n …)
¶#s16(n …)
¶#u32(n …)
¶#s32(n …)
¶#u64(n …)
¶#s64(n …)
¶#f16(n …)
¶#f32(n …)
¶#f64(n …)
¶#c32(n …)
¶#c64(n …)
¶#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)
[R7RS vector.@] 長さlenの@vectorを作成して返します。各要素はfillで 初期化されます。正確な整数のベクタに対しては、fillは正確な整数でなければならず、 また有効な範囲内の値でなければなりません。 fillが省略された場合、各要素の初期値は不定です。
(make-u8vector 4 0) ⇒ #u8(0 0 0 0)
objがユニフォームベクタのいずれかなら#t
を、
そうでなければ#f
を返します。
特定の型のuvectorを検査する述語については後で説明します。
uvectoruvの長さ(要素数)を返します。 uvがuvectorでなければエラーを投げます。
特定の型のuvectorの長さを取る手続きは、scheme.vector.@
および
gauche.uvector
にあります (gauche.uvector
- ユニフォームベクタライブラリ参照)。
uvectorの内容がバイナリデータとして占有する大きさを知りたければ、
gauche.uvector
のuvector-size
が使えます。
汎用的なuvectorのアクセサです。uvector uvのk番目の 要素を返します。kが範囲外の場合、fallbackが与えられていればそれが 返され、そうでなければエラーが投げられます。
この手続きは様々な種類のユニフォームベクタに対して動作するような一般的なコードを
書く際にとても便利ですが、それぞれの種類のユニフォームベクタ専用の
アクセサに比べると遅いです。Gaucheのコンパイラは@vector-ref
の
呼び出しを認識して非常に効率の良いコードを出すのに対し、
この手続きは通常の手続き呼び出しになるからです。内部のループ内で呼び出す場合、
これは大きな差になるかもしれません。
型ごと専用のアクセサは下で説明します。
なお、(setter uvector-ref)
はuvector-set!
です。
汎用的なuvectorのセッターです。uvector uvのk番目の要素を valで置き換えます。 kが範囲外であったり、 uvが変更不可である場合はエラーが投げられます。
省略可能な引数clampが、valが正しい範囲外の数であった場合の動作を指定します。
この引数は#f
か、
シンボルlow
、high
、both
のいずれかでなければなりません。
この意味についてはgauche.uvector
- ユニフォームベクタライブラリを参照してください。
デフォルトは#f
で、範囲外の値についてはエラーを投げます。
型ごとの述語、アクセサ、セッタはここで提供されます。
他の手続きについてはscheme.vector.@
やgauche.uvector
を
利用してください (gauche.uvector
- ユニフォームベクタライブラリ参照)。
[R7RS vector.@]
objが@vectorなら#t
を、そうでなければ#f
を返します。
@
の部分はuvectorタグ(u8
等)です。
[R7RS vector.@]
@vector vecのk番目の要素を返します。
@
の部分は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)
[R7RS vector.@]
@vector vecのk番目の要素に数値nをセットします。
@
の部分はuvectorタグ(u8
等)です。
省略可能な引数clampが、nが正しい範囲外の数であった場合の動作を指定します。
この引数は#f
か、
シンボルlow
、high
、both
のいずれかでなければなりません。
この意味については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)
二種類の変換手続きが提供されます。 最初のは、文字列とu8/s8ベクタとを相互に変換するもので、 文字列のマルチバイト表現をバイトベクタとみなします。 もうひとつは文字列とu32/s32ベクタとを相互に変換するもので、 文字列をUnicodeコードポイントの列とみなします。
ポータブルなSchemekコードを書くには、SRFI-181が提供する 文字列とバイトベクタの変換手続きが使えるでしょう。 文字エンコーディングを指定することもできます (符号変換ポート参照)。
与えられた文字列の内部表現のバイト列と同じバイト列を持つs8vectorもしくは u8vectorを返します。省略可能な範囲引数start、endは、 変換される文字列中の文字位置を指定します (バイト位置ではないことに注意)。
デフォルトでは、元の文字列の内容が新たに作られる変更可能なユニフォームベクタへと
コピーされ、そのベクタが返されます。しかし、省略可能引数immutable?に
真の値が渡された場合、返されるユニフォームベクタは変更不可能となり、
また文字列本体のコピーが避けられる可能性があります。
(Gaucheでは、文字列本体は変更不可能で、string-set!
は新たな
文字列本体を作り出します。したがってstring->u8vector
の
immutable?
に#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(...) ; 変更不可、元の文字列と内容を共有
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)
与えられたs8vectorもしくはu8vector vecのバイト列と同じ内部バイト列を 持つ文字列を作成して返します。省略可能な範囲引数start、endは、 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として不正な値を持っていた場合は、 不完全な文字列が返されます。
与えられた文字列stringの各文字の内部コードを値として持つ s32vectorもしくはu32vectorを返します。 省略可能な範囲引数start、endは、 変換される文字列中の文字位置を指定します。
省略可能なendian引数は、uvectorにコードポイント値を格納する際の
バイトオーダーを指定します。省略された場合や#f
の場合は、
プラットフォームのネイティブバイトオーダーが使われます。
シンボルbig-endian
、big
、
little-endian
、little
、arm-little-endian
で
特定のバイトオーダーを指定できます。
結果のuvectorにアクセスする時にはネイティブバイトオーダーが使われることに注意してください。
これらの手続きは、文字列中の文字をランダムにアクセスする場合に便利です。
targetは変更可能なs32vectorもしくはu32vectorでなければなりません。 targetの場所tstartから、stringの各文字のコードポイントを 順に埋めてゆきます。targetベクタの終端に達するか、文字が無くなるまで繰り返します。
省略可能な引数startとendはstring内の文字位置のインデックスで、 考慮するstringの範囲を制限します。
省略可能なendian引数は、uvectorにコードポイント値を格納する際の
バイトオーダーを指定します。省略された場合や#f
の場合は、
プラットフォームのネイティブバイトオーダーが使われます。
シンボルbig-endian
、big
、
little-endian
、little
、arm-little-endian
で
特定のバイトオーダーを指定できます。
結果のuvectorにアクセスする時にはネイティブバイトオーダーが使われることに注意してください。
startとendを考えなければ、 これらの手続きは次のコードのような動作をします:
(lambda (vec) (map-to <string> integer->char vec)))
省略可能な範囲引数start、endは、 vec中の変換されるべき範囲を指定します。
省略可能引数terminatorは、正確な整数か#f
でなければ
なりません (#f
がデフォルト)。正確な整数が与えられ、
入力にその数値が見つかった場合は、出力の文字列はその直前で
打ちきられます。
省略可能なendian引数は、uvectorにコードポイント値を格納する際の
バイトオーダーを指定します。省略された場合や#f
の場合は、
プラットフォームのネイティブバイトオーダーが使われます。
シンボルbig-endian
、big
、
little-endian
、little
、arm-little-endian
で
特定のバイトオーダーを指定できます。
(u32vector->string '#u32(65 66 0 67 68) 0 5 0) ⇒ "AB"
ビットベクタはビットの並びです。各「ビット」は、0/1の数値としても、
#f
/#t
の論理値としても解釈可能です。
最初の見方では、ビットベクタをユニフォームベクタの一種と考えることもできますが、
インタフェースがそこそこ違っているので、別の型としました。
Gaucheはコアでごく基本的な手続きを提供し、また
gauche.bitvector
モジュールで包括的なビットベクタユーティリティを提供します
(gauche.bitvector
- ビットベクタユーティリティ参照)。
ポータブルなプログラムを書く場合は、SRFI-178がビットベクタライブラリを定義しているので
それを使うと良いでしょう。SRFI-178はGaucheの提供するもののサブセットになっています
(srfi.178
- ビットベクタライブラリ参照)。
ビットベクタクラス。<sequence>
を継承し、ジェネリックなシーケンス操作も使えます。
(ジェネリックなref
については、
外部表現との親和性からbitvector-ref/int
が使われます)。
#*b…
¶[SRFI-178]
ビットベクタリテラルは、#*
のあとに0
や1
が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
であれば、この形のリテラルに対して警告が出されます
(リーダー字句モード)。
将来的には#*"..."
はビットベクタと文字列として読まれるように徐々に以降する予定です。
[SRFI-178]
ビットベクタAPIでビットが必要なところには、論理値(#f
/#t
)あるいは
正確な整数 (0/1)を渡すことができます。これらの手続きは有効なビット値をそれぞれ0/1もしくは
#f
/#t
に揃えます。bitが有効なビット値でなければエラーが投げられます。
[SRFI-178] 要素がb …であるビットベクタを作って返します。 各引数はビット値でなければなりません (論理値か0か1)。
(bitvector 0 1 0 0 1 0 0 0 1) ⇒ #*010010001 (bitvector) ⇒ #*
[SRFI-178] 長さlenのビットベクタを作って返します。各要素はinitで初期化されます。 initはビット値(論理値か0か1)でなければなりません。
initが省略された場合、ビットベクタの内容は未定義です。 (今のところ0で初期化されますが、それをあてにしてはいけません)。
(make-bitvector 5 #f) ⇒ #*00000 (make-bitvector 7 1) ⇒ #*1111111
[SRFI-178]
objがビットベクタなら#t
を、そうでなければ#f
を返します。
[SRFI-178] lisはビット値(論理値、0、1)のリストでなければなりません。 それらの値を要素とするビットベクタを作って返します。
(list->bitvector '(#t #f #t #t #f)) ⇒ #*10110 (list->bitvector '(0 1 1 1 0 1 0 1)) ⇒ #*01110101
[SRFI-178]
s
がビットベクタリテラルとして有効な文字列
(#*b...
でbが0
か1
)
であれば、それで表現されるビットベクタを返します。そうでなければ#f
が返されます。
(string->bitvector "#*1010001") ⇒ #*1010001 (string->bitvector "#*1001020") ⇒ #f
これはシーケンスとしての変換ではなく、外部表現からの変換であることに注意してください。
[SRFI-178]
ビットベクタbvの外部表現#*b...
を文字列として返します。
(bitvector->string #*1001010) ⇒ "#*1001010"
これはシーケンスとしての変換ではなく、外部表現への変換であることに注意してください。
[SRFI-178+] ビットベクタbvのk番目の要素を、それぞれ整数0/1か論理値として返します。 kが範囲外だった場合、fallbackが与えられていればそれが返され、 与えられていなければエラーが投げられます。 fallback引数はGaucheの拡張です。
(bitvector-ref/int #*1010001 0) ⇒ 1 (bitvector-ref/bool #*1010001 0) ⇒ #t
万能アクセサref
/~
をビットベクタに使った場合は、
整数値が返されます (万能アクセサ)。
(~ #*11001001 1) ⇒ 1
[SRFI-178]
ビットベクタbvのk番目の要素にビット値bitをセットします。
bitは0、1、#f
、#t
のいずれかでなければなりません。
kが範囲外ならエラーが投げられます。
この手続きはbitvector-ref/int
とbitvector-ref/bool
のsetterとして
設定されています。また、ビットベクタはシーケンスなので、
(setter ref)
/(setter ~)
も使えます。
(rlet1 z (make-bitvector 5 0) (set! (~ z 2) #t)) ⇒ #00100
[SRFI-178] ビットベクタbvのコピーを作って返します。 省略可能引数start、endでインデックスが与えられた場合は、 その範囲内がコピーされます。startは含まれ、endは含まれません。
(bitvector-copy #*101001000 3) ⇒ #*001000 (bitvector-copy #*100101000 2 7) ⇒ #*01010
[SRFI-178] ビットベクタsrcの内容を、 変更可能なビットベクタtargetのtstartインデックス以降にコピーして targetの内容を書き換えます。省略可能なsstart、sendは srcのコピーされる範囲を限定します。
(rlet1 v (make-bitvector 10 0) (bitvector-copy! v 3 #*101101110 2 6)) ⇒ #*0001101000
それぞれ、ビットベクタ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
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を参照してください。
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
大きさsizeのweak ベクタを作成して返します。
weak ベクタ wvecの大きさを返します。
weak ベクタ wvecのk番目の要素を返します。
weak-vector-ref
はkが負の値であったりベクタの長さより
大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback
が与えられている場合はその値が返されます。
該当する要素が既にガベージコレクトされていた場合、fallbackが
与えられていればそれが、そうでなければ#f
が返されます。
gauche.sequence
モジュールをロードしていれば、
メソッドref
も同じ目的で使えます。
weak ベクタ wvecのk番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。