# 機能設計書 18-ArrayList

## 概要

本ドキュメントは、VBCorLibライブラリにおける動的配列リスト機能「ArrayList」クラスの機能設計について記述する。

### 本機能の処理概要

ArrayListクラスは、動的にサイズが増加するリストコレクションを提供するクラスである。.NET FrameworkのSystem.Collections.ArrayListクラスと互換性のあるAPIを持ち、VBAの標準配列の固定サイズ制約を解消する。内部にVariant配列を持ち、要素の追加・削除・検索・ソートなど、配列操作に必要な機能を包括的に提供する。

**業務上の目的・背景**：VBAの標準配列は宣言時にサイズを決定する必要があり、動的なサイズ変更にはReDimが必要となる。ArrayListはこの制約を解消し、要素数に応じて自動的にサイズが調整される柔軟なリストを提供する。

**機能の利用シーン**：
- 可変長のデータコレクション管理
- データの動的な追加・削除
- リストのソート・検索処理
- For Each ループによるイテレーション
- 他のコレクションへのデータ変換

**主要な処理内容**：
1. 要素操作（Add、Insert、Remove、RemoveAt、Clear）
2. 要素アクセス（Item、IndexOf、LastIndexOf、Contains）
3. 範囲操作（AddRange、InsertRange、RemoveRange、GetRange、SetRange）
4. ソート・検索（Sort、BinarySearch、Reverse）
5. 変換（ToArray、CopyTo）
6. 容量管理（Capacity、Count、TrimToSize）

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Value | Variant | Yes | 追加/挿入する値 | 任意の値（オブジェクト含む） |
| Index | Long | Yes | 操作対象のインデックス | 0以上Count以下 |
| Source | Variant | Yes | AddRange/InsertRangeのソース | Array、ICollection、Collection |
| Comparer | IComparer | No | Sort/BinarySearchの比較オブジェクト | IComparer実装 |
| ArrayType | VbVarType | No | ToArrayの配列型 | 有効なVbVarType |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Item(Index) | Variant | 指定位置の要素 |
| Add戻り値 | Long | 追加された位置のインデックス |
| IndexOf戻り値 | Long | 要素の位置（未発見時-1） |
| Contains戻り値 | Boolean | 要素の存在有無 |
| BinarySearch戻り値 | Long | 検索結果インデックス（未発見時負数） |
| ToArray戻り値 | Variant | 配列に変換された要素 |
| Count | Long | 要素数 |
| Capacity | Long | 内部配列の容量 |
| Clone戻り値 | ArrayList | 浅いコピー |
| GetRange戻り値 | ArrayList | 範囲ビュー |

### 出力先

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

## 処理フロー

### 処理シーケンス

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

2. Add呼び出し
   └─ EnsureCapacityで容量確認
   └─ Countの位置に要素追加
   └─ Count++
   └─ 追加位置のインデックスを返却

3. Insert呼び出し
   └─ インデックスバリデーション
   └─ EnsureCapacityで容量確認
   └─ 挿入位置以降の要素を後方移動
   └─ 挿入位置に要素設定
   └─ Count++

4. Sort呼び出し
   └─ 範囲バリデーション
   └─ CorArray.SortExで内部配列をソート
   └─ Version++

5. For Each使用
   └─ NewEnumでIUnknownを返却
   └─ ArrayListEnumeratorで要素をイテレート
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{メソッド種別}
    B -->|Add| C[EnsureCapacity]
    C --> D[mItems(mCount) = Value]
    D --> E[mCount++]
    E --> F[mVersion++]
    F --> G[インデックス返却]
    B -->|Insert| H{Index有効?}
    H -->|No| I[ArgumentOutOfRangeException]
    H -->|Yes| J[EnsureCapacity]
    J --> K[InsertSpace]
    K --> L[mItems(Index) = Value]
    L --> E
    B -->|Remove| M[IndexOf検索]
    M --> N{見つかった?}
    N -->|No| O[何もしない]
    N -->|Yes| P[RemoveAt呼び出し]
    B -->|RemoveAt| Q{Index有効?}
    Q -->|No| R[ArgumentOutOfRangeException]
    Q -->|Yes| S[要素クリア]
    S --> T[RemoveSpace]
    T --> U[mCount--]
    U --> F
    B -->|Sort| V[範囲バリデーション]
    V --> W[CorArray.SortEx]
    W --> F
    G --> X[終了]
    O --> X
    I --> X
    R --> X
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルト容量 | 初期容量は16要素 | 新規インスタンス生成時 |
| BR-002 | 容量拡張戦略 | 容量不足時は現在の2倍に拡張 | EnsureCapacity時 |
| BR-003 | 0ベースインデックス | 全インデックスは0ベース | インデックス指定時 |
| BR-004 | シャローコピー | Cloneは浅いコピーを作成（参照型はポインタコピー） | Clone呼び出し時 |
| BR-005 | バージョン管理 | 変更時にVersionをインクリメント | 変更操作時 |
| BR-006 | 列挙中の変更検出 | 列挙中に変更されると例外 | For Each中の変更時 |

### 計算ロジック

**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
```

**BinarySearch**:
```
' ソート済み前提の二分探索
' 戻り値が負数の場合：Not(戻り値) が挿入位置
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentOutOfRangeException | Indexが負またはCount超過 | 有効な範囲を指定 |
| - | ArgumentNullException | Sourceがnull（AddRange等） | 有効なソースを指定 |
| - | ArgumentException | Index + Count > Count（範囲操作） | 有効な範囲を指定 |
| - | RankException | 多次元配列を指定（AddRange等） | 1次元配列を使用 |
| - | InvalidOperationException | 列挙中の変更 | 列挙完了後に変更 |
| - | InvalidCastException | ToArrayで変換不可能な型 | 互換性のある型を指定 |

