OpenMS
Loading...
Searching...
No Matches
AhoCorasickAmbiguous.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Chris Bielow $
6// $Authors: Chris Bielow $
7// --------------------------------------------------------------------------
8
9#pragma once
10
12#include <bitset>
13#include <cassert>
14#include <cstring>
15#include <functional> // for std::hash
16#include <limits>
17#include <queue>
18#include <string>
19#include <cstdint>
20#include <unordered_map>
21#include <vector>
22#include <bit> // for std::popcount
23
24namespace OpenMS
25{
28 constexpr char const AAtoChar[28] = {
29 'A', // 00 Ala Alanine
30 'Y', // 01 Tyr Tyrosine
31 'C', // 02 Cys Cysteine
32 'D', // 03 Asp Aspartic Acid // B
33 'N', // 04 Asn Asparagine // B
34 'F', // 05 Phe Phenylalanine
35 'G', // 06 Gly Glycine
36 'H', // 07 His Histidine
37 'I', // 08 Ile Isoleucine // J
38 'L', // 09 Leu Leucine // J
39 'K', // 10 Lys Lysine
40 'W', // 11 Trp Tryptophan
41 'M', // 12 Met Methionine
42 'O', // 13 Pyl Pyrrolysine
43 'P', // 14 Pro Proline
44 'E', // 15 Glu Glutamic Acid // Z
45 'Q', // 16 Gln Glutamine // Z
46 'R', // 17 Arg Arginine
47 'S', // 18 Ser Serine
48 'T', // 19 Thr Threonine
49 'U', // 20 Selenocysteine
50 'V', // 21 Val Valine
51 // ambiguous AAs start here (index: 22...25)
52 'B', // 22 Aspartic Acid, Asparagine $ // the ambAA's need to be consecutive (B,J,Z,X,$)
53 'J', // 23 Leucine, Isoleucine $
54 'Z', // 24 Glutamic Acid, Glutamine $
55 'X', // 25 Unknown
56 // non-regular AA's, which are special
57 '$', // 26 superAA, i.e. it models a mismatch, which can be anything, including AAAs
58 '?', // 27 invalid AA (will usually be skipped) -- must be the last AA (AA::operator++ and others rely on it)
59 };
60
63 constexpr char const CharToAA[256] = {
64 // ASCII char (7-bit Int with values from 0..127) --> amino acid
65 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 0
66 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 1
67 // $
68 27, 27, 27, 27, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 2
69 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 3
70
71 // , A, B, C, D, E, F, G, H, I, J, K, L, M, N, O,
72 27, 00, 22, 02, 03, 15, 05, 06, 07, 8, 23, 10, 9, 12, 04, 13, // 4
73
74 // P, Q, R, S, T, U, V, W, X, Y, Z, , , , , ,
75 14, 16, 17, 18, 19, 20, 21, 11, 25, 01, 24, 27, 27, 27, 27, 27, // 5
76
77 // , a, b, c, d, e, f, g, h, i, j, k, l, m, n, o,
78 27, 00, 22, 02, 03, 15, 05, 06, 07, 8, 23, 10, 9, 12, 04, 13, // 6
79
80 // p, q, r, s, t, u, v, w, x, y, z, , , , , ,
81 14, 16, 17, 18, 19, 20, 21, 11, 25, 01, 24, 27, 27, 27, 27, 27, // 7
82
83 // bytes 128..255 (high bit set: extended ASCII / UTF-8 continuation bytes) --> invalid AA ('?')
84 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 8
85 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 9
86 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 10
87 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 11
88 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 12
89 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 13
90 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 14
91 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, // 15
92 };
93
96 struct OPENMS_DLLAPI Hit {
97 using T = uint32_t;
98 Hit() = default;
99 Hit(T needle_index, T needle_length, T query_pos) : needle_index(needle_index), needle_length(needle_length), query_pos(query_pos) {};
103 bool operator==(const Hit& rhs) const
104 {
105 return needle_index == rhs.needle_index && needle_length == rhs.needle_length && query_pos == rhs.query_pos;
106 }
107 };
108
111 struct OPENMS_DLLAPI AA
112 {
114 constexpr AA() : aa_(AA('?').aa_)
115 {
116 }
117
121 constexpr explicit AA(const char c) : aa_(CharToAA[(unsigned char)c])
122 {
123 }
124
126 constexpr uint8_t operator()() const
127 {
128 return aa_;
129 }
130
132 constexpr bool operator==(const AA other) const
133 {
134 return aa_ == other.aa_;
135 }
136
138 constexpr bool operator<=(const AA other) const
139 {
140 return aa_ <= other.aa_;
141 }
142
144 constexpr bool isAmbiguous() const
145 {
146 return aa_ >= AA('B').aa_;
147 }
148
150 constexpr bool isValid() const
151 {
152 return aa_ != AA('?').aa_;
153 }
154
156 constexpr bool isValidForPeptide() const
157 {
158 return aa_ <= AA('X').aa_; // '$' or '?'
159 }
160
162 constexpr AA& operator++()
163 {
164 ++aa_;
165 assert(aa_ <= AA('?').aa_); // make sure we don't overflow
166 return *this;
167 }
168
170 constexpr AA operator++(int)
171 {
172 AA r(*this);
173 ++aa_;
174 assert(aa_ <= AA('?').aa_); // make sure we don't overflow
175 return r;
176 }
177
179 constexpr AA operator-(const AA rhs) const
180 {
181 AA r(*this);
182 r.aa_ -= rhs.aa_;
183 return r;
184 }
185
187 constexpr char toChar() const
188 {
189 return AAtoChar[aa_];
190 }
191
194 static AA fromIndex(size_t index) noexcept
195 {
196 OPENMS_PRECONDITION(index < unambiguousAACount(), "AA::fromIndex(): index must be in [0, unambiguousAACount())");
197 AA r;
198 r.aa_ = static_cast<uint8_t>(index);
199 return r;
200 }
201
203 static size_t unambiguousAACount()
204 {
205 static_assert(AA('V').aa_ - AA('A').aa_ + 1 == 22, "Unambiguous AA count must be 22 (A-Z, excluding B, J, Z, X)");
206 static_assert(AA('A').aa_ == 0, "A must be the first AA in the enumeration");
207 static_assert(AA('V').aa_ == 21, "V must be the last unambiguous AA in the enumeration");
208 return AA('V').aa_ - AA('A').aa_ + 1;
209 }
210
211 private:
212 uint8_t aa_;
213 };
214
217 class OPENMS_DLLAPI Index
218 {
219 public:
220 using T = uint32_t;
222 constexpr Index() = default;
223
225 constexpr Index(T val) : i_(val) {};
226
228 constexpr bool isInvalid() const
229 {
230 return i_ == std::numeric_limits<T>::max();
231 }
232
234 constexpr bool isValid() const
235 {
236 return i_ != std::numeric_limits<T>::max();
237 }
238
240 constexpr T operator()() const
241 {
242 return i_;
243 }
244
246 constexpr bool operator==(const Index other) const
247 {
248 return i_ == other.i_;
249 }
250
252 constexpr T& pos()
253 {
254 return i_;
255 }
256
258 constexpr T pos() const
259 {
260 return i_;
261 }
262 private:
263 T i_ = std::numeric_limits<T>::max();
264 };
265 } // namespace OpenMS
266
267// this needs to go into namespace std
268template<> struct std::hash<OpenMS::Index>
269{
270 std::size_t operator()(OpenMS::Index const& s) const noexcept
271 {
272 return std::hash<OpenMS::Index::T> {}(s());
273 }
274};
275
276namespace OpenMS
277{
279 struct Bitset {
280 uint32_t bits = 0;
281
282 // Set bit at position `pos` (0-based)
283 void set(int pos) {
284 bits |= (1u << pos);
285 }
286
287 // Clear bit at position `pos`
288 void clear(int pos) {
289 bits &= ~(1u << pos);
290 }
291
292 // Check if bit at position `pos` is set
293 bool test(int pos) const {
294 return (bits >> pos) & 1u;
295 }
296
297 // Left shift the bitset by `n` positions
298 Bitset operator<<(int n) const {
299 Bitset o = *this;
300 return o <<= n;
301 }
302
303 // Left shift the bitset by `n` positions
305 if (n > 31)
306 { // if we shift more than 31 bits, behaviour is undefined (e.g. GCC/Clang/MSVC will not modify 'bits' if n==32)
307 bits = 0; // shift out all bits
308 }
309 else
310 {
311 bits <<= n;
312 }
313 return *this;
314 }
315
316 // Count number of set bits (population count)
317 int pop_count() const {
318 return std::popcount(bits);
319 }
320 }; // end Bitset
321
322
325 struct OPENMS_DLLAPI ACNode
326 {
328 ACNode() {};
329
331 ACNode(const AA label, const uint8_t depth) : edge(label)
332 {
333 depth_and_hits.depth = depth;
334 }
335
337 struct DepthHits {
339 {
340 memset(this, 0, sizeof *this); // make sure bitfields are 0; C++20 allows {} initialization ...
341 };
342 uint8_t has_hit: 1;
343 // we could add another bit here to distinguish between a local hit and suffix hit, but on Windows, this slows it down
344 uint8_t depth : 7;
345 };
346
347 using ChildCountType = uint8_t;
348
349 // do not use std::bitset, since GCC/clang wastes 8 bytes here.
350 //std::bitset<26> children_bitset; ///< bitfield of children (if tree is in BFS order); 26 bits are enough to cover all AA incl. (B,J,X,Z)
352 Index suffix {0};
353 Index first_child {0};
354 AA edge {0};
355 ChildCountType nr_children = 0;
357 };
358
359 // forward declaration
360 struct ACTrieState;
361
363 struct OPENMS_DLLAPI ACScout
364 {
366 ACScout() = delete;
367
369 ACScout(const char* query_pos, Index tree_pos, uint8_t max_aa, uint8_t max_mm, uint8_t max_prefix_loss);
370
372 size_t textPos(const ACTrieState& state) const;
373
377
378 const char* it_query = 0;
380 uint8_t max_aaa_leftover {0};
381 uint8_t max_mm_leftover {0};
382 uint8_t max_prefix_loss_leftover {0};
383 };
384
387 AA nextValidAA(const char*& it_q);
388
391 struct OPENMS_DLLAPI ACTrieState
392 {
393 friend ACScout;
396 void setQuery(const std::string& haystack);
397
401 size_t textPos() const;
402
405 const char* textPosIt() const;
406
408 const std::string& getQuery() const;
409
413
414 std::vector<Hit> hits;
418 std::queue<ACScout> scouts;
420 private:
424 const char* it_q_ = "";
425 std::string query_;
426 };
427
429 class OPENMS_DLLAPI ACTrie
430 {
431 public:
438 ACTrie(uint32_t max_aaa = 0, uint32_t max_mm = 0);
439
442
449 void addNeedle(const std::string& needle);
450
454 void addNeedles(const std::vector<std::string>& needles);
455
458 void addNeedlesAndCompress(const std::vector<std::string>& needles);
459
460 size_t size() const
461 {
462 return trie_.size();
463 }
464
473
475 size_t getNeedleCount() const;
476
479 void setMaxAAACount(const uint32_t max_aaa);
480
482 uint32_t getMaxAAACount() const;
483
486 void setMaxMMCount(const uint32_t max_mm);
487
489 uint32_t getMaxMMCount() const;
490
494 bool nextHits(ACTrieState& state) const;
495
498 void getAllHits(ACTrieState& state) const;
499
500 private:
504 bool nextHitsNoClear_(ACTrieState& state) const;
505
509 Index add_(const Index from, const AA edge);
510
519 bool addHits_(Index i, const size_t text_pos, std::vector<Hit>& hits) const;
520
522 bool addHitsScout_(Index i, const ACScout& scout, const size_t text_pos, std::vector<Hit>& hits, const int current_scout_depths) const;
523
528 Index follow_(const Index i, const AA edge) const;
529
532 bool followScout_(ACScout& scout, const AA edge, ACTrieState& state) const;
533
536 Index stepPrimary_(const Index i, const AA edge, ACTrieState& state) const;
537
540 bool stepScout_(ACScout& scout, ACTrieState& state) const;
541
544 void createScouts_(const Index i, const AA fromAA, const AA toAA, ACTrieState& state, const uint32_t aaa_left, const uint32_t mm_left) const;
545
547 void createSubScouts_(const ACScout& prototype, const AA fromAA, const AA toAA, ACTrieState& state) const;
548
550 void createMMScouts_(const Index i, const AA except_fromAA, const AA except_toAA, const AA except_edge, ACTrieState& state, const uint32_t aaa_left, const uint32_t mm_left) const;
551
553 void createMMSubScouts_(const ACScout& prototype, const AA except_fromAA, const AA except_toAA, const AA except_edge, ACTrieState& state) const;
554
556 Index findChildNaive_(Index parent, AA child_label);
557
559 Index findChildBFS_(const Index parent, const AA child_label) const;
560
561 std::vector<ACNode> trie_;
562 uint32_t needle_count_ {0};
563 uint32_t max_aaa_ {0};
564 uint32_t max_mm_ {0};
565
567 std::vector<std::vector<uint32_t>> vec_index2needles_ = { {} }; // one empty element to allow capacity doubling; note: sparse vector but still much faster and less memory than unordered_map
569 std::vector<std::vector<Index>> vec_index2children_naive_ = { {} }; // one empty element to allow capacity doubling
570 };
571
572} // namespace OpenMS
573
An Aho Corasick trie (a set of nodes with suffix links mainly)
Definition AhoCorasickAmbiguous.h:430
void createMMScouts_(const Index i, const AA except_fromAA, const AA except_toAA, const AA except_edge, ACTrieState &state, const uint32_t aaa_left, const uint32_t mm_left) const
Same as createScouts_, but instantiate all possible AA's except for those in the range from except_fr...
void setMaxMMCount(const uint32_t max_mm)
uint32_t getMaxMMCount() const
Maximum number of mismatches allowed during search.
size_t size() const
Definition AhoCorasickAmbiguous.h:460
ACTrie(uint32_t max_aaa=0, uint32_t max_mm=0)
Default C'tor which just creates a root node.
void addNeedlesAndCompress(const std::vector< std::string > &needles)
bool followScout_(ACScout &scout, const AA edge, ACTrieState &state) const
bool nextHitsNoClear_(ACTrieState &state) const
std::vector< ACNode > trie_
the trie, in either naive structure or BFS order (after compressTrie)
Definition AhoCorasickAmbiguous.h:561
Index add_(const Index from, const AA edge)
Index stepPrimary_(const Index i, const AA edge, ACTrieState &state) const
void addNeedle(const std::string &needle)
void setMaxAAACount(const uint32_t max_aaa)
void addNeedles(const std::vector< std::string > &needles)
void createSubScouts_(const ACScout &prototype, const AA fromAA, const AA toAA, ACTrieState &state) const
Create scouts from a scout with an AAA or MM, using prototype as template, following edges in range f...
bool addHitsScout_(Index i, const ACScout &scout, const size_t text_pos, std::vector< Hit > &hits, const int current_scout_depths) const
same as addHits_, but only follows the suffix chain until the scout loses its prefix
Index follow_(const Index i, const AA edge) const
void getAllHits(ACTrieState &state) const
Index findChildBFS_(const Index parent, const AA child_label) const
After compression (BFS trie), obtain the child with edge child_label from parent; if it does not exis...
bool addHits_(Index i, const size_t text_pos, std::vector< Hit > &hits) const
Add all hits occurring in node i (including all its suffix hits)
void createMMSubScouts_(const ACScout &prototype, const AA except_fromAA, const AA except_toAA, const AA except_edge, ACTrieState &state) const
Same as createSubScouts_, but instantiate all possible AA's except for those in the range from except...
uint32_t getMaxAAACount() const
Maximum number of ambiguous amino acids allowed during search.
Index findChildNaive_(Index parent, AA child_label)
During needle addition (naive trie), obtain the child with edge child_label from parent; if it does n...
size_t getNeedleCount() const
How many needles were added to the trie? (this includes empty needles, which are skipped by addNeedle...
void compressTrie()
Traverses the trie in BFS order and makes it more compact and efficient to traverse.
bool stepScout_(ACScout &scout, ACTrieState &state) const
void createScouts_(const Index i, const AA fromAA, const AA toAA, ACTrieState &state, const uint32_t aaa_left, const uint32_t mm_left) const
bool nextHits(ACTrieState &state) const
Definition AhoCorasickAmbiguous.h:218
constexpr T operator()() const
convert to a number (might be invalid, check with .isValid() first)
Definition AhoCorasickAmbiguous.h:240
uint32_t T
Definition AhoCorasickAmbiguous.h:220
constexpr bool isValid() const
is this Index valid, i.e. an actual index into a vector?
Definition AhoCorasickAmbiguous.h:234
constexpr bool isInvalid() const
is this Index invalid, i.e. should not be dereferenced
Definition AhoCorasickAmbiguous.h:228
T i_
internal number representation; invalid state by default
Definition AhoCorasickAmbiguous.h:263
constexpr Index()=default
default C'tor; creates an invalid index
constexpr T & pos()
allows to set the index, using index.pos() = 3; or simply read its value
Definition AhoCorasickAmbiguous.h:252
constexpr Index(T val)
C'tor from T.
Definition AhoCorasickAmbiguous.h:225
constexpr bool operator==(const Index other) const
equality operator
Definition AhoCorasickAmbiguous.h:246
constexpr T pos() const
allows to read the index, using index.pos()
Definition AhoCorasickAmbiguous.h:258
#define OPENMS_PRECONDITION(condition, message)
Precondition macro.
Definition openms/include/OpenMS/CONCEPT/Macros.h:91
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
constexpr char const AAtoChar[28]
Definition AhoCorasickAmbiguous.h:28
AA nextValidAA(const char *&it_q)
constexpr char const CharToAA[256]
Definition AhoCorasickAmbiguous.h:63
Definition AhoCorasickAmbiguous.h:112
static size_t unambiguousAACount()
Returns the number of unambiguous amino acids (A-Z, excluding B, J, Z, X), i.e. 22.
Definition AhoCorasickAmbiguous.h:203
constexpr bool isValid() const
is AA a letter or '$' ?
Definition AhoCorasickAmbiguous.h:150
constexpr AA(const char c)
Definition AhoCorasickAmbiguous.h:121
constexpr bool isAmbiguous() const
is AA a 'B', 'J', 'Z', 'X', or '$' ?
Definition AhoCorasickAmbiguous.h:144
constexpr bool isValidForPeptide() const
is the AA a letter, i.e. A-Z or a-z?
Definition AhoCorasickAmbiguous.h:156
constexpr AA operator++(int)
Post-increment operator (advance to next AA)
Definition AhoCorasickAmbiguous.h:170
constexpr char toChar() const
Convert this AA to a single letter representation, i.e. 'A'..'V', 'B', 'J', 'Z', 'X',...
Definition AhoCorasickAmbiguous.h:187
uint8_t aa_
internal representation as 1-byte integer
Definition AhoCorasickAmbiguous.h:212
static AA fromIndex(size_t index) noexcept
Definition AhoCorasickAmbiguous.h:194
constexpr AA & operator++()
Pre-increment operator (advance to next AA)
Definition AhoCorasickAmbiguous.h:162
constexpr bool operator<=(const AA other) const
less-or-equal operator
Definition AhoCorasickAmbiguous.h:138
constexpr uint8_t operator()() const
yields the internal 8bit representation
Definition AhoCorasickAmbiguous.h:126
constexpr AA operator-(const AA rhs) const
Decrement operator.
Definition AhoCorasickAmbiguous.h:179
constexpr AA()
Default C'tor; creates an invalid AA.
Definition AhoCorasickAmbiguous.h:114
constexpr bool operator==(const AA other) const
equality operator
Definition AhoCorasickAmbiguous.h:132
internal struct to steal one bit from depth to use as hit indicator
Definition AhoCorasickAmbiguous.h:337
DepthHits()
Definition AhoCorasickAmbiguous.h:338
uint8_t depth
depth of node in the trie
Definition AhoCorasickAmbiguous.h:344
uint8_t has_hit
does a pattern end here (or when following suffix links)?
Definition AhoCorasickAmbiguous.h:342
Definition AhoCorasickAmbiguous.h:326
Bitset children_bitset
bitfield of children (if tree is in BFS order); 26 bits are enough to cover all AA incl....
Definition AhoCorasickAmbiguous.h:351
DepthHits depth_and_hits
depth of node in the tree and one bit if a needle ends in this node or any of its suffices
Definition AhoCorasickAmbiguous.h:356
ACNode(const AA label, const uint8_t depth)
C'tor from an edge label (from parent to this node) and a depth in the tree.
Definition AhoCorasickAmbiguous.h:331
uint8_t ChildCountType
Definition AhoCorasickAmbiguous.h:347
ACNode()
Default C'tor.
Definition AhoCorasickAmbiguous.h:328
a spin-off search path through the trie, which can deal with ambiguous AAs and mismatches
Definition AhoCorasickAmbiguous.h:364
ACScout()=delete
No default C'tor.
Index tree_pos
position in trie
Definition AhoCorasickAmbiguous.h:379
ACScout(const char *query_pos, Index tree_pos, uint8_t max_aa, uint8_t max_mm, uint8_t max_prefix_loss)
C'tor with arguments.
size_t textPos(const ACTrieState &state) const
Where in the text are we currently?
Definition AhoCorasickAmbiguous.h:392
std::vector< Hit > hits
Definition AhoCorasickAmbiguous.h:414
void setQuery(const std::string &haystack)
std::string query_
current query ( = haystack = text)
Definition AhoCorasickAmbiguous.h:425
size_t textPos() const
const std::string & getQuery() const
The current query.
Index tree_pos
position in trie (for the Primary)
Definition AhoCorasickAmbiguous.h:419
const char * textPosIt() const
std::queue< ACScout > scouts
Definition AhoCorasickAmbiguous.h:418
friend ACScout
Definition AhoCorasickAmbiguous.h:393
Custom bitset which uses a 32-bit integer to store bits (instead of 8 bytes for std::bitset<32> on Cl...
Definition AhoCorasickAmbiguous.h:279
Bitset & operator<<=(int n)
Definition AhoCorasickAmbiguous.h:304
Bitset operator<<(int n) const
Definition AhoCorasickAmbiguous.h:298
void clear(int pos)
Definition AhoCorasickAmbiguous.h:288
int pop_count() const
Definition AhoCorasickAmbiguous.h:317
bool test(int pos) const
Definition AhoCorasickAmbiguous.h:293
void set(int pos)
Definition AhoCorasickAmbiguous.h:283
uint32_t bits
Definition AhoCorasickAmbiguous.h:280
Definition AhoCorasickAmbiguous.h:96
uint32_t T
Definition AhoCorasickAmbiguous.h:97
T query_pos
Definition AhoCorasickAmbiguous.h:102
T needle_index
Definition AhoCorasickAmbiguous.h:100
T needle_length
Definition AhoCorasickAmbiguous.h:101
bool operator==(const Hit &rhs) const
Definition AhoCorasickAmbiguous.h:103
Hit()=default
Hit(T needle_index, T needle_length, T query_pos)
Definition AhoCorasickAmbiguous.h:99
std::size_t operator()(OpenMS::Index const &s) const noexcept
Definition AhoCorasickAmbiguous.h:270