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
133
134
135
136
137
138
139
140
141
142
// SPDX-FileCopyrightText: 2026 John Moxley
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Div policy — the per-`(N, SCALE)` algorithm matcher for decimal
//! division.
//!
//! `D<Int<N>, SCALE>::div_with` delegates directly to the one shared
//! [`dispatch`] generic function, mirroring [`crate::policy::mul`] and the
//! canonical policy shape (see `docs/ARCHITECTURE.md` → "Policy file
//! structure"):
//!
//! 1. an [`Algorithm`] enum — the real division algorithms, no `Default`
//! variant;
//! 2. a [`Select`] verdict — a settled algorithm or "the value decides"
//! (div has no value split, so `ByValue` is never returned);
//! 3. a `const fn` [`select`] keyed on `(N, SCALE)`, total over the key;
//! 4. dispatch via an inline `const { select::<N, SCALE>() }` 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.
//!
//! # Work width — expanded in limbs, no `Int<2N>` type
//!
//! Decimal division scales the numerator by `10^SCALE` (`a * 10^SCALE`),
//! which spans up to `2N` limbs, before dividing by `b`. Rather than thread
//! a work *type* `Int<2N>` (unnameable from `N` on stable), the
//! [`WidenScale`](Algorithm::WidenScale) kernel forms the scaled numerator
//! directly in a `ComputeLimbs` limb buffer and divides via the int layer's
//! width-agnostic `div_rem`. So `dispatch` carries no work-width parameter;
//! it adds only `where Limbs<N>: ComputeLimbs` for the scratch buffer.
//!
//! The `10^SCALE` multiplier is evaluated here via `Int::<N>::TEN.pow(SCALE)`
//! (folds at compile time per `(N, SCALE)`) and threaded into the kernel.
use crate;
use crateInt;
use crateRoundingMode;
// ── 1. the real division algorithms — NAMED, no `Default` ─────────────
/// The division algorithms this policy chooses between. Variants are the
/// CamelCase of each kernel fn's name minus the `div_` prefix
/// (`div_widen_scale` → `WidenScale`, `div_schoolbook` → `Schoolbook`).
// ── 2. the verdict ────────────────────────────────────────────────────
/// A settled algorithm, or "the value decides". The div picker always
/// returns `ByAlgorithm`; `ByValue` is part of the canonical shape for
/// uniformity and `select` never returns it.
// ── 3. the matcher: const, keyed on `(N, SCALE)`, total over the key ──
/// Pick the division algorithm for storage limb count `N` and decimal
/// `SCALE`. Total over the key; `Native` at `N == 2`, `WidenScale`
/// otherwise.
const
// ── 4. the shared dispatch: resolve the verdict, then dispatch ────────
/// Decimal division dispatch for storage `Int<N>` and decimal `SCALE`.
///
/// The `const { select }` block folds away at every concrete `N`, leaving a
/// direct call to the chosen kernel. The `2N`-wide scaled numerator lives
/// in the kernel's `ComputeLimbs` scratch buffer, so no work-width type is
/// named here.
pub