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
143
144
145
146
147
148
// SPDX-FileCopyrightText: 2026 John Moxley
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Rem policy — the per-`(N, SCALE)` algorithm matcher for decimal
//! remainder.
//!
//! `D<Int<N>, SCALE>` remainder delegates to [`RemPolicy::rem_impl`],
//! which forwards to the one shared [`dispatch`] function. `dispatch`
//! follows the canonical policy shape (see `docs/ARCHITECTURE.md` →
//! "Policy file structure"), mirroring [`crate::policy::add`]:
//!
//! 1. an [`Algorithm`] enum — the real remainder algorithm, no `Default`
//! variant;
//! 2. a [`Select`] verdict — a settled algorithm or "the value decides"
//! (rem 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: each concrete `D<Int<N>, SCALE>`
//! compiles to a direct call to one kernel, no runtime branch.
//!
//! # The two algorithms and the width split
//!
//! Decimal remainder requires no rescaling when both operands share the same
//! `SCALE`: because both carry the same `10^SCALE` factor, the storage-level
//! remainder is the answer. The split is purely on storage width `N`:
//!
//! * **`N <= 2`** (D18 / D38) → `rem_native`: the storage value fits a single
//! hardware integer, so the remainder is a direct primitive `%` (`i64 %` at
//! `N == 1`, `i128 %` at `N == 2`). Microbenched at the dispatch seam:
//! native beats `rem_int_layer` ~1.5x at D18 and ~8x at D38 by skipping the
//! generic unpack-to-magnitude / divmod / signed-repack.
//! * **`N >= 3`** → `rem_int_layer`: the magnitude exceeds a single hardware
//! integer, so it unpacks to unsigned magnitudes and runs the const-`N`
//! divmod, detecting the `MIN % -ONE` overflow up front.
//!
//! Both follow the same overflow contract: a zero divisor and the
//! `MIN % -ONE` overflow both panic in BOTH debug and release (the default
//! operator never silently wraps to `0`). `ByValue` is present for
//! canonical-shape uniformity; `select` never returns it.
use crateInt;
// ── 1. the real remainder algorithm — NAMED, no `Default` ─────────────
/// The remainder algorithms this policy chooses between. The single variant
/// is the CamelCase of the kernel fn's name minus the `rem_` function
/// prefix (`rem_int_layer` → `IntLayer`) — strict 1:1 with the kernel fn.
// ── 2. the verdict ────────────────────────────────────────────────────
/// A settled algorithm, or "the value decides". The rem picker always
/// returns `ByAlgorithm`. `ByValue` is part of the canonical shape for
/// uniformity; `select` never returns it.
// ── 3. the matcher: const, keyed on `(N, SCALE)`, total over the key ──
/// Pick the remainder algorithm for storage limb count `N` and decimal
/// `SCALE`. Total over the key; `IntLayer` wins at every `(N, SCALE)`.
const
// ── 4. the dispatcher: fold the verdict, then dispatch ────────────────
/// Decimal remainder dispatcher for storage `Int<N>` and decimal `SCALE`.
///
/// Resolves the compile-time algorithm verdict via
/// `const { select::<N, SCALE>() }` (folds per monomorphisation; dead arms
/// are eliminated in release) then dispatches exhaustively over
/// [`Algorithm`].
///
/// Not `const fn`: matches the existing non-`const` `Rem` operator on
/// `D<Int<N>, SCALE>`.
pub
// ── per-type `RemPolicy` trait ────────────────────────────────────────
/// Per-type policy: which kernel a `D<Int<N>, SCALE>` uses for `%`.
pub