1/*!
2Lower level primitive types that are useful in a variety of circumstances.
34# Overview
56This list represents the principle types in this module and briefly describes
7when you might want to use them.
89* [`PatternID`] - A type that represents the identifier of a regex pattern.
10This is probably the most widely used type in this module (which is why it's
11also re-exported in the crate root).
12* [`StateID`] - A type the represents the identifier of a finite automaton
13state. This is used for both NFAs and DFAs, with the notable exception of
14the hybrid NFA/DFA. (The hybrid NFA/DFA uses a special purpose "lazy" state
15identifier.)
16* [`SmallIndex`] - The internal representation of both a `PatternID` and a
17`StateID`. Its purpose is to serve as a type that can index memory without
18being as big as a `usize` on 64-bit targets. The main idea behind this type
19is that there are many things in regex engines that will, in practice, never
20overflow a 32-bit integer. (For example, like the number of patterns in a regex
21or the number of states in an NFA.) Thus, a `SmallIndex` can be used to index
22memory without peppering `as` casts everywhere. Moreover, it forces callers
23to handle errors in the case where, somehow, the value would otherwise overflow
24either a 32-bit integer or a `usize` (e.g., on 16-bit targets).
25*/
2627// The macro we use to define some types below adds methods that we don't
28// use on some of the types. There isn't much, so we just squash the warning.
29#![allow(dead_code)]
3031use alloc::vec::Vec;
3233use crate::util::int::{Usize, U16, U32, U64};
3435/// A type that represents a "small" index.
36///
37/// The main idea of this type is to provide something that can index memory,
38/// but uses less memory than `usize` on 64-bit systems. Specifically, its
39/// representation is always a `u32` and has `repr(transparent)` enabled. (So
40/// it is safe to transmute between a `u32` and a `SmallIndex`.)
41///
42/// A small index is typically useful in cases where there is no practical way
43/// that the index will overflow a 32-bit integer. A good example of this is
44/// an NFA state. If you could somehow build an NFA with `2^30` states, its
45/// memory usage would be exorbitant and its runtime execution would be so
46/// slow as to be completely worthless. Therefore, this crate generally deems
47/// it acceptable to return an error if it would otherwise build an NFA that
48/// requires a slice longer than what a 32-bit integer can index. In exchange,
49/// we can use 32-bit indices instead of 64-bit indices in various places.
50///
51/// This type ensures this by providing a constructor that will return an error
52/// if its argument cannot fit into the type. This makes it much easier to
53/// handle these sorts of boundary cases that are otherwise extremely subtle.
54///
55/// On all targets, this type guarantees that its value will fit in a `u32`,
56/// `i32`, `usize` and an `isize`. This means that on 16-bit targets, for
57/// example, this type's maximum value will never overflow an `isize`,
58/// which means it will never overflow a `i16` even though its internal
59/// representation is still a `u32`.
60///
61/// The purpose for making the type fit into even signed integer types like
62/// `isize` is to guarantee that the difference between any two small indices
63/// is itself also a small index. This is useful in certain contexts, e.g.,
64/// for delta encoding.
65///
66/// # Other types
67///
68/// The following types wrap `SmallIndex` to provide a more focused use case:
69///
70/// * [`PatternID`] is for representing the identifiers of patterns.
71/// * [`StateID`] is for representing the identifiers of states in finite
72/// automata. It is used for both NFAs and DFAs.
73///
74/// # Representation
75///
76/// This type is always represented internally by a `u32` and is marked as
77/// `repr(transparent)`. Thus, this type always has the same representation as
78/// a `u32`. It is thus safe to transmute between a `u32` and a `SmallIndex`.
79///
80/// # Indexing
81///
82/// For convenience, callers may use a `SmallIndex` to index slices.
83///
84/// # Safety
85///
86/// While a `SmallIndex` is meant to guarantee that its value fits into `usize`
87/// without using as much space as a `usize` on all targets, callers must
88/// not rely on this property for safety. Callers may choose to rely on this
89/// property for correctness however. For example, creating a `SmallIndex` with
90/// an invalid value can be done in entirely safe code. This may in turn result
91/// in panics or silent logical errors.
92#[derive(
93#[automatically_derived]
impl ::core::clone::Clone for SmallIndex {
#[inline]
fn clone(&self) -> SmallIndex {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SmallIndex { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for SmallIndex {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "SmallIndex",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for SmallIndex {
#[inline]
fn default() -> SmallIndex {
SmallIndex(::core::default::Default::default())
}
}Default, #[automatically_derived]
impl ::core::cmp::Eq for SmallIndex {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for SmallIndex {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for SmallIndex {
#[inline]
fn eq(&self, other: &SmallIndex) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for SmallIndex {
#[inline]
fn partial_cmp(&self, other: &SmallIndex)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for SmallIndex {
#[inline]
fn cmp(&self, other: &SmallIndex) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord,
94)]
95#[repr(transparent)]
96pub(crate) struct SmallIndex(u32);
9798impl SmallIndex {
99/// The maximum index value.
100#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
101pub const MAX: SmallIndex =
102// FIXME: Use as_usize() once const functions in traits are stable.
103SmallIndex::new_unchecked(core::i32::MAXas usize - 1);
104105/// The maximum index value.
106#[cfg(target_pointer_width = "16")]
107pub const MAX: SmallIndex =
108 SmallIndex::new_unchecked(core::isize::MAX - 1);
109110/// The total number of values that can be represented as a small index.
111pub const LIMIT: usize = SmallIndex::MAX.as_usize() + 1;
112113/// The zero index value.
114pub const ZERO: SmallIndex = SmallIndex::new_unchecked(0);
115116/// The number of bytes that a single small index uses in memory.
117pub const SIZE: usize = core::mem::size_of::<SmallIndex>();
118119/// Create a new small index.
120 ///
121 /// If the given index exceeds [`SmallIndex::MAX`], then this returns
122 /// an error.
123#[inline]
124pub fn new(index: usize) -> Result<SmallIndex, SmallIndexError> {
125SmallIndex::try_from(index)
126 }
127128/// Create a new small index without checking whether the given value
129 /// exceeds [`SmallIndex::MAX`].
130 ///
131 /// Using this routine with an invalid index value will result in
132 /// unspecified behavior, but *not* undefined behavior. In particular, an
133 /// invalid index value is likely to cause panics or possibly even silent
134 /// logical errors.
135 ///
136 /// Callers must never rely on a `SmallIndex` to be within a certain range
137 /// for memory safety.
138#[inline]
139pub const fn new_unchecked(index: usize) -> SmallIndex {
140// FIXME: Use as_u32() once const functions in traits are stable.
141SmallIndex::from_u32_unchecked(indexas u32)
142 }
143144/// Create a new small index from a `u32` without checking whether the
145 /// given value exceeds [`SmallIndex::MAX`].
146 ///
147 /// Using this routine with an invalid index value will result in
148 /// unspecified behavior, but *not* undefined behavior. In particular, an
149 /// invalid index value is likely to cause panics or possibly even silent
150 /// logical errors.
151 ///
152 /// Callers must never rely on a `SmallIndex` to be within a certain range
153 /// for memory safety.
154#[inline]
155pub const fn from_u32_unchecked(index: u32) -> SmallIndex {
156SmallIndex(index)
157 }
158159/// Like [`SmallIndex::new`], but panics if the given index is not valid.
160#[inline]
161pub fn must(index: usize) -> SmallIndex {
162SmallIndex::new(index).expect("invalid small index")
163 }
164165/// Return this small index as a `usize`. This is guaranteed to never
166 /// overflow `usize`.
167#[inline]
168pub const fn as_usize(&self) -> usize {
169// FIXME: Use as_usize() once const functions in traits are stable.
170self.0 as usize171 }
172173/// Return this small index as a `u64`. This is guaranteed to never
174 /// overflow.
175#[inline]
176pub const fn as_u64(&self) -> u64 {
177// FIXME: Use u64::from() once const functions in traits are stable.
178self.0 as u64179 }
180181/// Return the internal `u32` of this small index. This is guaranteed to
182 /// never overflow `u32`.
183#[inline]
184pub const fn as_u32(&self) -> u32 {
185self.0
186}
187188/// Return the internal `u32` of this small index represented as an `i32`.
189 /// This is guaranteed to never overflow an `i32`.
190#[inline]
191pub const fn as_i32(&self) -> i32 {
192// This is OK because we guarantee that our max value is <= i32::MAX.
193self.0 as i32194 }
195196/// Returns one more than this small index as a usize.
197 ///
198 /// Since a small index has constraints on its maximum value, adding `1` to
199 /// it will always fit in a `usize`, `isize`, `u32` and a `i32`.
200#[inline]
201pub fn one_more(&self) -> usize {
202self.as_usize() + 1
203}
204205/// Decode this small index from the bytes given using the native endian
206 /// byte order for the current target.
207 ///
208 /// If the decoded integer is not representable as a small index for the
209 /// current target, then this returns an error.
210#[inline]
211pub fn from_ne_bytes(
212 bytes: [u8; 4],
213 ) -> Result<SmallIndex, SmallIndexError> {
214let id = u32::from_ne_bytes(bytes);
215if id > SmallIndex::MAX.as_u32() {
216return Err(SmallIndexError { attempted: u64::from(id) });
217 }
218Ok(SmallIndex::new_unchecked(id.as_usize()))
219 }
220221/// Decode this small index from the bytes given using the native endian
222 /// byte order for the current target.
223 ///
224 /// This is analogous to [`SmallIndex::new_unchecked`] in that is does not
225 /// check whether the decoded integer is representable as a small index.
226#[inline]
227pub fn from_ne_bytes_unchecked(bytes: [u8; 4]) -> SmallIndex {
228SmallIndex::new_unchecked(u32::from_ne_bytes(bytes).as_usize())
229 }
230231/// Return the underlying small index integer as raw bytes in native endian
232 /// format.
233#[inline]
234pub fn to_ne_bytes(&self) -> [u8; 4] {
235self.0.to_ne_bytes()
236 }
237}
238239impl<T> core::ops::Index<SmallIndex> for [T] {
240type Output = T;
241242#[inline]
243fn index(&self, index: SmallIndex) -> &T {
244&self[index.as_usize()]
245 }
246}
247248impl<T> core::ops::IndexMut<SmallIndex> for [T] {
249#[inline]
250fn index_mut(&mut self, index: SmallIndex) -> &mut T {
251&mut self[index.as_usize()]
252 }
253}
254255impl<T> core::ops::Index<SmallIndex> for Vec<T> {
256type Output = T;
257258#[inline]
259fn index(&self, index: SmallIndex) -> &T {
260&self[index.as_usize()]
261 }
262}
263264impl<T> core::ops::IndexMut<SmallIndex> for Vec<T> {
265#[inline]
266fn index_mut(&mut self, index: SmallIndex) -> &mut T {
267&mut self[index.as_usize()]
268 }
269}
270271impl From<StateID> for SmallIndex {
272fn from(sid: StateID) -> SmallIndex {
273sid.0
274}
275}
276277impl From<PatternID> for SmallIndex {
278fn from(pid: PatternID) -> SmallIndex {
279pid.0
280}
281}
282283impl From<u8> for SmallIndex {
284fn from(index: u8) -> SmallIndex {
285SmallIndex::new_unchecked(usize::from(index))
286 }
287}
288289impl TryFrom<u16> for SmallIndex {
290type Error = SmallIndexError;
291292fn try_from(index: u16) -> Result<SmallIndex, SmallIndexError> {
293if u32::from(index) > SmallIndex::MAX.as_u32() {
294return Err(SmallIndexError { attempted: u64::from(index) });
295 }
296Ok(SmallIndex::new_unchecked(index.as_usize()))
297 }
298}
299300impl TryFrom<u32> for SmallIndex {
301type Error = SmallIndexError;
302303fn try_from(index: u32) -> Result<SmallIndex, SmallIndexError> {
304if index > SmallIndex::MAX.as_u32() {
305return Err(SmallIndexError { attempted: u64::from(index) });
306 }
307Ok(SmallIndex::new_unchecked(index.as_usize()))
308 }
309}
310311impl TryFrom<u64> for SmallIndex {
312type Error = SmallIndexError;
313314fn try_from(index: u64) -> Result<SmallIndex, SmallIndexError> {
315if index > SmallIndex::MAX.as_u64() {
316return Err(SmallIndexError { attempted: index });
317 }
318Ok(SmallIndex::new_unchecked(index.as_usize()))
319 }
320}
321322impl TryFrom<usize> for SmallIndex {
323type Error = SmallIndexError;
324325fn try_from(index: usize) -> Result<SmallIndex, SmallIndexError> {
326if index > SmallIndex::MAX.as_usize() {
327return Err(SmallIndexError { attempted: index.as_u64() });
328 }
329Ok(SmallIndex::new_unchecked(index))
330 }
331}
332333/// This error occurs when a small index could not be constructed.
334///
335/// This occurs when given an integer exceeding the maximum small index value.
336///
337/// When the `std` feature is enabled, this implements the `Error` trait.
338#[derive(#[automatically_derived]
impl ::core::clone::Clone for SmallIndexError {
#[inline]
fn clone(&self) -> SmallIndexError {
SmallIndexError {
attempted: ::core::clone::Clone::clone(&self.attempted),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SmallIndexError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SmallIndexError", "attempted", &&self.attempted)
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for SmallIndexError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u64>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for SmallIndexError {
#[inline]
fn eq(&self, other: &SmallIndexError) -> bool {
self.attempted == other.attempted
}
}PartialEq)]
339pub struct SmallIndexError {
340 attempted: u64,
341}
342343impl SmallIndexError {
344/// Returns the value that could not be converted to a small index.
345pub fn attempted(&self) -> u64 {
346self.attempted
347 }
348}
349350#[cfg(feature = "std")]
351impl std::error::Errorfor SmallIndexError {}
352353impl core::fmt::Displayfor SmallIndexError {
354fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
355f.write_fmt(format_args!("failed to create small index from {0:?}, which exceeds {1:?}",
self.attempted(), SmallIndex::MAX))write!(
356f,
357"failed to create small index from {:?}, which exceeds {:?}",
358self.attempted(),
359 SmallIndex::MAX,
360 )361 }
362}
363364#[derive(#[automatically_derived]
impl ::core::clone::Clone for SmallIndexIter {
#[inline]
fn clone(&self) -> SmallIndexIter {
SmallIndexIter { rng: ::core::clone::Clone::clone(&self.rng) }
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SmallIndexIter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SmallIndexIter", "rng", &&self.rng)
}
}Debug)]
365pub(crate) struct SmallIndexIter {
366 rng: core::ops::Range<usize>,
367}
368369impl Iteratorfor SmallIndexIter {
370type Item = SmallIndex;
371372fn next(&mut self) -> Option<SmallIndex> {
373if self.rng.start >= self.rng.end {
374return None;
375 }
376let next_id = self.rng.start + 1;
377let id = core::mem::replace(&mut self.rng.start, next_id);
378// new_unchecked is OK since we asserted that the number of
379 // elements in this iterator will fit in an ID at construction.
380Some(SmallIndex::new_unchecked(id))
381 }
382}
383384macro_rules! index_type_impls {
385 ($name:ident, $err:ident, $iter:ident, $withiter:ident) => {
386impl $name {
387/// The maximum value.
388pub const MAX: $name = $name(SmallIndex::MAX);
389390/// The total number of values that can be represented.
391pub const LIMIT: usize = SmallIndex::LIMIT;
392393/// The zero value.
394pub const ZERO: $name = $name(SmallIndex::ZERO);
395396/// The number of bytes that a single value uses in memory.
397pub const SIZE: usize = SmallIndex::SIZE;
398399/// Create a new value that is represented by a "small index."
400 ///
401 /// If the given index exceeds the maximum allowed value, then this
402 /// returns an error.
403#[inline]
404pub fn new(value: usize) -> Result<$name, $err> {
405 SmallIndex::new(value).map($name).map_err($err)
406 }
407408/// Create a new value without checking whether the given argument
409 /// exceeds the maximum.
410 ///
411 /// Using this routine with an invalid value will result in
412 /// unspecified behavior, but *not* undefined behavior. In
413 /// particular, an invalid ID value is likely to cause panics or
414 /// possibly even silent logical errors.
415 ///
416 /// Callers must never rely on this type to be within a certain
417 /// range for memory safety.
418#[inline]
419pub const fn new_unchecked(value: usize) -> $name {
420$name(SmallIndex::new_unchecked(value))
421 }
422423/// Create a new value from a `u32` without checking whether the
424 /// given value exceeds the maximum.
425 ///
426 /// Using this routine with an invalid value will result in
427 /// unspecified behavior, but *not* undefined behavior. In
428 /// particular, an invalid ID value is likely to cause panics or
429 /// possibly even silent logical errors.
430 ///
431 /// Callers must never rely on this type to be within a certain
432 /// range for memory safety.
433#[inline]
434pub const fn from_u32_unchecked(index: u32) -> $name {
435$name(SmallIndex::from_u32_unchecked(index))
436 }
437438/// Like `new`, but panics if the given value is not valid.
439#[inline]
440pub fn must(value: usize) -> $name {
441$name::new(value).expect(concat!(
442"invalid ",
443stringify!($name),
444" value"
445))
446 }
447448/// Return the internal value as a `usize`. This is guaranteed to
449 /// never overflow `usize`.
450#[inline]
451pub const fn as_usize(&self) -> usize {
452self.0.as_usize()
453 }
454455/// Return the internal value as a `u64`. This is guaranteed to
456 /// never overflow.
457#[inline]
458pub const fn as_u64(&self) -> u64 {
459self.0.as_u64()
460 }
461462/// Return the internal value as a `u32`. This is guaranteed to
463 /// never overflow `u32`.
464#[inline]
465pub const fn as_u32(&self) -> u32 {
466self.0.as_u32()
467 }
468469/// Return the internal value as a `i32`. This is guaranteed to
470 /// never overflow an `i32`.
471#[inline]
472pub const fn as_i32(&self) -> i32 {
473self.0.as_i32()
474 }
475476/// Returns one more than this value as a usize.
477 ///
478 /// Since values represented by a "small index" have constraints
479 /// on their maximum value, adding `1` to it will always fit in a
480 /// `usize`, `u32` and a `i32`.
481#[inline]
482pub fn one_more(&self) -> usize {
483self.0.one_more()
484 }
485486/// Decode this value from the bytes given using the native endian
487 /// byte order for the current target.
488 ///
489 /// If the decoded integer is not representable as a small index
490 /// for the current target, then this returns an error.
491#[inline]
492pub fn from_ne_bytes(bytes: [u8; 4]) -> Result<$name, $err> {
493 SmallIndex::from_ne_bytes(bytes).map($name).map_err($err)
494 }
495496/// Decode this value from the bytes given using the native endian
497 /// byte order for the current target.
498 ///
499 /// This is analogous to `new_unchecked` in that is does not check
500 /// whether the decoded integer is representable as a small index.
501#[inline]
502pub fn from_ne_bytes_unchecked(bytes: [u8; 4]) -> $name {
503$name(SmallIndex::from_ne_bytes_unchecked(bytes))
504 }
505506/// Return the underlying integer as raw bytes in native endian
507 /// format.
508#[inline]
509pub fn to_ne_bytes(&self) -> [u8; 4] {
510self.0.to_ne_bytes()
511 }
512513/// Returns an iterator over all values from 0 up to and not
514 /// including the given length.
515 ///
516 /// If the given length exceeds this type's limit, then this
517 /// panics.
518pub(crate) fn iter(len: usize) -> $iter {
519$iter::new(len)
520 }
521 }
522523// We write our own Debug impl so that we get things like PatternID(5)
524 // instead of PatternID(SmallIndex(5)).
525impl core::fmt::Debug for $name {
526fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
527 f.debug_tuple(stringify!($name)).field(&self.as_u32()).finish()
528 }
529 }
530531impl<T> core::ops::Index<$name> for [T] {
532type Output = T;
533534#[inline]
535fn index(&self, index: $name) -> &T {
536&self[index.as_usize()]
537 }
538 }
539540impl<T> core::ops::IndexMut<$name> for [T] {
541#[inline]
542fn index_mut(&mut self, index: $name) -> &mut T {
543&mut self[index.as_usize()]
544 }
545 }
546547impl<T> core::ops::Index<$name> for Vec<T> {
548type Output = T;
549550#[inline]
551fn index(&self, index: $name) -> &T {
552&self[index.as_usize()]
553 }
554 }
555556impl<T> core::ops::IndexMut<$name> for Vec<T> {
557#[inline]
558fn index_mut(&mut self, index: $name) -> &mut T {
559&mut self[index.as_usize()]
560 }
561 }
562563impl From<SmallIndex> for $name {
564fn from(index: SmallIndex) -> $name {
565$name(index)
566 }
567 }
568569impl From<u8> for $name {
570fn from(value: u8) -> $name {
571$name(SmallIndex::from(value))
572 }
573 }
574575impl TryFrom<u16> for $name {
576type Error = $err;
577578fn try_from(value: u16) -> Result<$name, $err> {
579 SmallIndex::try_from(value).map($name).map_err($err)
580 }
581 }
582583impl TryFrom<u32> for $name {
584type Error = $err;
585586fn try_from(value: u32) -> Result<$name, $err> {
587 SmallIndex::try_from(value).map($name).map_err($err)
588 }
589 }
590591impl TryFrom<u64> for $name {
592type Error = $err;
593594fn try_from(value: u64) -> Result<$name, $err> {
595 SmallIndex::try_from(value).map($name).map_err($err)
596 }
597 }
598599impl TryFrom<usize> for $name {
600type Error = $err;
601602fn try_from(value: usize) -> Result<$name, $err> {
603 SmallIndex::try_from(value).map($name).map_err($err)
604 }
605 }
606607/// This error occurs when an ID could not be constructed.
608 ///
609 /// This occurs when given an integer exceeding the maximum allowed
610 /// value.
611 ///
612 /// When the `std` feature is enabled, this implements the `Error`
613 /// trait.
614#[derive(Clone, Debug, Eq, PartialEq)]
615pub struct $err(SmallIndexError);
616617impl $err {
618/// Returns the value that could not be converted to an ID.
619pub fn attempted(&self) -> u64 {
620self.0.attempted()
621 }
622 }
623624#[cfg(feature = "std")]
625impl std::error::Error for $err {}
626627impl core::fmt::Display for $err {
628fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
629write!(
630 f,
631"failed to create {} from {:?}, which exceeds {:?}",
632stringify!($name),
633self.attempted(),
634$name::MAX,
635 )
636 }
637 }
638639#[derive(Clone, Debug)]
640pub(crate) struct $iter(SmallIndexIter);
641642impl $iter {
643fn new(len: usize) -> $iter {
644assert!(
645 len <= $name::LIMIT,
646"cannot create iterator for {} when number of \
647 elements exceed {:?}",
648stringify!($name),
649$name::LIMIT,
650 );
651$iter(SmallIndexIter { rng: 0..len })
652 }
653 }
654655impl Iterator for $iter {
656type Item = $name;
657658fn next(&mut self) -> Option<$name> {
659self.0.next().map($name)
660 }
661 }
662663/// An iterator adapter that is like std::iter::Enumerate, but attaches
664 /// small index values instead. It requires `ExactSizeIterator`. At
665 /// construction, it ensures that the index of each element in the
666 /// iterator is representable in the corresponding small index type.
667#[derive(Clone, Debug)]
668pub(crate) struct $withiter<I> {
669 it: I,
670 ids: $iter,
671 }
672673impl<I: Iterator + ExactSizeIterator> $withiter<I> {
674fn new(it: I) -> $withiter<I> {
675let ids = $name::iter(it.len());
676$withiter { it, ids }
677 }
678 }
679680impl<I: Iterator + ExactSizeIterator> Iterator for $withiter<I> {
681type Item = ($name, I::Item);
682683fn next(&mut self) -> Option<($name, I::Item)> {
684let item = self.it.next()?;
685// Number of elements in this iterator must match, according
686 // to contract of ExactSizeIterator.
687let id = self.ids.next().unwrap();
688Some((id, item))
689 }
690 }
691 };
692}
693694/// The identifier of a pattern in an Aho-Corasick automaton.
695///
696/// It is represented by a `u32` even on 64-bit systems in order to conserve
697/// space. Namely, on all targets, this type guarantees that its value will
698/// fit in a `u32`, `i32`, `usize` and an `isize`. This means that on 16-bit
699/// targets, for example, this type's maximum value will never overflow an
700/// `isize`, which means it will never overflow a `i16` even though its
701/// internal representation is still a `u32`.
702///
703/// # Safety
704///
705/// While a `PatternID` is meant to guarantee that its value fits into `usize`
706/// without using as much space as a `usize` on all targets, callers must
707/// not rely on this property for safety. Callers may choose to rely on this
708/// property for correctness however. For example, creating a `StateID` with an
709/// invalid value can be done in entirely safe code. This may in turn result in
710/// panics or silent logical errors.
711#[derive(#[automatically_derived]
impl ::core::clone::Clone for PatternID {
#[inline]
fn clone(&self) -> PatternID {
let _: ::core::clone::AssertParamIsClone<SmallIndex>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PatternID { }Copy, #[automatically_derived]
impl ::core::default::Default for PatternID {
#[inline]
fn default() -> PatternID {
PatternID(::core::default::Default::default())
}
}Default, #[automatically_derived]
impl ::core::cmp::Eq for PatternID {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<SmallIndex>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for PatternID {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for PatternID {
#[inline]
fn eq(&self, other: &PatternID) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for PatternID {
#[inline]
fn partial_cmp(&self, other: &PatternID)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for PatternID {
#[inline]
fn cmp(&self, other: &PatternID) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord)]
712#[repr(transparent)]
713pub struct PatternID(SmallIndex);
714715/// The identifier of a finite automaton state.
716///
717/// It is represented by a `u32` even on 64-bit systems in order to conserve
718/// space. Namely, on all targets, this type guarantees that its value will
719/// fit in a `u32`, `i32`, `usize` and an `isize`. This means that on 16-bit
720/// targets, for example, this type's maximum value will never overflow an
721/// `isize`, which means it will never overflow a `i16` even though its
722/// internal representation is still a `u32`.
723///
724/// # Safety
725///
726/// While a `StateID` is meant to guarantee that its value fits into `usize`
727/// without using as much space as a `usize` on all targets, callers must
728/// not rely on this property for safety. Callers may choose to rely on this
729/// property for correctness however. For example, creating a `StateID` with an
730/// invalid value can be done in entirely safe code. This may in turn result in
731/// panics or silent logical errors.
732#[derive(#[automatically_derived]
impl ::core::clone::Clone for StateID {
#[inline]
fn clone(&self) -> StateID {
let _: ::core::clone::AssertParamIsClone<SmallIndex>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for StateID { }Copy, #[automatically_derived]
impl ::core::default::Default for StateID {
#[inline]
fn default() -> StateID { StateID(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::cmp::Eq for StateID {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<SmallIndex>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for StateID {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for StateID {
#[inline]
fn eq(&self, other: &StateID) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for StateID {
#[inline]
fn partial_cmp(&self, other: &StateID)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for StateID {
#[inline]
fn cmp(&self, other: &StateID) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord)]
733#[repr(transparent)]
734pub struct StateID(SmallIndex);
735736impl PatternID {
/// The maximum value.
pub const MAX: PatternID = PatternID(SmallIndex::MAX);
/// The total number of values that can be represented.
pub const LIMIT: usize = SmallIndex::LIMIT;
/// The zero value.
pub const ZERO: PatternID = PatternID(SmallIndex::ZERO);
/// The number of bytes that a single value uses in memory.
pub const SIZE: usize = SmallIndex::SIZE;
/// Create a new value that is represented by a "small index."
///
/// If the given index exceeds the maximum allowed value, then this
/// returns an error.
#[inline]
pub fn new(value: usize) -> Result<PatternID, PatternIDError> {
SmallIndex::new(value).map(PatternID).map_err(PatternIDError)
}
/// Create a new value without checking whether the given argument
/// exceeds the maximum.
///
/// Using this routine with an invalid value will result in
/// unspecified behavior, but *not* undefined behavior. In
/// particular, an invalid ID value is likely to cause panics or
/// possibly even silent logical errors.
///
/// Callers must never rely on this type to be within a certain
/// range for memory safety.
#[inline]
pub const fn new_unchecked(value: usize) -> PatternID {
PatternID(SmallIndex::new_unchecked(value))
}
/// Create a new value from a `u32` without checking whether the
/// given value exceeds the maximum.
///
/// Using this routine with an invalid value will result in
/// unspecified behavior, but *not* undefined behavior. In
/// particular, an invalid ID value is likely to cause panics or
/// possibly even silent logical errors.
///
/// Callers must never rely on this type to be within a certain
/// range for memory safety.
#[inline]
pub const fn from_u32_unchecked(index: u32) -> PatternID {
PatternID(SmallIndex::from_u32_unchecked(index))
}
/// Like `new`, but panics if the given value is not valid.
#[inline]
pub fn must(value: usize) -> PatternID {
PatternID::new(value).expect("invalid PatternID value")
}
/// Return the internal value as a `usize`. This is guaranteed to
/// never overflow `usize`.
#[inline]
pub const fn as_usize(&self) -> usize { self.0.as_usize() }
/// Return the internal value as a `u64`. This is guaranteed to
/// never overflow.
#[inline]
pub const fn as_u64(&self) -> u64 { self.0.as_u64() }
/// Return the internal value as a `u32`. This is guaranteed to
/// never overflow `u32`.
#[inline]
pub const fn as_u32(&self) -> u32 { self.0.as_u32() }
/// Return the internal value as a `i32`. This is guaranteed to
/// never overflow an `i32`.
#[inline]
pub const fn as_i32(&self) -> i32 { self.0.as_i32() }
/// Returns one more than this value as a usize.
///
/// Since values represented by a "small index" have constraints
/// on their maximum value, adding `1` to it will always fit in a
/// `usize`, `u32` and a `i32`.
#[inline]
pub fn one_more(&self) -> usize { self.0.one_more() }
/// Decode this value from the bytes given using the native endian
/// byte order for the current target.
///
/// If the decoded integer is not representable as a small index
/// for the current target, then this returns an error.
#[inline]
pub fn from_ne_bytes(bytes: [u8; 4])
-> Result<PatternID, PatternIDError> {
SmallIndex::from_ne_bytes(bytes).map(PatternID).map_err(PatternIDError)
}
/// Decode this value from the bytes given using the native endian
/// byte order for the current target.
///
/// This is analogous to `new_unchecked` in that is does not check
/// whether the decoded integer is representable as a small index.
#[inline]
pub fn from_ne_bytes_unchecked(bytes: [u8; 4]) -> PatternID {
PatternID(SmallIndex::from_ne_bytes_unchecked(bytes))
}
/// Return the underlying integer as raw bytes in native endian
/// format.
#[inline]
pub fn to_ne_bytes(&self) -> [u8; 4] { self.0.to_ne_bytes() }
/// Returns an iterator over all values from 0 up to and not
/// including the given length.
///
/// If the given length exceeds this type's limit, then this
/// panics.
pub(crate) fn iter(len: usize) -> PatternIDIter {
PatternIDIter::new(len)
}
}
impl core::fmt::Debug for PatternID {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_tuple("PatternID").field(&self.as_u32()).finish()
}
}
impl<T> core::ops::Index<PatternID> for [T] {
type Output = T;
#[inline]
fn index(&self, index: PatternID) -> &T { &self[index.as_usize()] }
}
impl<T> core::ops::IndexMut<PatternID> for [T] {
#[inline]
fn index_mut(&mut self, index: PatternID) -> &mut T {
&mut self[index.as_usize()]
}
}
impl<T> core::ops::Index<PatternID> for Vec<T> {
type Output = T;
#[inline]
fn index(&self, index: PatternID) -> &T { &self[index.as_usize()] }
}
impl<T> core::ops::IndexMut<PatternID> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: PatternID) -> &mut T {
&mut self[index.as_usize()]
}
}
impl From<SmallIndex> for PatternID {
fn from(index: SmallIndex) -> PatternID { PatternID(index) }
}
impl From<u8> for PatternID {
fn from(value: u8) -> PatternID { PatternID(SmallIndex::from(value)) }
}
impl TryFrom<u16> for PatternID {
type Error = PatternIDError;
fn try_from(value: u16) -> Result<PatternID, PatternIDError> {
SmallIndex::try_from(value).map(PatternID).map_err(PatternIDError)
}
}
impl TryFrom<u32> for PatternID {
type Error = PatternIDError;
fn try_from(value: u32) -> Result<PatternID, PatternIDError> {
SmallIndex::try_from(value).map(PatternID).map_err(PatternIDError)
}
}
impl TryFrom<u64> for PatternID {
type Error = PatternIDError;
fn try_from(value: u64) -> Result<PatternID, PatternIDError> {
SmallIndex::try_from(value).map(PatternID).map_err(PatternIDError)
}
}
impl TryFrom<usize> for PatternID {
type Error = PatternIDError;
fn try_from(value: usize) -> Result<PatternID, PatternIDError> {
SmallIndex::try_from(value).map(PatternID).map_err(PatternIDError)
}
}
/// This error occurs when an ID could not be constructed.
///
/// This occurs when given an integer exceeding the maximum allowed
/// value.
///
/// When the `std` feature is enabled, this implements the `Error`
/// trait.
pub struct PatternIDError(SmallIndexError);
#[automatically_derived]
impl ::core::clone::Clone for PatternIDError {
#[inline]
fn clone(&self) -> PatternIDError {
PatternIDError(::core::clone::Clone::clone(&self.0))
}
}
#[automatically_derived]
impl ::core::fmt::Debug for PatternIDError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "PatternIDError",
&&self.0)
}
}
#[automatically_derived]
impl ::core::cmp::Eq for PatternIDError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<SmallIndexError>;
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for PatternIDError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for PatternIDError {
#[inline]
fn eq(&self, other: &PatternIDError) -> bool { self.0 == other.0 }
}
impl PatternIDError {
/// Returns the value that could not be converted to an ID.
pub fn attempted(&self) -> u64 { self.0.attempted() }
}
impl std::error::Error for PatternIDError { }
impl core::fmt::Display for PatternIDError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_fmt(format_args!("failed to create {0} from {1:?}, which exceeds {2:?}",
"PatternID", self.attempted(), PatternID::MAX))
}
}
pub(crate) struct PatternIDIter(SmallIndexIter);
#[automatically_derived]
impl ::core::clone::Clone for PatternIDIter {
#[inline]
fn clone(&self) -> PatternIDIter {
PatternIDIter(::core::clone::Clone::clone(&self.0))
}
}
#[automatically_derived]
impl ::core::fmt::Debug for PatternIDIter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "PatternIDIter",
&&self.0)
}
}
impl PatternIDIter {
fn new(len: usize) -> PatternIDIter {
if !(len <= PatternID::LIMIT) {
{
::core::panicking::panic_fmt(format_args!("cannot create iterator for {0} when number of elements exceed {1:?}",
"PatternID", PatternID::LIMIT));
}
};
PatternIDIter(SmallIndexIter { rng: 0..len })
}
}
impl Iterator for PatternIDIter {
type Item = PatternID;
fn next(&mut self) -> Option<PatternID> { self.0.next().map(PatternID) }
}
/// An iterator adapter that is like std::iter::Enumerate, but attaches
/// small index values instead. It requires `ExactSizeIterator`. At
/// construction, it ensures that the index of each element in the
/// iterator is representable in the corresponding small index type.
pub(crate) struct WithPatternIDIter<I> {
it: I,
ids: PatternIDIter,
}
#[automatically_derived]
impl<I: ::core::clone::Clone> ::core::clone::Clone for WithPatternIDIter<I> {
#[inline]
fn clone(&self) -> WithPatternIDIter<I> {
WithPatternIDIter {
it: ::core::clone::Clone::clone(&self.it),
ids: ::core::clone::Clone::clone(&self.ids),
}
}
}
#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for WithPatternIDIter<I> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"WithPatternIDIter", "it", &self.it, "ids", &&self.ids)
}
}
impl<I: Iterator + ExactSizeIterator> WithPatternIDIter<I> {
fn new(it: I) -> WithPatternIDIter<I> {
let ids = PatternID::iter(it.len());
WithPatternIDIter { it, ids }
}
}
impl<I: Iterator + ExactSizeIterator> Iterator for WithPatternIDIter<I> {
type Item = (PatternID, I::Item);
fn next(&mut self) -> Option<(PatternID, I::Item)> {
let item = self.it.next()?;
let id = self.ids.next().unwrap();
Some((id, item))
}
}index_type_impls!(PatternID, PatternIDError, PatternIDIter, WithPatternIDIter);
737impl StateID {
/// The maximum value.
pub const MAX: StateID = StateID(SmallIndex::MAX);
/// The total number of values that can be represented.
pub const LIMIT: usize = SmallIndex::LIMIT;
/// The zero value.
pub const ZERO: StateID = StateID(SmallIndex::ZERO);
/// The number of bytes that a single value uses in memory.
pub const SIZE: usize = SmallIndex::SIZE;
/// Create a new value that is represented by a "small index."
///
/// If the given index exceeds the maximum allowed value, then this
/// returns an error.
#[inline]
pub fn new(value: usize) -> Result<StateID, StateIDError> {
SmallIndex::new(value).map(StateID).map_err(StateIDError)
}
/// Create a new value without checking whether the given argument
/// exceeds the maximum.
///
/// Using this routine with an invalid value will result in
/// unspecified behavior, but *not* undefined behavior. In
/// particular, an invalid ID value is likely to cause panics or
/// possibly even silent logical errors.
///
/// Callers must never rely on this type to be within a certain
/// range for memory safety.
#[inline]
pub const fn new_unchecked(value: usize) -> StateID {
StateID(SmallIndex::new_unchecked(value))
}
/// Create a new value from a `u32` without checking whether the
/// given value exceeds the maximum.
///
/// Using this routine with an invalid value will result in
/// unspecified behavior, but *not* undefined behavior. In
/// particular, an invalid ID value is likely to cause panics or
/// possibly even silent logical errors.
///
/// Callers must never rely on this type to be within a certain
/// range for memory safety.
#[inline]
pub const fn from_u32_unchecked(index: u32) -> StateID {
StateID(SmallIndex::from_u32_unchecked(index))
}
/// Like `new`, but panics if the given value is not valid.
#[inline]
pub fn must(value: usize) -> StateID {
StateID::new(value).expect("invalid StateID value")
}
/// Return the internal value as a `usize`. This is guaranteed to
/// never overflow `usize`.
#[inline]
pub const fn as_usize(&self) -> usize { self.0.as_usize() }
/// Return the internal value as a `u64`. This is guaranteed to
/// never overflow.
#[inline]
pub const fn as_u64(&self) -> u64 { self.0.as_u64() }
/// Return the internal value as a `u32`. This is guaranteed to
/// never overflow `u32`.
#[inline]
pub const fn as_u32(&self) -> u32 { self.0.as_u32() }
/// Return the internal value as a `i32`. This is guaranteed to
/// never overflow an `i32`.
#[inline]
pub const fn as_i32(&self) -> i32 { self.0.as_i32() }
/// Returns one more than this value as a usize.
///
/// Since values represented by a "small index" have constraints
/// on their maximum value, adding `1` to it will always fit in a
/// `usize`, `u32` and a `i32`.
#[inline]
pub fn one_more(&self) -> usize { self.0.one_more() }
/// Decode this value from the bytes given using the native endian
/// byte order for the current target.
///
/// If the decoded integer is not representable as a small index
/// for the current target, then this returns an error.
#[inline]
pub fn from_ne_bytes(bytes: [u8; 4]) -> Result<StateID, StateIDError> {
SmallIndex::from_ne_bytes(bytes).map(StateID).map_err(StateIDError)
}
/// Decode this value from the bytes given using the native endian
/// byte order for the current target.
///
/// This is analogous to `new_unchecked` in that is does not check
/// whether the decoded integer is representable as a small index.
#[inline]
pub fn from_ne_bytes_unchecked(bytes: [u8; 4]) -> StateID {
StateID(SmallIndex::from_ne_bytes_unchecked(bytes))
}
/// Return the underlying integer as raw bytes in native endian
/// format.
#[inline]
pub fn to_ne_bytes(&self) -> [u8; 4] { self.0.to_ne_bytes() }
/// Returns an iterator over all values from 0 up to and not
/// including the given length.
///
/// If the given length exceeds this type's limit, then this
/// panics.
pub(crate) fn iter(len: usize) -> StateIDIter { StateIDIter::new(len) }
}
impl core::fmt::Debug for StateID {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.debug_tuple("StateID").field(&self.as_u32()).finish()
}
}
impl<T> core::ops::Index<StateID> for [T] {
type Output = T;
#[inline]
fn index(&self, index: StateID) -> &T { &self[index.as_usize()] }
}
impl<T> core::ops::IndexMut<StateID> for [T] {
#[inline]
fn index_mut(&mut self, index: StateID) -> &mut T {
&mut self[index.as_usize()]
}
}
impl<T> core::ops::Index<StateID> for Vec<T> {
type Output = T;
#[inline]
fn index(&self, index: StateID) -> &T { &self[index.as_usize()] }
}
impl<T> core::ops::IndexMut<StateID> for Vec<T> {
#[inline]
fn index_mut(&mut self, index: StateID) -> &mut T {
&mut self[index.as_usize()]
}
}
impl From<SmallIndex> for StateID {
fn from(index: SmallIndex) -> StateID { StateID(index) }
}
impl From<u8> for StateID {
fn from(value: u8) -> StateID { StateID(SmallIndex::from(value)) }
}
impl TryFrom<u16> for StateID {
type Error = StateIDError;
fn try_from(value: u16) -> Result<StateID, StateIDError> {
SmallIndex::try_from(value).map(StateID).map_err(StateIDError)
}
}
impl TryFrom<u32> for StateID {
type Error = StateIDError;
fn try_from(value: u32) -> Result<StateID, StateIDError> {
SmallIndex::try_from(value).map(StateID).map_err(StateIDError)
}
}
impl TryFrom<u64> for StateID {
type Error = StateIDError;
fn try_from(value: u64) -> Result<StateID, StateIDError> {
SmallIndex::try_from(value).map(StateID).map_err(StateIDError)
}
}
impl TryFrom<usize> for StateID {
type Error = StateIDError;
fn try_from(value: usize) -> Result<StateID, StateIDError> {
SmallIndex::try_from(value).map(StateID).map_err(StateIDError)
}
}
/// This error occurs when an ID could not be constructed.
///
/// This occurs when given an integer exceeding the maximum allowed
/// value.
///
/// When the `std` feature is enabled, this implements the `Error`
/// trait.
pub struct StateIDError(SmallIndexError);
#[automatically_derived]
impl ::core::clone::Clone for StateIDError {
#[inline]
fn clone(&self) -> StateIDError {
StateIDError(::core::clone::Clone::clone(&self.0))
}
}
#[automatically_derived]
impl ::core::fmt::Debug for StateIDError {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "StateIDError",
&&self.0)
}
}
#[automatically_derived]
impl ::core::cmp::Eq for StateIDError {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<SmallIndexError>;
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for StateIDError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for StateIDError {
#[inline]
fn eq(&self, other: &StateIDError) -> bool { self.0 == other.0 }
}
impl StateIDError {
/// Returns the value that could not be converted to an ID.
pub fn attempted(&self) -> u64 { self.0.attempted() }
}
impl std::error::Error for StateIDError { }
impl core::fmt::Display for StateIDError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_fmt(format_args!("failed to create {0} from {1:?}, which exceeds {2:?}",
"StateID", self.attempted(), StateID::MAX))
}
}
pub(crate) struct StateIDIter(SmallIndexIter);
#[automatically_derived]
impl ::core::clone::Clone for StateIDIter {
#[inline]
fn clone(&self) -> StateIDIter {
StateIDIter(::core::clone::Clone::clone(&self.0))
}
}
#[automatically_derived]
impl ::core::fmt::Debug for StateIDIter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "StateIDIter",
&&self.0)
}
}
impl StateIDIter {
fn new(len: usize) -> StateIDIter {
if !(len <= StateID::LIMIT) {
{
::core::panicking::panic_fmt(format_args!("cannot create iterator for {0} when number of elements exceed {1:?}",
"StateID", StateID::LIMIT));
}
};
StateIDIter(SmallIndexIter { rng: 0..len })
}
}
impl Iterator for StateIDIter {
type Item = StateID;
fn next(&mut self) -> Option<StateID> { self.0.next().map(StateID) }
}
/// An iterator adapter that is like std::iter::Enumerate, but attaches
/// small index values instead. It requires `ExactSizeIterator`. At
/// construction, it ensures that the index of each element in the
/// iterator is representable in the corresponding small index type.
pub(crate) struct WithStateIDIter<I> {
it: I,
ids: StateIDIter,
}
#[automatically_derived]
impl<I: ::core::clone::Clone> ::core::clone::Clone for WithStateIDIter<I> {
#[inline]
fn clone(&self) -> WithStateIDIter<I> {
WithStateIDIter {
it: ::core::clone::Clone::clone(&self.it),
ids: ::core::clone::Clone::clone(&self.ids),
}
}
}
#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for WithStateIDIter<I> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"WithStateIDIter", "it", &self.it, "ids", &&self.ids)
}
}
impl<I: Iterator + ExactSizeIterator> WithStateIDIter<I> {
fn new(it: I) -> WithStateIDIter<I> {
let ids = StateID::iter(it.len());
WithStateIDIter { it, ids }
}
}
impl<I: Iterator + ExactSizeIterator> Iterator for WithStateIDIter<I> {
type Item = (StateID, I::Item);
fn next(&mut self) -> Option<(StateID, I::Item)> {
let item = self.it.next()?;
let id = self.ids.next().unwrap();
Some((id, item))
}
}index_type_impls!(StateID, StateIDError, StateIDIter, WithStateIDIter);
738739/// A utility trait that defines a couple of adapters for making it convenient
740/// to access indices as "small index" types. We require ExactSizeIterator so
741/// that iterator construction can do a single check to make sure the index of
742/// each element is representable by its small index type.
743pub(crate) trait IteratorIndexExt: Iterator {
744fn with_pattern_ids(self) -> WithPatternIDIter<Self>
745where
746Self: Sized + ExactSizeIterator,
747 {
748WithPatternIDIter::new(self)
749 }
750751fn with_state_ids(self) -> WithStateIDIter<Self>
752where
753Self: Sized + ExactSizeIterator,
754 {
755WithStateIDIter::new(self)
756 }
757}
758759impl<I: Iterator> IteratorIndexExtfor I {}