# 機能設計書 100-C\contains

## 概要

本ドキュメントは、Hack Standard Library (HSL) の `HH\Lib\C\contains` 関数の機能設計について記述する。この関数は、Traversableに指定した値が含まれているかどうかを厳密等価（===）で判定する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
コレクション内に特定の値が存在するかを確認する処理は、データの重複チェック、メンバーシップ判定、バリデーションなどで最も基本的かつ頻繁に使用される操作の一つである。本機能は、Traversableの各要素と指定された値を厳密等価（===）で比較し、一致する要素が存在するかを判定する。keysetやConstSetに対してはO(1)の高速な判定を提供する最適化も実装されている。

**機能の利用シーン**：
- ユーザーIDがメンバーリストに含まれているかチェックする際
- 入力値が許可リスト（ホワイトリスト）に含まれているか確認する際
- 重複値の検出処理
- フラグや状態が特定の値セットに含まれているか判定する際

**主要な処理内容**：
1. 入力がkeysetまたはConstSetの場合、O(1)のcontains_keyで判定（最適化）
2. それ以外の場合、Traversableを走査し、各要素と厳密等価（===）で比較
3. 一致する要素が見つかった時点でtrueを返却（早期リターン）
4. すべての要素を走査して見つからなければfalseを返却

**関連システム・外部連携**：
- 内部で`C\contains_key`関数を使用（keysetやConstSetの最適化）
- `C\contains_key`（キーの存在確認）とは別の関数

**権限による制御**：
特になし。純粋な計算処理のため、権限による制御は行わない。

## 関連画面

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

## 機能種別

計算処理（判定処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<T1> | Yes | 検索対象のコレクション | readonly |
| $value | T2 | Yes | 検索する値 | readonly |

### 入力データソース

関数呼び出し時の引数として渡されるTraversableインスタンスと検索値。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | bool | 値が含まれていればtrue、含まれていなければfalse |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 最適化チェック
   └─ $traversableがkeysetまたはConstSetの場合
   └─ $valueがarraykeyの場合、contains_keyで判定して返却
2. 線形探索
   └─ Traversableを走査
   └─ 各要素と$valueを===で比較
   └─ 一致すれば即座にtrueを返却
3. 一致なし
   └─ falseを返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{$traversable is keyset or ConstSet?}
    B -->|Yes| C{$value is arraykey?}
    C -->|Yes| D[contains_key($traversable, $value)]
    D --> E[結果を返却]
    C -->|No| F[falseを返却]
    B -->|No| G{traversable走査}
    G --> H{$value === $v?}
    H -->|Yes| I[trueを返却]
    H -->|No| J[次の要素へ]
    J --> G
    G -->|完了| K[falseを返却]
    E --> L[終了]
    F --> L
    I --> L
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 厳密比較 | 値の比較は厳密等価（===）で行う | 全ての比較時 |
| BR-02 | 型の厳密性 | int型の3とstring型の'3'は異なる値として扱う | 全ての比較時 |
| BR-03 | keyset最適化 | keysetやConstSetに対してはO(1)で判定 | 入力がkeysetまたはConstSet |
| BR-04 | 非arraykey値 | keysetやConstSetに対して非arraykey値を検索した場合はfalse | 値がarraykeyでない場合 |

### 計算ロジック

- 時間計算量: O(n) - 通常のTraversableの場合、nはサイズ
- 時間計算量: O(1) - keysetやConstSetの場合
- 空間計算量: O(1)

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

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

該当なし。本機能はインメモリでのコレクション操作のみを行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 特にエラーケースなし | - |

### リトライ仕様

該当なし。純粋関数であり、同じ入力に対しては常に同じ結果を返す。

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

該当なし。インメモリ操作のみ。

## パフォーマンス要件

- 時間計算量: O(n) - 通常ケース、O(1) - keyset/ConstSet
- 空間計算量: O(1)
- 早期リターンにより、見つかり次第処理終了

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

特になし。純粋なデータ判定処理であり、外部リソースへのアクセスは行わない。

## 備考

- readonly修飾子により、入力の不変性が保証されている
- ジェネリクスに`<<__NonDisjoint>>`アトリビュートがあり、T1とT2が重なる可能性を許容
- PHPのin_array($value, $array, true)に相当するが、型安全性が向上している
- dict、vec、配列を含むvecなど、複雑なネスト構造の比較も可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | (Hack言語仕様) | - | keysetやConstSetはO(1)のメンバーシップチェックが可能 |
| 1-2 | (Hack言語仕様) | - | `<<__NonDisjoint>>`は型パラメータが重なることを許容するアトリビュート |

**読解のコツ**: 厳密等価（===）は型と値の両方が一致する場合のみtrueを返す。これにより、型の異なる値（例：3と'3'）は異なるものとして扱われる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | introspect.php | `src/c/introspect.php` | contains関数の実装本体 |

**主要処理フロー**:
1. **41-47行目**: ドキュメントコメント - 機能と計算量の説明
2. **48-54行目**: 関数シグネチャ - NonDisjointアトリビュートとreadonly修飾子
3. **55-57行目**: keyset/ConstSet最適化 - contains_keyで判定
4. **58-62行目**: 線形探索 - ===で比較
5. **63行目**: return false

#### Step 3: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | introspect.php | `src/c/introspect.php` | contains_key関数の実装 |

**主要処理フロー**:
- **66-81行目**: contains_key - array_key_existsを使用したO(1)判定

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

```
C\contains($traversable, $value)
    │
    ├─ $traversable is keyset<_> || $traversable is ConstSet<_>
    │      │
    │      ├─ $value is arraykey
    │      │      └─ C\contains_key($traversable, $value)
    │      │             └─ \array_key_exists($key, $container)
    │      │
    │      └─ return false  [非arraykeyの場合]
    │
    └─ foreach ($traversable as $v)  [線形探索]
           │
           └─ $value === $v  [厳密比較]
```

### データフロー図

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

$traversable ─────────▶ 型チェック ──▶┐
                                      │
                        keyset/Set ──▶ contains_key ──▶ bool
                                      │
                        その他 ─────▶ 線形探索(===) ──▶ bool
                                      │
$value ──────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| introspect.php | `src/c/introspect.php` | ソース | contains関数の実装 |
| CIntrospectTest.php | `tests/c/CIntrospectTest.php` | テスト | contains関数のユニットテスト |
