1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-FileCopyrightText: 2026 John Moxley
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Decimal equality policy — the per-`(N, M, S1, S2)` algorithm matcher
//! for `PartialEq<D<Int<M>, S2>> for D<Int<N>, S1>`.
//!
//! See `docs/ARCHITECTURE.md` → "Policy file structure".
//!
//! `D<Int<N>, S1>::eq` delegates to [`deq_dispatch`], which follows the
//! canonical policy shape:
//!
//! 1. an [`Algorithm`] enum — the real equality algorithms, no `Default`
//! variant;
//! 2. a [`Select`] verdict — a settled algorithm or "the value decides"
//! (equality choice is fully determined by the const generics, so
//! `ByValue` is never returned);
//! 3. a `const fn` [`select`] keyed on `(S1, S2)`, total over the key;
//! 4. dispatch via an inline `const { select::<N, S1, S2>() }` block, then
//! an **exhaustive** `match algo` — no `_`, no panic.
//!
//! Because `select` is `const` and keyed only on the const generics, the
//! `const { … }` block folds per monomorphisation and every unchosen arm
//! is dead-arm-eliminated in release: each concrete `(N, S1, S2)` compiles
//! to a direct call to one kernel, no runtime branch.
//!
//! # Why two algorithms
//!
//! Equality is derived from [`crate::policy::dcmp::dcmp_dispatch`]: two
//! values are equal when their comparison is `Equal`. When `S1 == S2` the
//! same-scale shortcut applies (plain cross-width integer compare); when
//! `S1 != S2` the cross-scale path is taken. This mirrors the two
//! `dcmp_dispatch` algorithms.
//!
//! # Naming collision avoidance
//!
//! The integer policy module `src/int/policy/` contains `eq` (and `cmp`)
//! policies for the `Int<N>` type. This file is `deq` (decimal eq) in
//! `src/policy/` to avoid any name collision with those int-tier modules.
use crateInt;
use cratedcmp_dispatch;
// ── 1. the real equality algorithms — NAMED, no `Default` ────────────
/// The equality algorithms this policy chooses between. Variants are the
/// CamelCase of each kernel name, strict 1:1 with the kernel functions.
// ── 2. the const verdict ──────────────────────────────────────────────
/// A settled algorithm, or "the value decides". The equality picker always
/// returns `ByAlgorithm`. `ByValue` is part of the canonical shape for
/// uniformity; `select` never returns it.
// ── 3. the matcher: const, keyed on `(S1, S2)`, total over the key ───
/// Pick the equality algorithm for decimal scales `S1` and `S2` with
/// storage limb count `N`. Total over the key:
/// - `S1 == S2` → `SameScale` (plain cross-width int equal);
/// - `S1 != S2` → `ScaledDiff` (cross-scale compare-for-Equal).
const
// ── algorithm kernels ─────────────────────────────────────────────────
/// Cross-width same-scale equality: plain integer equal on raw storage.
const
/// Cross-width cross-scale equality: test that the comparison is `Equal`.
const
// ── 4. the dispatcher: fold the verdict, then dispatch ────────────────
/// Decimal equality dispatcher for storage `Int<N>` / `Int<M>`, scales
/// `S1` / `S2`. Const-folds to a direct call to one kernel per
/// monomorphisation.
///
/// `const fn`: both kernels are `const fn`, so the dispatcher is too.
pub const