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
149
150
151
152
153
154
use crate;
/// Rounds up the given value `x` to the next power of two.
///
/// Examples:
/// - `roundup64(5)` -> 8
/// - `roundup64(8)` -> 8
///
/// # Arguments
///
/// * `x` – An unsigned 64-bit integer to round up.
///
/// # Returns
///
/// * The smallest power of two greater than or equal to `x`.
pub const
/// Returns the complementary DNA/RNA base for the given ASCII byte.
///
/// Looks up the byte in the `COMPL_BASES` table, which maps:
/// `A ↔ T`, `C ↔ G` (uppercase and lowercase), `U/u → A`, and all others to `N`.
///
/// # Arguments
///
/// * `b` – An ASCII byte representing a nucleotide.
///
/// # Returns
///
/// * The ASCII byte for the complementary base, or `b'N'` if outside A/C/G/T/U.
pub const
/// Encodes a nucleotide ASCII byte into its 2-bit code (0‒3), or 4 for invalid.
///
/// Uses the `SEQ_NT4_TABLE`, which assigns:
/// - A/a → 0
/// - C/c → 1
/// - G/g → 2
/// - T/t, U/u → 3
/// - Any other ASCII byte → 4
///
/// # Arguments
///
/// * `b` – An ASCII byte representing a nucleotide.
///
/// # Returns
///
/// * A 2-bit encoding (0..=3) for valid nucleotides, or 4 for any other byte.
pub const
/// Largest `m1` index at which a strobemer iterator can still produce an item.
///
/// Both iterators stop at the first position whose search window runs past the
/// last `l`-mer, and that bound only tightens as the index grows, so this makes
/// the remaining length exact:
///
/// - order 2 needs `idx + w_min ≤ end_hash` when shrinking, `idx + w_max ≤ end_hash` otherwise
/// - order 3 needs `idx + w_max + w_min ≤ end_hash` when shrinking, `idx + 2·w_max ≤ end_hash` otherwise
///
/// # Arguments
///
/// * `n` – Strobemer order (2 or 3).
/// * `shrink` – Whether terminal windows may be shortened.
/// * `w_min`, `w_max` – Window offsets.
/// * `end_hash` – Index of the last `l`-mer (`seq.len() - l`).
///
/// # Returns
///
/// * `Some(idx)` – The last usable starting index.
/// * `None` – No position qualifies, or `n` is out of range.
pub const
/// Validates parameters for strobemer construction and returns early on error.
///
/// This macro is intended to be invoked at the start of constructors or functions
/// that require:
/// - A non-empty, ASCII-only sequence slice (`$seq`)
/// - An order (`$n`) of either 2 or 3
/// - A strobe length (`$l`) between 1 and 64
/// - Window offsets (`$w_min`, `$w_max`) where both are > 0 and `w_min ≤ w_max`
/// - Sequence length sufficient to accommodate `(n - 1)` windows of size `(w_max + 1)`
/// - Sequence length of at least `l`, so that one strobe fits
///
/// Returns the corresponding `StrobeError` on any validation failure:
/// - `InvalidSequence` if the sequence is empty
/// - `InvalidOrder` if `n < 2`
/// - `OrderNotSupported` if `n > 3`
/// - `StrobeLengthTooSmall` if `l` is outside [1..=64]
/// - `InvalidWindowOffsets` if `w_min` or `w_max` are zero or `w_min > w_max`
/// - `SequenceTooShort` if `seq.len()` is too small for the given parameters
///
/// # Example
///
/// ```ignore
/// validate_params!(seq, n, l, w_min, w_max);
/// ```