stack:
push/pop/peek/lenなど、スタック操作の基本 API を提供します。- parser や探索処理で使いやすい軽量なスタック実装を提供します。
- スタック本体は
Vec<.T>で表し、内部でヘッダ[len, cap, data_ptr]を保持します。 - 容量不足時は 2 倍拡張して
reallocします。
stack_push/stack_clearは更新後のStack<.T>を返します。stack_popはOption<.T>を返します。stack_peekは値のみを返します。stack_free後のスタック値は再利用できません。
stack_len/stack_is_empty/stack_peek/stack_popは O(1)。stack_pushはならし O(1)、拡張発生時のみ O(n)。
追加の使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/option" as *
#import "core/field" as *
#import "core/result" as *
fn main <()*>i32> ():
let st0 <Stack<i32>>:
<Stack<i32>> new
|> uwok
|> push 10
|> uwok
|> push 20
|> uwok
let ok0 if eq len st0 2 1 0;
let st1 <Stack<i32>>:
<Stack<i32>> new
|> uwok
|> push 10
|> uwok
|> push 20
|> uwok
let ok1 match peek st1:
Option::Some x:
if eq x 20 1 0
Option::None:
0
let st2 <Stack<i32>>:
<Stack<i32>> new
|> uwok
|> push 10
|> uwok
|> push 20
|> uwok
let p pop st2;
let ok2 match p:
Option::Some x:
if eq x 20 1 0
Option::None:
0
let s01 <i32> add ok0 ok1;
add s01 ok2使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/string" as s
#import "alloc/diag/error" as *
#import "core/option" as *
#import "core/field" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<str>>:
<Stack<str>> new
|> uwok
|> push "a"
|> uwok
|> push "b"
|> uwok
let p pop st;
let ok0 match p:
Option::Some x:
if s::str_eq x "b" 1 0
Option::None:
0
ok0stack_header_len_ptr: ヘッダの length
目的
[len, cap, data_ptr]形式 のヘッダ領域 から length欄 をMemPtr<i32>として得 ます。
実装
- ヘッダ
先頭 の 4 byte をi32欄 として解釈 します。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_header_cap_ptr: ヘッダの capacity
目的
- ヘッダ
中 の capacity欄 をMemPtr<i32>として得 ます。
実装
- ヘッダ
先頭 から 4 byte進 めた位置 をi32欄 として扱 います。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_header_data_ptr_ptr: ヘッダの data pointer
目的
- データ
領域 の raw address を保持 する欄 をMemPtr<i32>として得 ます。
実装
- ヘッダ
先頭 から 8 byte進 めた位置 をi32欄 として扱 います。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_len_raw:
目的
Stackの length欄 をi32として読 みます。
実装
- ヘッダの length
欄 を rawload_i32で参照 します。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_cap_raw:
目的
Stackの capacity欄 をi32として読 みます。
実装
- ヘッダの capacity
欄 を rawload_i32で参照 します。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_data_ptr:
目的
Stackの要素 領域 先頭 をMemPtr<.T>として返 します。
実装
- ヘッダに
保持 した raw address を読 み、MemPtr<.T>で包 みます。
注意
公開 API ではなく、Stack内部 の補助 です。
計算量
- O(1)
stack_new: 空のスタックを作る
目的
既定 容量 の空 スタックを作成 し、Stack<.T>として返 します。
実装
- 12 byte のヘッダ
領域 と、既定 容量 ぶんの要素 領域 を別々 に確保 します。 - ヘッダには
[len, cap, data_ptr]を保存 し、Stack<.T>はそのヘッダ先頭 を保持 します。
注意
失敗 するとResult::Err Diagを返 します。返 るStack<.T>は内部 ヘッダの所有権 を持 つので、不要 になったらstack_freeで解放 します。
計算量
時間 計算量 は O(1)、追加 の空間 計算量 も O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<i32>>:
stack_new<i32>
|> uwok
if stack_is_empty<i32> st 0 1stack_push: 末尾に要素を積む
目的
itemを末尾 に積 み、更新後 のスタックを返 します。
実装
容量 が足 りる場合 は末尾 に直接 書 き込 みます。容量 不足 なら 2倍 に拡張 し、realloc_ptrでデータ領域 を移動 してから追加 します。
注意
更新後 のStack<.T>を返 すので、呼 び出 し側 で束縛 し直 す必要 があります。拡張 が発生 した場合 、内部 データ領域 の番地 は変 わりえます。
計算量
償却 時間 計算量 は O(1)、拡張 発生時 の最悪 時間 計算量 は O(n) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let mut st <Stack<i32>>:
stack_new<i32>
|> uwok
set st:
stack_push<i32> st 10
|> uwok
if eq stack_len<i32> st 1 0 1stack_pop: 末尾要素を取り出す
目的
末尾 要素 を取 り出 し、存在 すればOption::Someとして返 します。
実装
len == 0ならOption::Noneを返 します。要素 がある場合 は最後 の添字 を計算 し、load後に length を 1減 らします。
注意
返 り値 はOption<.T>です。空 スタックを異常 にせず、Noneで表 します。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/option" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<i32>>:
stack_new<i32>
|> uwok
|> stack_push<i32> 10
|> uwok
let p stack_pop<i32> st;
match p:
Option::Some x:
if eq x 10 0 1
Option::None:
1stack_peek: 末尾要素を覗く
目的
末尾 要素 を削除 せずに参照 したいときに使 います。
実装
stack_popと同様 に最後 の添字 を求 めますが、length は更新 しません。
注意
返 り値 はOption<.T>です。空 スタックではNoneを返 します。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/option" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<i32>>:
stack_new<i32>
|> uwok
|> stack_push<i32> 20
|> uwok
match stack_peek<i32> st:
Option::Some x:
if eq x 20 0 1
Option::None:
1stack_len: 長さを返す
目的
現在 の要素数 を返 します。
実装
- ヘッダ
先頭 の length欄 を読 むだけです。
注意
変更 を伴 わない読 み取 り API です。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let mut st <Stack<i32>> uwok stack_new<i32>;
set st uwok stack_push<i32> st 1;
set st uwok stack_push<i32> st 2;
if eq stack_len<i32> st 2 0 1stack_is_empty: 空か判定する
目的
- スタックが
空 かどうかをboolで返 します。
実装
stack_lenで要素数 を得 て 0 と比較 します。
注意
変更 を伴 わない読 み取 り API です。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<i32>> uwok stack_new<i32>;
if stack_is_empty<i32> st 0 1stack_clear: すべての要素を削除する
目的
要素数 を 0 に戻 し、スタックを空 にします。
実装
- ヘッダの length
欄 だけを書き換 えます。
注意
確保 ずみの容量 は維持 され、メモリは解放 されません。更新後 のStack<.T>を返 すので、呼 び出 し側 で束縛 し直 します。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let mut st <Stack<i32>> uwok stack_new<i32>;
set st uwok stack_push<i32> st 9;
set st stack_clear<i32> st;
if stack_is_empty<i32> st 0 1stack_free: メモリを解放する
目的
Stack<.T>が所有 するデータ領域 とヘッダ領域 を解放 します。
実装
- capacity からデータ
領域 の byte数 を計算 してdealloc_ptr<.T>を呼 び、続 けてヘッダ 12 byte も解放 します。
注意
解放後 にstkを再利用 してはいけません。Stack<.T>の所有権 を消費 する終端 操作として扱 います。
計算量
時間 計算量 は O(1) です。
使い方:
TEST
#entry main
#target std
#import "alloc/collections/stack" as *
#import "alloc/diag/error" as *
#import "core/result" as *
fn main <()*>i32> ():
let st <Stack<i32>> uwok stack_new<i32>;
stack_free<i32> st;
0new: stack_new の短縮名
push: stack_push の短縮名
pop: stack_pop の短縮名
peek: stack_peek の短縮名
len: stack_len の短縮名
is_empty: stack_is_empty の短縮名
clear: stack_clear の短縮名
free: stack_free の短縮名