# 機能設計書 19-Stack

## 概要

本ドキュメントは、VBCorLibライブラリにおける後入れ先出しコレクション機能「Stack」クラスの機能設計について記述する。

### 本機能の処理概要

Stackクラスは、後入れ先出し（LIFO: Last-In-First-Out）のコレクションを提供するクラスである。.NET FrameworkのSystem.Collections.Stackクラスと互換性のあるAPIを持ち、内部にVariant配列を持って要素を管理する。Push操作でスタックの最上部に要素を追加し、Pop操作で最上部の要素を取り出す。

**業務上の目的・背景**：スタックは再帰処理の明示的実装、Undo/Redo機能、式の評価（逆ポーランド記法）、深さ優先探索など、様々なアルゴリズムで使用される基本データ構造である。VBAには標準でスタック構造がないため、Stackクラスがこのギャップを埋める。

**機能の利用シーン**：
- Undo/Redo機能の実装
- 式の評価（電卓アプリケーション等）
- 深さ優先探索（DFS）アルゴリズム
- 再帰処理の非再帰実装
- 括弧の対応チェック

**主要な処理内容**：
1. 要素追加（Push）- スタック最上部への追加
2. 要素取り出し（Pop）- スタック最上部からの取り出し
3. 要素参照（Peek）- スタック最上部の参照（取り出さない）
4. 検索（Contains）- 要素の存在確認
5. 変換（ToArray、CopyTo）
6. クリア（Clear）

**関連システム・外部連携**：ICollection、IEnumerable、ICloneableインターフェースを実装し、他のVBCorLibコンポーネントとの相互運用が可能。

**権限による制御**：本機能には権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Simply VB Unit Runner | 主画面 | テストスイート内のStackテスト（StackTests）の実行 |

## 機能種別

コレクション処理 / データ構造

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Value | Variant | Yes | Pushで追加する値 | 任意の値（オブジェクト含む） |
| Value | Variant | Yes | Containsで検索する値 | 任意の値 |
| Arr | Variant | Yes | CopyToのコピー先配列 | 1次元配列 |
| Index | Long | Yes | CopyToの開始インデックス | 配列下限以上 |

### 入力データソース

プログラムからの直接呼び出し（パラメータ指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Pop戻り値 | Variant | スタック最上部から取り出した要素 |
| Peek戻り値 | Variant | スタック最上部の要素（取り出さない） |
| Contains戻り値 | Boolean | 要素の存在有無 |
| ToArray戻り値 | Variant() | 配列に変換された要素（LIFO順） |
| Count | Long | 要素数 |
| Clone戻り値 | Stack | 浅いコピー |

### 出力先

呼び出し元への戻り値として返却

## 処理フロー

### 処理シーケンス

```
1. インスタンス生成
   └─ 初期容量（デフォルト16）でVariant配列確保
   └─ Countを0に初期化

2. Push呼び出し
   └─ EnsureCapacityで容量確認
   └─ mItems(mCount)に要素追加
   └─ Count++
   └─ Version++

3. Pop呼び出し
   └─ Countが0なら例外
   └─ Count--
   └─ mItems(mCount)の値を取得
   └─ mItems(mCount)をクリア
   └─ Version++
   └─ 取得した値を返却

4. Peek呼び出し
   └─ Countが0なら例外
   └─ mItems(mCount - 1)の値を返却（削除しない）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{メソッド種別}
    B -->|Push| C[EnsureCapacity]
    C --> D[mItems(mCount) = Value]
    D --> E[mCount++]
    E --> F[mVersion++]
    F --> G[終了]
    B -->|Pop| H{mCount > 0?}
    H -->|No| I[InvalidOperationException]
    H -->|Yes| J[mCount--]
    J --> K[Result = mItems(mCount)]
    K --> L[mItems(mCount) = Empty]
    L --> F
    B -->|Peek| M{mCount > 0?}
    M -->|No| N[InvalidOperationException]
    M -->|Yes| O[Return mItems(mCount - 1)]
    O --> G
    B -->|Contains| P[CorArray.IndexOf検索]
    P --> Q{見つかった?}
    Q -->|Yes| R[Return True]
    Q -->|No| S[Return False]
    R --> G
    S --> G
    I --> G
    N --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | LIFO順序 | 後から追加した要素が先に取り出される | Push/Pop操作 |
| BR-002 | デフォルト容量 | 初期容量は16要素 | 新規インスタンス生成時 |
| BR-003 | 容量拡張戦略 | 容量不足時は現在の2倍に拡張 | EnsureCapacity時 |
| BR-004 | 空スタック操作 | 空スタックへのPop/PeekはInvalidOperationException | Pop/Peek呼び出し時 |
| BR-005 | シャローコピー | Cloneは浅いコピーを作成 | Clone呼び出し時 |
| BR-006 | バージョン管理 | 変更時にVersionをインクリメント | Push/Pop/Clear |
| BR-007 | ToArray順序 | ToArrayはLIFO順（最上部が最初）で配列を返す | ToArray呼び出し時 |

### 計算ロジック

**EnsureCapacity**:
```
If RequiredCapacity > mCapacity Then
    NewCapacity = mCapacity * 2
    If RequiredCapacity > NewCapacity Then
        NewCapacity = RequiredCapacity
    End If
    ReDim Preserve mItems(0 To NewCapacity - 1)
    mCapacity = NewCapacity
End If
```

**ToArray逆順コピー**:
```
For i = 0 To mCount - 1
    Result(i) = mItems(mCount - i - 1)