### リトライ仕様

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

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

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

## パフォーマンス要件

- Add: O(1)の償却定数時間
- Insert/RemoveAt: O(n)（要素の移動が必要）
- IndexOf/Contains: O(n)の線形検索
- BinarySearch: O(log n)（ソート済み前提）
- Sort: O(n log n)

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

- 参照型要素は浅いコピーとなるため、Clone後も同一オブジェクトを参照
- 大量データの場合はメモリ使用量に注意

## 備考

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

---

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

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

### 推奨読解順序

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

ArrayListクラスは内部にVariant配列を持ち、これが要素のコンテナとなる。

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

**主要なメンバ変数**:
- **70行目**: `mItems() As Variant` - 内部配列
- **71行目**: `mCount As Long` - 要素数
- **72行目**: `mCapacity As Long` - 配列容量
- **73行目**: `mVersion As Long` - バージョン（変更検出用）

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

#### Step 2: 要素追加・削除を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ArrayList.cls | `Source/CorLib/System.Collections/ArrayList.cls` | Add、Insert、Remove、RemoveAt |

**主要処理フロー**:
1. **88-91行目**: Addメソッド - CountにInsertして位置を返却
2. **424-433行目**: Insertメソッド - 空間確保と要素設定
3. **564-571行目**: Removeメソッド - IndexOf検索後RemoveAt
4. **579-587行目**: RemoveAtメソッド - 要素クリアと空間削除

#### Step 3: 検索・ソートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ArrayList.cls | `Source/CorLib/System.Collections/ArrayList.cls` | IndexOf、BinarySearch、Sort |

**主要処理フロー**:
- **399-415行目**: IndexOfメソッド - CorArray.IndexOfに委譲
- **174-188行目**: BinarySearchExメソッド - CorArray.BinarySearchExに委譲
- **661-674行目**: Sortメソッド - CorArray.SortExに委譲

#### Step 4: 範囲操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ArrayList.cls | `Source/CorLib/System.Collections/ArrayList.cls` | AddRange、InsertRange、RemoveRange、GetRange |

**主要処理フロー**:
- **109-111行目**: AddRangeメソッド - InsertRange(mCount, Source)に委譲
- **444-450行目**: InsertRangeメソッド - WriteRangeで一括追加
- **594-610行目**: RemoveRangeメソッド - 範囲削除と空間詰め
- **378-389行目**: GetRangeメソッド - RangedArrayListで範囲ビュー

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

```
ArrayList (インスタンス)
    │
    ├─ Add(Value) / Insert(Index, Value)
    │      ├─ EnsureCapacity
    │      ├─ InsertSpace (Insert時)
    │      └─ VariantCopyInd
    │
    ├─ AddRange(Source) / InsertRange(Index, Source)
    │      └─ WriteRange
    │             ├─ WriteArray / WriteVBCollection / WriteICollection
    │             └─ WriteCollection → EnsureCapacity, Helper.MoveVariant
    │
    ├─ Remove(Value)
    │      ├─ IndexOf
    │      └─ RemoveAt
    │
    ├─ RemoveAt(Index) / RemoveRange(Index, Count)
    │      ├─ 要素クリア (Empty)
    │      └─ RemoveSpace (CopyMemory, ZeroMemory)
    │
    ├─ IndexOf(Value) / Contains(Value)
    │      └─ CorArray.IndexOf
    │
    ├─ BinarySearch(Value, Comparer)
    │      └─ CorArray.BinarySearchEx
    │
    ├─ Sort(Index, Count, Comparer)
    │      └─ CorArray.SortEx
    │
    ├─ Reverse(Index, Count)
    │      └─ CorArray.Reverse
    │
    ├─ GetRange(Index, Count)
    │      └─ New RangedArrayList.Init(Me, Index, Count)
    │
    ├─ Clone()
    │      └─ New ArrayList.InitClone(mItems, mCount)
    │
    └─ ToArray(ArrayType)
           └─ CorArray.CreateInstance + CorArray.CopyEx
```

### データフロー図

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

Value ──────────────────▶ Add ────────────────────▶ Index (Long)
                             │
                             ▼
                    EnsureCapacity
                             │
                             ▼
                    mItems(mCount) = Value
                             │
                             ▼
                         mCount++

Source (Array/Collection) ─▶ AddRange ────────────▶ （なし）
                                │
                                ▼
                        WriteRange
                                │
                                ▼
                    For Each Value In Source

Value ──────────────────▶ IndexOf ────────────────▶ Index / -1
                             │
                             ▼
                    CorArray.IndexOf

（なし） ───────────────▶ ToArray ─────────────────▶ Variant配列
                             │
                             ▼
                    CorArray.CreateInstance
                             │
                             ▼
                    CorArray.CopyEx
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ArrayList.cls | `Source/CorLib/System.Collections/ArrayList.cls` | ソース | メインクラス定義 |
| ArrayListTests.cls | `Source/Tests/System.Collections/ArrayListTests.cls` | テスト | 単体テストケース |
| RangedArrayList.cls | `Source/CorLib/System.Collections/RangedArrayList.cls` | ソース | GetRange用の範囲ビュー |
| ArrayListEnumerator.cls | `Source/CorLib/System.Collections/ArrayListEnumerator.cls` | ソース | For Each用列挙子 |
| IList.cls | `Source/CorLib/System.Collections/IList.cls` | ソース | リストインターフェース |
| ICollection.cls | `Source/CorLib/System.Collections/ICollection.cls` | ソース | コレクションインターフェース |
| CorArray.cls | `Source/CorLib/System/CorArray.cls` | ソース | 配列操作ユーティリティ |
| Constructors.cls | `Source/CorLib/Constructors.cls` | ソース | NewArrayListコンストラクタ |
