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
// SPDX-FileCopyrightText: 2026 John Moxley
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Add policy — the default-delegating algorithm matcher for integer addition.
//!
//! `Int<N>::wrapping_add` and the `Add` operator delegate to [`dispatch`],
//! which follows the canonical policy shape (see `docs/ARCHITECTURE.md` →
//! "Policy file structure"):
//!
//! 1. an [`Algorithm`] enum — the real addition algorithm(s), no `Default`
//! variant;
//! 2. a [`Select`] verdict — a settled algorithm or "the value decides";
//! 3. a `const fn` [`select`] keyed on `N`, total over the key;
//! 4. dispatch via an inline `const { select::<N>() }` block, then an
//! **exhaustive** `match algo` — no `_`, no panic.
//!
//! Because `select` is `const` and keyed only on the const generic `N`,
//! the `const { … }` block folds per monomorphisation and the unchosen arm
//! is dead-arm-eliminated in release: each concrete `Int<N>` compiles to a
//! direct call to the ripple-carry limb kernel, no runtime branch.
//!
//! # Why there is only one algorithm
//!
//! Integer addition is width-independent: the ripple-carry accumulator in
//! [`crate::int::algos::support::limbs::add_assign_fixed`] is the unique correct
//! choice at every limb count `N`. There is no crossover threshold, no
//! value-dependent split, and no work-width widening (work width ==
//! storage width). The `ByValue` arm of [`Select`] is present for
//! canonical-shape uniformity; `select` never returns it.
//!
//! # Why `dispatch` is `const fn`
//!
//! `Int<N>::wrapping_add` is itself `const fn` and is called from const
//! constructors and other `const fn` contexts across the crate. `dispatch`
//! therefore must also be `const fn`. A pure-`ByAlgorithm` dispatch can
//! satisfy this: the `ByValue` arm simply returns the default algorithm tag
//! without invoking the fn pointer (calling a fn pointer is not permitted in
//! `const fn`; merely matching the variant is fine).
use crateadd_ripple_carry;
use crateInt;
// ── 1. the real addition algorithm — NAMED, no `Default` ─────────────
/// The addition algorithms this policy chooses between. The single variant
/// is the CamelCase of the kernel fn's name minus the `add_` function
/// prefix (`add_ripple_carry` → `RippleCarry`) — strict 1:1 with the
/// kernel fn.
// ── 2. the verdict ────────────────────────────────────────────────────
/// A settled algorithm, or "the value decides". The add picker always
/// returns `ByAlgorithm`: the choice is fully determined by `N` (which
/// is constant, and the same algorithm wins at every `N`). `ByValue` is
/// part of the canonical shape for uniformity across functions; `select`
/// never returns it.
// ── 3. the matcher: const, keyed on `N`, total over the key ──────────
/// Pick the addition algorithm for storage limb count `N`. Total over the
/// key; addition is width-independent so `RippleCarry` wins at every `N`.
const
// ── 4. the dispatcher: fold the verdict, then dispatch ────────────────
/// Wrapping integer addition dispatcher for `Int<N>`.
///
/// Resolves the compile-time algorithm verdict via
/// `const { select::<N>() }` (folds per monomorphisation; dead arms are
/// eliminated in release) then dispatches exhaustively over [`Algorithm`].
///
/// Must be `const fn`: `Int<N>::wrapping_add` is itself `const fn` and is
/// called from `const` contexts across the crate. The `ByValue` arm
/// returns the default algorithm tag without invoking the fn pointer,
/// satisfying the `const fn` constraint.
pub const
/// Checked door over the SAME verdict: routes to the fused
/// single-pass checked kernel (`add_ripple_carry_checked` — ripple +
/// overflow verdict in one traversal, the `Option` returned directly).
/// `Int::checked_add` (and through it the decimal `+` operator's
/// panic-on-overflow contract) enters here; the layered
/// `wrapping_add`-then-sign-check shape it replaces measured ≈2× the
/// bare loop at 24 limbs in by-value moves between the layers.
pub const