Next
```

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidOperationException | 空スタックへのPop | Countを確認してから操作 |
| - | InvalidOperationException | 空スタックへのPeek | Countを確認してから操作 |
| - | ArgumentNullException | CopyToでArrがNull | 有効な配列を指定 |
| - | ArgumentException | CopyToで多次元配列 | 1次元配列を使用 |
| - | ArgumentOutOfRangeException | CopyToでIndex < LBound | 有効なインデックスを指定 |

### リトライ仕様

コレクション操作処理であるため、リトライは不要。

## トランザクション仕様

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- Push: O(1)の償却定数時間（容量拡張時を除く）
- Pop: O(1)の定数時間
- Peek: O(1)の定数時間
- Contains: O(n)の線形時間

## セキュリティ考慮事項

- 参照型要素は浅いコピーとなるため、Clone後も同一オブジェクトを参照
- Pop後は内部配列からの参照をクリアしてメモリリークを防止

## 備考

- Persistable属性を持ち、PropertyBagによるシリアライズが可能
- IVersionableインターフェースでバージョン追跡を実装

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Stackクラスは内部にVariant配列を持ち、配列の末尾側をスタックの最上部として使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Stack.cls | `Source/CorLib/System.Collections/Stack.cls` | クラス構造、メンバ変数、実装インターフェース |

**主要なメンバ変数**:
- **58行目**: `mItems() As Variant` - 内部配列
- **59行目**: `mCount As Long` - 要素数（スタックポインタ）
- **60行目**: `mVersion As Long` - バージョン（変更検出用）
- **61行目**: `mCapacity As Long` - 配列容量

**実装インターフェース**（47-51行目）:
- IObject, ICloneable, IEnumerable, ICollection, IVersionable

#### Step 2: Push/Pop/Peekを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Stack.cls | `Source/CorLib/System.Collections/Stack.cls` | Push、Pop、Peek |

**主要処理フロー**:
1. **205-210行目**: Pushメソッド - EnsureCapacity後に末尾に追加
2. **189-196行目**: Popメソッド - 末尾から取り出し、Emptyでクリア
3. **175-180行目**: Peekメソッド - 末尾を参照（削除しない）

#### Step 3: 検索・変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Stack.cls | `Source/CorLib/System.Collections/Stack.cls` | Contains、ToArray、CopyTo |

**主要処理フロー**:
- **94-96行目**: Containsメソッド - CorArray.IndexOfで検索
- **218-228行目**: ToArrayメソッド - 逆順でコピー
- **105-116行目**: CopyToメソッド - 配列にコピー後Reverse

#### Step 4: 初期化・クローンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Stack.cls | `Source/CorLib/System.Collections/Stack.cls` | Clone、Clear、Init |

**主要処理フロー**:
- **82-85行目**: Cloneメソッド - InitCloneで浅いコピー
- **68-72行目**: Clearメソッド - 配列再初期化
- **252-254行目**: Initメソッド - コレクションからの初期化

### プログラム呼び出し階層図

```
Stack (インスタンス)
    │
    ├─ Push(Value)
    │      ├─ EnsureCapacity(mCount + 1)
    │      └─ VariantCopyInd(mItems(mCount), Value)
    │
    ├─ Pop()
    │      ├─ 空チェック
    │      └─ Helper.MoveVariant(Pop, mItems(mCount))
    │
    ├─ Peek()
    │      ├─ 空チェック
    │      └─ VariantCopy(Peek, mItems(mCount - 1))
    │
    ├─ Contains(Value)
    │      └─ CorArray.IndexOf(mItems, Value, 0, mCount)
    │
    ├─ ToArray()
    │      └─ 逆順コピー (For i = 0 To mCount - 1)
    │
    ├─ CopyTo(Arr, Index)
    │      ├─ CorArray.CopyEx(mItems, Arr)
    │      └─ CorArray.Reverse(Arr)
    │
    ├─ Clone()
    │      └─ New Stack.InitClone(mItems, mCount)
    │
    └─ Clear()
           └─ ReDim mItems(0 To mCapacity - 1)
```

### データフロー図

```
[入力]               [処理]                    [出力]

Value ──────────────▶ Push ─────────────────────▶ （なし）
                         │
                         ▼
                 EnsureCapacity
                         │
                         ▼
                 mItems(mCount) = Value
                         │
                         ▼
                     mCount++

（なし） ───────────▶ Pop ──────────────────────▶ Variant
                         │
                         ▼
                     mCount--
                         │
                         ▼
                 Result = mItems(mCount)
                         │
                         ▼
                 mItems(mCount) = Empty

（なし） ───────────▶ Peek ─────────────────────▶ Variant
                         │
                         ▼
                 Return mItems(mCount - 1)

（なし） ───────────▶ ToArray ──────────────────▶ Variant()
                         │                    (LIFO順)
                         ▼
                   逆順コピー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Stack.cls | `Source/CorLib/System.Collections/Stack.cls` | ソース | メインクラス定義 |
| StackTests.cls | `Source/Tests/System.Collections/StackTests.cls` | テスト | 単体テストケース |
| StackEnumerator.cls | `Source/CorLib/System.Collections/StackEnumerator.cls` | ソース | For Each用列挙子 |
| ICollection.cls | `Source/CorLib/System.Collections/ICollection.cls` | ソース | コレクションインターフェース |
| CorArray.cls | `Source/CorLib/System/CorArray.cls` | ソース | 配列操作ユーティリティ |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewStackコンストラクタ |
