# 機能設計書 77-reverse

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`reverse`関数の機能設計を記述する。この関数は、Traversableの要素を逆順にした新しいvecを生成する機能を提供する。

### 本機能の処理概要

`Vec\reverse`関数は、入力されたTraversableの要素を逆順に並べ替えた新しいvecを返却する。入力のTraversableはそのまま保持され、新しいvecが生成される（非破壊的操作）。

**業務上の目的・背景**：データの逆順処理は、様々な場面で必要となる。例えば、時系列データを新しい順から古い順に表示する、スタック的なデータ構造を扱う、ソート結果を逆順にするなどのケースである。`reverse`関数は、このような逆順処理を効率的かつ型安全に実行することを可能にする。

**機能の利用シーン**：
- 時系列データを逆順で表示する
- ソート結果を降順から昇順に（またはその逆に）変換する
- スタック的なデータ操作を行う
- 履歴データを最新順に並べ替える

**主要な処理内容**：
1. 入力としてTraversableを受け取る
2. Traversableをvecに変換する
3. インプレースで要素を逆順に入れ替える
4. 逆順になったvecを返却する

**関連システム・外部連携**：本機能は純粋な関数であり、外部システムとの連携はない。内部でC\count関数を使用する。

**権限による制御**：本機能は純粋関数（Pure Function）であり、権限による制御は適用されない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 画面なし | - | 本プロジェクトはUIを持たないライブラリ |

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<Tv> | Yes | 逆順にする対象のコレクション | なし（空コレクションも許容） |

### 入力データソース

関数引数として直接渡される。Traversableとして許容される型には、vec、dict、keyset、Vector、Map、Set、およびカスタムIteratorが含まれる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 要素が逆順になった新しいvec |

### 出力先

関数の戻り値として呼び出し元に返却される。

## 処理フロー

### 処理シーケンス

```
1. Traversableをvecに変換
   └─ $vec = cast_clear_legacy_array_mark($traversable)
2. 両端のインデックスを初期化
   └─ $lo = 0, $hi = C\count($vec) - 1
3. 両端から中央に向かって要素を入れ替え
   └─ while ($lo < $hi)
       ├─ $temp = $vec[$lo]
       ├─ $vec[$lo] = $vec[$hi]
       ├─ $vec[$hi] = $temp
       ├─ $lo++
       └─ $hi--
4. 逆順になったvecを返却
   └─ return $vec
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[$traversableをvecに変換]
    B --> C[$lo = 0, $hi = count - 1]
    C --> D{$lo < $hi?}
    D -->|Yes| E[$temp = $vec[$lo]]
    E --> F[$vec[$lo] = $vec[$hi]]
    F --> G[$vec[$hi] = $temp]
    G --> H[$lo++, $hi--]
    H --> D
    D -->|No| I[$vecを返却]
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-77-01 | 完全逆順 | すべての要素が逆順になる | 常時 |
| BR-77-02 | 空入力処理 | 空のTraversableは空のvecを返す | 入力が空の場合 |
| BR-77-03 | 単一要素 | 単一要素の場合はその要素のみを含むvecを返す | 要素数が1の場合 |
| BR-77-04 | キー破棄 | KeyedTraversableのキーは破棄される | KeyedTraversable入力時 |
| BR-77-05 | 非破壊操作 | 入力のTraversableは変更されない | 常時 |

### 計算ロジック

- 入れ替え回数 = floor(n / 2)
- 出力[i] = 入力[n - 1 - i] for i in 0..n-1

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

### 操作別データベース影響一覧

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は例外をスローしない | - |

### リトライ仕様

本機能にリトライ仕様はない。

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

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- 時間計算量: O(n) - nは入力要素数
- 空間計算量: O(n) - 結果格納用のvec（入力の変換に使用）

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

本機能は純粋関数であり、特別なセキュリティ考慮事項はない。

## 備考

- インプレースの入れ替えアルゴリズムを使用しており、追加のメモリ割り当ては最小限
- 内部関数`cast_clear_legacy_array_mark`を使用してレガシー配列マークをクリアする

---

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

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

### 推奨読解順序

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

`reverse`関数はシンプルなvec操作を行う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | Traversable<Tv>とvec<Tv>の関係を理解する |

**読解のコツ**: Hackのvecは可変長の配列であり、インデックスアクセスが可能。インプレースの入れ替えが効率的に行える。

#### Step 2: 補助関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cast.php | `src/vec/cast.php` | cast_clear_legacy_array_mark関数の実装を確認 |
| 2-2 | C\count | HSL C名前空間 | 要素数のカウント関数を理解 |

#### Step 3: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order.php | `src/vec/order.php` | reverse関数の定義と実装を確認 |

**主要処理フロー**:
1. **46-48行目**: 関数シグネチャ - Traversableを受け取りvecを返す
2. **49行目**: cast_clear_legacy_array_markでvecに変換
3. **50行目**: 両端のインデックスを初期化（$lo = 0, $hi = count - 1）
4. **51-54行目**: whileループで両端から中央に向かって入れ替え
5. **55行目**: 結果を返却

#### Step 4: テストケースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | VecOrderTest.php | `tests/vec/VecOrderTest.php` | reverse関数のテストケースを確認 |

**主要処理フロー**:
- **95-110行目**: provideTestReverseメソッドでテストデータを提供
- **97-100行目**: 数値配列の逆順テスト
- **101-104行目**: 文字列Vectorの逆順テスト
- **105-108行目**: Iteratorの逆順テスト
- **112-118行目**: 実際のテスト実行メソッド

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

```
呼び出し元コード
    │
    └─ Vec\reverse($traversable)
           │
           ├─ cast_clear_legacy_array_mark($traversable) → $vec
           │
           ├─ C\count($vec) → 要素数取得
           │
           └─ for ループ（両端入れ替え）
                  │
                  └─ $lo と $hi の要素を入れ替え
```

### データフロー図

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

Traversable<Tv>            ───▶  vecに変換
                                      │
                                      ▼
                                 両端入れ替え          ───▶  vec<Tv>
                                 $lo ⟷ $hi

例:
vec[1, 2, 3, 4, 5]         ───▶  reverse処理  ───▶  vec[5, 4, 3, 2, 1]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order.php | `src/vec/order.php` | ソース | reverse関数の実装 |
| cast.php | `src/vec/cast.php` | ソース | cast_clear_legacy_array_mark関数の実装 |
| VecOrderTest.php | `tests/vec/VecOrderTest.php` | テスト | reverse関数のユニットテスト |
