diff --git a/.lock b/.lock new file mode 100644 index 000000000..e69de29bb diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/bstr/all.html b/bstr/all.html new file mode 100644 index 000000000..7ed273fdf --- /dev/null +++ b/bstr/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Traits

Functions

\ No newline at end of file diff --git a/bstr/bstr/struct.BStr.html b/bstr/bstr/struct.BStr.html new file mode 100644 index 000000000..f5db14f77 --- /dev/null +++ b/bstr/bstr/struct.BStr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.BStr.html...

+ + + \ No newline at end of file diff --git a/bstr/escape_bytes/struct.EscapeBytes.html b/bstr/escape_bytes/struct.EscapeBytes.html new file mode 100644 index 000000000..9f3f91ccf --- /dev/null +++ b/bstr/escape_bytes/struct.EscapeBytes.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.EscapeBytes.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/fn.B.html b/bstr/ext_slice/fn.B.html new file mode 100644 index 000000000..b2172fd37 --- /dev/null +++ b/bstr/ext_slice/fn.B.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/fn.B.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.Bytes.html b/bstr/ext_slice/struct.Bytes.html new file mode 100644 index 000000000..498033243 --- /dev/null +++ b/bstr/ext_slice/struct.Bytes.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Bytes.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.FieldsWith.html b/bstr/ext_slice/struct.FieldsWith.html new file mode 100644 index 000000000..e778e6990 --- /dev/null +++ b/bstr/ext_slice/struct.FieldsWith.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.FieldsWith.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.Find.html b/bstr/ext_slice/struct.Find.html new file mode 100644 index 000000000..269561d7d --- /dev/null +++ b/bstr/ext_slice/struct.Find.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Find.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.FindReverse.html b/bstr/ext_slice/struct.FindReverse.html new file mode 100644 index 000000000..c89f2081f --- /dev/null +++ b/bstr/ext_slice/struct.FindReverse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.FindReverse.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.Finder.html b/bstr/ext_slice/struct.Finder.html new file mode 100644 index 000000000..fd517547c --- /dev/null +++ b/bstr/ext_slice/struct.Finder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Finder.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.FinderReverse.html b/bstr/ext_slice/struct.FinderReverse.html new file mode 100644 index 000000000..50b9ad2ce --- /dev/null +++ b/bstr/ext_slice/struct.FinderReverse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.FinderReverse.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.Lines.html b/bstr/ext_slice/struct.Lines.html new file mode 100644 index 000000000..9f640093c --- /dev/null +++ b/bstr/ext_slice/struct.Lines.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Lines.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.LinesWithTerminator.html b/bstr/ext_slice/struct.LinesWithTerminator.html new file mode 100644 index 000000000..1caf77778 --- /dev/null +++ b/bstr/ext_slice/struct.LinesWithTerminator.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.LinesWithTerminator.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.Split.html b/bstr/ext_slice/struct.Split.html new file mode 100644 index 000000000..f7b99d074 --- /dev/null +++ b/bstr/ext_slice/struct.Split.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Split.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.SplitN.html b/bstr/ext_slice/struct.SplitN.html new file mode 100644 index 000000000..bf7f8d991 --- /dev/null +++ b/bstr/ext_slice/struct.SplitN.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.SplitN.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.SplitNReverse.html b/bstr/ext_slice/struct.SplitNReverse.html new file mode 100644 index 000000000..fc62cf8b9 --- /dev/null +++ b/bstr/ext_slice/struct.SplitNReverse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.SplitNReverse.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/struct.SplitReverse.html b/bstr/ext_slice/struct.SplitReverse.html new file mode 100644 index 000000000..95a6dba77 --- /dev/null +++ b/bstr/ext_slice/struct.SplitReverse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.SplitReverse.html...

+ + + \ No newline at end of file diff --git a/bstr/ext_slice/trait.ByteSlice.html b/bstr/ext_slice/trait.ByteSlice.html new file mode 100644 index 000000000..e28197ace --- /dev/null +++ b/bstr/ext_slice/trait.ByteSlice.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/trait.ByteSlice.html...

+ + + \ No newline at end of file diff --git a/bstr/fn.B.html b/bstr/fn.B.html new file mode 100644 index 000000000..ee5939a12 --- /dev/null +++ b/bstr/fn.B.html @@ -0,0 +1,31 @@ +B in bstr - Rust

Function bstr::B

source ·
pub fn B<'a, B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> &'a [u8] 
Expand description

A short-hand constructor for building a &[u8].

+

This idiosyncratic constructor is useful for concisely building byte string +slices. Its primary utility is in conveniently writing byte string literals +in a uniform way. For example, consider this code that does not compile:

+ +
let strs = vec![b"a", b"xy"];
+

The above code doesn’t compile because the type of the byte string literal +b"a" is &'static [u8; 1], and the type of b"xy" is +&'static [u8; 2]. Since their types aren’t the same, they can’t be stored +in the same Vec. (This is dissimilar from normal Unicode string slices, +where both "a" and "xy" have the same type of &'static str.)

+

One way of getting the above code to compile is to convert byte strings to +slices. You might try this:

+ +
let strs = vec![&b"a", &b"xy"];
+

But this just creates values with type & &'static [u8; 1] and +& &'static [u8; 2]. Instead, you need to force the issue like so:

+ +
let strs = vec![&b"a"[..], &b"xy"[..]];
+// or
+let strs = vec![b"a".as_ref(), b"xy".as_ref()];
+

But neither of these are particularly convenient to type, especially when +it’s something as common as a string literal. Thus, this constructor +permits writing the following instead:

+ +
use bstr::B;
+
+let strs = vec![B("a"), B(b"xy")];
+

Notice that this also lets you mix and match both string literals and byte +string literals. This can be quite convenient!

+
\ No newline at end of file diff --git a/bstr/fn.decode_last_utf8.html b/bstr/fn.decode_last_utf8.html new file mode 100644 index 000000000..31017c4a2 --- /dev/null +++ b/bstr/fn.decode_last_utf8.html @@ -0,0 +1,37 @@ +decode_last_utf8 in bstr - Rust

Function bstr::decode_last_utf8

source ·
pub fn decode_last_utf8<B: AsRef<[u8]>>(slice: B) -> (Option<char>, usize)
Expand description

UTF-8 decode a single Unicode scalar value from the end of a slice.

+

When successful, the corresponding Unicode scalar value is returned along +with the number of bytes it was encoded with. The number of bytes consumed +for a successful decode is always between 1 and 4, inclusive.

+

When unsuccessful, None is returned along with the number of bytes that +make up a maximal prefix of a valid UTF-8 code unit sequence. In this case, +the number of bytes consumed is always between 0 and 3, inclusive, where +0 is only returned when slice is empty.

+

Examples

+

Basic usage:

+ +
use bstr::decode_last_utf8;
+
+// Decoding a valid codepoint.
+let (ch, size) = decode_last_utf8(b"\xE2\x98\x83");
+assert_eq!(Some('☃'), ch);
+assert_eq!(3, size);
+
+// Decoding an incomplete codepoint.
+let (ch, size) = decode_last_utf8(b"\xE2\x98");
+assert_eq!(None, ch);
+assert_eq!(2, size);
+

This example shows how to iterate over all codepoints in UTF-8 encoded +bytes in reverse, while replacing invalid UTF-8 sequences with the +replacement codepoint:

+ +
use bstr::{B, decode_last_utf8};
+
+let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+let mut chars = vec![];
+while !bytes.is_empty() {
+    let (ch, size) = decode_last_utf8(bytes);
+    bytes = &bytes[..bytes.len()-size];
+    chars.push(ch.unwrap_or('\u{FFFD}'));
+}
+assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+
\ No newline at end of file diff --git a/bstr/fn.decode_utf8.html b/bstr/fn.decode_utf8.html new file mode 100644 index 000000000..f858cc4c5 --- /dev/null +++ b/bstr/fn.decode_utf8.html @@ -0,0 +1,37 @@ +decode_utf8 in bstr - Rust

Function bstr::decode_utf8

source ·
pub fn decode_utf8<B: AsRef<[u8]>>(slice: B) -> (Option<char>, usize)
Expand description

UTF-8 decode a single Unicode scalar value from the beginning of a slice.

+

When successful, the corresponding Unicode scalar value is returned along +with the number of bytes it was encoded with. The number of bytes consumed +for a successful decode is always between 1 and 4, inclusive.

+

When unsuccessful, None is returned along with the number of bytes that +make up a maximal prefix of a valid UTF-8 code unit sequence. In this case, +the number of bytes consumed is always between 0 and 3, inclusive, where +0 is only returned when slice is empty.

+

Examples

+

Basic usage:

+ +
use bstr::decode_utf8;
+
+// Decoding a valid codepoint.
+let (ch, size) = decode_utf8(b"\xE2\x98\x83");
+assert_eq!(Some('☃'), ch);
+assert_eq!(3, size);
+
+// Decoding an incomplete codepoint.
+let (ch, size) = decode_utf8(b"\xE2\x98");
+assert_eq!(None, ch);
+assert_eq!(2, size);
+

This example shows how to iterate over all codepoints in UTF-8 encoded +bytes, while replacing invalid UTF-8 sequences with the replacement +codepoint:

+ +
use bstr::{B, decode_utf8};
+
+let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+let mut chars = vec![];
+while !bytes.is_empty() {
+    let (ch, size) = decode_utf8(bytes);
+    bytes = &bytes[size..];
+    chars.push(ch.unwrap_or('\u{FFFD}'));
+}
+assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+
\ No newline at end of file diff --git a/bstr/index.html b/bstr/index.html new file mode 100644 index 000000000..0a1517bbe --- /dev/null +++ b/bstr/index.html @@ -0,0 +1,341 @@ +bstr - Rust

Crate bstr

source ·
Expand description

A byte string library.

+

Byte strings are just like standard Unicode strings with one very important +difference: byte strings are only conventionally UTF-8 while Rust’s standard +Unicode strings are guaranteed to be valid UTF-8. The primary motivation for +byte strings is for handling arbitrary bytes that are mostly UTF-8.

+

Overview

+

This crate provides two important traits that provide string oriented methods +on &[u8] and Vec<u8> types:

+
    +
  • ByteSlice extends the [u8] type with additional +string oriented methods.
  • +
  • ByteVec extends the Vec<u8> type with additional +string oriented methods.
  • +
+

Additionally, this crate provides two concrete byte string types that deref to +[u8] and Vec<u8>. These are useful for storing byte string types, and come +with convenient std::fmt::Debug implementations:

+
    +
  • BStr is a byte string slice, analogous to str.
  • +
  • BString is an owned growable byte string buffer, +analogous to String.
  • +
+

Additionally, the free function B serves as a convenient short +hand for writing byte string literals.

+

Quick examples

+

Byte strings build on the existing APIs for Vec<u8> and &[u8], with +additional string oriented methods. Operations such as iterating over +graphemes, searching for substrings, replacing substrings, trimming and case +conversion are examples of things not provided on the standard library &[u8] +APIs but are provided by this crate. For example, this code iterates over all +of occurrences of a substring:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+
+let mut matches = vec![];
+for start in s.find_iter("foo") {
+    matches.push(start);
+}
+assert_eq!(matches, [0, 8, 12, 21]);
+

Here’s another example showing how to do a search and replace (and also showing +use of the B function):

+ +
use bstr::{B, ByteSlice};
+
+let old = B("foo ☃☃☃ foo foo quux foo");
+let new = old.replace("foo", "hello");
+assert_eq!(new, B("hello ☃☃☃ hello hello quux hello"));
+

And here’s an example that shows case conversion, even in the presence of +invalid UTF-8:

+ +
use bstr::{ByteSlice, ByteVec};
+
+let mut lower = Vec::from("hello β");
+lower[0] = b'\xFF';
+// lowercase β is uppercased to Β
+assert_eq!(lower.to_uppercase(), b"\xFFELLO \xCE\x92");
+

Convenient debug representation

+

When working with byte strings, it is often useful to be able to print them +as if they were byte strings and not sequences of integers. While this crate +cannot affect the std::fmt::Debug implementations for [u8] and Vec<u8>, +this crate does provide the BStr and BString types which have convenient +std::fmt::Debug implementations.

+

For example, this

+ +
use bstr::ByteSlice;
+
+let mut bytes = Vec::from("hello β");
+bytes[0] = b'\xFF';
+
+println!("{:?}", bytes.as_bstr());
+

will output "\xFFello β".

+

This example works because the +ByteSlice::as_bstr +method converts any &[u8] to a &BStr.

+

When should I use byte strings?

+

This library reflects my belief that UTF-8 by convention is a better trade +off in some circumstances than guaranteed UTF-8.

+

The first time this idea hit me was in the implementation of Rust’s regex +engine. In particular, very little of the internal implementation cares at all +about searching valid UTF-8 encoded strings. Indeed, internally, the +implementation converts &str from the API to &[u8] fairly quickly and +just deals with raw bytes. UTF-8 match boundaries are then guaranteed by the +finite state machine itself rather than any specific string type. This makes it +possible to not only run regexes on &str values, but also on &[u8] values.

+

Why would you ever want to run a regex on a &[u8] though? Well, &[u8] is +the fundamental way at which one reads data from all sorts of streams, via the +standard library’s Read +trait. In particular, there is no platform independent way to determine whether +what you’re reading from is some binary file or a human readable text file. +Therefore, if you’re writing a program to search files, you probably need to +deal with &[u8] directly unless you’re okay with first converting it to a +&str and dropping any bytes that aren’t valid UTF-8. (Or otherwise determine +the encoding—which is often impractical—and perform a transcoding step.) +Often, the simplest and most robust way to approach this is to simply treat the +contents of a file as if it were mostly valid UTF-8 and pass through invalid +UTF-8 untouched. This may not be the most correct approach though!

+

One case in particular exacerbates these issues, and that’s memory mapping +a file. When you memory map a file, that file may be gigabytes big, but all +you get is a &[u8]. Converting that to a &str all in one go is generally +not a good idea because of the costs associated with doing so, and also +because it generally causes one to do two passes over the data instead of +one, which is quite undesirable. It is of course usually possible to do it an +incremental way by only parsing chunks at a time, but this is often complex to +do or impractical. For example, many regex engines only accept one contiguous +sequence of bytes at a time with no way to perform incremental matching.

+

bstr in public APIs

+

This library is past version 1 and is expected to remain at version 1 for +the foreseeable future. Therefore, it is encouraged to put types from bstr +(like BStr and BString) in your public API if that makes sense for your +crate.

+

With that said, in general, it should be possible to avoid putting anything +in this crate into your public APIs. Namely, you should never need to use the +ByteSlice or ByteVec traits as bounds on public APIs, since their only +purpose is to extend the methods on the concrete types [u8] and Vec<u8>, +respectively. Similarly, it should not be necessary to put either the BStr or +BString types into public APIs. If you want to use them internally, then they +can be converted to/from [u8]/Vec<u8> as needed. The conversions are free.

+

So while it shouldn’t ever be 100% necessary to make bstr a public +dependency, there may be cases where it is convenient to do so. This is an +explicitly supported use case of bstr, and as such, major version releases +should be exceptionally rare.

+

Differences with standard strings

+

The primary difference between [u8] and str is that the former is +conventionally UTF-8 while the latter is guaranteed to be UTF-8. The phrase +“conventionally UTF-8” means that a [u8] may contain bytes that do not form +a valid UTF-8 sequence, but operations defined on the type in this crate are +generally most useful on valid UTF-8 sequences. For example, iterating over +Unicode codepoints or grapheme clusters is an operation that is only defined +on valid UTF-8. Therefore, when invalid UTF-8 is encountered, the Unicode +replacement codepoint is substituted. Thus, a byte string that is not UTF-8 at +all is of limited utility when using these crate.

+

However, not all operations on byte strings are specifically Unicode aware. For +example, substring search has no specific Unicode semantics ascribed to it. It +works just as well for byte strings that are completely valid UTF-8 as for byte +strings that contain no valid UTF-8 at all. Similarly for replacements and +various other operations that do not need any Unicode specific tailoring.

+

Aside from the difference in how UTF-8 is handled, the APIs between [u8] and +str (and Vec<u8> and String) are intentionally very similar, including +maintaining the same behavior for corner cases in things like substring +splitting. There are, however, some differences:

+
    +
  • Substring search is not done with matches, but instead, find_iter. +In general, this crate does not define any generic +Pattern +infrastructure, and instead prefers adding new methods for different +argument types. For example, matches can search by a char or a &str, +where as find_iter can only search by a byte string. find_char can be +used for searching by a char.
  • +
  • Since SliceConcatExt in the standard library is unstable, it is not +possible to reuse that to implement join and concat methods. Instead, +join and concat are provided as free +functions that perform a similar task.
  • +
  • This library bundles in a few more Unicode operations, such as grapheme, +word and sentence iterators. More operations, such as normalization and +case folding, may be provided in the future.
  • +
  • Some String/str APIs will panic if a particular index was not on a valid +UTF-8 code unit sequence boundary. Conversely, no such checking is performed +in this crate, as is consistent with treating byte strings as a sequence of +bytes. This means callers are responsible for maintaining a UTF-8 invariant +if that’s important.
  • +
  • Some routines provided by this crate, such as starts_with_str, have a +_str suffix to differentiate them from similar routines already defined +on the [u8] type. The difference is that starts_with requires its +parameter to be a &[u8], where as starts_with_str permits its parameter +to by anything that implements AsRef<[u8]>, which is more flexible. This +means you can write bytes.starts_with_str("☃") instead of +bytes.starts_with("☃".as_bytes()).
  • +
+

Otherwise, you should find most of the APIs between this crate and the standard +library string APIs to be very similar, if not identical.

+

Handling of invalid UTF-8

+

Since byte strings are only conventionally UTF-8, there is no guarantee +that byte strings contain valid UTF-8. Indeed, it is perfectly legal for a +byte string to contain arbitrary bytes. However, since this library defines +a string type, it provides many operations specified by Unicode. These +operations are typically only defined over codepoints, and thus have no real +meaning on bytes that are invalid UTF-8 because they do not map to a particular +codepoint.

+

For this reason, whenever operations defined only on codepoints are used, this +library will automatically convert invalid UTF-8 to the Unicode replacement +codepoint, U+FFFD, which looks like this: . For example, an +iterator over codepoints will yield a Unicode +replacement codepoint whenever it comes across bytes that are not valid UTF-8:

+ +
use bstr::ByteSlice;
+
+let bs = b"a\xFF\xFFz";
+let chars: Vec<char> = bs.chars().collect();
+assert_eq!(vec!['a', '\u{FFFD}', '\u{FFFD}', 'z'], chars);
+

There are a few ways in which invalid bytes can be substituted with a Unicode +replacement codepoint. One way, not used by this crate, is to replace every +individual invalid byte with a single replacement codepoint. In contrast, the +approach this crate uses is called the “substitution of maximal subparts,” as +specified by the Unicode Standard (Chapter 3, Section 9). (This approach is +also used by W3C’s Encoding Standard.) In +this strategy, a replacement codepoint is inserted whenever a byte is found +that cannot possibly lead to a valid UTF-8 code unit sequence. If there were +previous bytes that represented a prefix of a well-formed UTF-8 code unit +sequence, then all of those bytes (up to 3) are substituted with a single +replacement codepoint. For example:

+ +
use bstr::ByteSlice;
+
+let bs = b"a\xF0\x9F\x87z";
+let chars: Vec<char> = bs.chars().collect();
+// The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of them
+// on their own are invalid. Only one replacement codepoint is substituted,
+// which demonstrates the "substitution of maximal subparts" strategy.
+assert_eq!(vec!['a', '\u{FFFD}', 'z'], chars);
+

If you do need to access the raw bytes for some reason in an iterator like +Chars, then you should use the iterator’s “indices” variant, which gives +the byte offsets containing the invalid UTF-8 bytes that were substituted with +the replacement codepoint. For example:

+ +
use bstr::{B, ByteSlice};
+
+let bs = b"a\xE2\x98z";
+let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
+// Even though the replacement codepoint is encoded as 3 bytes itself, the
+// byte range given here is only two bytes, corresponding to the original
+// raw bytes.
+assert_eq!(vec![(0, 1, 'a'), (1, 3, '\u{FFFD}'), (3, 4, 'z')], chars);
+
+// Thus, getting the original raw bytes is as simple as slicing the original
+// byte string:
+let chars: Vec<&[u8]> = bs.char_indices().map(|(s, e, _)| &bs[s..e]).collect();
+assert_eq!(vec![B("a"), B(b"\xE2\x98"), B("z")], chars);
+

File paths and OS strings

+

One of the premiere features of Rust’s standard library is how it handles file +paths. In particular, it makes it very hard to write incorrect code while +simultaneously providing a correct cross platform abstraction for manipulating +file paths. The key challenge that one faces with file paths across platforms +is derived from the following observations:

+
    +
  • On most Unix-like systems, file paths are an arbitrary sequence of bytes.
  • +
  • On Windows, file paths are an arbitrary sequence of 16-bit integers.
  • +
+

(In both cases, certain sequences aren’t allowed. For example a NUL byte is +not allowed in either case. But we can ignore this for the purposes of this +section.)

+

Byte strings, like the ones provided in this crate, line up really well with +file paths on Unix like systems, which are themselves just arbitrary sequences +of bytes. It turns out that if you treat them as “mostly UTF-8,” then things +work out pretty well. On the contrary, byte strings don’t really work +that well on Windows because it’s not possible to correctly roundtrip file +paths between 16-bit integers and something that looks like UTF-8 without +explicitly defining an encoding to do this for you, which is anathema to byte +strings, which are just bytes.

+

Rust’s standard library elegantly solves this problem by specifying an +internal encoding for file paths that’s only used on Windows called +WTF-8. Its key properties are that they +permit losslessly roundtripping file paths on Windows by extending UTF-8 to +support an encoding of surrogate codepoints, while simultaneously supporting +zero-cost conversion from Rust’s Unicode strings to file paths. (Since UTF-8 is +a proper subset of WTF-8.)

+

The fundamental point at which the above strategy fails is when you want to +treat file paths as things that look like strings in a zero cost way. In most +cases, this is actually the wrong thing to do, but some cases call for it, +for example, glob or regex matching on file paths. This is because WTF-8 is +treated as an internal implementation detail, and there is no way to access +those bytes via a public API. Therefore, such consumers are limited in what +they can do:

+
    +
  1. One could re-implement WTF-8 and re-encode file paths on Windows to WTF-8 +by accessing their underlying 16-bit integer representation. Unfortunately, +this isn’t zero cost (it introduces a second WTF-8 decoding step) and it’s +not clear this is a good thing to do, since WTF-8 should ideally remain an +internal implementation detail. This is roughly the approach taken by the +os_str_bytes crate.
  2. +
  3. One could instead declare that they will not handle paths on Windows that +are not valid UTF-16, and return an error when one is encountered.
  4. +
  5. Like (2), but instead of returning an error, lossily decode the file path +on Windows that isn’t valid UTF-16 into UTF-16 by replacing invalid bytes +with the Unicode replacement codepoint.
  6. +
+

While this library may provide facilities for (1) in the future, currently, +this library only provides facilities for (2) and (3). In particular, a suite +of conversion functions are provided that permit converting between byte +strings, OS strings and file paths. For owned byte strings, they are:

+ +

For byte string slices, they are:

+ +

On Unix, all of these conversions are rigorously zero cost, which gives one +a way to ergonomically deal with raw file paths exactly as they are using +normal string-related functions. On Windows, these conversion routines perform +a UTF-8 check and either return an error or lossily decode the file path +into valid UTF-8, depending on which function you use. This means that you +cannot roundtrip all file paths on Windows correctly using these conversion +routines. However, this may be an acceptable downside since such file paths +are exceptionally rare. Moreover, roundtripping isn’t always necessary, for +example, if all you’re doing is filtering based on file paths.

+

The reason why using byte strings for this is potentially superior than the +standard library’s approach is that a lot of Rust code is already lossily +converting file paths to Rust’s Unicode strings, which are required to be valid +UTF-8, and thus contain latent bugs on Unix where paths with invalid UTF-8 are +not terribly uncommon. If you instead use byte strings, then you’re guaranteed +to write correct code for Unix, at the cost of getting a corner case wrong on +Windows.

+

Cargo features

+

This crates comes with a few features that control standard library, serde +and Unicode support.

+
    +
  • std - Enabled by default. This provides APIs that require the standard +library, such as Vec<u8> and PathBuf. Enabling this feature also enables +the alloc feature and any other relevant std features for dependencies.
  • +
  • alloc - Enabled by default. This provides APIs that require allocations +via the alloc crate, such as Vec<u8>.
  • +
  • unicode - Enabled by default. This provides APIs that require sizable +Unicode data compiled into the binary. This includes, but is not limited to, +grapheme/word/sentence segmenters. When this is disabled, basic support such +as UTF-8 decoding is still included. Note that currently, enabling this +feature also requires enabling the std feature. It is expected that this +limitation will be lifted at some point.
  • +
  • serde - Enables implementations of serde traits for BStr, and also +BString when alloc is enabled.
  • +
+

Structs

  • A wrapper for &[u8] that provides convenient string oriented trait impls.
  • An iterator over the bytes in a byte string.
  • An iterator over Unicode scalar values in a byte string and their +byte index positions.
  • An iterator over Unicode scalar values in a byte string.
  • An iterator of char values that represent an escaping of arbitrary bytes.
  • An iterator over fields in the byte string, separated by a predicate over +codepoints.
  • An iterator over non-overlapping substring matches.
  • An iterator over non-overlapping substring matches in reverse.
  • A single substring searcher fixed to a particular needle.
  • A single substring reverse searcher fixed to a particular needle.
  • An iterator over all lines in a byte string, without their terminators.
  • An iterator over all lines in a byte string, including their terminators.
  • An iterator over substrings in a byte string, split by a separator.
  • An iterator over at most n substrings in a byte string, split by a +separator.
  • An iterator over at most n substrings in a byte string, split by a +separator, in reverse.
  • An iterator over substrings in a byte string, split by a separator, in +reverse.
  • A chunk of valid UTF-8, possibly followed by invalid UTF-8 bytes.
  • An iterator over chunks of valid UTF-8 in a byte slice.
  • An error that occurs when UTF-8 decoding fails.

Traits

  • A trait that extends &[u8] with string oriented methods.

Functions

  • A short-hand constructor for building a &[u8].
  • UTF-8 decode a single Unicode scalar value from the end of a slice.
  • UTF-8 decode a single Unicode scalar value from the beginning of a slice.
\ No newline at end of file diff --git a/bstr/sidebar-items.js b/bstr/sidebar-items.js new file mode 100644 index 000000000..e9a515096 --- /dev/null +++ b/bstr/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["B","decode_last_utf8","decode_utf8"],"struct":["BStr","Bytes","CharIndices","Chars","EscapeBytes","FieldsWith","Find","FindReverse","Finder","FinderReverse","Lines","LinesWithTerminator","Split","SplitN","SplitNReverse","SplitReverse","Utf8Chunk","Utf8Chunks","Utf8Error"],"trait":["ByteSlice"]}; \ No newline at end of file diff --git a/bstr/struct.BStr.html b/bstr/struct.BStr.html new file mode 100644 index 000000000..b000be81e --- /dev/null +++ b/bstr/struct.BStr.html @@ -0,0 +1,2444 @@ +BStr in bstr - Rust

Struct bstr::BStr

source ·
pub struct BStr { /* private fields */ }
Expand description

A wrapper for &[u8] that provides convenient string oriented trait impls.

+

If you need ownership or a growable byte string buffer, then use +BString.

+

Using a &BStr is just like using a &[u8], since BStr +implements Deref to [u8]. So all methods available on [u8] +are also available on BStr.

+

Representation

+

A &BStr has the same representation as a &str. That is, a &BStr is +a fat pointer which consists of a pointer to some bytes and a length.

+

Trait implementations

+

The BStr type has a number of trait implementations, and in particular, +defines equality and ordinal comparisons between &BStr, &str and +&[u8] for convenience.

+

The Debug implementation for BStr shows its bytes as a normal string. +For invalid UTF-8, hex escape sequences are used.

+

The Display implementation behaves as if BStr were first lossily +converted to a str. Invalid UTF-8 bytes are substituted with the Unicode +replacement codepoint, which looks like this: �.

+

Implementations§

source§

impl BStr

source

pub fn new<'a, B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> &'a BStr

Directly creates a BStr slice from anything that can be converted +to a byte slice.

+

This is very similar to the B function, except this +returns a &BStr instead of a &[u8].

+

This is a cost-free conversion.

+
Example
+

You can create BStr’s from byte arrays, byte slices or even string +slices:

+ +
use bstr::BStr;
+
+let a = BStr::new(b"abc");
+let b = BStr::new(&b"abc"[..]);
+let c = BStr::new("abc");
+
+assert_eq!(a, b);
+assert_eq!(a, c);
+

Methods from Deref<Target = [u8]>§

source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
source

pub fn trim_ascii_start(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
source

pub fn trim_ascii_end(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
source

pub fn trim_ascii(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the last item in the slice.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice, or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable reference to the first N elements of the slice, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable reference to the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+    assert_eq!(last, &[1, 2]);
+    assert_eq!(elements, &[0]);
+}
+
source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last element of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable pointer to the last item in the slice.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Panics
+

Panics if a or b are out of bounds.

+
Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
source

pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where + F: FnMut(&T, &T) -> bool,

🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
source

pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>where + F: FnMut(&T, &T) -> bool,

🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])

🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
source

pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])

🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an +index from the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> boolwhere + T: PartialEq<T>,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])where + T: Ord,

Reorder the slice such that the element at index is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])where + T: PartialEq<T>,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T) -> K, + K: PartialEq<K>,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)where + T: Clone,

Fills self with elements by cloning value.

+
Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> boolwhere + T: PartialOrd<T>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere + F: FnMut(&'a T, &'a T) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere + F: FnMut(&'a T) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usizewhere + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
source

pub fn flatten(&self) -> &[T]

🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
source

pub fn flatten_mut(&mut self) -> &mut [T]

🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn sort(&mut self)where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T, Global>where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T, Global>where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8, Global>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8, Global>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl AsMut<[u8]> for BStr

source§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsMut<BStr> for [u8]

source§

fn as_mut(&mut self) -> &mut BStr

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<[u8]> for BStr

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<BStr> for [u8]

source§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<BStr> for BStr

source§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<BStr> for str

source§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<[u8]> for BStr

source§

fn borrow(&self) -> &[u8]

Immutably borrows from an owned value. Read more
source§

impl Borrow<BStr> for [u8]

source§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
source§

impl Borrow<BStr> for str

source§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<[u8]> for BStr

source§

fn borrow_mut(&mut self) -> &mut [u8]

Mutably borrows from an owned value. Read more
source§

impl BorrowMut<BStr> for [u8]

source§

fn borrow_mut(&mut self) -> &mut BStr

Mutably borrows from an owned value. Read more
source§

impl Debug for BStr

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Default for &'a BStr

source§

fn default() -> &'a BStr

Returns the “default value” for a type. Read more
source§

impl<'a> Default for &'a mut BStr

source§

fn default() -> &'a mut BStr

Returns the “default value” for a type. Read more
source§

impl Deref for BStr

§

type Target = [u8]

The resulting type after dereferencing.
source§

fn deref(&self) -> &[u8]

Dereferences the value.
source§

impl DerefMut for BStr

source§

fn deref_mut(&mut self) -> &mut [u8]

Mutably dereferences the value.
source§

impl Display for BStr

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a [u8]> for &'a BStr

source§

fn from(s: &'a [u8]) -> &'a BStr

Converts to this type from the input type.
source§

impl<'a, const N: usize> From<&'a [u8; N]> for &'a BStr

source§

fn from(s: &'a [u8; N]) -> &'a BStr

Converts to this type from the input type.
source§

impl<'a> From<&'a BStr> for &'a [u8]

source§

fn from(s: &'a BStr) -> &'a [u8]

Converts to this type from the input type.
source§

impl<'a> From<&'a str> for &'a BStr

source§

fn from(s: &'a str) -> &'a BStr

Converts to this type from the input type.
source§

impl Hash for BStr

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
source§

impl Index<Range<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, r: Range<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<RangeFrom<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, r: RangeFrom<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<RangeFull> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, _: RangeFull) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<RangeInclusive<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, r: RangeInclusive<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<RangeTo<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, r: RangeTo<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<RangeToInclusive<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
source§

fn index(&self, r: RangeToInclusive<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
source§

impl Index<usize> for BStr

§

type Output = u8

The returned type after indexing.
source§

fn index(&self, idx: usize) -> &u8

Performs the indexing (container[index]) operation. Read more
source§

impl IndexMut<Range<usize>> for BStr

source§

fn index_mut(&mut self, r: Range<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<RangeFrom<usize>> for BStr

source§

fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<RangeFull> for BStr

source§

fn index_mut(&mut self, _: RangeFull) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<RangeInclusive<usize>> for BStr

source§

fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<RangeTo<usize>> for BStr

source§

fn index_mut(&mut self, r: RangeTo<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<RangeToInclusive<usize>> for BStr

source§

fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
source§

impl IndexMut<usize> for BStr

source§

fn index_mut(&mut self, idx: usize) -> &mut u8

Performs the mutable indexing (container[index]) operation. Read more
source§

impl Ord for BStr

source§

fn cmp(&self, other: &BStr) -> Ordering

This method returns an Ordering between self and other. Read more
source§

impl<'a, 'b> PartialEq<&'a [u8]> for BStr

source§

fn eq(&self, other: &&'a [u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<&'a str> for BStr

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<[u8]> for BStr

source§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<BStr> for &'a [u8]

source§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<BStr> for &'a str

source§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<BStr> for [u8]

source§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<BStr> for str

source§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialEq<str> for BStr

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<BStr> for BStr

source§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, 'b> PartialOrd<&'a [u8]> for BStr

source§

fn partial_cmp(&self, other: &&'a [u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<&'a str> for BStr

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<[u8]> for BStr

source§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<BStr> for &'a [u8]

source§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<BStr> for &'a str

source§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<BStr> for [u8]

source§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<BStr> for str

source§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a, 'b> PartialOrd<str> for BStr

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<BStr> for BStr

source§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a BStr> for &'a str

§

type Error = Utf8Error

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a BStr) -> Result<&'a str, Utf8Error>

Performs the conversion.
source§

impl Eq for BStr

Auto Trait Implementations§

§

impl RefUnwindSafe for BStr

§

impl Send for BStr

§

impl !Sized for BStr

§

impl Sync for BStr

§

impl Unpin for BStr

§

impl UnwindSafe for BStr

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
\ No newline at end of file diff --git a/bstr/struct.Bytes.html b/bstr/struct.Bytes.html new file mode 100644 index 000000000..b7064321f --- /dev/null +++ b/bstr/struct.Bytes.html @@ -0,0 +1,214 @@ +Bytes in bstr - Rust

Struct bstr::Bytes

source ·
pub struct Bytes<'a> { /* private fields */ }
Expand description

An iterator over the bytes in a byte string.

+

'a is the lifetime of the byte string being traversed.

+

Implementations§

source§

impl<'a> Bytes<'a>

source

pub fn as_bytes(&self) -> &'a [u8]

Views the remaining underlying data as a subslice of the original data. +This has the same lifetime as the original slice, +and so the iterator can continue to be used while this exists.

+

Trait Implementations§

source§

impl<'a> Clone for Bytes<'a>

source§

fn clone(&self) -> Bytes<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Bytes<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> DoubleEndedIterator for Bytes<'a>

source§

fn next_back(&mut self) -> Option<u8>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a> ExactSizeIterator for Bytes<'a>

source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Bytes<'a>

§

type Item = u8

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<u8>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.0.0 · source§

fn rposition<P>(&mut self, predicate: P) -> Option<usize>where + P: FnMut(Self::Item) -> bool, + Self: Sized + ExactSizeIterator + DoubleEndedIterator,

Searches for an element in an iterator from the right, returning its +index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for Bytes<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Bytes<'a>

§

impl<'a> Send for Bytes<'a>

§

impl<'a> Sync for Bytes<'a>

§

impl<'a> Unpin for Bytes<'a>

§

impl<'a> UnwindSafe for Bytes<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.CharIndices.html b/bstr/struct.CharIndices.html new file mode 100644 index 000000000..7146cd3df --- /dev/null +++ b/bstr/struct.CharIndices.html @@ -0,0 +1,235 @@ +CharIndices in bstr - Rust

Struct bstr::CharIndices

source ·
pub struct CharIndices<'a> { /* private fields */ }
Expand description

An iterator over Unicode scalar values in a byte string and their +byte index positions.

+

When invalid UTF-8 byte sequences are found, they are substituted with the +Unicode replacement codepoint (U+FFFD) using the +“maximal subpart” strategy.

+

Note that this is slightly different from the CharIndices iterator +provided by the standard library. Aside from working on possibly invalid +UTF-8, this iterator provides both the corresponding starting and ending +byte indices of each codepoint yielded. The ending position is necessary to +slice the original byte string when invalid UTF-8 bytes are converted into +a Unicode replacement codepoint, since a single replacement codepoint can +substitute anywhere from 1 to 3 invalid bytes (inclusive).

+

This iterator is created by the +char_indices method provided +by the ByteSlice extension trait for &[u8].

+

Implementations§

source§

impl<'a> CharIndices<'a>

source

pub fn as_bytes(&self) -> &'a [u8]

View the underlying data as a subslice of the original data.

+

The slice returned has the same lifetime as the original slice, and so +the iterator can continue to be used while this exists.

+
Examples
+
use bstr::ByteSlice;
+
+let mut it = b"abc".char_indices();
+
+assert_eq!(b"abc", it.as_bytes());
+it.next();
+assert_eq!(b"bc", it.as_bytes());
+it.next();
+it.next();
+assert_eq!(b"", it.as_bytes());
+

Trait Implementations§

source§

impl<'a> Clone for CharIndices<'a>

source§

fn clone(&self) -> CharIndices<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for CharIndices<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> DoubleEndedIterator for CharIndices<'a>

source§

fn next_back(&mut self) -> Option<(usize, usize, char)>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a> Iterator for CharIndices<'a>

§

type Item = (usize, usize, char)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<(usize, usize, char)>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for CharIndices<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for CharIndices<'a>

§

impl<'a> Send for CharIndices<'a>

§

impl<'a> Sync for CharIndices<'a>

§

impl<'a> Unpin for CharIndices<'a>

§

impl<'a> UnwindSafe for CharIndices<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Chars.html b/bstr/struct.Chars.html new file mode 100644 index 000000000..0fc2de426 --- /dev/null +++ b/bstr/struct.Chars.html @@ -0,0 +1,227 @@ +Chars in bstr - Rust

Struct bstr::Chars

source ·
pub struct Chars<'a> { /* private fields */ }
Expand description

An iterator over Unicode scalar values in a byte string.

+

When invalid UTF-8 byte sequences are found, they are substituted with the +Unicode replacement codepoint (U+FFFD) using the +“maximal subpart” strategy.

+

This iterator is created by the +chars method provided by the +ByteSlice extension trait for &[u8].

+

Implementations§

source§

impl<'a> Chars<'a>

source

pub fn as_bytes(&self) -> &'a [u8]

View the underlying data as a subslice of the original data.

+

The slice returned has the same lifetime as the original slice, and so +the iterator can continue to be used while this exists.

+
Examples
+
use bstr::ByteSlice;
+
+let mut chars = b"abc".chars();
+
+assert_eq!(b"abc", chars.as_bytes());
+chars.next();
+assert_eq!(b"bc", chars.as_bytes());
+chars.next();
+chars.next();
+assert_eq!(b"", chars.as_bytes());
+

Trait Implementations§

source§

impl<'a> Clone for Chars<'a>

source§

fn clone(&self) -> Chars<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Chars<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> DoubleEndedIterator for Chars<'a>

source§

fn next_back(&mut self) -> Option<char>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a> Iterator for Chars<'a>

§

type Item = char

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<char>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Chars<'a>

§

impl<'a> Send for Chars<'a>

§

impl<'a> Sync for Chars<'a>

§

impl<'a> Unpin for Chars<'a>

§

impl<'a> UnwindSafe for Chars<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.EscapeBytes.html b/bstr/struct.EscapeBytes.html new file mode 100644 index 000000000..2a8f285e9 --- /dev/null +++ b/bstr/struct.EscapeBytes.html @@ -0,0 +1,197 @@ +EscapeBytes in bstr - Rust

Struct bstr::EscapeBytes

source ·
pub struct EscapeBytes<'a> { /* private fields */ }
Expand description

An iterator of char values that represent an escaping of arbitrary bytes.

+

The lifetime parameter 'a refers to the lifetime of the bytes being +escaped.

+

This iterator is created by the +ByteSlice::escape_bytes method.

+

Trait Implementations§

source§

impl<'a> Clone for EscapeBytes<'a>

source§

fn clone(&self) -> EscapeBytes<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for EscapeBytes<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Display for EscapeBytes<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Iterator for EscapeBytes<'a>

§

type Item = char

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<char>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for EscapeBytes<'a>

§

impl<'a> Send for EscapeBytes<'a>

§

impl<'a> Sync for EscapeBytes<'a>

§

impl<'a> Unpin for EscapeBytes<'a>

§

impl<'a> UnwindSafe for EscapeBytes<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.FieldsWith.html b/bstr/struct.FieldsWith.html new file mode 100644 index 000000000..20c9da79a --- /dev/null +++ b/bstr/struct.FieldsWith.html @@ -0,0 +1,201 @@ +FieldsWith in bstr - Rust

Struct bstr::FieldsWith

source ·
pub struct FieldsWith<'a, F> { /* private fields */ }
Expand description

An iterator over fields in the byte string, separated by a predicate over +codepoints.

+

This iterator splits a byte string based on its predicate function such +that the elements returned are separated by contiguous runs of codepoints +for which the predicate returns true.

+

'a is the lifetime of the byte string being split, while F is the type +of the predicate, i.e., FnMut(char) -> bool.

+

Trait Implementations§

source§

impl<'a, F: Debug> Debug for FieldsWith<'a, F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F>

§

type Item = &'a [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'a [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a, F> RefUnwindSafe for FieldsWith<'a, F>where + F: RefUnwindSafe,

§

impl<'a, F> Send for FieldsWith<'a, F>where + F: Send,

§

impl<'a, F> Sync for FieldsWith<'a, F>where + F: Sync,

§

impl<'a, F> Unpin for FieldsWith<'a, F>where + F: Unpin,

§

impl<'a, F> UnwindSafe for FieldsWith<'a, F>where + F: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Find.html b/bstr/struct.Find.html new file mode 100644 index 000000000..07e1f56a8 --- /dev/null +++ b/bstr/struct.Find.html @@ -0,0 +1,193 @@ +Find in bstr - Rust

Struct bstr::Find

source ·
pub struct Find<'h, 'n> { /* private fields */ }
Expand description

An iterator over non-overlapping substring matches.

+

Matches are reported by the byte offset at which they begin.

+

'h is the lifetime of the haystack while 'n is the lifetime of the +needle.

+

Trait Implementations§

source§

impl<'h, 'n> Debug for Find<'h, 'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 'n> Iterator for Find<'h, 'n>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 'n> RefUnwindSafe for Find<'h, 'n>

§

impl<'h, 'n> Send for Find<'h, 'n>

§

impl<'h, 'n> Sync for Find<'h, 'n>

§

impl<'h, 'n> Unpin for Find<'h, 'n>

§

impl<'h, 'n> UnwindSafe for Find<'h, 'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.FindReverse.html b/bstr/struct.FindReverse.html new file mode 100644 index 000000000..00936ff13 --- /dev/null +++ b/bstr/struct.FindReverse.html @@ -0,0 +1,193 @@ +FindReverse in bstr - Rust

Struct bstr::FindReverse

source ·
pub struct FindReverse<'h, 'n> { /* private fields */ }
Expand description

An iterator over non-overlapping substring matches in reverse.

+

Matches are reported by the byte offset at which they begin.

+

'h is the lifetime of the haystack while 'n is the lifetime of the +needle.

+

Trait Implementations§

source§

impl<'h, 'n> Debug for FindReverse<'h, 'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 'n> Iterator for FindReverse<'h, 'n>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 'n> RefUnwindSafe for FindReverse<'h, 'n>

§

impl<'h, 'n> Send for FindReverse<'h, 'n>

§

impl<'h, 'n> Sync for FindReverse<'h, 'n>

§

impl<'h, 'n> Unpin for FindReverse<'h, 'n>

§

impl<'h, 'n> UnwindSafe for FindReverse<'h, 'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Finder.html b/bstr/struct.Finder.html new file mode 100644 index 000000000..b044825a3 --- /dev/null +++ b/bstr/struct.Finder.html @@ -0,0 +1,51 @@ +Finder in bstr - Rust

Struct bstr::Finder

source ·
pub struct Finder<'a>(/* private fields */);
Expand description

A single substring searcher fixed to a particular needle.

+

The purpose of this type is to permit callers to construct a substring +searcher that can be used to search haystacks without the overhead of +constructing the searcher in the first place. This is a somewhat niche +concern when it’s necessary to re-use the same needle to search multiple +different haystacks with as little overhead as possible. In general, using +ByteSlice::find +or +ByteSlice::find_iter +is good enough, but Finder is useful when you can meaningfully observe +searcher construction time in a profile.

+

When the std feature is enabled, then this type has an into_owned +version which permits building a Finder that is not connected to the +lifetime of its needle.

+

Implementations§

source§

impl<'a> Finder<'a>

source

pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a>

Create a new finder for the given needle.

+
source

pub fn needle(&self) -> &[u8]

Returns the needle that this finder searches for.

+

Note that the lifetime of the needle returned is tied to the lifetime +of the finder, and may be shorter than the 'a lifetime. Namely, a +finder’s needle can be either borrowed or owned, so the lifetime of the +needle returned must necessarily be the shorter of the two.

+
source

pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize>

Returns the index of the first occurrence of this needle in the given +haystack.

+

The haystack may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::Finder;
+
+let haystack = "foo bar baz";
+assert_eq!(Some(0), Finder::new("foo").find(haystack));
+assert_eq!(Some(4), Finder::new("bar").find(haystack));
+assert_eq!(None, Finder::new("quux").find(haystack));
+

Trait Implementations§

source§

impl<'a> Clone for Finder<'a>

source§

fn clone(&self) -> Finder<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Finder<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Finder<'a>

§

impl<'a> Send for Finder<'a>

§

impl<'a> Sync for Finder<'a>

§

impl<'a> Unpin for Finder<'a>

§

impl<'a> UnwindSafe for Finder<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.FinderReverse.html b/bstr/struct.FinderReverse.html new file mode 100644 index 000000000..7c3be18d7 --- /dev/null +++ b/bstr/struct.FinderReverse.html @@ -0,0 +1,51 @@ +FinderReverse in bstr - Rust

Struct bstr::FinderReverse

source ·
pub struct FinderReverse<'a>(/* private fields */);
Expand description

A single substring reverse searcher fixed to a particular needle.

+

The purpose of this type is to permit callers to construct a substring +searcher that can be used to search haystacks without the overhead of +constructing the searcher in the first place. This is a somewhat niche +concern when it’s necessary to re-use the same needle to search multiple +different haystacks with as little overhead as possible. In general, using +ByteSlice::rfind +or +ByteSlice::rfind_iter +is good enough, but FinderReverse is useful when you can meaningfully +observe searcher construction time in a profile.

+

When the std feature is enabled, then this type has an into_owned +version which permits building a FinderReverse that is not connected to +the lifetime of its needle.

+

Implementations§

source§

impl<'a> FinderReverse<'a>

source

pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a>

Create a new reverse finder for the given needle.

+
source

pub fn needle(&self) -> &[u8]

Returns the needle that this finder searches for.

+

Note that the lifetime of the needle returned is tied to the lifetime +of this finder, and may be shorter than the 'a lifetime. Namely, +a finder’s needle can be either borrowed or owned, so the lifetime of +the needle returned must necessarily be the shorter of the two.

+
source

pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize>

Returns the index of the last occurrence of this needle in the given +haystack.

+

The haystack may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::FinderReverse;
+
+let haystack = "foo bar baz";
+assert_eq!(Some(0), FinderReverse::new("foo").rfind(haystack));
+assert_eq!(Some(4), FinderReverse::new("bar").rfind(haystack));
+assert_eq!(None, FinderReverse::new("quux").rfind(haystack));
+

Trait Implementations§

source§

impl<'a> Clone for FinderReverse<'a>

source§

fn clone(&self) -> FinderReverse<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for FinderReverse<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for FinderReverse<'a>

§

impl<'a> Send for FinderReverse<'a>

§

impl<'a> Sync for FinderReverse<'a>

§

impl<'a> Unpin for FinderReverse<'a>

§

impl<'a> UnwindSafe for FinderReverse<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Lines.html b/bstr/struct.Lines.html new file mode 100644 index 000000000..a203112bb --- /dev/null +++ b/bstr/struct.Lines.html @@ -0,0 +1,224 @@ +Lines in bstr - Rust

Struct bstr::Lines

source ·
pub struct Lines<'a> { /* private fields */ }
Expand description

An iterator over all lines in a byte string, without their terminators.

+

For this iterator, the only line terminators recognized are \r\n and +\n.

+

'a is the lifetime of the byte string being iterated over.

+

Implementations§

source§

impl<'a> Lines<'a>

source

pub fn as_bytes(&self) -> &'a [u8]

Return a copy of the rest of the underlying bytes without affecting the +iterator itself.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+bar\r
+baz";
+let mut lines = s.lines();
+assert_eq!(lines.next(), Some(B("foo")));
+assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
+

Trait Implementations§

source§

impl<'a> Clone for Lines<'a>

source§

fn clone(&self) -> Lines<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Lines<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> DoubleEndedIterator for Lines<'a>

source§

fn next_back(&mut self) -> Option<Self::Item>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a> Iterator for Lines<'a>

§

type Item = &'a [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'a [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for Lines<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Lines<'a>

§

impl<'a> Send for Lines<'a>

§

impl<'a> Sync for Lines<'a>

§

impl<'a> Unpin for Lines<'a>

§

impl<'a> UnwindSafe for Lines<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.LinesWithTerminator.html b/bstr/struct.LinesWithTerminator.html new file mode 100644 index 000000000..8915a732d --- /dev/null +++ b/bstr/struct.LinesWithTerminator.html @@ -0,0 +1,229 @@ +LinesWithTerminator in bstr - Rust
pub struct LinesWithTerminator<'a> { /* private fields */ }
Expand description

An iterator over all lines in a byte string, including their terminators.

+

For this iterator, the only line terminator recognized is \n. (Since +line terminators are included, this also handles \r\n line endings.)

+

Line terminators are only included if they are present in the original +byte string. For example, the last line in a byte string may not end with +a line terminator.

+

Concatenating all elements yielded by this iterator is guaranteed to yield +the original byte string.

+

'a is the lifetime of the byte string being iterated over.

+

Implementations§

source§

impl<'a> LinesWithTerminator<'a>

source

pub fn as_bytes(&self) -> &'a [u8]

Return a copy of the rest of the underlying bytes without affecting the +iterator itself.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+bar\r
+baz";
+let mut lines = s.lines_with_terminator();
+assert_eq!(lines.next(), Some(B("foo\n")));
+assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
+

Trait Implementations§

source§

impl<'a> Clone for LinesWithTerminator<'a>

source§

fn clone(&self) -> LinesWithTerminator<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for LinesWithTerminator<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> DoubleEndedIterator for LinesWithTerminator<'a>

source§

fn next_back(&mut self) -> Option<Self::Item>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a> Iterator for LinesWithTerminator<'a>

§

type Item = &'a [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'a [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for LinesWithTerminator<'a>

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Split.html b/bstr/struct.Split.html new file mode 100644 index 000000000..cdf582be8 --- /dev/null +++ b/bstr/struct.Split.html @@ -0,0 +1,192 @@ +Split in bstr - Rust

Struct bstr::Split

source ·
pub struct Split<'h, 's> { /* private fields */ }
Expand description

An iterator over substrings in a byte string, split by a separator.

+

'h is the lifetime of the byte string being split (the haystack), while +'s is the lifetime of the byte string doing the splitting.

+

Trait Implementations§

source§

impl<'h, 's> Debug for Split<'h, 's>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 's> Iterator for Split<'h, 's>

§

type Item = &'h [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'h [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 's> RefUnwindSafe for Split<'h, 's>

§

impl<'h, 's> Send for Split<'h, 's>

§

impl<'h, 's> Sync for Split<'h, 's>

§

impl<'h, 's> Unpin for Split<'h, 's>

§

impl<'h, 's> UnwindSafe for Split<'h, 's>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.SplitN.html b/bstr/struct.SplitN.html new file mode 100644 index 000000000..eb781e4ea --- /dev/null +++ b/bstr/struct.SplitN.html @@ -0,0 +1,193 @@ +SplitN in bstr - Rust

Struct bstr::SplitN

source ·
pub struct SplitN<'h, 's> { /* private fields */ }
Expand description

An iterator over at most n substrings in a byte string, split by a +separator.

+

'h is the lifetime of the byte string being split (the haystack), while +'s is the lifetime of the byte string doing the splitting.

+

Trait Implementations§

source§

impl<'h, 's> Debug for SplitN<'h, 's>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 's> Iterator for SplitN<'h, 's>

§

type Item = &'h [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'h [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 's> RefUnwindSafe for SplitN<'h, 's>

§

impl<'h, 's> Send for SplitN<'h, 's>

§

impl<'h, 's> Sync for SplitN<'h, 's>

§

impl<'h, 's> Unpin for SplitN<'h, 's>

§

impl<'h, 's> UnwindSafe for SplitN<'h, 's>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.SplitNReverse.html b/bstr/struct.SplitNReverse.html new file mode 100644 index 000000000..ce7007ce9 --- /dev/null +++ b/bstr/struct.SplitNReverse.html @@ -0,0 +1,193 @@ +SplitNReverse in bstr - Rust

Struct bstr::SplitNReverse

source ·
pub struct SplitNReverse<'h, 's> { /* private fields */ }
Expand description

An iterator over at most n substrings in a byte string, split by a +separator, in reverse.

+

'h is the lifetime of the byte string being split (the haystack), while +'s is the lifetime of the byte string doing the splitting.

+

Trait Implementations§

source§

impl<'h, 's> Debug for SplitNReverse<'h, 's>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 's> Iterator for SplitNReverse<'h, 's>

§

type Item = &'h [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'h [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 's> RefUnwindSafe for SplitNReverse<'h, 's>

§

impl<'h, 's> Send for SplitNReverse<'h, 's>

§

impl<'h, 's> Sync for SplitNReverse<'h, 's>

§

impl<'h, 's> Unpin for SplitNReverse<'h, 's>

§

impl<'h, 's> UnwindSafe for SplitNReverse<'h, 's>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.SplitReverse.html b/bstr/struct.SplitReverse.html new file mode 100644 index 000000000..024b8e802 --- /dev/null +++ b/bstr/struct.SplitReverse.html @@ -0,0 +1,193 @@ +SplitReverse in bstr - Rust

Struct bstr::SplitReverse

source ·
pub struct SplitReverse<'h, 's> { /* private fields */ }
Expand description

An iterator over substrings in a byte string, split by a separator, in +reverse.

+

'h is the lifetime of the byte string being split (the haystack), while +'s is the lifetime of the byte string doing the splitting.

+

Trait Implementations§

source§

impl<'h, 's> Debug for SplitReverse<'h, 's>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 's> Iterator for SplitReverse<'h, 's>

§

type Item = &'h [u8]

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'h [u8]>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 's> RefUnwindSafe for SplitReverse<'h, 's>

§

impl<'h, 's> Send for SplitReverse<'h, 's>

§

impl<'h, 's> Sync for SplitReverse<'h, 's>

§

impl<'h, 's> Unpin for SplitReverse<'h, 's>

§

impl<'h, 's> UnwindSafe for SplitReverse<'h, 's>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Utf8Chunk.html b/bstr/struct.Utf8Chunk.html new file mode 100644 index 000000000..dd4f4f70a --- /dev/null +++ b/bstr/struct.Utf8Chunk.html @@ -0,0 +1,38 @@ +Utf8Chunk in bstr - Rust

Struct bstr::Utf8Chunk

source ·
pub struct Utf8Chunk<'a> { /* private fields */ }
Expand description

A chunk of valid UTF-8, possibly followed by invalid UTF-8 bytes.

+

This is yielded by the +Utf8Chunks +iterator, which can be created via the +ByteSlice::utf8_chunks +method.

+

The 'a lifetime parameter corresponds to the lifetime of the bytes that +are being iterated over.

+

Implementations§

source§

impl<'a> Utf8Chunk<'a>

source

pub fn valid(&self) -> &'a str

Returns the (possibly empty) valid UTF-8 bytes in this chunk.

+

This may be empty if there are consecutive sequences of invalid UTF-8 +bytes.

+
source

pub fn invalid(&self) -> &'a [u8]

Returns the (possibly empty) invalid UTF-8 bytes in this chunk that +immediately follow the valid UTF-8 bytes in this chunk.

+

This is only empty when this chunk corresponds to the last chunk in +the original bytes.

+

The maximum length of this slice is 3. That is, invalid UTF-8 byte +sequences greater than 1 always correspond to a valid prefix of +a valid UTF-8 encoded codepoint. This corresponds to the “substitution +of maximal subparts” strategy that is described in more detail in the +docs for the +ByteSlice::to_str_lossy +method.

+
source

pub fn incomplete(&self) -> bool

Returns whether the invalid sequence might still become valid if more +bytes are added.

+

Returns true if the end of the input was reached unexpectedly, +without encountering an unexpected byte.

+

This can only be the case for the last chunk.

+

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Utf8Chunk<'a>

§

impl<'a> Send for Utf8Chunk<'a>

§

impl<'a> Sync for Utf8Chunk<'a>

§

impl<'a> Unpin for Utf8Chunk<'a>

§

impl<'a> UnwindSafe for Utf8Chunk<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Utf8Chunks.html b/bstr/struct.Utf8Chunks.html new file mode 100644 index 000000000..a0ed0643d --- /dev/null +++ b/bstr/struct.Utf8Chunks.html @@ -0,0 +1,193 @@ +Utf8Chunks in bstr - Rust

Struct bstr::Utf8Chunks

source ·
pub struct Utf8Chunks<'a> { /* private fields */ }
Expand description

An iterator over chunks of valid UTF-8 in a byte slice.

+

See utf8_chunks.

+

Trait Implementations§

source§

impl<'a> Clone for Utf8Chunks<'a>

source§

fn clone(&self) -> Utf8Chunks<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Utf8Chunks<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Iterator for Utf8Chunks<'a>

§

type Item = Utf8Chunk<'a>

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Utf8Chunk<'a>>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for Utf8Chunks<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Utf8Chunks<'a>

§

impl<'a> Send for Utf8Chunks<'a>

§

impl<'a> Sync for Utf8Chunks<'a>

§

impl<'a> Unpin for Utf8Chunks<'a>

§

impl<'a> UnwindSafe for Utf8Chunks<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/struct.Utf8Error.html b/bstr/struct.Utf8Error.html new file mode 100644 index 000000000..f504501af --- /dev/null +++ b/bstr/struct.Utf8Error.html @@ -0,0 +1,77 @@ +Utf8Error in bstr - Rust

Struct bstr::Utf8Error

source ·
pub struct Utf8Error { /* private fields */ }
Expand description

An error that occurs when UTF-8 decoding fails.

+

This error occurs when attempting to convert a non-UTF-8 byte +string to a Rust string that must be valid UTF-8. For example, +to_str is one such method.

+

Example

+

This example shows what happens when a given byte sequence is invalid, +but ends with a sequence that is a possible prefix of valid UTF-8.

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"foobar\xF1\x80\x80");
+let err = s.to_str().unwrap_err();
+assert_eq!(err.valid_up_to(), 6);
+assert_eq!(err.error_len(), None);
+

This example shows what happens when a given byte sequence contains +invalid UTF-8.

+ +
use bstr::ByteSlice;
+
+let s = b"foobar\xF1\x80\x80quux";
+let err = s.to_str().unwrap_err();
+assert_eq!(err.valid_up_to(), 6);
+// The error length reports the maximum number of bytes that correspond to
+// a valid prefix of a UTF-8 encoded codepoint.
+assert_eq!(err.error_len(), Some(3));
+
+// In contrast to the above which contains a single invalid prefix,
+// consider the case of multiple individual bytes that are never valid
+// prefixes. Note how the value of error_len changes!
+let s = b"foobar\xFF\xFFquux";
+let err = s.to_str().unwrap_err();
+assert_eq!(err.valid_up_to(), 6);
+assert_eq!(err.error_len(), Some(1));
+
+// The fact that it's an invalid prefix does not change error_len even
+// when it immediately precedes the end of the string.
+let s = b"foobar\xFF";
+let err = s.to_str().unwrap_err();
+assert_eq!(err.valid_up_to(), 6);
+assert_eq!(err.error_len(), Some(1));
+

Implementations§

source§

impl Utf8Error

source

pub fn valid_up_to(&self) -> usize

Returns the byte index of the position immediately following the last +valid UTF-8 byte.

+
Example
+

This examples shows how valid_up_to can be used to retrieve a +possibly empty prefix that is guaranteed to be valid UTF-8:

+ +
use bstr::ByteSlice;
+
+let s = b"foobar\xF1\x80\x80quux";
+let err = s.to_str().unwrap_err();
+
+// This is guaranteed to never panic.
+let string = s[..err.valid_up_to()].to_str().unwrap();
+assert_eq!(string, "foobar");
+
source

pub fn error_len(&self) -> Option<usize>

Returns the total number of invalid UTF-8 bytes immediately following +the position returned by valid_up_to. This value is always at least +1, but can be up to 3 if bytes form a valid prefix of some UTF-8 +encoded codepoint.

+

If the end of the original input was found before a valid UTF-8 encoded +codepoint could be completed, then this returns None. This is useful +when processing streams, where a None value signals that more input +might be needed.

+

Trait Implementations§

source§

impl Clone for Utf8Error

source§

fn clone(&self) -> Utf8Error

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Utf8Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Utf8Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Utf8Error> for Utf8Error

source§

fn eq(&self, other: &Utf8Error) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Utf8Error

source§

impl StructuralEq for Utf8Error

source§

impl StructuralPartialEq for Utf8Error

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/bstr/trait.ByteSlice.html b/bstr/trait.ByteSlice.html new file mode 100644 index 000000000..01962480c --- /dev/null +++ b/bstr/trait.ByteSlice.html @@ -0,0 +1,1065 @@ +ByteSlice in bstr - Rust

Trait bstr::ByteSlice

source ·
pub trait ByteSlice: Sealed {
+
Show 44 methods // Provided methods + fn as_bstr(&self) -> &BStr { ... } + fn as_bstr_mut(&mut self) -> &mut BStr { ... } + fn to_str(&self) -> Result<&str, Utf8Error> { ... } + unsafe fn to_str_unchecked(&self) -> &str { ... } + fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool { ... } + fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool { ... } + fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool { ... } + fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> { ... } + fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> { ... } + fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>( + &'h self, + needle: &'n B + ) -> Find<'h, 'n> { ... } + fn rfind_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>( + &'h self, + needle: &'n B + ) -> FindReverse<'h, 'n> { ... } + fn find_byte(&self, byte: u8) -> Option<usize> { ... } + fn rfind_byte(&self, byte: u8) -> Option<usize> { ... } + fn find_char(&self, ch: char) -> Option<usize> { ... } + fn rfind_char(&self, ch: char) -> Option<usize> { ... } + fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> { ... } + fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> { ... } + fn rfind_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> { ... } + fn rfind_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> { ... } + fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F> { ... } + fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + splitter: &'s B + ) -> Split<'h, 's> { ... } + fn rsplit_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + splitter: &'s B + ) -> SplitReverse<'h, 's> { ... } + fn split_once_str<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &B + ) -> Option<(&'a [u8], &'a [u8])> { ... } + fn rsplit_once_str<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &B + ) -> Option<(&'a [u8], &'a [u8])> { ... } + fn splitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + limit: usize, + splitter: &'s B + ) -> SplitN<'h, 's> { ... } + fn rsplitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + limit: usize, + splitter: &'s B + ) -> SplitNReverse<'h, 's> { ... } + fn bytes(&self) -> Bytes<'_> { ... } + fn chars(&self) -> Chars<'_> { ... } + fn char_indices(&self) -> CharIndices<'_> { ... } + fn utf8_chunks(&self) -> Utf8Chunks<'_> { ... } + fn lines(&self) -> Lines<'_> { ... } + fn lines_with_terminator(&self) -> LinesWithTerminator<'_> { ... } + fn trim_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8] { ... } + fn trim_start_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8] { ... } + fn trim_end_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8] { ... } + fn make_ascii_lowercase(&mut self) { ... } + fn make_ascii_uppercase(&mut self) { ... } + fn escape_bytes(&self) -> EscapeBytes<'_> { ... } + fn reverse_bytes(&mut self) { ... } + fn reverse_chars(&mut self) { ... } + fn is_ascii(&self) -> bool { ... } + fn is_utf8(&self) -> bool { ... } + fn last_byte(&self) -> Option<u8> { ... } + fn find_non_ascii_byte(&self) -> Option<usize> { ... } +
}
Expand description

A trait that extends &[u8] with string oriented methods.

+

This trait is sealed and cannot be implemented outside of bstr.

+

Provided Methods§

source

fn as_bstr(&self) -> &BStr

Return this byte slice as a &BStr.

+

Use &BStr is useful because of its fmt::Debug representation +and various other trait implementations (such as PartialEq and +PartialOrd). In particular, the Debug implementation for BStr +shows its bytes as a normal string. For invalid UTF-8, hex escape +sequences are used.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+println!("{:?}", b"foo\xFFbar".as_bstr());
+
source

fn as_bstr_mut(&mut self) -> &mut BStr

Return this byte slice as a &mut BStr.

+

Use &mut BStr is useful because of its fmt::Debug representation +and various other trait implementations (such as PartialEq and +PartialOrd). In particular, the Debug implementation for BStr +shows its bytes as a normal string. For invalid UTF-8, hex escape +sequences are used.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut bytes = *b"foo\xFFbar";
+println!("{:?}", &mut bytes.as_bstr_mut());
+
source

fn to_str(&self) -> Result<&str, Utf8Error>

Safely convert this byte string into a &str if it’s valid UTF-8.

+

If this byte string is not valid UTF-8, then an error is returned. The +error returned indicates the first invalid byte found and the length +of the error.

+

In cases where a lossy conversion to &str is acceptable, then use one +of the to_str_lossy or +to_str_lossy_into +methods.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let s = B("☃βツ").to_str()?;
+assert_eq!("☃βツ", s);
+
+let mut bstring = <Vec<u8>>::from("☃βツ");
+bstring.push(b'\xFF');
+let err = bstring.to_str().unwrap_err();
+assert_eq!(8, err.valid_up_to());
+
source

unsafe fn to_str_unchecked(&self) -> &str

Unsafely convert this byte string into a &str, without checking for +valid UTF-8.

+
Safety
+

Callers must ensure that this byte string is valid UTF-8 before +calling this method. Converting a byte string into a &str that is +not valid UTF-8 is considered undefined behavior.

+

This routine is useful in performance sensitive contexts where the +UTF-8 validity of the byte string is already known and it is +undesirable to pay the cost of an additional UTF-8 validation check +that to_str performs.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+// SAFETY: This is safe because string literals are guaranteed to be
+// valid UTF-8 by the Rust compiler.
+let s = unsafe { B("☃βツ").to_str_unchecked() };
+assert_eq!("☃βツ", s);
+
source

fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool

Returns true if and only if this byte string contains the given needle.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".contains_str("foo"));
+assert!(b"foo bar".contains_str("bar"));
+assert!(!b"foo".contains_str("foobar"));
+
source

fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool

Returns true if and only if this byte string has the given prefix.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".starts_with_str("foo"));
+assert!(!b"foo bar".starts_with_str("bar"));
+assert!(!b"foo".starts_with_str("foobar"));
+
source

fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool

Returns true if and only if this byte string has the given suffix.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".ends_with_str("bar"));
+assert!(!b"foo bar".ends_with_str("foo"));
+assert!(!b"bar".ends_with_str("foobar"));
+
source

fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize>

Returns the index of the first occurrence of the given needle.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

Note that if you’re are searching for the same needle in many +different small haystacks, it may be faster to initialize a +Finder once, and reuse it for each search.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar baz";
+assert_eq!(Some(0), s.find("foo"));
+assert_eq!(Some(4), s.find("bar"));
+assert_eq!(None, s.find("quux"));
+
source

fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize>

Returns the index of the last occurrence of the given needle.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

Note that if you’re are searching for the same needle in many +different small haystacks, it may be faster to initialize a +FinderReverse once, and reuse it for +each search.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar baz";
+assert_eq!(Some(0), s.rfind("foo"));
+assert_eq!(Some(4), s.rfind("bar"));
+assert_eq!(Some(8), s.rfind("ba"));
+assert_eq!(None, s.rfind("quux"));
+
source

fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>( + &'h self, + needle: &'n B +) -> Find<'h, 'n>

Returns an iterator of the non-overlapping occurrences of the given +needle. The iterator yields byte offset positions indicating the start +of each match.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+let matches: Vec<usize> = s.find_iter("foo").collect();
+assert_eq!(matches, vec![0, 8, 12, 21]);
+

An empty string matches at every position, including the position +immediately following the last byte:

+ +
use bstr::ByteSlice;
+
+let matches: Vec<usize> = b"foo".find_iter("").collect();
+assert_eq!(matches, vec![0, 1, 2, 3]);
+
+let matches: Vec<usize> = b"".find_iter("").collect();
+assert_eq!(matches, vec![0]);
+
source

fn rfind_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>( + &'h self, + needle: &'n B +) -> FindReverse<'h, 'n>

Returns an iterator of the non-overlapping occurrences of the given +needle in reverse. The iterator yields byte offset positions indicating +the start of each match.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+let matches: Vec<usize> = s.rfind_iter("foo").collect();
+assert_eq!(matches, vec![21, 12, 8, 0]);
+

An empty string matches at every position, including the position +immediately following the last byte:

+ +
use bstr::ByteSlice;
+
+let matches: Vec<usize> = b"foo".rfind_iter("").collect();
+assert_eq!(matches, vec![3, 2, 1, 0]);
+
+let matches: Vec<usize> = b"".rfind_iter("").collect();
+assert_eq!(matches, vec![0]);
+
source

fn find_byte(&self, byte: u8) -> Option<usize>

Returns the index of the first occurrence of the given byte. If the +byte does not occur in this byte string, then None is returned.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(10), b"foo bar baz".find_byte(b'z'));
+assert_eq!(None, b"foo bar baz".find_byte(b'y'));
+
source

fn rfind_byte(&self, byte: u8) -> Option<usize>

Returns the index of the last occurrence of the given byte. If the +byte does not occur in this byte string, then None is returned.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(10), b"foo bar baz".rfind_byte(b'z'));
+assert_eq!(None, b"foo bar baz".rfind_byte(b'y'));
+
source

fn find_char(&self, ch: char) -> Option<usize>

Returns the index of the first occurrence of the given codepoint. +If the codepoint does not occur in this byte string, then None is +returned.

+

Note that if one searches for the replacement codepoint, \u{FFFD}, +then only explicit occurrences of that encoding will be found. Invalid +UTF-8 sequences will not be matched.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(Some(10), b"foo bar baz".find_char('z'));
+assert_eq!(Some(4), B("αβγγδ").find_char('γ'));
+assert_eq!(None, b"foo bar baz".find_char('y'));
+
source

fn rfind_char(&self, ch: char) -> Option<usize>

Returns the index of the last occurrence of the given codepoint. +If the codepoint does not occur in this byte string, then None is +returned.

+

Note that if one searches for the replacement codepoint, \u{FFFD}, +then only explicit occurrences of that encoding will be found. Invalid +UTF-8 sequences will not be matched.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(Some(10), b"foo bar baz".rfind_char('z'));
+assert_eq!(Some(6), B("αβγγδ").rfind_char('γ'));
+assert_eq!(None, b"foo bar baz".rfind_char('y'));
+
source

fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize>

Returns the index of the first occurrence of any of the bytes in the +provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".find_byteset(b"zr"), Some(6));
+assert_eq!(b"foo baz bar".find_byteset(b"bzr"), Some(4));
+assert_eq!(None, b"foo baz bar".find_byteset(b"\t\n"));
+// The empty byteset never matches.
+assert_eq!(None, b"abc".find_byteset(b""));
+assert_eq!(None, b"".find_byteset(b""));
+
source

fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize>

Returns the index of the first occurrence of a byte that is not a +member of the provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".find_not_byteset(b"fo "), Some(4));
+assert_eq!(b"\t\tbaz bar".find_not_byteset(b" \t\r\n"), Some(2));
+assert_eq!(b"foo\nbaz\tbar".find_not_byteset(b"\t\n"), Some(0));
+// The negation of the empty byteset matches everything.
+assert_eq!(Some(0), b"abc".find_not_byteset(b""));
+// But an empty string never contains anything.
+assert_eq!(None, b"".find_not_byteset(b""));
+
source

fn rfind_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize>

Returns the index of the last occurrence of any of the bytes in the +provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and duplicate +bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".rfind_byteset(b"agb"), Some(9));
+assert_eq!(b"foo baz bar".rfind_byteset(b"rabz "), Some(10));
+assert_eq!(b"foo baz bar".rfind_byteset(b"\n123"), None);
+
source

fn rfind_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize>

Returns the index of the last occurrence of a byte that is not a member +of the provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz,\t".rfind_not_byteset(b",\t"), Some(10));
+assert_eq!(b"foo baz bar".rfind_not_byteset(b"rabz "), Some(2));
+assert_eq!(None, b"foo baz bar".rfind_not_byteset(b"barfoz "));
+
source

fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F>

Returns an iterator over the fields in a byte string, separated by +contiguous codepoints satisfying the given predicate.

+

If this byte string is not valid UTF-8, then the given closure will +be called with a Unicode replacement codepoint when invalid UTF-8 +bytes are seen.

+
Example
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo999999bar1quux123456";
+let fields: Vec<&[u8]> = s.fields_with(|c| c.is_numeric()).collect();
+assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
+

A byte string consisting of all codepoints satisfying the predicate +yields no elements:

+ +
use bstr::ByteSlice;
+
+assert_eq!(0, b"1911354563".fields_with(|c| c.is_numeric()).count());
+
source

fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + splitter: &'s B +) -> Split<'h, 's>

Returns an iterator over substrings of this byte string, separated +by the given byte string. Each element yielded is guaranteed not to +include the splitter substring.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"Mary had a little lamb".split_str(" ").collect();
+assert_eq!(x, vec![
+    B("Mary"), B("had"), B("a"), B("little"), B("lamb"),
+]);
+
+let x: Vec<&[u8]> = b"".split_str("X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<&[u8]> = b"lionXXtigerXleopard".split_str("X").collect();
+assert_eq!(x, vec![B("lion"), B(""), B("tiger"), B("leopard")]);
+
+let x: Vec<&[u8]> = b"lion::tiger::leopard".split_str("::").collect();
+assert_eq!(x, vec![B("lion"), B("tiger"), B("leopard")]);
+

If a string contains multiple contiguous separators, you will end up +with empty strings yielded by the iterator:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"||||a||b|c".split_str("|").collect();
+assert_eq!(x, vec![
+    B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+]);
+
+let x: Vec<&[u8]> = b"(///)".split_str("/").collect();
+assert_eq!(x, vec![B("("), B(""), B(""), B(")")]);
+

Separators at the start or end of a string are neighbored by empty +strings.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"010".split_str("0").collect();
+assert_eq!(x, vec![B(""), B("1"), B("")]);
+

When the empty string is used as a separator, it splits every byte +in the byte string, along with the beginning and end of the byte +string.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"rust".split_str("").collect();
+assert_eq!(x, vec![
+    B(""), B("r"), B("u"), B("s"), B("t"), B(""),
+]);
+
+// Splitting by an empty string is not UTF-8 aware. Elements yielded
+// may not be valid UTF-8!
+let x: Vec<&[u8]> = B("☃").split_str("").collect();
+assert_eq!(x, vec![
+    B(""), B(b"\xE2"), B(b"\x98"), B(b"\x83"), B(""),
+]);
+

Contiguous separators, especially whitespace, can lead to possibly +surprising behavior. For example, this code is correct:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"    a  b c".split_str(" ").collect();
+assert_eq!(x, vec![
+    B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+]);
+

It does not give you ["a", "b", "c"]. For that behavior, use +fields instead.

+
source

fn rsplit_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + splitter: &'s B +) -> SplitReverse<'h, 's>

Returns an iterator over substrings of this byte string, separated by +the given byte string, in reverse. Each element yielded is guaranteed +not to include the splitter substring.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> =
+    b"Mary had a little lamb".rsplit_str(" ").collect();
+assert_eq!(x, vec![
+    B("lamb"), B("little"), B("a"), B("had"), B("Mary"),
+]);
+
+let x: Vec<&[u8]> = b"".rsplit_str("X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<&[u8]> = b"lionXXtigerXleopard".rsplit_str("X").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B(""), B("lion")]);
+
+let x: Vec<&[u8]> = b"lion::tiger::leopard".rsplit_str("::").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B("lion")]);
+

If a string contains multiple contiguous separators, you will end up +with empty strings yielded by the iterator:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"||||a||b|c".rsplit_str("|").collect();
+assert_eq!(x, vec![
+    B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+]);
+
+let x: Vec<&[u8]> = b"(///)".rsplit_str("/").collect();
+assert_eq!(x, vec![B(")"), B(""), B(""), B("(")]);
+

Separators at the start or end of a string are neighbored by empty +strings.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"010".rsplit_str("0").collect();
+assert_eq!(x, vec![B(""), B("1"), B("")]);
+

When the empty string is used as a separator, it splits every byte +in the byte string, along with the beginning and end of the byte +string.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"rust".rsplit_str("").collect();
+assert_eq!(x, vec![
+    B(""), B("t"), B("s"), B("u"), B("r"), B(""),
+]);
+
+// Splitting by an empty string is not UTF-8 aware. Elements yielded
+// may not be valid UTF-8!
+let x: Vec<&[u8]> = B("☃").rsplit_str("").collect();
+assert_eq!(x, vec![B(""), B(b"\x83"), B(b"\x98"), B(b"\xE2"), B("")]);
+

Contiguous separators, especially whitespace, can lead to possibly +surprising behavior. For example, this code is correct:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"    a  b c".rsplit_str(" ").collect();
+assert_eq!(x, vec![
+    B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+]);
+

It does not give you ["a", "b", "c"].

+
source

fn split_once_str<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &B +) -> Option<(&'a [u8], &'a [u8])>

Split this byte string at the first occurrence of splitter.

+

If the splitter is found in the byte string, returns a tuple +containing the parts of the string before and after the first occurrence +of splitter respectively. Otherwise, if there are no occurrences of +splitter in the byte string, returns None.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

If you need to split on the last instance of a delimiter instead, see +the ByteSlice::rsplit_once_str method .

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(
+    B("foo,bar").split_once_str(","),
+    Some((B("foo"), B("bar"))),
+);
+assert_eq!(
+    B("foo,bar,baz").split_once_str(","),
+    Some((B("foo"), B("bar,baz"))),
+);
+assert_eq!(B("foo").split_once_str(","), None);
+assert_eq!(B("foo,").split_once_str(b","), Some((B("foo"), B(""))));
+assert_eq!(B(",foo").split_once_str(b","), Some((B(""), B("foo"))));
+
source

fn rsplit_once_str<'a, B: ?Sized + AsRef<[u8]>>( + &'a self, + splitter: &B +) -> Option<(&'a [u8], &'a [u8])>

Split this byte string at the last occurrence of splitter.

+

If the splitter is found in the byte string, returns a tuple +containing the parts of the string before and after the last occurrence +of splitter, respectively. Otherwise, if there are no occurrences of +splitter in the byte string, returns None.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

If you need to split on the first instance of a delimiter instead, see +the ByteSlice::split_once_str method.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(
+    B("foo,bar").rsplit_once_str(","),
+    Some((B("foo"), B("bar"))),
+);
+assert_eq!(
+    B("foo,bar,baz").rsplit_once_str(","),
+    Some((B("foo,bar"), B("baz"))),
+);
+assert_eq!(B("foo").rsplit_once_str(","), None);
+assert_eq!(B("foo,").rsplit_once_str(b","), Some((B("foo"), B(""))));
+assert_eq!(B(",foo").rsplit_once_str(b","), Some((B(""), B("foo"))));
+
source

fn splitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + limit: usize, + splitter: &'s B +) -> SplitN<'h, 's>

Returns an iterator of at most limit substrings of this byte string, +separated by the given byte string. If limit substrings are yielded, +then the last substring will contain the remainder of this byte string.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<_> = b"Mary had a little lamb".splitn_str(3, " ").collect();
+assert_eq!(x, vec![B("Mary"), B("had"), B("a little lamb")]);
+
+let x: Vec<_> = b"".splitn_str(3, "X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<_> = b"lionXXtigerXleopard".splitn_str(3, "X").collect();
+assert_eq!(x, vec![B("lion"), B(""), B("tigerXleopard")]);
+
+let x: Vec<_> = b"lion::tiger::leopard".splitn_str(2, "::").collect();
+assert_eq!(x, vec![B("lion"), B("tiger::leopard")]);
+
+let x: Vec<_> = b"abcXdef".splitn_str(1, "X").collect();
+assert_eq!(x, vec![B("abcXdef")]);
+
+let x: Vec<_> = b"abcdef".splitn_str(2, "X").collect();
+assert_eq!(x, vec![B("abcdef")]);
+
+let x: Vec<_> = b"abcXdef".splitn_str(0, "X").collect();
+assert!(x.is_empty());
+
source

fn rsplitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>( + &'h self, + limit: usize, + splitter: &'s B +) -> SplitNReverse<'h, 's>

Returns an iterator of at most limit substrings of this byte string, +separated by the given byte string, in reverse. If limit substrings +are yielded, then the last substring will contain the remainder of this +byte string.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<_> =
+    b"Mary had a little lamb".rsplitn_str(3, " ").collect();
+assert_eq!(x, vec![B("lamb"), B("little"), B("Mary had a")]);
+
+let x: Vec<_> = b"".rsplitn_str(3, "X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<_> = b"lionXXtigerXleopard".rsplitn_str(3, "X").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B("lionX")]);
+
+let x: Vec<_> = b"lion::tiger::leopard".rsplitn_str(2, "::").collect();
+assert_eq!(x, vec![B("leopard"), B("lion::tiger")]);
+
+let x: Vec<_> = b"abcXdef".rsplitn_str(1, "X").collect();
+assert_eq!(x, vec![B("abcXdef")]);
+
+let x: Vec<_> = b"abcdef".rsplitn_str(2, "X").collect();
+assert_eq!(x, vec![B("abcdef")]);
+
+let x: Vec<_> = b"abcXdef".rsplitn_str(0, "X").collect();
+assert!(x.is_empty());
+
source

fn bytes(&self) -> Bytes<'_>

Returns an iterator over the bytes in this byte string.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"foobar";
+let bytes: Vec<u8> = bs.bytes().collect();
+assert_eq!(bytes, bs);
+
source

fn chars(&self) -> Chars<'_>

Returns an iterator over the Unicode scalar values in this byte string. +If invalid UTF-8 is encountered, then the Unicode replacement codepoint +is yielded instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<char> = bs.chars().collect();
+assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+

Codepoints can also be iterated over in reverse:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<char> = bs.chars().rev().collect();
+assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+
source

fn char_indices(&self) -> CharIndices<'_>

Returns an iterator over the Unicode scalar values in this byte string +along with their starting and ending byte index positions. If invalid +UTF-8 is encountered, then the Unicode replacement codepoint is yielded +instead.

+

Note that this is slightly different from the CharIndices iterator +provided by the standard library. Aside from working on possibly +invalid UTF-8, this iterator provides both the corresponding starting +and ending byte indices of each codepoint yielded. The ending position +is necessary to slice the original byte string when invalid UTF-8 bytes +are converted into a Unicode replacement codepoint, since a single +replacement codepoint can substitute anywhere from 1 to 3 invalid bytes +(inclusive).

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
+assert_eq!(chars, vec![
+    (0, 3, '☃'),
+    (3, 4, '\u{FFFD}'),
+    (4, 8, '𝞃'),
+    (8, 10, '\u{FFFD}'),
+    (10, 11, 'a'),
+]);
+

Codepoints can also be iterated over in reverse:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<(usize, usize, char)> = bs
+    .char_indices()
+    .rev()
+    .collect();
+assert_eq!(chars, vec![
+    (10, 11, 'a'),
+    (8, 10, '\u{FFFD}'),
+    (4, 8, '𝞃'),
+    (3, 4, '\u{FFFD}'),
+    (0, 3, '☃'),
+]);
+
source

fn utf8_chunks(&self) -> Utf8Chunks<'_>

Iterate over chunks of valid UTF-8.

+

The iterator returned yields chunks of valid UTF-8 separated by invalid +UTF-8 bytes, if they exist. Invalid UTF-8 bytes are always 1-3 bytes, +which are determined via the “substitution of maximal subparts” +strategy described in the docs for the +ByteSlice::to_str_lossy +method.

+
Examples
+

This example shows how to gather all valid and invalid chunks from a +byte slice:

+ +
use bstr::{ByteSlice, Utf8Chunk};
+
+let bytes = b"foo\xFD\xFEbar\xFF";
+
+let (mut valid_chunks, mut invalid_chunks) = (vec![], vec![]);
+for chunk in bytes.utf8_chunks() {
+    if !chunk.valid().is_empty() {
+        valid_chunks.push(chunk.valid());
+    }
+    if !chunk.invalid().is_empty() {
+        invalid_chunks.push(chunk.invalid());
+    }
+}
+
+assert_eq!(valid_chunks, vec!["foo", "bar"]);
+assert_eq!(invalid_chunks, vec![b"\xFD", b"\xFE", b"\xFF"]);
+
source

fn lines(&self) -> Lines<'_>

An iterator over all lines in a byte string, without their +terminators.

+

For this iterator, the only line terminators recognized are \r\n and +\n.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+
+bar\r
+baz
+
+
+quux";
+let lines: Vec<&[u8]> = s.lines().collect();
+assert_eq!(lines, vec![
+    B("foo"), B(""), B("bar"), B("baz"), B(""), B(""), B("quux"),
+]);
+
source

fn lines_with_terminator(&self) -> LinesWithTerminator<'_>

An iterator over all lines in a byte string, including their +terminators.

+

For this iterator, the only line terminator recognized is \n. (Since +line terminators are included, this also handles \r\n line endings.)

+

Line terminators are only included if they are present in the original +byte string. For example, the last line in a byte string may not end +with a line terminator.

+

Concatenating all elements yielded by this iterator is guaranteed to +yield the original byte string.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+
+bar\r
+baz
+
+
+quux";
+let lines: Vec<&[u8]> = s.lines_with_terminator().collect();
+assert_eq!(lines, vec![
+    B("foo\n"),
+    B("\n"),
+    B("bar\r\n"),
+    B("baz\n"),
+    B("\n"),
+    B("\n"),
+    B("quux"),
+]);
+
source

fn trim_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8]

Return a byte string slice with leading and trailing characters +satisfying the given predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_with(|c| c.is_numeric()), B("foo5bar"));
+
source

fn trim_start_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8]

Return a byte string slice with leading characters satisfying the given +predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_start_with(|c| c.is_numeric()), B("foo5bar789"));
+
source

fn trim_end_with<F: FnMut(char) -> bool>(&self, trim: F) -> &[u8]

Return a byte string slice with trailing characters satisfying the +given predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_end_with(|c| c.is_numeric()), B("123foo5bar"));
+
source

fn make_ascii_lowercase(&mut self)

Convert this byte string to its lowercase ASCII equivalent in place.

+

In this case, lowercase is only defined in ASCII letters. Namely, the +letters A-Z are converted to a-z. All other bytes remain unchanged.

+

If you don’t need to do the conversion in +place and instead prefer convenience, then use +to_ascii_lowercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("HELLO Β");
+s.make_ascii_lowercase();
+assert_eq!(s, "hello Β".as_bytes());
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let mut s = <Vec<u8>>::from_slice(b"FOO\xFFBAR\xE2\x98BAZ");
+s.make_ascii_lowercase();
+assert_eq!(s, B(b"foo\xFFbar\xE2\x98baz"));
+
source

fn make_ascii_uppercase(&mut self)

Convert this byte string to its uppercase ASCII equivalent in place.

+

In this case, uppercase is only defined in ASCII letters. Namely, the +letters a-z are converted to A-Z. All other bytes remain unchanged.

+

If you don’t need to do the conversion in +place and instead prefer convenience, then use +to_ascii_uppercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("hello β");
+s.make_ascii_uppercase();
+assert_eq!(s, B("HELLO β"));
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let mut s = <Vec<u8>>::from_slice(b"foo\xFFbar\xE2\x98baz");
+s.make_ascii_uppercase();
+assert_eq!(s, B(b"FOO\xFFBAR\xE2\x98BAZ"));
+
source

fn escape_bytes(&self) -> EscapeBytes<'_>

Escapes this byte string into a sequence of char values.

+

When the sequence of char values is concatenated into a string, the +result is always valid UTF-8. Any unprintable or invalid UTF-8 in this +byte string are escaped using using \xNN notation. Moreover, the +characters \0, \r, \n, \t and \ are escaped as well.

+

This is useful when one wants to get a human readable view of the raw +bytes that is also valid UTF-8.

+

The iterator returned implements the Display trait. So one can do +b"foo\xFFbar".escape_bytes().to_string() to get a String with its +bytes escaped.

+

The dual of this function is [ByteVec::unescape_bytes].

+

Note that this is similar to, but not equivalent to the Debug +implementation on BStr and [BString]. The Debug implementations +also use the debug representation for all Unicode codepoints. However, +this escaping routine only escapes individual bytes. All Unicode +codepoints above U+007F are passed through unchanged without any +escaping.

+
Examples
+
use bstr::{B, ByteSlice};
+
+assert_eq!(r"foo\xFFbar", b"foo\xFFbar".escape_bytes().to_string());
+assert_eq!(r"foo\nbar", b"foo\nbar".escape_bytes().to_string());
+assert_eq!(r"foo\tbar", b"foo\tbar".escape_bytes().to_string());
+assert_eq!(r"foo\\bar", b"foo\\bar".escape_bytes().to_string());
+assert_eq!(r"foo☃bar", B("foo☃bar").escape_bytes().to_string());
+
source

fn reverse_bytes(&mut self)

Reverse the bytes in this string, in place.

+

This is not necessarily a well formed operation! For example, if this +byte string contains valid UTF-8 that isn’t ASCII, then reversing the +string will likely result in invalid UTF-8 and otherwise non-sensical +content.

+

Note that this is equivalent to the generic [u8]::reverse method. +This method is provided to permit callers to explicitly differentiate +between reversing bytes, codepoints and graphemes.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("hello");
+s.reverse_bytes();
+assert_eq!(s, "olleh".as_bytes());
+
source

fn reverse_chars(&mut self)

Reverse the codepoints in this string, in place.

+

If this byte string is valid UTF-8, then its reversal by codepoint +is also guaranteed to be valid UTF-8.

+

This operation is equivalent to the following, but without allocating:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+
+let mut chars: Vec<char> = s.chars().collect();
+chars.reverse();
+
+let reversed: String = chars.into_iter().collect();
+assert_eq!(reversed, "rab☃oof");
+

Note that this is not necessarily a well formed operation. For example, +if this byte string contains grapheme clusters with more than one +codepoint, then those grapheme clusters will not necessarily be +preserved. If you’d like to preserve grapheme clusters, then use +reverse_graphemes instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+s.reverse_chars();
+assert_eq!(s, "rab☃oof".as_bytes());
+

This example shows that not all reversals lead to a well formed string. +For example, in this case, combining marks are used to put accents over +some letters, and those accent marks must appear after the codepoints +they modify.

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("résumé");
+s.reverse_chars();
+assert_eq!(s, B(b"\xCC\x81emus\xCC\x81er"));
+

A word of warning: the above example relies on the fact that +résumé is in decomposed normal form, which means there are separate +codepoints for the accents above e. If it is instead in composed +normal form, then the example works:

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("résumé");
+s.reverse_chars();
+assert_eq!(s, B("émusér"));
+

The point here is to be cautious and not assume that just because +reverse_chars works in one case, that it therefore works in all +cases.

+
source

fn is_ascii(&self) -> bool

Returns true if and only if every byte in this byte string is ASCII.

+

ASCII is an encoding that defines 128 codepoints. A byte corresponds to +an ASCII codepoint if and only if it is in the inclusive range +[0, 127].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert!(B("abc").is_ascii());
+assert!(!B("☃βツ").is_ascii());
+assert!(!B(b"\xFF").is_ascii());
+
source

fn is_utf8(&self) -> bool

Returns true if and only if the entire byte string is valid UTF-8.

+

If you need location information about where a byte string’s first +invalid UTF-8 byte is, then use the to_str method.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert!(B("abc").is_utf8());
+assert!(B("☃βツ").is_utf8());
+// invalid bytes
+assert!(!B(b"abc\xFF").is_utf8());
+// surrogate encoding
+assert!(!B(b"\xED\xA0\x80").is_utf8());
+// incomplete sequence
+assert!(!B(b"\xF0\x9D\x9Ca").is_utf8());
+// overlong sequence
+assert!(!B(b"\xF0\x82\x82\xAC").is_utf8());
+
source

fn last_byte(&self) -> Option<u8>

Returns the last byte in this byte string, if it’s non-empty. If this +byte string is empty, this returns None.

+

Note that this is like the generic [u8]::last, except this returns +the byte by value instead of a reference to the byte.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(b'z'), b"baz".last_byte());
+assert_eq!(None, b"".last_byte());
+
source

fn find_non_ascii_byte(&self) -> Option<usize>

Returns the index of the first non-ASCII byte in this byte string (if +any such indices exist). Specifically, it returns the index of the +first byte with a value greater than or equal to 0x80.

+
Examples
+

Basic usage:

+ +
use bstr::{ByteSlice, B};
+
+assert_eq!(Some(3), b"abc\xff".find_non_ascii_byte());
+assert_eq!(None, b"abcde".find_non_ascii_byte());
+assert_eq!(Some(0), B("😀").find_non_ascii_byte());
+

Implementations on Foreign Types§

source§

impl<const N: usize> ByteSlice for [u8; N]

source§

impl ByteSlice for [u8]

Implementors§

\ No newline at end of file diff --git a/bstr/utf8/fn.decode.html b/bstr/utf8/fn.decode.html new file mode 100644 index 000000000..bf4a8bbfe --- /dev/null +++ b/bstr/utf8/fn.decode.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/fn.decode_utf8.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/fn.decode_last.html b/bstr/utf8/fn.decode_last.html new file mode 100644 index 000000000..266c86194 --- /dev/null +++ b/bstr/utf8/fn.decode_last.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/fn.decode_last_utf8.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/struct.CharIndices.html b/bstr/utf8/struct.CharIndices.html new file mode 100644 index 000000000..170d585f1 --- /dev/null +++ b/bstr/utf8/struct.CharIndices.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.CharIndices.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/struct.Chars.html b/bstr/utf8/struct.Chars.html new file mode 100644 index 000000000..cd0f70649 --- /dev/null +++ b/bstr/utf8/struct.Chars.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Chars.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/struct.Utf8Chunk.html b/bstr/utf8/struct.Utf8Chunk.html new file mode 100644 index 000000000..33d58af5c --- /dev/null +++ b/bstr/utf8/struct.Utf8Chunk.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Utf8Chunk.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/struct.Utf8Chunks.html b/bstr/utf8/struct.Utf8Chunks.html new file mode 100644 index 000000000..da5b637a9 --- /dev/null +++ b/bstr/utf8/struct.Utf8Chunks.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Utf8Chunks.html...

+ + + \ No newline at end of file diff --git a/bstr/utf8/struct.Utf8Error.html b/bstr/utf8/struct.Utf8Error.html new file mode 100644 index 000000000..2c0fe9c9b --- /dev/null +++ b/bstr/utf8/struct.Utf8Error.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../bstr/struct.Utf8Error.html...

+ + + \ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 000000000..0b0382bd8 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["bstr","memchr","roe"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 000000000..ca5a10cfe --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Help

Rustdoc help

Back
\ No newline at end of file diff --git a/implementors/bstr/ext_slice/trait.ByteSlice.js b/implementors/bstr/ext_slice/trait.ByteSlice.js new file mode 100644 index 000000000..5dfad1518 --- /dev/null +++ b/implementors/bstr/ext_slice/trait.ByteSlice.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/borrow/trait.Borrow.js b/implementors/core/borrow/trait.Borrow.js new file mode 100644 index 000000000..ad4d00b5d --- /dev/null +++ b/implementors/core/borrow/trait.Borrow.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl Borrow<BStr> for [u8]"],["impl Borrow<BStr> for str"],["impl Borrow<[u8]> for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/borrow/trait.BorrowMut.js b/implementors/core/borrow/trait.BorrowMut.js new file mode 100644 index 000000000..93f5ef981 --- /dev/null +++ b/implementors/core/borrow/trait.BorrowMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl BorrowMut<[u8]> for BStr"],["impl BorrowMut<BStr> for [u8]"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 000000000..ab3f71195 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl<'a> Clone for EscapeBytes<'a>"],["impl<'a> Clone for Bytes<'a>"],["impl<'a> Clone for FinderReverse<'a>"],["impl Clone for Utf8Error"],["impl<'a> Clone for Lines<'a>"],["impl<'a> Clone for CharIndices<'a>"],["impl<'a> Clone for LinesWithTerminator<'a>"],["impl<'a> Clone for Finder<'a>"],["impl<'a> Clone for Utf8Chunks<'a>"],["impl<'a> Clone for Chars<'a>"]], +"memchr":[["impl Clone for Finder"],["impl Clone for Two"],["impl<'a, 'h> Clone for OneIter<'a, 'h>"],["impl<'a, 'h> Clone for ThreeIter<'a, 'h>"],["impl Clone for One"],["impl Clone for Three"],["impl Clone for Finder"],["impl Clone for Finder"],["impl Clone for Three"],["impl Clone for Three"],["impl Clone for One"],["impl Clone for Two"],["impl Clone for FinderRev"],["impl Clone for FinderBuilder"],["impl<'a, 'h> Clone for ThreeIter<'a, 'h>"],["impl<'n> Clone for Finder<'n>"],["impl Clone for Pair"],["impl Clone for Finder"],["impl<'h> Clone for Memchr3<'h>"],["impl<'a, 'h> Clone for OneIter<'a, 'h>"],["impl<'n> Clone for FinderRev<'n>"],["impl Clone for FinderRev"],["impl<'h> Clone for Memchr2<'h>"],["impl<'h> Clone for Memchr<'h>"],["impl Clone for Two"],["impl Clone for PrefilterConfig"],["impl Clone for Finder"],["impl<'a, 'h> Clone for ThreeIter<'a, 'h>"],["impl<'a, 'h> Clone for TwoIter<'a, 'h>"],["impl<'a, 'h> Clone for TwoIter<'a, 'h>"],["impl<'a, 'h> Clone for OneIter<'a, 'h>"],["impl<'a, 'h> Clone for TwoIter<'a, 'h>"],["impl Clone for One"]], +"roe":[["impl Clone for InvalidCaseMappingMode"],["impl<'a> Clone for Uppercase<'a>"],["impl<'a> Clone for Lowercase<'a>"],["impl Clone for UppercaseMode"],["impl Clone for LowercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Eq.js b/implementors/core/cmp/trait.Eq.js new file mode 100644 index 000000000..7aa1318a0 --- /dev/null +++ b/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl Eq for BStr"],["impl Eq for Utf8Error"]], +"roe":[["impl Eq for UppercaseMode"],["impl Eq for LowercaseMode"],["impl Eq for InvalidCaseMappingMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Ord.js b/implementors/core/cmp/trait.Ord.js new file mode 100644 index 000000000..16a4ee085 --- /dev/null +++ b/implementors/core/cmp/trait.Ord.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl Ord for BStr"]], +"roe":[["impl Ord for LowercaseMode"],["impl Ord for InvalidCaseMappingMode"],["impl Ord for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialEq.js b/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 000000000..8b5ffd93a --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl<'a, 'b> PartialEq<[u8]> for BStr"],["impl<'a, 'b> PartialEq<&'a [u8]> for BStr"],["impl<'a, 'b> PartialEq<BStr> for [u8]"],["impl<'a, 'b> PartialEq<&'a str> for BStr"],["impl<'a, 'b> PartialEq<str> for BStr"],["impl<'a, 'b> PartialEq<BStr> for &'a str"],["impl<'a, 'b> PartialEq<BStr> for str"],["impl<'a, 'b> PartialEq<BStr> for &'a [u8]"],["impl PartialEq<Utf8Error> for Utf8Error"],["impl PartialEq<BStr> for BStr"]], +"roe":[["impl PartialEq<LowercaseMode> for LowercaseMode"],["impl PartialEq<InvalidCaseMappingMode> for InvalidCaseMappingMode"],["impl PartialEq<UppercaseMode> for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialOrd.js b/implementors/core/cmp/trait.PartialOrd.js new file mode 100644 index 000000000..1dfa21131 --- /dev/null +++ b/implementors/core/cmp/trait.PartialOrd.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl<'a, 'b> PartialOrd<BStr> for [u8]"],["impl<'a, 'b> PartialOrd<[u8]> for BStr"],["impl<'a, 'b> PartialOrd<&'a str> for BStr"],["impl<'a, 'b> PartialOrd<BStr> for &'a str"],["impl<'a, 'b> PartialOrd<BStr> for str"],["impl<'a, 'b> PartialOrd<BStr> for &'a [u8]"],["impl<'a, 'b> PartialOrd<&'a [u8]> for BStr"],["impl PartialOrd<BStr> for BStr"],["impl<'a, 'b> PartialOrd<str> for BStr"]], +"roe":[["impl PartialOrd<InvalidCaseMappingMode> for InvalidCaseMappingMode"],["impl PartialOrd<UppercaseMode> for UppercaseMode"],["impl PartialOrd<LowercaseMode> for LowercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsMut.js b/implementors/core/convert/trait.AsMut.js new file mode 100644 index 000000000..c2ee6cd27 --- /dev/null +++ b/implementors/core/convert/trait.AsMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl AsMut<[u8]> for BStr"],["impl AsMut<BStr> for [u8]"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.AsRef.js b/implementors/core/convert/trait.AsRef.js new file mode 100644 index 000000000..17a0eb424 --- /dev/null +++ b/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl AsRef<BStr> for BStr"],["impl AsRef<BStr> for [u8]"],["impl AsRef<BStr> for str"],["impl AsRef<[u8]> for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.From.js b/implementors/core/convert/trait.From.js new file mode 100644 index 000000000..f7b9cb09b --- /dev/null +++ b/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl<'a> From<&'a [u8]> for &'a BStr"],["impl<'a> From<&'a BStr> for &'a [u8]"],["impl<'a> From<&'a str> for &'a BStr"],["impl<'a, const N: usize> From<&'a [u8; N]> for &'a BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.TryFrom.js b/implementors/core/convert/trait.TryFrom.js new file mode 100644 index 000000000..7880ac5d0 --- /dev/null +++ b/implementors/core/convert/trait.TryFrom.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl<'a> TryFrom<&'a BStr> for &'a str"]], +"roe":[["impl TryFrom<&str> for LowercaseMode"],["impl TryFrom<&str> for UppercaseMode"],["impl TryFrom<&[u8]> for LowercaseMode"],["impl TryFrom<Option<&[u8]>> for UppercaseMode"],["impl TryFrom<Option<&str>> for LowercaseMode"],["impl TryFrom<Option<&[u8]>> for LowercaseMode"],["impl TryFrom<Option<&str>> for UppercaseMode"],["impl TryFrom<&[u8]> for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 000000000..32047396b --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl<'a> Default for &'a BStr"],["impl<'a> Default for &'a mut BStr"]], +"memchr":[["impl Default for FinderBuilder"],["impl Default for PrefilterConfig"]], +"roe":[["impl Default for InvalidCaseMappingMode"],["impl Default for LowercaseMode"],["impl Default for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/error/trait.Error.js b/implementors/core/error/trait.Error.js new file mode 100644 index 000000000..156a65492 --- /dev/null +++ b/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"roe":[["impl Error for InvalidCaseMappingMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 000000000..02a755126 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl Debug for BStr"],["impl Debug for Utf8Error"],["impl<'a> Debug for FinderReverse<'a>"],["impl<'a> Debug for Finder<'a>"],["impl<'a> Debug for Lines<'a>"],["impl<'a> Debug for CharIndices<'a>"],["impl<'a> Debug for LinesWithTerminator<'a>"],["impl<'a> Debug for Bytes<'a>"],["impl<'a, F: Debug> Debug for FieldsWith<'a, F>"],["impl<'h, 'n> Debug for FindReverse<'h, 'n>"],["impl<'h, 's> Debug for SplitN<'h, 's>"],["impl<'h, 'n> Debug for Find<'h, 'n>"],["impl<'h, 's> Debug for SplitReverse<'h, 's>"],["impl<'a> Debug for Chars<'a>"],["impl<'h, 's> Debug for SplitNReverse<'h, 's>"],["impl<'a> Debug for EscapeBytes<'a>"],["impl<'h, 's> Debug for Split<'h, 's>"],["impl<'a> Debug for Utf8Chunks<'a>"]], +"memchr":[["impl<'h> Debug for Memchr3<'h>"],["impl Debug for Three"],["impl Debug for Three"],["impl Debug for Pair"],["impl<'a, 'h> Debug for TwoIter<'a, 'h>"],["impl Debug for Three"],["impl Debug for FinderRev"],["impl Debug for Two"],["impl<'h, 'n> Debug for FindRevIter<'h, 'n>"],["impl<'n> Debug for Finder<'n>"],["impl<'n> Debug for FinderRev<'n>"],["impl Debug for Finder"],["impl Debug for Finder"],["impl Debug for Two"],["impl Debug for Finder"],["impl<'a, 'h> Debug for OneIter<'a, 'h>"],["impl Debug for FinderRev"],["impl Debug for Finder"],["impl Debug for One"],["impl<'a, 'h> Debug for TwoIter<'a, 'h>"],["impl<'a, 'h> Debug for ThreeIter<'a, 'h>"],["impl Debug for Finder"],["impl<'h> Debug for Memchr<'h>"],["impl Debug for One"],["impl<'h> Debug for Memchr2<'h>"],["impl<'a, 'h> Debug for TwoIter<'a, 'h>"],["impl Debug for Finder"],["impl<'h, 'n> Debug for FindIter<'h, 'n>"],["impl Debug for PrefilterConfig"],["impl<'a, 'h> Debug for OneIter<'a, 'h>"],["impl Debug for FinderBuilder"],["impl Debug for One"],["impl<'a, 'h> Debug for OneIter<'a, 'h>"],["impl Debug for Two"],["impl<'a, 'h> Debug for ThreeIter<'a, 'h>"],["impl<'a, 'h> Debug for ThreeIter<'a, 'h>"]], +"roe":[["impl Debug for UppercaseMode"],["impl<'a> Debug for Uppercase<'a>"],["impl Debug for LowercaseMode"],["impl Debug for InvalidCaseMappingMode"],["impl<'a> Debug for Lowercase<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Display.js b/implementors/core/fmt/trait.Display.js new file mode 100644 index 000000000..34ef8a1cf --- /dev/null +++ b/implementors/core/fmt/trait.Display.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl Display for Utf8Error"],["impl Display for BStr"],["impl<'a> Display for EscapeBytes<'a>"]], +"roe":[["impl Display for InvalidCaseMappingMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/hash/trait.Hash.js b/implementors/core/hash/trait.Hash.js new file mode 100644 index 000000000..3604424d1 --- /dev/null +++ b/implementors/core/hash/trait.Hash.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl Hash for BStr"]], +"roe":[["impl Hash for InvalidCaseMappingMode"],["impl Hash for LowercaseMode"],["impl Hash for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js b/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js new file mode 100644 index 000000000..c80f1d1db --- /dev/null +++ b/implementors/core/iter/traits/double_ended/trait.DoubleEndedIterator.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl<'a> DoubleEndedIterator for Chars<'a>"],["impl<'a> DoubleEndedIterator for Bytes<'a>"],["impl<'a> DoubleEndedIterator for CharIndices<'a>"],["impl<'a> DoubleEndedIterator for LinesWithTerminator<'a>"],["impl<'a> DoubleEndedIterator for Lines<'a>"]], +"memchr":[["impl<'h> DoubleEndedIterator for Memchr<'h>"],["impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>"],["impl<'h> DoubleEndedIterator for Memchr2<'h>"],["impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>"],["impl<'h> DoubleEndedIterator for Memchr3<'h>"],["impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>"],["impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js b/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js new file mode 100644 index 000000000..4d1bdd2cd --- /dev/null +++ b/implementors/core/iter/traits/exact_size/trait.ExactSizeIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl<'a> ExactSizeIterator for Bytes<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/iterator/trait.Iterator.js b/implementors/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 000000000..12d9c740b --- /dev/null +++ b/implementors/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F>"],["impl<'a> Iterator for Utf8Chunks<'a>"],["impl<'a> Iterator for LinesWithTerminator<'a>"],["impl<'h, 's> Iterator for SplitReverse<'h, 's>"],["impl<'h, 'n> Iterator for Find<'h, 'n>"],["impl<'a> Iterator for Chars<'a>"],["impl<'h, 's> Iterator for Split<'h, 's>"],["impl<'a> Iterator for Lines<'a>"],["impl<'h, 's> Iterator for SplitNReverse<'h, 's>"],["impl<'h, 'n> Iterator for FindReverse<'h, 'n>"],["impl<'a> Iterator for Bytes<'a>"],["impl<'a> Iterator for EscapeBytes<'a>"],["impl<'a> Iterator for CharIndices<'a>"],["impl<'h, 's> Iterator for SplitN<'h, 's>"]], +"memchr":[["impl<'a, 'h> Iterator for TwoIter<'a, 'h>"],["impl<'a, 'h> Iterator for ThreeIter<'a, 'h>"],["impl<'h> Iterator for Memchr2<'h>"],["impl<'a, 'h> Iterator for OneIter<'a, 'h>"],["impl<'h, 'n> Iterator for FindIter<'h, 'n>"],["impl<'a, 'h> Iterator for TwoIter<'a, 'h>"],["impl<'a, 'h> Iterator for OneIter<'a, 'h>"],["impl<'a, 'h> Iterator for OneIter<'a, 'h>"],["impl<'h, 'n> Iterator for FindRevIter<'h, 'n>"],["impl<'a, 'h> Iterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> Iterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> Iterator for TwoIter<'a, 'h>"],["impl<'h> Iterator for Memchr3<'h>"],["impl<'h> Iterator for Memchr<'h>"]], +"roe":[["impl<'a> Iterator for Uppercase<'a>"],["impl<'a> Iterator for Lowercase<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/iter/traits/marker/trait.FusedIterator.js b/implementors/core/iter/traits/marker/trait.FusedIterator.js new file mode 100644 index 000000000..f2b50d561 --- /dev/null +++ b/implementors/core/iter/traits/marker/trait.FusedIterator.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl<'a> FusedIterator for Lines<'a>"],["impl<'a> FusedIterator for LinesWithTerminator<'a>"],["impl<'a> FusedIterator for Utf8Chunks<'a>"],["impl<'a> FusedIterator for CharIndices<'a>"],["impl<'a> FusedIterator for Bytes<'a>"]], +"memchr":[["impl<'a, 'h> FusedIterator for TwoIter<'a, 'h>"],["impl<'a, 'h> FusedIterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> FusedIterator for OneIter<'a, 'h>"],["impl<'a, 'h> FusedIterator for ThreeIter<'a, 'h>"],["impl<'a, 'h> FusedIterator for OneIter<'a, 'h>"],["impl<'h> FusedIterator for Memchr3<'h>"],["impl<'h> FusedIterator for Memchr<'h>"],["impl<'a, 'h> FusedIterator for TwoIter<'a, 'h>"],["impl<'h> FusedIterator for Memchr2<'h>"]], +"roe":[["impl<'a> FusedIterator for Lowercase<'a>"],["impl<'a> FusedIterator for Uppercase<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Copy.js b/implementors/core/marker/trait.Copy.js new file mode 100644 index 000000000..25affd37f --- /dev/null +++ b/implementors/core/marker/trait.Copy.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"memchr":[["impl Copy for Two"],["impl Copy for Two"],["impl Copy for Three"],["impl Copy for Three"],["impl Copy for Two"],["impl Copy for One"],["impl Copy for One"],["impl Copy for FinderRev"],["impl Copy for Finder"],["impl Copy for Finder"],["impl Copy for PrefilterConfig"],["impl Copy for Finder"],["impl Copy for One"],["impl Copy for Finder"],["impl Copy for Three"],["impl Copy for Pair"]], +"roe":[["impl Copy for UppercaseMode"],["impl Copy for LowercaseMode"],["impl Copy for InvalidCaseMappingMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 000000000..fae94b151 --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl Freeze for BStr",1,["bstr::bstr::BStr"]],["impl<'a> Freeze for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> Freeze for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> Freeze for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> Freeze for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> Freeze for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> Freeze for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> Freeze for FieldsWith<'a, F>where\n F: Freeze,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> Freeze for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> Freeze for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> Freeze for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> Freeze for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> Freeze for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> Freeze for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> Freeze for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> Freeze for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> Freeze for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> Freeze for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl Freeze for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl Freeze for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> Freeze for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl Freeze for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> Freeze for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl Freeze for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> Freeze for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl Freeze for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl Freeze for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl Freeze for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl Freeze for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl Freeze for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl Freeze for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl Freeze for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl Freeze for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> Freeze for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl Freeze for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> Freeze for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl Freeze for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> Freeze for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl Freeze for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl Freeze for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> Freeze for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl Freeze for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> Freeze for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl Freeze for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> Freeze for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl Freeze for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> Freeze for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> Freeze for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> Freeze for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl Freeze for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> Freeze for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> Freeze for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> Freeze for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> Freeze for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl Freeze for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> Freeze for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> Freeze for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl Freeze for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl Freeze for LowercaseMode",1,["roe::LowercaseMode"]],["impl Freeze for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 000000000..ac0dbc5bb --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl Send for BStr",1,["bstr::bstr::BStr"]],["impl<'a> Send for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> Send for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> Send for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> Send for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> Send for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> Send for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> Send for FieldsWith<'a, F>where\n F: Send,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> Send for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> Send for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> Send for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> Send for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> Send for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> Send for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> Send for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> Send for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> Send for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> Send for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl Send for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl Send for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> Send for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl Send for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> Send for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl Send for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> Send for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl Send for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl Send for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl Send for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl Send for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl Send for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl Send for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl Send for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl Send for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> Send for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl Send for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> Send for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl Send for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> Send for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl Send for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl Send for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> Send for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl Send for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> Send for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl Send for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> Send for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl Send for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> Send for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> Send for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> Send for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl Send for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> Send for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> Send for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> Send for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> Send for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl Send for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> Send for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> Send for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl Send for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl Send for LowercaseMode",1,["roe::LowercaseMode"]],["impl Send for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sized.js b/implementors/core/marker/trait.Sized.js new file mode 100644 index 000000000..3b59821a9 --- /dev/null +++ b/implementors/core/marker/trait.Sized.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl !Sized for BStr",1,["bstr::bstr::BStr"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralEq.js b/implementors/core/marker/trait.StructuralEq.js new file mode 100644 index 000000000..89e481e76 --- /dev/null +++ b/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl StructuralEq for Utf8Error"]], +"roe":[["impl StructuralEq for InvalidCaseMappingMode"],["impl StructuralEq for UppercaseMode"],["impl StructuralEq for LowercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralPartialEq.js b/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 000000000..17ced7dc6 --- /dev/null +++ b/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"bstr":[["impl StructuralPartialEq for Utf8Error"]], +"roe":[["impl StructuralPartialEq for LowercaseMode"],["impl StructuralPartialEq for InvalidCaseMappingMode"],["impl StructuralPartialEq for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 000000000..3b760957a --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl Sync for BStr",1,["bstr::bstr::BStr"]],["impl<'a> Sync for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> Sync for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> Sync for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> Sync for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> Sync for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> Sync for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> Sync for FieldsWith<'a, F>where\n F: Sync,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> Sync for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> Sync for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> Sync for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> Sync for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> Sync for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> Sync for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> Sync for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> Sync for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> Sync for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> Sync for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl Sync for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl Sync for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> Sync for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl Sync for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> Sync for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl Sync for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> Sync for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl Sync for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl Sync for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl Sync for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl Sync for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl Sync for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl Sync for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl Sync for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl Sync for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> Sync for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl Sync for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> Sync for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl Sync for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> Sync for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl Sync for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl Sync for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> Sync for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl Sync for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> Sync for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl Sync for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> Sync for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl Sync for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> Sync for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> Sync for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> Sync for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl Sync for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> Sync for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> Sync for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> Sync for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> Sync for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl Sync for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> Sync for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> Sync for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl Sync for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl Sync for LowercaseMode",1,["roe::LowercaseMode"]],["impl Sync for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 000000000..4aa298639 --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl Unpin for BStr",1,["bstr::bstr::BStr"]],["impl<'a> Unpin for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> Unpin for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> Unpin for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> Unpin for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> Unpin for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> Unpin for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> Unpin for FieldsWith<'a, F>where\n F: Unpin,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> Unpin for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> Unpin for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> Unpin for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> Unpin for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> Unpin for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> Unpin for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> Unpin for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> Unpin for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> Unpin for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> Unpin for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl Unpin for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl Unpin for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> Unpin for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl Unpin for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> Unpin for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl Unpin for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> Unpin for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl Unpin for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl Unpin for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl Unpin for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl Unpin for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl Unpin for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl Unpin for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl Unpin for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl Unpin for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> Unpin for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl Unpin for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> Unpin for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl Unpin for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> Unpin for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl Unpin for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl Unpin for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> Unpin for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl Unpin for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> Unpin for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl Unpin for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> Unpin for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl Unpin for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> Unpin for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> Unpin for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> Unpin for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl Unpin for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> Unpin for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> Unpin for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> Unpin for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> Unpin for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl Unpin for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> Unpin for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> Unpin for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl Unpin for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl Unpin for LowercaseMode",1,["roe::LowercaseMode"]],["impl Unpin for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/deref/trait.Deref.js b/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 000000000..afa0559e6 --- /dev/null +++ b/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl Deref for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/deref/trait.DerefMut.js b/implementors/core/ops/deref/trait.DerefMut.js new file mode 100644 index 000000000..ae9d7792c --- /dev/null +++ b/implementors/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl DerefMut for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.Index.js b/implementors/core/ops/index/trait.Index.js new file mode 100644 index 000000000..1f717e3c7 --- /dev/null +++ b/implementors/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl Index<RangeFull> for BStr"],["impl Index<RangeInclusive<usize>> for BStr"],["impl Index<usize> for BStr"],["impl Index<RangeTo<usize>> for BStr"],["impl Index<Range<usize>> for BStr"],["impl Index<RangeFrom<usize>> for BStr"],["impl Index<RangeToInclusive<usize>> for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/index/trait.IndexMut.js b/implementors/core/ops/index/trait.IndexMut.js new file mode 100644 index 000000000..40001a3ca --- /dev/null +++ b/implementors/core/ops/index/trait.IndexMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"bstr":[["impl IndexMut<RangeTo<usize>> for BStr"],["impl IndexMut<RangeToInclusive<usize>> for BStr"],["impl IndexMut<usize> for BStr"],["impl IndexMut<RangeFull> for BStr"],["impl IndexMut<Range<usize>> for BStr"],["impl IndexMut<RangeInclusive<usize>> for BStr"],["impl IndexMut<RangeFrom<usize>> for BStr"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 000000000..894ac7e8a --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl RefUnwindSafe for BStr",1,["bstr::bstr::BStr"]],["impl<'a> RefUnwindSafe for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> RefUnwindSafe for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> RefUnwindSafe for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> RefUnwindSafe for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> RefUnwindSafe for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> RefUnwindSafe for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> RefUnwindSafe for FieldsWith<'a, F>where\n F: RefUnwindSafe,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> RefUnwindSafe for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> RefUnwindSafe for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> RefUnwindSafe for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> RefUnwindSafe for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> RefUnwindSafe for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> RefUnwindSafe for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> RefUnwindSafe for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> RefUnwindSafe for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> RefUnwindSafe for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> RefUnwindSafe for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl RefUnwindSafe for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl RefUnwindSafe for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl RefUnwindSafe for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl RefUnwindSafe for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl RefUnwindSafe for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl RefUnwindSafe for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl RefUnwindSafe for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl RefUnwindSafe for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl RefUnwindSafe for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl RefUnwindSafe for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl RefUnwindSafe for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl RefUnwindSafe for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl RefUnwindSafe for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl RefUnwindSafe for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> RefUnwindSafe for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> RefUnwindSafe for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> RefUnwindSafe for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl RefUnwindSafe for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> RefUnwindSafe for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> RefUnwindSafe for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> RefUnwindSafe for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> RefUnwindSafe for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl RefUnwindSafe for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> RefUnwindSafe for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> RefUnwindSafe for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl RefUnwindSafe for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl RefUnwindSafe for LowercaseMode",1,["roe::LowercaseMode"]],["impl RefUnwindSafe for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 000000000..2afd0b4ab --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"bstr":[["impl UnwindSafe for BStr",1,["bstr::bstr::BStr"]],["impl<'a> UnwindSafe for EscapeBytes<'a>",1,["bstr::escape_bytes::EscapeBytes"]],["impl<'a> UnwindSafe for Finder<'a>",1,["bstr::ext_slice::Finder"]],["impl<'a> UnwindSafe for FinderReverse<'a>",1,["bstr::ext_slice::FinderReverse"]],["impl<'h, 'n> UnwindSafe for Find<'h, 'n>",1,["bstr::ext_slice::Find"]],["impl<'h, 'n> UnwindSafe for FindReverse<'h, 'n>",1,["bstr::ext_slice::FindReverse"]],["impl<'a> UnwindSafe for Bytes<'a>",1,["bstr::ext_slice::Bytes"]],["impl<'a, F> UnwindSafe for FieldsWith<'a, F>where\n F: UnwindSafe,",1,["bstr::ext_slice::FieldsWith"]],["impl<'h, 's> UnwindSafe for Split<'h, 's>",1,["bstr::ext_slice::Split"]],["impl<'h, 's> UnwindSafe for SplitReverse<'h, 's>",1,["bstr::ext_slice::SplitReverse"]],["impl<'h, 's> UnwindSafe for SplitN<'h, 's>",1,["bstr::ext_slice::SplitN"]],["impl<'h, 's> UnwindSafe for SplitNReverse<'h, 's>",1,["bstr::ext_slice::SplitNReverse"]],["impl<'a> UnwindSafe for Lines<'a>",1,["bstr::ext_slice::Lines"]],["impl<'a> UnwindSafe for LinesWithTerminator<'a>",1,["bstr::ext_slice::LinesWithTerminator"]],["impl<'a> UnwindSafe for Chars<'a>",1,["bstr::utf8::Chars"]],["impl<'a> UnwindSafe for CharIndices<'a>",1,["bstr::utf8::CharIndices"]],["impl<'a> UnwindSafe for Utf8Chunks<'a>",1,["bstr::utf8::Utf8Chunks"]],["impl<'a> UnwindSafe for Utf8Chunk<'a>",1,["bstr::utf8::Utf8Chunk"]],["impl UnwindSafe for Utf8Error",1,["bstr::utf8::Utf8Error"]]], +"memchr":[["impl UnwindSafe for One",1,["memchr::arch::all::memchr::One"]],["impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::all::memchr::OneIter"]],["impl UnwindSafe for Two",1,["memchr::arch::all::memchr::Two"]],["impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::all::memchr::TwoIter"]],["impl UnwindSafe for Three",1,["memchr::arch::all::memchr::Three"]],["impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::all::memchr::ThreeIter"]],["impl UnwindSafe for Finder",1,["memchr::arch::all::packedpair::Finder"]],["impl UnwindSafe for Pair",1,["memchr::arch::all::packedpair::Pair"]],["impl UnwindSafe for Finder",1,["memchr::arch::all::rabinkarp::Finder"]],["impl UnwindSafe for FinderRev",1,["memchr::arch::all::rabinkarp::FinderRev"]],["impl UnwindSafe for Finder",1,["memchr::arch::all::shiftor::Finder"]],["impl UnwindSafe for Finder",1,["memchr::arch::all::twoway::Finder"]],["impl UnwindSafe for FinderRev",1,["memchr::arch::all::twoway::FinderRev"]],["impl UnwindSafe for One",1,["memchr::arch::x86_64::avx2::memchr::One"]],["impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::OneIter"]],["impl UnwindSafe for Two",1,["memchr::arch::x86_64::avx2::memchr::Two"]],["impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::TwoIter"]],["impl UnwindSafe for Three",1,["memchr::arch::x86_64::avx2::memchr::Three"]],["impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::avx2::memchr::ThreeIter"]],["impl UnwindSafe for Finder",1,["memchr::arch::x86_64::avx2::packedpair::Finder"]],["impl UnwindSafe for One",1,["memchr::arch::x86_64::sse2::memchr::One"]],["impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::OneIter"]],["impl UnwindSafe for Two",1,["memchr::arch::x86_64::sse2::memchr::Two"]],["impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::TwoIter"]],["impl UnwindSafe for Three",1,["memchr::arch::x86_64::sse2::memchr::Three"]],["impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>",1,["memchr::arch::x86_64::sse2::memchr::ThreeIter"]],["impl UnwindSafe for Finder",1,["memchr::arch::x86_64::sse2::packedpair::Finder"]],["impl<'h> UnwindSafe for Memchr<'h>",1,["memchr::memchr::Memchr"]],["impl<'h> UnwindSafe for Memchr2<'h>",1,["memchr::memchr::Memchr2"]],["impl<'h> UnwindSafe for Memchr3<'h>",1,["memchr::memchr::Memchr3"]],["impl UnwindSafe for PrefilterConfig",1,["memchr::memmem::searcher::PrefilterConfig"]],["impl<'h, 'n> UnwindSafe for FindIter<'h, 'n>",1,["memchr::memmem::FindIter"]],["impl<'h, 'n> UnwindSafe for FindRevIter<'h, 'n>",1,["memchr::memmem::FindRevIter"]],["impl<'n> UnwindSafe for Finder<'n>",1,["memchr::memmem::Finder"]],["impl<'n> UnwindSafe for FinderRev<'n>",1,["memchr::memmem::FinderRev"]],["impl UnwindSafe for FinderBuilder",1,["memchr::memmem::FinderBuilder"]]], +"roe":[["impl<'a> UnwindSafe for Lowercase<'a>",1,["roe::lowercase::Lowercase"]],["impl<'a> UnwindSafe for Uppercase<'a>",1,["roe::uppercase::Uppercase"]],["impl UnwindSafe for InvalidCaseMappingMode",1,["roe::InvalidCaseMappingMode"]],["impl UnwindSafe for LowercaseMode",1,["roe::LowercaseMode"]],["impl UnwindSafe for UppercaseMode",1,["roe::UppercaseMode"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/str/traits/trait.FromStr.js b/implementors/core/str/traits/trait.FromStr.js new file mode 100644 index 000000000..eadddd709 --- /dev/null +++ b/implementors/core/str/traits/trait.FromStr.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"roe":[["impl FromStr for LowercaseMode"],["impl FromStr for UppercaseMode"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.js b/implementors/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.js new file mode 100644 index 000000000..e0253e944 --- /dev/null +++ b/implementors/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"memchr":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/memchr/all.html b/memchr/all.html new file mode 100644 index 000000000..14f33ee8d --- /dev/null +++ b/memchr/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Functions

\ No newline at end of file diff --git a/memchr/arch/all/fn.is_equal.html b/memchr/arch/all/fn.is_equal.html new file mode 100644 index 000000000..da7724818 --- /dev/null +++ b/memchr/arch/all/fn.is_equal.html @@ -0,0 +1,13 @@ +is_equal in memchr::arch::all - Rust

Function memchr::arch::all::is_equal

source ·
pub fn is_equal(x: &[u8], y: &[u8]) -> bool
Expand description

Compare corresponding bytes in x and y for equality.

+

That is, this returns true if and only if x.len() == y.len() and +x[i] == y[i] for all 0 <= i < x.len().

+

Inlining

+

This routine is marked inline(always). If you want to call this function +in a way that is not always inlined, you’ll need to wrap a call to it in +another function that is marked as inline(never) or just inline.

+

Motivation

+

Why not use slice equality instead? Well, slice equality usually results in +a call out to the current platform’s libc which might not be inlineable +or have other overhead. This routine isn’t guaranteed to be a win, but it +might be in some cases.

+
\ No newline at end of file diff --git a/memchr/arch/all/fn.is_equal_raw.html b/memchr/arch/all/fn.is_equal_raw.html new file mode 100644 index 000000000..6feefa14f --- /dev/null +++ b/memchr/arch/all/fn.is_equal_raw.html @@ -0,0 +1,28 @@ +is_equal_raw in memchr::arch::all - Rust

Function memchr::arch::all::is_equal_raw

source ·
pub unsafe fn is_equal_raw(x: *const u8, y: *const u8, n: usize) -> bool
Expand description

Compare n bytes at the given pointers for equality.

+

This returns true if and only if *x.add(i) == *y.add(i) for all +0 <= i < n.

+

Inlining

+

This routine is marked inline(always). If you want to call this function +in a way that is not always inlined, you’ll need to wrap a call to it in +another function that is marked as inline(never) or just inline.

+

Motivation

+

Why not use slice equality instead? Well, slice equality usually results in +a call out to the current platform’s libc which might not be inlineable +or have other overhead. This routine isn’t guaranteed to be a win, but it +might be in some cases.

+

Safety

+
    +
  • Both x and y must be valid for reads of up to n bytes.
  • +
  • Both x and y must point to an initialized value.
  • +
  • Both x and y must each point to an allocated object and +must either be in bounds or at most one byte past the end of the +allocated object. x and y do not need to point to the same allocated +object, but they may.
  • +
  • Both x and y must be derived from a pointer to their respective +allocated objects.
  • +
  • The distance between x and x+n must not overflow isize. Similarly +for y and y+n.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+
\ No newline at end of file diff --git a/memchr/arch/all/fn.is_prefix.html b/memchr/arch/all/fn.is_prefix.html new file mode 100644 index 000000000..36386e638 --- /dev/null +++ b/memchr/arch/all/fn.is_prefix.html @@ -0,0 +1,8 @@ +is_prefix in memchr::arch::all - Rust

Function memchr::arch::all::is_prefix

source ·
pub fn is_prefix(haystack: &[u8], needle: &[u8]) -> bool
Expand description

Returns true if and only if needle is a prefix of haystack.

+

This uses a latency optimized variant of memcmp internally which might +make this faster for very short strings.

+

Inlining

+

This routine is marked inline(always). If you want to call this function +in a way that is not always inlined, you’ll need to wrap a call to it in +another function that is marked as inline(never) or just inline.

+
\ No newline at end of file diff --git a/memchr/arch/all/fn.is_suffix.html b/memchr/arch/all/fn.is_suffix.html new file mode 100644 index 000000000..b0a06569e --- /dev/null +++ b/memchr/arch/all/fn.is_suffix.html @@ -0,0 +1,8 @@ +is_suffix in memchr::arch::all - Rust

Function memchr::arch::all::is_suffix

source ·
pub fn is_suffix(haystack: &[u8], needle: &[u8]) -> bool
Expand description

Returns true if and only if needle is a suffix of haystack.

+

This uses a latency optimized variant of memcmp internally which might +make this faster for very short strings.

+

Inlining

+

This routine is marked inline(always). If you want to call this function +in a way that is not always inlined, you’ll need to wrap a call to it in +another function that is marked as inline(never) or just inline.

+
\ No newline at end of file diff --git a/memchr/arch/all/index.html b/memchr/arch/all/index.html new file mode 100644 index 000000000..b2ed2b906 --- /dev/null +++ b/memchr/arch/all/index.html @@ -0,0 +1,5 @@ +memchr::arch::all - Rust

Module memchr::arch::all

source ·
Expand description

Contains architecture independent routines.

+

These routines are often used as a “fallback” implementation when the more +specialized architecture dependent routines are unavailable.

+

Modules

Functions

  • Compare corresponding bytes in x and y for equality.
  • Compare n bytes at the given pointers for equality.
  • Returns true if and only if needle is a prefix of haystack.
  • Returns true if and only if needle is a suffix of haystack.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/index.html b/memchr/arch/all/memchr/index.html new file mode 100644 index 000000000..13b696975 --- /dev/null +++ b/memchr/arch/all/memchr/index.html @@ -0,0 +1,20 @@ +memchr::arch::all::memchr - Rust

Module memchr::arch::all::memchr

source ·
Expand description

Provides architecture independent implementations of memchr and friends.

+

The main types in this module are One, Two and Three. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers +are typically slower than hand-coded vector routines accomplishing the same +task, but are also typically faster than naive scalar code. These routines +effectively work by treating a usize as a vector of 8-bit lanes, and thus +achieves some level of data parallelism even without explicit vector support.

+

The One searcher also provides a One::count routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using One::find repeatedly. (OneIter specializes its +Iterator::count implementation to use this routine.)

+

Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it’s +probably (but not necessarily) better to just use a simple [bool; 256] array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency.

+

Structs

  • Finds all occurrences of a single byte in a haystack.
  • An iterator over all occurrences of a single byte in a haystack.
  • Finds all occurrences of three bytes in a haystack.
  • An iterator over all occurrences of three possible bytes in a haystack.
  • Finds all occurrences of two bytes in a haystack.
  • An iterator over all occurrences of two possible bytes in a haystack.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/sidebar-items.js b/memchr/arch/all/memchr/sidebar-items.js new file mode 100644 index 000000000..9e7b0311e --- /dev/null +++ b/memchr/arch/all/memchr/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["One","OneIter","Three","ThreeIter","Two","TwoIter"]}; \ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.One.html b/memchr/arch/all/memchr/struct.One.html new file mode 100644 index 000000000..dc02f12c7 --- /dev/null +++ b/memchr/arch/all/memchr/struct.One.html @@ -0,0 +1,94 @@ +One in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::One

source ·
pub struct One { /* private fields */ }
Expand description

Finds all occurrences of a single byte in a haystack.

+

Implementations§

source§

impl One

source

pub fn new(needle: u8) -> One

Create a new searcher that finds occurrences of the byte given.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of the needle in the given haystack. If no +such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of the needle in the given haystack. If no +such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub fn count(&self, haystack: &[u8]) -> usize

Counts all occurrences of this byte in the given haystack.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize

Counts all occurrences of this byte in the given haystack represented +by raw pointers.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, 0 will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h>

Returns an iterator over all occurrences of the needle byte in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for One

source§

fn clone(&self) -> One

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for One

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for One

Auto Trait Implementations§

§

impl RefUnwindSafe for One

§

impl Send for One

§

impl Sync for One

§

impl Unpin for One

§

impl UnwindSafe for One

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.OneIter.html b/memchr/arch/all/memchr/struct.OneIter.html new file mode 100644 index 000000000..a50278d8f --- /dev/null +++ b/memchr/arch/all/memchr/struct.OneIter.html @@ -0,0 +1,214 @@ +OneIter in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::OneIter

source ·
pub struct OneIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of a single byte in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the One::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying One searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for OneIter<'a, 'h>

source§

fn clone(&self) -> OneIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for OneIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for OneIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>

§

impl<'a, 'h> Send for OneIter<'a, 'h>

§

impl<'a, 'h> Sync for OneIter<'a, 'h>

§

impl<'a, 'h> Unpin for OneIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.Three.html b/memchr/arch/all/memchr/struct.Three.html new file mode 100644 index 000000000..36261ced3 --- /dev/null +++ b/memchr/arch/all/memchr/struct.Three.html @@ -0,0 +1,78 @@ +Three in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::Three

source ·
pub struct Three { /* private fields */ }
Expand description

Finds all occurrences of three bytes in a haystack.

+

That is, this reports matches of one of three possible bytes. For example, +searching for a, b or o in afoobar would report matches at offsets +0, 2, 3, 4 and 5.

+

Implementations§

source§

impl Three

source

pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Three

Create a new searcher that finds occurrences of the three needle bytes +given.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h>

Returns an iterator over all occurrences of one of the needle bytes in +the given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Three

source§

fn clone(&self) -> Three

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Three

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Three

Auto Trait Implementations§

§

impl RefUnwindSafe for Three

§

impl Send for Three

§

impl Sync for Three

§

impl Unpin for Three

§

impl UnwindSafe for Three

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.ThreeIter.html b/memchr/arch/all/memchr/struct.ThreeIter.html new file mode 100644 index 000000000..ce51d6fd9 --- /dev/null +++ b/memchr/arch/all/memchr/struct.ThreeIter.html @@ -0,0 +1,215 @@ +ThreeIter in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::ThreeIter

source ·
pub struct ThreeIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of three possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Three::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Three searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for ThreeIter<'a, 'h>

source§

fn clone(&self) -> ThreeIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for ThreeIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for ThreeIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>

§

impl<'a, 'h> Send for ThreeIter<'a, 'h>

§

impl<'a, 'h> Sync for ThreeIter<'a, 'h>

§

impl<'a, 'h> Unpin for ThreeIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.Two.html b/memchr/arch/all/memchr/struct.Two.html new file mode 100644 index 000000000..f1f5640ea --- /dev/null +++ b/memchr/arch/all/memchr/struct.Two.html @@ -0,0 +1,78 @@ +Two in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::Two

source ·
pub struct Two { /* private fields */ }
Expand description

Finds all occurrences of two bytes in a haystack.

+

That is, this reports matches of one of two possible bytes. For example, +searching for a or b in afoobar would report matches at offsets 0, +4 and 5.

+

Implementations§

source§

impl Two

source

pub fn new(needle1: u8, needle2: u8) -> Two

Create a new searcher that finds occurrences of the two needle bytes +given.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value for a non-empty haystack is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h>

Returns an iterator over all occurrences of one of the needle bytes in +the given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Two

source§

fn clone(&self) -> Two

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Two

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Two

Auto Trait Implementations§

§

impl RefUnwindSafe for Two

§

impl Send for Two

§

impl Sync for Two

§

impl Unpin for Two

§

impl UnwindSafe for Two

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/memchr/struct.TwoIter.html b/memchr/arch/all/memchr/struct.TwoIter.html new file mode 100644 index 000000000..a9b5bc11d --- /dev/null +++ b/memchr/arch/all/memchr/struct.TwoIter.html @@ -0,0 +1,215 @@ +TwoIter in memchr::arch::all::memchr - Rust

Struct memchr::arch::all::memchr::TwoIter

source ·
pub struct TwoIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of two possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Two::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Two searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for TwoIter<'a, 'h>

source§

fn clone(&self) -> TwoIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for TwoIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for TwoIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>

§

impl<'a, 'h> Send for TwoIter<'a, 'h>

§

impl<'a, 'h> Sync for TwoIter<'a, 'h>

§

impl<'a, 'h> Unpin for TwoIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/packedpair/index.html b/memchr/arch/all/packedpair/index.html new file mode 100644 index 000000000..024a6bcb6 --- /dev/null +++ b/memchr/arch/all/packedpair/index.html @@ -0,0 +1,10 @@ +memchr::arch::all::packedpair - Rust

Module memchr::arch::all::packedpair

source ·
Expand description

Provides an architecture independent implementation of the “packed pair” +algorithm.

+

The “packed pair” algorithm is based on the generic SIMD algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for. Note that +this module provides an architecture independent version that doesn’t do as +good of a job keeping the search for candidates inside a SIMD hot path. It +however can be good enough in many circumstances.

+

Structs

  • An architecture independent “packed pair” finder.
  • A pair of byte offsets into a needle to use as a predicate.

Traits

  • This trait allows the user to customize the heuristic used to determine the +relative frequency of a given byte in the dataset being searched.
\ No newline at end of file diff --git a/memchr/arch/all/packedpair/sidebar-items.js b/memchr/arch/all/packedpair/sidebar-items.js new file mode 100644 index 000000000..5c26eba81 --- /dev/null +++ b/memchr/arch/all/packedpair/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder","Pair"],"trait":["HeuristicFrequencyRank"]}; \ No newline at end of file diff --git a/memchr/arch/all/packedpair/struct.Finder.html b/memchr/arch/all/packedpair/struct.Finder.html new file mode 100644 index 000000000..217bb1aee --- /dev/null +++ b/memchr/arch/all/packedpair/struct.Finder.html @@ -0,0 +1,36 @@ +Finder in memchr::arch::all::packedpair - Rust

Struct memchr::arch::all::packedpair::Finder

source ·
pub struct Finder { /* private fields */ }
Expand description

An architecture independent “packed pair” finder.

+

This finder picks two bytes that it believes have high predictive power for +indicating an overall match of a needle. At search time, it reports offsets +where the needle could match based on whether the pair of bytes it chose +match.

+

This is architecture independent because it utilizes memchr to find the +occurrence of one of the bytes in the pair, and then checks whether the +second byte matches. If it does, in the case of Finder::find_prefilter, +the location at which the needle could match is returned.

+

It is generally preferred to use architecture specific routines for a +“packed pair” prefilter, but this can be a useful fallback when the +architecture independent routines are unavailable.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Option<Finder>

Create a new prefilter that reports possible locations where the given +needle matches.

+
source

pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder>

Create a new prefilter using the pair given.

+

If the prefilter could not be constructed, then None is returned.

+

This constructor permits callers to control precisely which pair of +bytes is used as a predicate.

+
source

pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize>

Run this finder on the given haystack as a prefilter.

+

If a candidate match is found, then an offset where the needle could +begin in the haystack is returned.

+
source

pub fn pair(&self) -> &Pair

Returns the pair of offsets (into the needle) used to check as a +predicate before confirming whether a needle exists at a particular +position.

+

Trait Implementations§

source§

impl Clone for Finder

source§

fn clone(&self) -> Finder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Finder

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/packedpair/struct.Pair.html b/memchr/arch/all/packedpair/struct.Pair.html new file mode 100644 index 000000000..de6b1e382 --- /dev/null +++ b/memchr/arch/all/packedpair/struct.Pair.html @@ -0,0 +1,58 @@ +Pair in memchr::arch::all::packedpair - Rust

Struct memchr::arch::all::packedpair::Pair

source ·
pub struct Pair { /* private fields */ }
Expand description

A pair of byte offsets into a needle to use as a predicate.

+

This pair is used as a predicate to quickly filter out positions in a +haystack in which a needle cannot match. In some cases, this pair can even +be used in vector algorithms such that the vector algorithm only switches +over to scalar code once this pair has been found.

+

A pair of offsets can be used in both substring search implementations and +in prefilters. The former will report matches of a needle in a haystack +where as the latter will only report possible matches of a needle.

+

The offsets are limited each to a maximum of 255 to keep memory usage low. +Moreover, it’s rarely advantageous to create a predicate using offsets +greater than 255 anyway.

+

The only guarantee enforced on the pair of offsets is that they are not +equivalent. It is not necessarily the case that index1 < index2 for +example. By convention, index1 corresponds to the byte in the needle +that is believed to be most the predictive. Note also that because of the +requirement that the indices be both valid for the needle used to build +the pair and not equal, it follows that a pair can only be constructed for +needles with length at least 2.

+

Implementations§

source§

impl Pair

source

pub fn new(needle: &[u8]) -> Option<Pair>

Create a new pair of offsets from the given needle.

+

If a pair could not be created (for example, if the needle is too +short), then None is returned.

+

This chooses the pair in the needle that is believed to be as +predictive of an overall match of the needle as possible.

+
source

pub fn with_ranker<R: HeuristicFrequencyRank>( + needle: &[u8], + ranker: R +) -> Option<Pair>

Create a new pair of offsets from the given needle and ranker.

+

This permits the caller to choose a background frequency distribution +with which bytes are selected. The idea is to select a pair of bytes +that is believed to strongly predict a match in the haystack. This +usually means selecting bytes that occur rarely in a haystack.

+

If a pair could not be created (for example, if the needle is too +short), then None is returned.

+
source

pub fn with_indices(needle: &[u8], index1: u8, index2: u8) -> Option<Pair>

Create a new pair using the offsets given for the needle given.

+

This bypasses any sort of heuristic process for choosing the offsets +and permits the caller to choose the offsets themselves.

+

Indices are limited to valid u8 values so that a Pair uses less +memory. It is not possible to create a Pair with offsets bigger than +u8::MAX. It’s likely that such a thing is not needed, but if it is, +it’s suggested to build your own bespoke algorithm because you’re +likely working on a very niche case. (File an issue if this suggestion +does not make sense to you.)

+

If a pair could not be created (for example, if the needle is too +short), then None is returned.

+
source

pub fn index1(&self) -> u8

Returns the first offset of the pair.

+
source

pub fn index2(&self) -> u8

Returns the second offset of the pair.

+

Trait Implementations§

source§

impl Clone for Pair

source§

fn clone(&self) -> Pair

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Pair

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Pair

Auto Trait Implementations§

§

impl RefUnwindSafe for Pair

§

impl Send for Pair

§

impl Sync for Pair

§

impl Unpin for Pair

§

impl UnwindSafe for Pair

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.html b/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.html new file mode 100644 index 000000000..335aa571f --- /dev/null +++ b/memchr/arch/all/packedpair/trait.HeuristicFrequencyRank.html @@ -0,0 +1,67 @@ +HeuristicFrequencyRank in memchr::arch::all::packedpair - Rust
pub trait HeuristicFrequencyRank {
+    // Required method
+    fn rank(&self, byte: u8) -> u8;
+}
Expand description

This trait allows the user to customize the heuristic used to determine the +relative frequency of a given byte in the dataset being searched.

+

The use of this trait can have a dramatic impact on performance depending +on the type of data being searched. The details of why are explained in the +docs of crate::memmem::Prefilter. To summarize, the core algorithm uses +a prefilter to quickly identify candidate matches that are later verified +more slowly. This prefilter is implemented in terms of trying to find +rare bytes at specific offsets that will occur less frequently in the +dataset. While the concept of a rare byte is similar for most datasets, +there are some specific datasets (like binary executables) that have +dramatically different byte distributions. For these datasets customizing +the byte frequency heuristic can have a massive impact on performance, and +might even need to be done at runtime.

+

The default implementation of HeuristicFrequencyRank reads from the +static frequency table defined in src/memmem/byte_frequencies.rs. This +is optimal for most inputs, so if you are unsure of the impact of using a +custom HeuristicFrequencyRank you should probably just use the default.

+

Example

+
use memchr::{
+    arch::all::packedpair::HeuristicFrequencyRank,
+    memmem::FinderBuilder,
+};
+
+/// A byte-frequency table that is good for scanning binary executables.
+struct Binary;
+
+impl HeuristicFrequencyRank for Binary {
+    fn rank(&self, byte: u8) -> u8 {
+        const TABLE: [u8; 256] = [
+            255, 128, 61, 43, 50, 41, 27, 28, 57, 15, 21, 13, 24, 17, 17,
+            89, 58, 16, 11, 7, 14, 23, 7, 6, 24, 9, 6, 5, 9, 4, 7, 16,
+            68, 11, 9, 6, 88, 7, 4, 4, 23, 9, 4, 8, 8, 5, 10, 4, 30, 11,
+            9, 24, 11, 5, 5, 5, 19, 11, 6, 17, 9, 9, 6, 8,
+            48, 58, 11, 14, 53, 40, 9, 9, 254, 35, 3, 6, 52, 23, 6, 6, 27,
+            4, 7, 11, 14, 13, 10, 11, 11, 5, 2, 10, 16, 12, 6, 19,
+            19, 20, 5, 14, 16, 31, 19, 7, 14, 20, 4, 4, 19, 8, 18, 20, 24,
+            1, 25, 19, 58, 29, 10, 5, 15, 20, 2, 2, 9, 4, 3, 5,
+            51, 11, 4, 53, 23, 39, 6, 4, 13, 81, 4, 186, 5, 67, 3, 2, 15,
+            0, 0, 1, 3, 2, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0,
+            12, 2, 1, 1, 3, 1, 1, 1, 6, 1, 2, 1, 3, 1, 1, 2, 9, 1, 1, 0,
+            2, 2, 4, 4, 11, 6, 7, 3, 6, 9, 4, 5,
+            46, 18, 8, 18, 17, 3, 8, 20, 16, 10, 3, 7, 175, 4, 6, 7, 13,
+            3, 7, 3, 3, 1, 3, 3, 10, 3, 1, 5, 2, 0, 1, 2,
+            16, 3, 5, 1, 6, 1, 1, 2, 58, 20, 3, 14, 12, 2, 1, 3, 16, 3, 5,
+            8, 3, 1, 8, 6, 17, 6, 5, 3, 8, 6, 13, 175,
+        ];
+        TABLE[byte as usize]
+    }
+}
+// Create a new finder with the custom heuristic.
+let finder = FinderBuilder::new()
+    .build_forward_with_ranker(Binary, b"\x00\x00\xdd\xdd");
+// Find needle with custom heuristic.
+assert!(finder.find(b"\x00\x00\x00\xdd\xdd").is_some());
+

Required Methods§

source

fn rank(&self, byte: u8) -> u8

Return the heuristic frequency rank of the given byte. A lower rank +means the byte is believed to occur less frequently in the haystack.

+

Some uses of this heuristic may treat arbitrary absolute rank values as +significant. For example, an implementation detail in this crate may +determine that heuristic prefilters are inappropriate if every byte in +the needle has a “high” rank.

+

Implementations on Foreign Types§

source§

impl<'a, R> HeuristicFrequencyRank for &'a Rwhere + R: HeuristicFrequencyRank,

This permits passing any implementation of HeuristicFrequencyRank as a +borrowed version of itself.

+
source§

fn rank(&self, byte: u8) -> u8

Implementors§

\ No newline at end of file diff --git a/memchr/arch/all/rabinkarp/index.html b/memchr/arch/all/rabinkarp/index.html new file mode 100644 index 000000000..16fd3e616 --- /dev/null +++ b/memchr/arch/all/rabinkarp/index.html @@ -0,0 +1,11 @@ +memchr::arch::all::rabinkarp - Rust

Module memchr::arch::all::rabinkarp

source ·
Expand description

An implementation of the Rabin-Karp substring search algorithm.

+

Rabin-Karp works by creating a hash of the needle provided and then computing +a rolling hash for each needle sized window in the haystack. When the rolling +hash matches the hash of the needle, a byte-wise comparison is done to check +if a match exists. The worst case time complexity of Rabin-Karp is O(m * n) where m ~ len(needle) and n ~ len(haystack). Its worst case space +complexity is constant.

+

The main utility of Rabin-Karp is that the searcher can be constructed very +quickly with very little memory. This makes it especially useful when searching +for small needles in small haystacks, as it might finish its search before a +beefier algorithm (like Two-Way) even starts.

+

Structs

  • A forward substring searcher using the Rabin-Karp algorithm.
  • A reverse substring searcher using the Rabin-Karp algorithm.
\ No newline at end of file diff --git a/memchr/arch/all/rabinkarp/sidebar-items.js b/memchr/arch/all/rabinkarp/sidebar-items.js new file mode 100644 index 000000000..6a8d46366 --- /dev/null +++ b/memchr/arch/all/rabinkarp/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder","FinderRev"]}; \ No newline at end of file diff --git a/memchr/arch/all/rabinkarp/struct.Finder.html b/memchr/arch/all/rabinkarp/struct.Finder.html new file mode 100644 index 000000000..7bf233299 --- /dev/null +++ b/memchr/arch/all/rabinkarp/struct.Finder.html @@ -0,0 +1,62 @@ +Finder in memchr::arch::all::rabinkarp - Rust

Struct memchr::arch::all::rabinkarp::Finder

source ·
pub struct Finder { /* private fields */ }
Expand description

A forward substring searcher using the Rabin-Karp algorithm.

+

Note that, as a lower level API, a Finder does not have access to the +needle it was constructed with. For this reason, executing a search +with a Finder requires passing both the needle and the haystack, +where the needle is exactly equivalent to the one given to the Finder +at construction time. This design was chosen so that callers can have +more precise control over where and how many times a needle is stored. +For example, in cases where Rabin-Karp is just one of several possible +substring search algorithms.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Finder

Create a new Rabin-Karp forward searcher for the given needle.

+

The needle may be empty. The empty needle matches at every byte offset.

+

Note that callers must pass the same needle to all search calls using +this Finder.

+
source

pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Return the first occurrence of the needle in the haystack +given. If no such occurrence exists, then None is returned.

+

The needle provided must match the needle given to this finder at +construction time.

+

The maximum value this can return is haystack.len(), which can only +occur when the needle and haystack both have length zero. Otherwise, +for non-empty haystacks, the maximum value is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + hstart: *const u8, + hend: *const u8, + nstart: *const u8, + nend: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and <= end. The pointer returned is only ever equivalent +to end when both the needle and haystack are empty. (That is, the +empty string matches the empty string.)

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+

Note that start and end below refer to both pairs of pointers given +to this routine. That is, the conditions apply to both hstart/hend +and nstart/nend.

+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
  • It must be the case that start <= end.
  • +
+

Trait Implementations§

source§

impl Clone for Finder

source§

fn clone(&self) -> Finder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/rabinkarp/struct.FinderRev.html b/memchr/arch/all/rabinkarp/struct.FinderRev.html new file mode 100644 index 000000000..76a53366b --- /dev/null +++ b/memchr/arch/all/rabinkarp/struct.FinderRev.html @@ -0,0 +1,51 @@ +FinderRev in memchr::arch::all::rabinkarp - Rust
pub struct FinderRev(/* private fields */);
Expand description

A reverse substring searcher using the Rabin-Karp algorithm.

+

Implementations§

source§

impl FinderRev

source

pub fn new(needle: &[u8]) -> FinderRev

Create a new Rabin-Karp reverse searcher for the given needle.

+
source

pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Return the last occurrence of the needle in the haystack +given. If no such occurrence exists, then None is returned.

+

The needle provided must match the needle given to this finder at +construction time.

+

The maximum value this can return is haystack.len(), which can only +occur when the needle and haystack both have length zero. Otherwise, +for non-empty haystacks, the maximum value is haystack.len() - 1.

+
source

pub unsafe fn rfind_raw( + &self, + hstart: *const u8, + hend: *const u8, + nstart: *const u8, + nend: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and <= end. The pointer returned is only ever equivalent +to end when both the needle and haystack are empty. (That is, the +empty string matches the empty string.)

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+

Note that start and end below refer to both pairs of pointers given +to this routine. That is, the conditions apply to both hstart/hend +and nstart/nend.

+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
  • It must be the case that start <= end.
  • +
+

Trait Implementations§

source§

impl Clone for FinderRev

source§

fn clone(&self) -> FinderRev

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FinderRev

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/shiftor/index.html b/memchr/arch/all/shiftor/index.html new file mode 100644 index 000000000..b6fa433db --- /dev/null +++ b/memchr/arch/all/shiftor/index.html @@ -0,0 +1,2 @@ +memchr::arch::all::shiftor - Rust

Module memchr::arch::all::shiftor

source ·
Expand description

An implementation of the Shift-Or substring search algorithm.

+

Structs

  • A forward substring searcher using the Shift-Or algorithm.
\ No newline at end of file diff --git a/memchr/arch/all/shiftor/sidebar-items.js b/memchr/arch/all/shiftor/sidebar-items.js new file mode 100644 index 000000000..9d56366c5 --- /dev/null +++ b/memchr/arch/all/shiftor/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder"]}; \ No newline at end of file diff --git a/memchr/arch/all/shiftor/struct.Finder.html b/memchr/arch/all/shiftor/struct.Finder.html new file mode 100644 index 000000000..f035fad44 --- /dev/null +++ b/memchr/arch/all/shiftor/struct.Finder.html @@ -0,0 +1,24 @@ +Finder in memchr::arch::all::shiftor - Rust

Struct memchr::arch::all::shiftor::Finder

source ·
pub struct Finder { /* private fields */ }
Expand description

A forward substring searcher using the Shift-Or algorithm.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Option<Finder>

Create a new Shift-Or forward searcher for the given needle.

+

The needle may be empty. The empty needle matches at every byte offset.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of the needle given to Finder::new in +the haystack given. If no such occurrence exists, then None is +returned.

+

Unlike most other substring search implementations in this crate, this +finder does not require passing the needle at search time. A match can +be determined without the needle at all since the required information +is already encoded into this finder at construction time.

+

The maximum value this can return is haystack.len(), which can only +occur when the needle and haystack both have length zero. Otherwise, +for non-empty haystacks, the maximum value is haystack.len() - 1.

+

Trait Implementations§

source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/sidebar-items.js b/memchr/arch/all/sidebar-items.js new file mode 100644 index 000000000..5f7c31083 --- /dev/null +++ b/memchr/arch/all/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["is_equal","is_equal_raw","is_prefix","is_suffix"],"mod":["memchr","packedpair","rabinkarp","shiftor","twoway"]}; \ No newline at end of file diff --git a/memchr/arch/all/twoway/index.html b/memchr/arch/all/twoway/index.html new file mode 100644 index 000000000..03b60d5b6 --- /dev/null +++ b/memchr/arch/all/twoway/index.html @@ -0,0 +1,17 @@ +memchr::arch::all::twoway - Rust

Module memchr::arch::all::twoway

source ·
Expand description

An implementation of the Two-Way substring search algorithm.

+

Finder can be built for forward searches, while FinderRev can be built +for reverse searches.

+

Two-Way makes for a nice general purpose substring search algorithm because of +its time and space complexity properties. It also performs well in practice. +Namely, with m = len(needle) and n = len(haystack), Two-Way takes O(m) +time to create a finder, O(1) space and O(n) search time. In other words, +the preprocessing step is quick, doesn’t require any heap memory and the worst +case search time is guaranteed to be linear in the haystack regardless of the +size of the needle.

+

While vector algorithms will usually beat Two-Way handedly, vector algorithms +also usually have pathological or edge cases that are better handled by Two-Way. +Moreover, not all targets support vector algorithms or implementations for them +simply may not exist yet.

+

Two-Way can be found in the memmem implementations in at least GNU libc and +musl.

+

Structs

  • A forward substring searcher that uses the Two-Way algorithm.
  • A reverse substring searcher that uses the Two-Way algorithm.
\ No newline at end of file diff --git a/memchr/arch/all/twoway/sidebar-items.js b/memchr/arch/all/twoway/sidebar-items.js new file mode 100644 index 000000000..6a8d46366 --- /dev/null +++ b/memchr/arch/all/twoway/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder","FinderRev"]}; \ No newline at end of file diff --git a/memchr/arch/all/twoway/struct.Finder.html b/memchr/arch/all/twoway/struct.Finder.html new file mode 100644 index 000000000..fc536d97c --- /dev/null +++ b/memchr/arch/all/twoway/struct.Finder.html @@ -0,0 +1,22 @@ +Finder in memchr::arch::all::twoway - Rust

Struct memchr::arch::all::twoway::Finder

source ·
pub struct Finder(/* private fields */);
Expand description

A forward substring searcher that uses the Two-Way algorithm.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Finder

Create a searcher that finds occurrences of the given needle.

+

An empty needle results in a match at every position in a haystack, +including at haystack.len().

+
source

pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Returns the first occurrence of needle in the given haystack, or +None if no such occurrence could be found.

+

The needle given must be the same as the needle provided to +Finder::new.

+

An empty needle results in a match at every position in a haystack, +including at haystack.len().

+

Trait Implementations§

source§

impl Clone for Finder

source§

fn clone(&self) -> Finder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Finder

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/all/twoway/struct.FinderRev.html b/memchr/arch/all/twoway/struct.FinderRev.html new file mode 100644 index 000000000..707e5ab8f --- /dev/null +++ b/memchr/arch/all/twoway/struct.FinderRev.html @@ -0,0 +1,22 @@ +FinderRev in memchr::arch::all::twoway - Rust

Struct memchr::arch::all::twoway::FinderRev

source ·
pub struct FinderRev(/* private fields */);
Expand description

A reverse substring searcher that uses the Two-Way algorithm.

+

Implementations§

source§

impl FinderRev

source

pub fn new(needle: &[u8]) -> FinderRev

Create a searcher that finds occurrences of the given needle.

+

An empty needle results in a match at every position in a haystack, +including at haystack.len().

+
source

pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Returns the last occurrence of needle in the given haystack, or +None if no such occurrence could be found.

+

The needle given must be the same as the needle provided to +FinderRev::new.

+

An empty needle results in a match at every position in a haystack, +including at haystack.len().

+

Trait Implementations§

source§

impl Clone for FinderRev

source§

fn clone(&self) -> FinderRev

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FinderRev

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for FinderRev

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/index.html b/memchr/arch/index.html new file mode 100644 index 000000000..93d1514de --- /dev/null +++ b/memchr/arch/index.html @@ -0,0 +1,4 @@ +memchr::arch - Rust

Module memchr::arch

source ·
Expand description

A module with low-level architecture dependent routines.

+

These routines are useful as primitives for tasks not covered by the higher +level crate API.

+

Modules

  • Contains architecture independent routines.
  • Vector algorithms for the x86_64 target.
\ No newline at end of file diff --git a/memchr/arch/sidebar-items.js b/memchr/arch/sidebar-items.js new file mode 100644 index 000000000..1bdc9066d --- /dev/null +++ b/memchr/arch/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["all","x86_64"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/index.html b/memchr/arch/x86_64/avx2/index.html new file mode 100644 index 000000000..017bb37c7 --- /dev/null +++ b/memchr/arch/x86_64/avx2/index.html @@ -0,0 +1,2 @@ +memchr::arch::x86_64::avx2 - Rust

Module memchr::arch::x86_64::avx2

source ·
Expand description

Algorithms for the x86_64 target using 256-bit vectors via AVX2.

+

Modules

  • This module defines 256-bit vector implementations of memchr and friends.
  • A 256-bit vector implementation of the “packed pair” SIMD algorithm.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/index.html b/memchr/arch/x86_64/avx2/memchr/index.html new file mode 100644 index 000000000..42d441883 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/index.html @@ -0,0 +1,17 @@ +memchr::arch::x86_64::avx2::memchr - Rust

Module memchr::arch::x86_64::avx2::memchr

source ·
Expand description

This module defines 256-bit vector implementations of memchr and friends.

+

The main types in this module are One, Two and Three. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task.

+

The One searcher also provides a One::count routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using One::find repeatedly. (OneIter specializes its +Iterator::count implementation to use this routine.)

+

Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it’s +probably (but not necessarily) better to just use a simple [bool; 256] array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency.

+

Structs

  • Finds all occurrences of a single byte in a haystack.
  • An iterator over all occurrences of a single byte in a haystack.
  • Finds all occurrences of three bytes in a haystack.
  • An iterator over all occurrences of three possible bytes in a haystack.
  • Finds all occurrences of two bytes in a haystack.
  • An iterator over all occurrences of two possible bytes in a haystack.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/sidebar-items.js b/memchr/arch/x86_64/avx2/memchr/sidebar-items.js new file mode 100644 index 000000000..9e7b0311e --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["One","OneIter","Three","ThreeIter","Two","TwoIter"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.One.html b/memchr/arch/x86_64/avx2/memchr/struct.One.html new file mode 100644 index 000000000..e06955d51 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.One.html @@ -0,0 +1,115 @@ +One in memchr::arch::x86_64::avx2::memchr - Rust

Struct memchr::arch::x86_64::avx2::memchr::One

source ·
pub struct One { /* private fields */ }
Expand description

Finds all occurrences of a single byte in a haystack.

+

Implementations§

source§

impl One

source

pub fn new(needle: u8) -> Option<One>

Create a new searcher that finds occurrences of the needle byte given.

+

This particular searcher is specialized to use AVX2 vector instructions +that typically make it quite fast. (SSE2 is used for haystacks that +are too short to accommodate an AVX2 vector.)

+

If either SSE2 or AVX2 is unavailable in the current environment, then +None is returned.

+
source

pub unsafe fn new_unchecked(needle: u8) -> One

Available on target features sse2 and avx2 only.

Create a new finder specific to AVX2 vectors and routines without +checking that either SSE2 or AVX2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute both sse2 and +avx2 instructions in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that One::new will return +a Some value. Similarly, when it is false, it is guaranteed that +One::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn count(&self, haystack: &[u8]) -> usize

Counts all occurrences of this byte in the given haystack.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize

Counts all occurrences of this byte in the given haystack represented +by raw pointers.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, 0 will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h>

Returns an iterator over all occurrences of the needle byte in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for One

source§

fn clone(&self) -> One

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for One

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for One

Auto Trait Implementations§

§

impl RefUnwindSafe for One

§

impl Send for One

§

impl Sync for One

§

impl Unpin for One

§

impl UnwindSafe for One

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.OneIter.html b/memchr/arch/x86_64/avx2/memchr/struct.OneIter.html new file mode 100644 index 000000000..ab4bc7638 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.OneIter.html @@ -0,0 +1,214 @@ +OneIter in memchr::arch::x86_64::avx2::memchr - Rust

Struct memchr::arch::x86_64::avx2::memchr::OneIter

source ·
pub struct OneIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of a single byte in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the One::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying One searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for OneIter<'a, 'h>

source§

fn clone(&self) -> OneIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for OneIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for OneIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for OneIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>

§

impl<'a, 'h> Send for OneIter<'a, 'h>

§

impl<'a, 'h> Sync for OneIter<'a, 'h>

§

impl<'a, 'h> Unpin for OneIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.Three.html b/memchr/arch/x86_64/avx2/memchr/struct.Three.html new file mode 100644 index 000000000..089d08163 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.Three.html @@ -0,0 +1,98 @@ +Three in memchr::arch::x86_64::avx2::memchr - Rust

Struct memchr::arch::x86_64::avx2::memchr::Three

source ·
pub struct Three { /* private fields */ }
Expand description

Finds all occurrences of three bytes in a haystack.

+

That is, this reports matches of one of three possible bytes. For example, +searching for a, b or o in afoobar would report matches at offsets +0, 2, 3, 4 and 5.

+

Implementations§

source§

impl Three

source

pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option<Three>

Create a new searcher that finds occurrences of the needle bytes given.

+

This particular searcher is specialized to use AVX2 vector instructions +that typically make it quite fast. (SSE2 is used for haystacks that +are too short to accommodate an AVX2 vector.)

+

If either SSE2 or AVX2 is unavailable in the current environment, then +None is returned.

+
source

pub unsafe fn new_unchecked(needle1: u8, needle2: u8, needle3: u8) -> Three

Available on target features sse2 and avx2 only.

Create a new finder specific to AVX2 vectors and routines without +checking that either SSE2 or AVX2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute both sse2 and +avx2 instructions in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Three::new will return +a Some value. Similarly, when it is false, it is guaranteed that +Three::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h>

Returns an iterator over all occurrences of the needle bytes in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Three

source§

fn clone(&self) -> Three

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Three

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Three

Auto Trait Implementations§

§

impl RefUnwindSafe for Three

§

impl Send for Three

§

impl Sync for Three

§

impl Unpin for Three

§

impl UnwindSafe for Three

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.ThreeIter.html b/memchr/arch/x86_64/avx2/memchr/struct.ThreeIter.html new file mode 100644 index 000000000..04e2a8824 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.ThreeIter.html @@ -0,0 +1,215 @@ +ThreeIter in memchr::arch::x86_64::avx2::memchr - Rust
pub struct ThreeIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of three possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Three::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Three searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for ThreeIter<'a, 'h>

source§

fn clone(&self) -> ThreeIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for ThreeIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for ThreeIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for ThreeIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>

§

impl<'a, 'h> Send for ThreeIter<'a, 'h>

§

impl<'a, 'h> Sync for ThreeIter<'a, 'h>

§

impl<'a, 'h> Unpin for ThreeIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.Two.html b/memchr/arch/x86_64/avx2/memchr/struct.Two.html new file mode 100644 index 000000000..9cbec9de5 --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.Two.html @@ -0,0 +1,98 @@ +Two in memchr::arch::x86_64::avx2::memchr - Rust

Struct memchr::arch::x86_64::avx2::memchr::Two

source ·
pub struct Two { /* private fields */ }
Expand description

Finds all occurrences of two bytes in a haystack.

+

That is, this reports matches of one of two possible bytes. For example, +searching for a or b in afoobar would report matches at offsets 0, +4 and 5.

+

Implementations§

source§

impl Two

source

pub fn new(needle1: u8, needle2: u8) -> Option<Two>

Create a new searcher that finds occurrences of the needle bytes given.

+

This particular searcher is specialized to use AVX2 vector instructions +that typically make it quite fast. (SSE2 is used for haystacks that +are too short to accommodate an AVX2 vector.)

+

If either SSE2 or AVX2 is unavailable in the current environment, then +None is returned.

+
source

pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two

Available on target features sse2 and avx2 only.

Create a new finder specific to AVX2 vectors and routines without +checking that either SSE2 or AVX2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute both sse2 and +avx2 instructions in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Two::new will return +a Some value. Similarly, when it is false, it is guaranteed that +Two::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h>

Returns an iterator over all occurrences of the needle bytes in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Two

source§

fn clone(&self) -> Two

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Two

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Two

Auto Trait Implementations§

§

impl RefUnwindSafe for Two

§

impl Send for Two

§

impl Sync for Two

§

impl Unpin for Two

§

impl UnwindSafe for Two

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/memchr/struct.TwoIter.html b/memchr/arch/x86_64/avx2/memchr/struct.TwoIter.html new file mode 100644 index 000000000..29728582a --- /dev/null +++ b/memchr/arch/x86_64/avx2/memchr/struct.TwoIter.html @@ -0,0 +1,215 @@ +TwoIter in memchr::arch::x86_64::avx2::memchr - Rust

Struct memchr::arch::x86_64::avx2::memchr::TwoIter

source ·
pub struct TwoIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of two possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Two::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Two searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for TwoIter<'a, 'h>

source§

fn clone(&self) -> TwoIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for TwoIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for TwoIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for TwoIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>

§

impl<'a, 'h> Send for TwoIter<'a, 'h>

§

impl<'a, 'h> Sync for TwoIter<'a, 'h>

§

impl<'a, 'h> Unpin for TwoIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/packedpair/index.html b/memchr/arch/x86_64/avx2/packedpair/index.html new file mode 100644 index 000000000..cdf8dec59 --- /dev/null +++ b/memchr/arch/x86_64/avx2/packedpair/index.html @@ -0,0 +1,5 @@ +memchr::arch::x86_64::avx2::packedpair - Rust

Module memchr::arch::x86_64::avx2::packedpair

source ·
Expand description

A 256-bit vector implementation of the “packed pair” SIMD algorithm.

+

The “packed pair” algorithm is based on the generic SIMD algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for.

+

Structs

  • A “packed pair” finder that uses 256-bit vector operations.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/packedpair/sidebar-items.js b/memchr/arch/x86_64/avx2/packedpair/sidebar-items.js new file mode 100644 index 000000000..9d56366c5 --- /dev/null +++ b/memchr/arch/x86_64/avx2/packedpair/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/packedpair/struct.Finder.html b/memchr/arch/x86_64/avx2/packedpair/struct.Finder.html new file mode 100644 index 000000000..8029970a2 --- /dev/null +++ b/memchr/arch/x86_64/avx2/packedpair/struct.Finder.html @@ -0,0 +1,56 @@ +Finder in memchr::arch::x86_64::avx2::packedpair - Rust
pub struct Finder { /* private fields */ }
Expand description

A “packed pair” finder that uses 256-bit vector operations.

+

This finder picks two bytes that it believes have high predictive power +for indicating an overall match of a needle. Depending on whether +Finder::find or Finder::find_prefilter is used, it reports offsets +where the needle matches or could match. In the prefilter case, candidates +are reported whenever the Pair of bytes given matches.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Option<Finder>

Create a new pair searcher. The searcher returned can either report +exact matches of needle or act as a prefilter and report candidate +positions of needle.

+

If AVX2 is unavailable in the current environment or if a Pair +could not be constructed from the needle given, then None is +returned.

+
source

pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder>

Create a new “packed pair” finder using the pair of bytes given.

+

This constructor permits callers to control precisely which pair of +bytes is used as a predicate.

+

If AVX2 is unavailable in the current environment, then None is +returned.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Finder::with_pair will +return a Some value. Similarly, when it is false, it is guaranteed +that Finder::with_pair will return a None value. Notice that this +does not guarantee that Finder::new will return a Finder. Namely, +even when Finder::is_available is true, it is not guaranteed that a +valid Pair can be found from the needle given.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Execute a search using AVX2 vectors and routines.

+
Panics
+

When haystack.len() is less than Finder::min_haystack_len.

+
source

pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize>

Run this finder on the given haystack as a prefilter.

+

If a candidate match is found, then an offset where the needle could +begin in the haystack is returned.

+
Panics
+

When haystack.len() is less than Finder::min_haystack_len.

+
source

pub fn pair(&self) -> &Pair

Returns the pair of offsets (into the needle) used to check as a +predicate before confirming whether a needle exists at a particular +position.

+
source

pub fn min_haystack_len(&self) -> usize

Returns the minimum haystack length that this Finder can search.

+

Using a haystack with length smaller than this in a search will result +in a panic. The reason for this restriction is that this finder is +meant to be a low-level component that is part of a larger substring +strategy. In that sense, it avoids trying to handle all cases and +instead only handles the cases that it can handle very well.

+

Trait Implementations§

source§

impl Clone for Finder

source§

fn clone(&self) -> Finder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Finder

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/avx2/sidebar-items.js b/memchr/arch/x86_64/avx2/sidebar-items.js new file mode 100644 index 000000000..1d6b803bd --- /dev/null +++ b/memchr/arch/x86_64/avx2/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["memchr","packedpair"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/index.html b/memchr/arch/x86_64/index.html new file mode 100644 index 000000000..6a91fa0b2 --- /dev/null +++ b/memchr/arch/x86_64/index.html @@ -0,0 +1,2 @@ +memchr::arch::x86_64 - Rust

Module memchr::arch::x86_64

source ·
Expand description

Vector algorithms for the x86_64 target.

+

Modules

  • Algorithms for the x86_64 target using 256-bit vectors via AVX2.
  • Algorithms for the x86_64 target using 128-bit vectors via SSE2.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sidebar-items.js b/memchr/arch/x86_64/sidebar-items.js new file mode 100644 index 000000000..b4b9df1dc --- /dev/null +++ b/memchr/arch/x86_64/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["avx2","sse2"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/index.html b/memchr/arch/x86_64/sse2/index.html new file mode 100644 index 000000000..2a57eddf5 --- /dev/null +++ b/memchr/arch/x86_64/sse2/index.html @@ -0,0 +1,2 @@ +memchr::arch::x86_64::sse2 - Rust

Module memchr::arch::x86_64::sse2

source ·
Expand description

Algorithms for the x86_64 target using 128-bit vectors via SSE2.

+

Modules

  • This module defines 128-bit vector implementations of memchr and friends.
  • A 128-bit vector implementation of the “packed pair” SIMD algorithm.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/index.html b/memchr/arch/x86_64/sse2/memchr/index.html new file mode 100644 index 000000000..5ce82c7ca --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/index.html @@ -0,0 +1,17 @@ +memchr::arch::x86_64::sse2::memchr - Rust

Module memchr::arch::x86_64::sse2::memchr

source ·
Expand description

This module defines 128-bit vector implementations of memchr and friends.

+

The main types in this module are One, Two and Three. They are for +searching for one, two or three distinct bytes, respectively, in a haystack. +Each type also has corresponding double ended iterators. These searchers are +typically much faster than scalar routines accomplishing the same task.

+

The One searcher also provides a One::count routine for efficiently +counting the number of times a single byte occurs in a haystack. This is +useful, for example, for counting the number of lines in a haystack. This +routine exists because it is usually faster, especially with a high match +count, then using One::find repeatedly. (OneIter specializes its +Iterator::count implementation to use this routine.)

+

Only one, two and three bytes are supported because three bytes is about +the point where one sees diminishing returns. Beyond this point and it’s +probably (but not necessarily) better to just use a simple [bool; 256] array +or similar. However, it depends mightily on the specific work-load and the +expected match frequency.

+

Structs

  • Finds all occurrences of a single byte in a haystack.
  • An iterator over all occurrences of a single byte in a haystack.
  • Finds all occurrences of three bytes in a haystack.
  • An iterator over all occurrences of three possible bytes in a haystack.
  • Finds all occurrences of two bytes in a haystack.
  • An iterator over all occurrences of two possible bytes in a haystack.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/sidebar-items.js b/memchr/arch/x86_64/sse2/memchr/sidebar-items.js new file mode 100644 index 000000000..9e7b0311e --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["One","OneIter","Three","ThreeIter","Two","TwoIter"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.One.html b/memchr/arch/x86_64/sse2/memchr/struct.One.html new file mode 100644 index 000000000..7afb20890 --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.One.html @@ -0,0 +1,114 @@ +One in memchr::arch::x86_64::sse2::memchr - Rust

Struct memchr::arch::x86_64::sse2::memchr::One

source ·
pub struct One(/* private fields */);
Expand description

Finds all occurrences of a single byte in a haystack.

+

Implementations§

source§

impl One

source

pub fn new(needle: u8) -> Option<One>

Create a new searcher that finds occurrences of the needle byte given.

+

This particular searcher is specialized to use SSE2 vector instructions +that typically make it quite fast.

+

If SSE2 is unavailable in the current environment, then None is +returned.

+
source

pub unsafe fn new_unchecked(needle: u8) -> One

Available with target feature sse2 only.

Create a new finder specific to SSE2 vectors and routines without +checking that SSE2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute sse2 instructions +in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that One::new will return +a Some value. Similarly, when it is false, it is guaranteed that +One::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn count(&self, haystack: &[u8]) -> usize

Counts all occurrences of this byte in the given haystack.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize

Counts all occurrences of this byte in the given haystack represented +by raw pointers.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, 0 will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h>

Returns an iterator over all occurrences of the needle byte in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for One

source§

fn clone(&self) -> One

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for One

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for One

Auto Trait Implementations§

§

impl RefUnwindSafe for One

§

impl Send for One

§

impl Sync for One

§

impl Unpin for One

§

impl UnwindSafe for One

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.OneIter.html b/memchr/arch/x86_64/sse2/memchr/struct.OneIter.html new file mode 100644 index 000000000..d47bdb361 --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.OneIter.html @@ -0,0 +1,214 @@ +OneIter in memchr::arch::x86_64::sse2::memchr - Rust

Struct memchr::arch::x86_64::sse2::memchr::OneIter

source ·
pub struct OneIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of a single byte in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the One::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying One searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for OneIter<'a, 'h>

source§

fn clone(&self) -> OneIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for OneIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for OneIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for OneIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for OneIter<'a, 'h>

§

impl<'a, 'h> Send for OneIter<'a, 'h>

§

impl<'a, 'h> Sync for OneIter<'a, 'h>

§

impl<'a, 'h> Unpin for OneIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for OneIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.Three.html b/memchr/arch/x86_64/sse2/memchr/struct.Three.html new file mode 100644 index 000000000..71727b321 --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.Three.html @@ -0,0 +1,97 @@ +Three in memchr::arch::x86_64::sse2::memchr - Rust

Struct memchr::arch::x86_64::sse2::memchr::Three

source ·
pub struct Three(/* private fields */);
Expand description

Finds all occurrences of three bytes in a haystack.

+

That is, this reports matches of one of three possible bytes. For example, +searching for a, b or o in afoobar would report matches at offsets +0, 2, 3, 4 and 5.

+

Implementations§

source§

impl Three

source

pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option<Three>

Create a new searcher that finds occurrences of the needle bytes given.

+

This particular searcher is specialized to use SSE2 vector instructions +that typically make it quite fast.

+

If SSE2 is unavailable in the current environment, then None is +returned.

+
source

pub unsafe fn new_unchecked(needle1: u8, needle2: u8, needle3: u8) -> Three

Available with target feature sse2 only.

Create a new finder specific to SSE2 vectors and routines without +checking that SSE2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute sse2 instructions +in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Three::new will return +a Some value. Similarly, when it is false, it is guaranteed that +Three::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h>

Returns an iterator over all occurrences of the needle byte in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Three

source§

fn clone(&self) -> Three

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Three

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Three

Auto Trait Implementations§

§

impl RefUnwindSafe for Three

§

impl Send for Three

§

impl Sync for Three

§

impl Unpin for Three

§

impl UnwindSafe for Three

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.ThreeIter.html b/memchr/arch/x86_64/sse2/memchr/struct.ThreeIter.html new file mode 100644 index 000000000..0b1bec3a4 --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.ThreeIter.html @@ -0,0 +1,215 @@ +ThreeIter in memchr::arch::x86_64::sse2::memchr - Rust
pub struct ThreeIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of three possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Three::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Three searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for ThreeIter<'a, 'h>

source§

fn clone(&self) -> ThreeIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for ThreeIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for ThreeIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for ThreeIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for ThreeIter<'a, 'h>

§

impl<'a, 'h> Send for ThreeIter<'a, 'h>

§

impl<'a, 'h> Sync for ThreeIter<'a, 'h>

§

impl<'a, 'h> Unpin for ThreeIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for ThreeIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.Two.html b/memchr/arch/x86_64/sse2/memchr/struct.Two.html new file mode 100644 index 000000000..ba440fe3e --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.Two.html @@ -0,0 +1,97 @@ +Two in memchr::arch::x86_64::sse2::memchr - Rust

Struct memchr::arch::x86_64::sse2::memchr::Two

source ·
pub struct Two(/* private fields */);
Expand description

Finds all occurrences of two bytes in a haystack.

+

That is, this reports matches of one of two possible bytes. For example, +searching for a or b in afoobar would report matches at offsets 0, +4 and 5.

+

Implementations§

source§

impl Two

source

pub fn new(needle1: u8, needle2: u8) -> Option<Two>

Create a new searcher that finds occurrences of the needle bytes given.

+

This particular searcher is specialized to use SSE2 vector instructions +that typically make it quite fast.

+

If SSE2 is unavailable in the current environment, then None is +returned.

+
source

pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two

Available with target feature sse2 only.

Create a new finder specific to SSE2 vectors and routines without +checking that SSE2 is available.

+
Safety
+

Callers must guarantee that it is safe to execute sse2 instructions +in the current environment.

+

Note that it is a common misconception that if one compiles for an +x86_64 target, then they therefore automatically have access to SSE2 +instructions. While this is almost always the case, it isn’t true in +100% of cases.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Two::new will return +a Some value. Similarly, when it is false, it is guaranteed that +Two::new will return a None value.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Return the first occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub fn rfind(&self, haystack: &[u8]) -> Option<usize>

Return the last occurrence of one of the needle bytes in the given +haystack. If no such occurrence exists, then None is returned.

+

The occurrence is reported as an offset into haystack. Its maximum +value is haystack.len() - 1.

+
source

pub unsafe fn find_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like find, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub unsafe fn rfind_raw( + &self, + start: *const u8, + end: *const u8 +) -> Option<*const u8>

Like rfind, but accepts and returns raw pointers.

+

When a match is found, the pointer returned is guaranteed to be +>= start and < end.

+

This routine is useful if you’re already using raw pointers and would +like to avoid converting back to a slice before executing a search.

+
Safety
+
    +
  • Both start and end must be valid for reads.
  • +
  • Both start and end must point to an initialized value.
  • +
  • Both start and end must point to the same allocated object and +must either be in bounds or at most one byte past the end of the +allocated object.
  • +
  • Both start and end must be derived from a pointer to the same +object.
  • +
  • The distance between start and end must not overflow isize.
  • +
  • The distance being in bounds must not rely on “wrapping around” the +address space.
  • +
+

Note that callers may pass a pair of pointers such that start >= end. +In that case, None will always be returned.

+
source

pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h>

Returns an iterator over all occurrences of the needle bytes in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl Clone for Two

source§

fn clone(&self) -> Two

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Two

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Two

Auto Trait Implementations§

§

impl RefUnwindSafe for Two

§

impl Send for Two

§

impl Sync for Two

§

impl Unpin for Two

§

impl UnwindSafe for Two

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/memchr/struct.TwoIter.html b/memchr/arch/x86_64/sse2/memchr/struct.TwoIter.html new file mode 100644 index 000000000..f2d650196 --- /dev/null +++ b/memchr/arch/x86_64/sse2/memchr/struct.TwoIter.html @@ -0,0 +1,215 @@ +TwoIter in memchr::arch::x86_64::sse2::memchr - Rust

Struct memchr::arch::x86_64::sse2::memchr::TwoIter

source ·
pub struct TwoIter<'a, 'h> { /* private fields */ }
Expand description

An iterator over all occurrences of two possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the Two::iter method.

+

The lifetime parameters are as follows:

+
    +
  • 'a refers to the lifetime of the underlying Two searcher.
  • +
  • 'h refers to the lifetime of the haystack being searched.
  • +
+

Trait Implementations§

source§

impl<'a, 'h> Clone for TwoIter<'a, 'h>

source§

fn clone(&self) -> TwoIter<'a, 'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, 'h> Debug for TwoIter<'a, 'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'a, 'h> Iterator for TwoIter<'a, 'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a, 'h> FusedIterator for TwoIter<'a, 'h>

Auto Trait Implementations§

§

impl<'a, 'h> RefUnwindSafe for TwoIter<'a, 'h>

§

impl<'a, 'h> Send for TwoIter<'a, 'h>

§

impl<'a, 'h> Sync for TwoIter<'a, 'h>

§

impl<'a, 'h> Unpin for TwoIter<'a, 'h>

§

impl<'a, 'h> UnwindSafe for TwoIter<'a, 'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/packedpair/index.html b/memchr/arch/x86_64/sse2/packedpair/index.html new file mode 100644 index 000000000..59bcd1c01 --- /dev/null +++ b/memchr/arch/x86_64/sse2/packedpair/index.html @@ -0,0 +1,5 @@ +memchr::arch::x86_64::sse2::packedpair - Rust

Module memchr::arch::x86_64::sse2::packedpair

source ·
Expand description

A 128-bit vector implementation of the “packed pair” SIMD algorithm.

+

The “packed pair” algorithm is based on the generic SIMD algorithm. The main +difference is that it (by default) uses a background distribution of byte +frequencies to heuristically select the pair of bytes to search for.

+

Structs

  • A “packed pair” finder that uses 128-bit vector operations.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/packedpair/sidebar-items.js b/memchr/arch/x86_64/sse2/packedpair/sidebar-items.js new file mode 100644 index 000000000..9d56366c5 --- /dev/null +++ b/memchr/arch/x86_64/sse2/packedpair/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Finder"]}; \ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/packedpair/struct.Finder.html b/memchr/arch/x86_64/sse2/packedpair/struct.Finder.html new file mode 100644 index 000000000..5807031f1 --- /dev/null +++ b/memchr/arch/x86_64/sse2/packedpair/struct.Finder.html @@ -0,0 +1,56 @@ +Finder in memchr::arch::x86_64::sse2::packedpair - Rust
pub struct Finder(/* private fields */);
Expand description

A “packed pair” finder that uses 128-bit vector operations.

+

This finder picks two bytes that it believes have high predictive power +for indicating an overall match of a needle. Depending on whether +Finder::find or Finder::find_prefilter is used, it reports offsets +where the needle matches or could match. In the prefilter case, candidates +are reported whenever the Pair of bytes given matches.

+

Implementations§

source§

impl Finder

source

pub fn new(needle: &[u8]) -> Option<Finder>

Create a new pair searcher. The searcher returned can either report +exact matches of needle or act as a prefilter and report candidate +positions of needle.

+

If SSE2 is unavailable in the current environment or if a Pair +could not be constructed from the needle given, then None is +returned.

+
source

pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder>

Create a new “packed pair” finder using the pair of bytes given.

+

This constructor permits callers to control precisely which pair of +bytes is used as a predicate.

+

If SSE2 is unavailable in the current environment, then None is +returned.

+
source

pub fn is_available() -> bool

Returns true when this implementation is available in the current +environment.

+

When this is true, it is guaranteed that Finder::with_pair will +return a Some value. Similarly, when it is false, it is guaranteed +that Finder::with_pair will return a None value. Notice that this +does not guarantee that Finder::new will return a Finder. Namely, +even when Finder::is_available is true, it is not guaranteed that a +valid Pair can be found from the needle given.

+

Note also that for the lifetime of a single program, if this returns +true then it will always return true.

+
source

pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize>

Execute a search using SSE2 vectors and routines.

+
Panics
+

When haystack.len() is less than Finder::min_haystack_len.

+
source

pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize>

Run this finder on the given haystack as a prefilter.

+

If a candidate match is found, then an offset where the needle could +begin in the haystack is returned.

+
Panics
+

When haystack.len() is less than Finder::min_haystack_len.

+
source

pub fn pair(&self) -> &Pair

Returns the pair of offsets (into the needle) used to check as a +predicate before confirming whether a needle exists at a particular +position.

+
source

pub fn min_haystack_len(&self) -> usize

Returns the minimum haystack length that this Finder can search.

+

Using a haystack with length smaller than this in a search will result +in a panic. The reason for this restriction is that this finder is +meant to be a low-level component that is part of a larger substring +strategy. In that sense, it avoids trying to handle all cases and +instead only handles the cases that it can handle very well.

+

Trait Implementations§

source§

impl Clone for Finder

source§

fn clone(&self) -> Finder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Finder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Finder

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/arch/x86_64/sse2/sidebar-items.js b/memchr/arch/x86_64/sse2/sidebar-items.js new file mode 100644 index 000000000..1d6b803bd --- /dev/null +++ b/memchr/arch/x86_64/sse2/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["memchr","packedpair"]}; \ No newline at end of file diff --git a/memchr/fn.memchr.html b/memchr/fn.memchr.html new file mode 100644 index 000000000..531d93525 --- /dev/null +++ b/memchr/fn.memchr.html @@ -0,0 +1,16 @@ +memchr in memchr - Rust

Function memchr::memchr

source ·
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize>
Expand description

Search for the first occurrence of a byte in a slice.

+

This returns the index corresponding to the first occurrence of needle in +haystack, or None if one is not found. If an index is returned, it is +guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().position(|&b| b == needle), this routine will attempt to +use highly optimized vector operations that can be an order of magnitude +faster (or more).

+

Example

+

This shows how to find the first position of a byte in a byte string.

+ +
use memchr::memchr;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memchr(b'k', haystack), Some(8));
+
\ No newline at end of file diff --git a/memchr/fn.memchr2.html b/memchr/fn.memchr2.html new file mode 100644 index 000000000..f9c57280e --- /dev/null +++ b/memchr/fn.memchr2.html @@ -0,0 +1,17 @@ +memchr2 in memchr - Rust

Function memchr::memchr2

source ·
pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize>
Expand description

Search for the first occurrence of two possible bytes in a haystack.

+

This returns the index corresponding to the first occurrence of one of the +needle bytes in haystack, or None if one is not found. If an index is +returned, it is guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().position(|&b| b == needle1 || b == needle2), this routine +will attempt to use highly optimized vector operations that can be an order +of magnitude faster (or more).

+

Example

+

This shows how to find the first position of one of two possible bytes in a +haystack.

+ +
use memchr::memchr2;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memchr2(b'k', b'q', haystack), Some(4));
+
\ No newline at end of file diff --git a/memchr/fn.memchr2_iter.html b/memchr/fn.memchr2_iter.html new file mode 100644 index 000000000..3ea100d52 --- /dev/null +++ b/memchr/fn.memchr2_iter.html @@ -0,0 +1,8 @@ +memchr2_iter in memchr - Rust

Function memchr::memchr2_iter

source ·
pub fn memchr2_iter<'h>(
+    needle1: u8,
+    needle2: u8,
+    haystack: &'h [u8]
+) -> Memchr2<'h> 
Expand description

Returns an iterator over all occurrences of the needles in a haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+
\ No newline at end of file diff --git a/memchr/fn.memchr3.html b/memchr/fn.memchr3.html new file mode 100644 index 000000000..81bd0f506 --- /dev/null +++ b/memchr/fn.memchr3.html @@ -0,0 +1,22 @@ +memchr3 in memchr - Rust

Function memchr::memchr3

source ·
pub fn memchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8]
+) -> Option<usize>
Expand description

Search for the first occurrence of three possible bytes in a haystack.

+

This returns the index corresponding to the first occurrence of one of the +needle bytes in haystack, or None if one is not found. If an index is +returned, it is guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().position(|&b| b == needle1 || b == needle2 || b == needle3), +this routine will attempt to use highly optimized vector operations that +can be an order of magnitude faster (or more).

+

Example

+

This shows how to find the first position of one of three possible bytes in +a haystack.

+ +
use memchr::memchr3;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memchr3(b'k', b'q', b'u', haystack), Some(4));
+
\ No newline at end of file diff --git a/memchr/fn.memchr3_iter.html b/memchr/fn.memchr3_iter.html new file mode 100644 index 000000000..56efdc5be --- /dev/null +++ b/memchr/fn.memchr3_iter.html @@ -0,0 +1,9 @@ +memchr3_iter in memchr - Rust

Function memchr::memchr3_iter

source ·
pub fn memchr3_iter<'h>(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &'h [u8]
+) -> Memchr3<'h> 
Expand description

Returns an iterator over all occurrences of the needles in a haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+
\ No newline at end of file diff --git a/memchr/fn.memchr_iter.html b/memchr/fn.memchr_iter.html new file mode 100644 index 000000000..17ddbbbbd --- /dev/null +++ b/memchr/fn.memchr_iter.html @@ -0,0 +1,4 @@ +memchr_iter in memchr - Rust

Function memchr::memchr_iter

source ·
pub fn memchr_iter<'h>(needle: u8, haystack: &'h [u8]) -> Memchr<'h> 
Expand description

Returns an iterator over all occurrences of the needle in a haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+
\ No newline at end of file diff --git a/memchr/fn.memrchr.html b/memchr/fn.memrchr.html new file mode 100644 index 000000000..f584a0c4c --- /dev/null +++ b/memchr/fn.memrchr.html @@ -0,0 +1,16 @@ +memrchr in memchr - Rust

Function memchr::memrchr

source ·
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize>
Expand description

Search for the last occurrence of a byte in a slice.

+

This returns the index corresponding to the last occurrence of needle in +haystack, or None if one is not found. If an index is returned, it is +guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().rposition(|&b| b == needle), this routine will attempt to +use highly optimized vector operations that can be an order of magnitude +faster (or more).

+

Example

+

This shows how to find the last position of a byte in a byte string.

+ +
use memchr::memrchr;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memrchr(b'o', haystack), Some(17));
+
\ No newline at end of file diff --git a/memchr/fn.memrchr2.html b/memchr/fn.memrchr2.html new file mode 100644 index 000000000..43696de7d --- /dev/null +++ b/memchr/fn.memrchr2.html @@ -0,0 +1,17 @@ +memrchr2 in memchr - Rust

Function memchr::memrchr2

source ·
pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize>
Expand description

Search for the last occurrence of two possible bytes in a haystack.

+

This returns the index corresponding to the last occurrence of one of the +needle bytes in haystack, or None if one is not found. If an index is +returned, it is guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().rposition(|&b| b == needle1 || b == needle2), this +routine will attempt to use highly optimized vector operations that can be +an order of magnitude faster (or more).

+

Example

+

This shows how to find the last position of one of two possible bytes in a +haystack.

+ +
use memchr::memrchr2;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memrchr2(b'k', b'o', haystack), Some(17));
+
\ No newline at end of file diff --git a/memchr/fn.memrchr2_iter.html b/memchr/fn.memrchr2_iter.html new file mode 100644 index 000000000..6b7584e0d --- /dev/null +++ b/memchr/fn.memrchr2_iter.html @@ -0,0 +1,7 @@ +memrchr2_iter in memchr - Rust

Function memchr::memrchr2_iter

source ·
pub fn memrchr2_iter(
+    needle1: u8,
+    needle2: u8,
+    haystack: &[u8]
+) -> Rev<Memchr2<'_>>
Expand description

Returns an iterator over all occurrences of the needles in a haystack, in +reverse.

+
\ No newline at end of file diff --git a/memchr/fn.memrchr3.html b/memchr/fn.memrchr3.html new file mode 100644 index 000000000..e9d5c0562 --- /dev/null +++ b/memchr/fn.memrchr3.html @@ -0,0 +1,22 @@ +memrchr3 in memchr - Rust

Function memchr::memrchr3

source ·
pub fn memrchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8]
+) -> Option<usize>
Expand description

Search for the last occurrence of three possible bytes in a haystack.

+

This returns the index corresponding to the last occurrence of one of the +needle bytes in haystack, or None if one is not found. If an index is +returned, it is guaranteed to be less than haystack.len().

+

While this is semantically the same as something like +haystack.iter().rposition(|&b| b == needle1 || b == needle2 || b == needle3), +this routine will attempt to use highly optimized vector operations that +can be an order of magnitude faster (or more).

+

Example

+

This shows how to find the last position of one of three possible bytes in +a haystack.

+ +
use memchr::memrchr3;
+
+let haystack = b"the quick brown fox";
+assert_eq!(memrchr3(b'k', b'o', b'n', haystack), Some(17));
+
\ No newline at end of file diff --git a/memchr/fn.memrchr3_iter.html b/memchr/fn.memrchr3_iter.html new file mode 100644 index 000000000..d5dca5564 --- /dev/null +++ b/memchr/fn.memrchr3_iter.html @@ -0,0 +1,8 @@ +memrchr3_iter in memchr - Rust

Function memchr::memrchr3_iter

source ·
pub fn memrchr3_iter(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8]
+) -> Rev<Memchr3<'_>>
Expand description

Returns an iterator over all occurrences of the needles in a haystack, in +reverse.

+
\ No newline at end of file diff --git a/memchr/fn.memrchr_iter.html b/memchr/fn.memrchr_iter.html new file mode 100644 index 000000000..29ffb506e --- /dev/null +++ b/memchr/fn.memrchr_iter.html @@ -0,0 +1,3 @@ +memrchr_iter in memchr - Rust

Function memchr::memrchr_iter

source ·
pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr<'_>>
Expand description

Returns an iterator over all occurrences of the needle in a haystack, in +reverse.

+
\ No newline at end of file diff --git a/memchr/index.html b/memchr/index.html new file mode 100644 index 000000000..e2717484f --- /dev/null +++ b/memchr/index.html @@ -0,0 +1,143 @@ +memchr - Rust

Crate memchr

source ·
Expand description

This library provides heavily optimized routines for string search primitives.

+

Overview

+

This section gives a brief high level overview of what this crate offers.

+
    +
  • The top-level module provides routines for searching for 1, 2 or 3 bytes +in the forward or reverse direction. When searching for more than one byte, +positions are considered a match if the byte at that position matches any +of the bytes.
  • +
  • The memmem sub-module provides forward and reverse substring search +routines.
  • +
+

In all such cases, routines operate on &[u8] without regard to encoding. This +is exactly what you want when searching either UTF-8 or arbitrary bytes.

+

Example: using memchr

+

This example shows how to use memchr to find the first occurrence of z in +a haystack:

+ +
use memchr::memchr;
+
+let haystack = b"foo bar baz quuz";
+assert_eq!(Some(10), memchr(b'z', haystack));
+

Example: matching one of three possible bytes

+

This examples shows how to use memrchr3 to find occurrences of a, b or +c, starting at the end of the haystack.

+ +
use memchr::memchr3_iter;
+
+let haystack = b"xyzaxyzbxyzc";
+
+let mut it = memchr3_iter(b'a', b'b', b'c', haystack).rev();
+assert_eq!(Some(11), it.next());
+assert_eq!(Some(7), it.next());
+assert_eq!(Some(3), it.next());
+assert_eq!(None, it.next());
+

Example: iterating over substring matches

+

This example shows how to use the memmem sub-module to find occurrences of +a substring in a haystack.

+ +
use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::find_iter(haystack, "foo");
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+

Example: repeating a search for the same needle

+

It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a memmem::Finder:

+ +
use memchr::memmem;
+
+let finder = memmem::Finder::new("foo");
+
+assert_eq!(Some(4), finder.find(b"baz foo quux"));
+assert_eq!(None, finder.find(b"quux baz bar"));
+

Why use this crate?

+

At first glance, the APIs provided by this crate might seem weird. Why provide +a dedicated routine like memchr for something that could be implemented +clearly and trivially in one line:

+ +
fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    haystack.iter().position(|&b| b == needle)
+}
+

Or similarly, why does this crate provide substring search routines when Rust’s +core library already provides them?

+ +
fn search(haystack: &str, needle: &str) -> Option<usize> {
+    haystack.find(needle)
+}
+

The primary reason for both of them to exist is performance. When it comes to +performance, at a high level at least, there are two primary ways to look at +it:

+
    +
  • Throughput: For this, think about it as, “given some very large haystack +and a byte that never occurs in that haystack, how long does it take to +search through it and determine that it, in fact, does not occur?”
  • +
  • Latency: For this, think about it as, “given a tiny haystack—just a +few bytes—how long does it take to determine if a byte is in it?”
  • +
+

The memchr routine in this crate has slightly worse latency than the +solution presented above, however, its throughput can easily be over an +order of magnitude faster. This is a good general purpose trade off to make. +You rarely lose, but often gain big.

+

NOTE: The name memchr comes from the corresponding routine in libc. A +key advantage of using this library is that its performance is not tied to its +quality of implementation in the libc you happen to be using, which can vary +greatly from platform to platform.

+

But what about substring search? This one is a bit more complicated. The +primary reason for its existence is still indeed performance, but it’s also +useful because Rust’s core library doesn’t actually expose any substring +search routine on arbitrary bytes. The only substring search routine that +exists works exclusively on valid UTF-8.

+

So if you have valid UTF-8, is there a reason to use this over the standard +library substring search routine? Yes. This routine is faster on almost every +metric, including latency. The natural question then, is why isn’t this +implementation in the standard library, even if only for searching on UTF-8? +The reason is that the implementation details for using SIMD in the standard +library haven’t quite been worked out yet.

+

NOTE: Currently, only x86_64, wasm32 and aarch64 targets have vector +accelerated implementations of memchr (and friends) and memmem.

+

Crate features

+
    +
  • std - When enabled (the default), this will permit features specific to +the standard library. Currently, the only thing used from the standard library +is runtime SIMD CPU feature detection. This means that this feature must be +enabled to get AVX2 accelerated routines on x86_64 targets without enabling +the avx2 feature at compile time, for example. When std is not enabled, +this crate will still attempt to use SSE2 accelerated routines on x86_64. It +will also use AVX2 accelerated routines when the avx2 feature is enabled at +compile time. In general, enable this feature if you can.
  • +
  • alloc - When enabled (the default), APIs in this crate requiring some +kind of allocation will become available. For example, the +memmem::Finder::into_ownedd API and the +arch::all::shiftor substring search +implementation. Otherwise, this crate is designed from the ground up to be +usable in core-only contexts, so the alloc feature doesn’t add much +currently. Notably, disabling std but enabling alloc will not result +in the use of AVX2 on x86_64 targets unless the avx2 feature is enabled +at compile time. (With std enabled, AVX2 can be used even without the avx2 +feature enabled at compile time by way of runtime CPU feature detection.)
  • +
  • logging - When enabled (disabled by default), the log crate is used +to emit log messages about what kinds of memchr and memmem algorithms +are used. Namely, both memchr and memmem have a number of different +implementation choices depending on the target and CPU, and the log messages +can help show what specific implementations are being used. Generally, this is +useful for debugging performance issues.
  • +
  • libc - DEPRECATED. Previously, this enabled the use of the target’s +memchr function from whatever libc was linked into the program. This +feature is now a no-op because this crate’s implementation of memchr should +now be sufficiently fast on a number of platforms that libc should no longer +be needed. (This feature is somewhat of a holdover from this crate’s origins. +Originally, this crate was literally just a safe wrapper function around the +memchr function from libc.)
  • +
+

Modules

  • A module with low-level architecture dependent routines.
  • This module provides forward and reverse substring search routines.

Structs

  • An iterator over all occurrences of a single byte in a haystack.
  • An iterator over all occurrences of two possible bytes in a haystack.
  • An iterator over all occurrences of three possible bytes in a haystack.

Functions

  • Search for the first occurrence of a byte in a slice.
  • Search for the first occurrence of two possible bytes in a haystack.
  • Returns an iterator over all occurrences of the needles in a haystack.
  • Search for the first occurrence of three possible bytes in a haystack.
  • Returns an iterator over all occurrences of the needles in a haystack.
  • Returns an iterator over all occurrences of the needle in a haystack.
  • Search for the last occurrence of a byte in a slice.
  • Search for the last occurrence of two possible bytes in a haystack.
  • Returns an iterator over all occurrences of the needles in a haystack, in +reverse.
  • Search for the last occurrence of three possible bytes in a haystack.
  • Returns an iterator over all occurrences of the needles in a haystack, in +reverse.
  • Returns an iterator over all occurrences of the needle in a haystack, in +reverse.
\ No newline at end of file diff --git a/memchr/memchr/fn.memchr.html b/memchr/memchr/fn.memchr.html new file mode 100644 index 000000000..080b88fb0 --- /dev/null +++ b/memchr/memchr/fn.memchr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memchr2.html b/memchr/memchr/fn.memchr2.html new file mode 100644 index 000000000..b43634a74 --- /dev/null +++ b/memchr/memchr/fn.memchr2.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr2.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memchr2_iter.html b/memchr/memchr/fn.memchr2_iter.html new file mode 100644 index 000000000..bed40a2a0 --- /dev/null +++ b/memchr/memchr/fn.memchr2_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr2_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memchr3.html b/memchr/memchr/fn.memchr3.html new file mode 100644 index 000000000..275f4bbef --- /dev/null +++ b/memchr/memchr/fn.memchr3.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr3.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memchr3_iter.html b/memchr/memchr/fn.memchr3_iter.html new file mode 100644 index 000000000..dc6d7fa6e --- /dev/null +++ b/memchr/memchr/fn.memchr3_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr3_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memchr_iter.html b/memchr/memchr/fn.memchr_iter.html new file mode 100644 index 000000000..e6424a721 --- /dev/null +++ b/memchr/memchr/fn.memchr_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memchr_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr.html b/memchr/memchr/fn.memrchr.html new file mode 100644 index 000000000..57d98444a --- /dev/null +++ b/memchr/memchr/fn.memrchr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr2.html b/memchr/memchr/fn.memrchr2.html new file mode 100644 index 000000000..ffc1e5875 --- /dev/null +++ b/memchr/memchr/fn.memrchr2.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr2.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr2_iter.html b/memchr/memchr/fn.memrchr2_iter.html new file mode 100644 index 000000000..c80c1ebfa --- /dev/null +++ b/memchr/memchr/fn.memrchr2_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr2_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr3.html b/memchr/memchr/fn.memrchr3.html new file mode 100644 index 000000000..ceb0775d2 --- /dev/null +++ b/memchr/memchr/fn.memrchr3.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr3.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr3_iter.html b/memchr/memchr/fn.memrchr3_iter.html new file mode 100644 index 000000000..781ba508b --- /dev/null +++ b/memchr/memchr/fn.memrchr3_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr3_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/fn.memrchr_iter.html b/memchr/memchr/fn.memrchr_iter.html new file mode 100644 index 000000000..ad5d91a36 --- /dev/null +++ b/memchr/memchr/fn.memrchr_iter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/fn.memrchr_iter.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/struct.Memchr.html b/memchr/memchr/struct.Memchr.html new file mode 100644 index 000000000..b360bbc06 --- /dev/null +++ b/memchr/memchr/struct.Memchr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/struct.Memchr.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/struct.Memchr2.html b/memchr/memchr/struct.Memchr2.html new file mode 100644 index 000000000..7aa16d909 --- /dev/null +++ b/memchr/memchr/struct.Memchr2.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/struct.Memchr2.html...

+ + + \ No newline at end of file diff --git a/memchr/memchr/struct.Memchr3.html b/memchr/memchr/struct.Memchr3.html new file mode 100644 index 000000000..0feeb01a8 --- /dev/null +++ b/memchr/memchr/struct.Memchr3.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../memchr/struct.Memchr3.html...

+ + + \ No newline at end of file diff --git a/memchr/memmem/enum.Prefilter.html b/memchr/memmem/enum.Prefilter.html new file mode 100644 index 000000000..5b1d9645e --- /dev/null +++ b/memchr/memmem/enum.Prefilter.html @@ -0,0 +1,40 @@ +Prefilter in memchr::memmem - Rust

Enum memchr::memmem::Prefilter

source ·
#[non_exhaustive]
pub enum Prefilter { + None, + Auto, +}
Expand description

Prefilter controls whether heuristics are used to accelerate searching.

+

A prefilter refers to the idea of detecting candidate matches very quickly, +and then confirming whether those candidates are full matches. This +idea can be quite effective since it’s often the case that looking for +candidates can be a lot faster than running a complete substring search +over the entire input. Namely, looking for candidates can be done with +extremely fast vectorized code.

+

The downside of a prefilter is that it assumes false positives (which are +candidates generated by a prefilter that aren’t matches) are somewhat rare +relative to the frequency of full matches. That is, if a lot of false +positives are generated, then it’s possible for search time to be worse +than if the prefilter wasn’t enabled in the first place.

+

Another downside of a prefilter is that it can result in highly variable +performance, where some cases are extraordinarily fast and others aren’t. +Typically, variable performance isn’t a problem, but it may be for your use +case.

+

The use of prefilters in this implementation does use a heuristic to detect +when a prefilter might not be carrying its weight, and will dynamically +disable its use. Nevertheless, this configuration option gives callers +the ability to disable prefilters if you have knowledge that they won’t be +useful.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

None

Never used a prefilter in substring search.

+
§

Auto

Automatically detect whether a heuristic prefilter should be used. If +it is used, then heuristics will be used to dynamically disable the +prefilter if it is believed to not be carrying its weight.

+

Trait Implementations§

source§

impl Clone for PrefilterConfig

source§

fn clone(&self) -> PrefilterConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PrefilterConfig

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for PrefilterConfig

source§

fn default() -> PrefilterConfig

Returns the “default value” for a type. Read more
source§

impl Copy for PrefilterConfig

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/memmem/fn.find.html b/memchr/memmem/fn.find.html new file mode 100644 index 000000000..1a716f2d8 --- /dev/null +++ b/memchr/memmem/fn.find.html @@ -0,0 +1,20 @@ +find in memchr::memmem - Rust

Function memchr::memmem::find

source ·
pub fn find(haystack: &[u8], needle: &[u8]) -> Option<usize>
Expand description

Returns the index of the first occurrence of the given needle.

+

Note that if you’re are searching for the same needle in many different +small haystacks, it may be faster to initialize a Finder once, +and reuse it for each search.

+

Complexity

+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+

Examples

+

Basic usage:

+ +
use memchr::memmem;
+
+let haystack = b"foo bar baz";
+assert_eq!(Some(0), memmem::find(haystack, b"foo"));
+assert_eq!(Some(4), memmem::find(haystack, b"bar"));
+assert_eq!(None, memmem::find(haystack, b"quux"));
+
\ No newline at end of file diff --git a/memchr/memmem/fn.find_iter.html b/memchr/memmem/fn.find_iter.html new file mode 100644 index 000000000..15f6f9435 --- /dev/null +++ b/memchr/memmem/fn.find_iter.html @@ -0,0 +1,23 @@ +find_iter in memchr::memmem - Rust

Function memchr::memmem::find_iter

source ·
pub fn find_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>(
+    haystack: &'h [u8],
+    needle: &'n N
+) -> FindIter<'h, 'n> 
Expand description

Returns an iterator over all non-overlapping occurrences of a substring in +a haystack.

+

Complexity

+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+

Examples

+

Basic usage:

+ +
use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+let mut it = memmem::find_iter(haystack, b"foo");
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+
\ No newline at end of file diff --git a/memchr/memmem/fn.rfind.html b/memchr/memmem/fn.rfind.html new file mode 100644 index 000000000..62c68be84 --- /dev/null +++ b/memchr/memmem/fn.rfind.html @@ -0,0 +1,21 @@ +rfind in memchr::memmem - Rust

Function memchr::memmem::rfind

source ·
pub fn rfind(haystack: &[u8], needle: &[u8]) -> Option<usize>
Expand description

Returns the index of the last occurrence of the given needle.

+

Note that if you’re are searching for the same needle in many different +small haystacks, it may be faster to initialize a FinderRev once, +and reuse it for each search.

+

Complexity

+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+

Examples

+

Basic usage:

+ +
use memchr::memmem;
+
+let haystack = b"foo bar baz";
+assert_eq!(Some(0), memmem::rfind(haystack, b"foo"));
+assert_eq!(Some(4), memmem::rfind(haystack, b"bar"));
+assert_eq!(Some(8), memmem::rfind(haystack, b"ba"));
+assert_eq!(None, memmem::rfind(haystack, b"quux"));
+
\ No newline at end of file diff --git a/memchr/memmem/fn.rfind_iter.html b/memchr/memmem/fn.rfind_iter.html new file mode 100644 index 000000000..920182e50 --- /dev/null +++ b/memchr/memmem/fn.rfind_iter.html @@ -0,0 +1,23 @@ +rfind_iter in memchr::memmem - Rust

Function memchr::memmem::rfind_iter

source ·
pub fn rfind_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>(
+    haystack: &'h [u8],
+    needle: &'n N
+) -> FindRevIter<'h, 'n> 
Expand description

Returns a reverse iterator over all non-overlapping occurrences of a +substring in a haystack.

+

Complexity

+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+

Examples

+

Basic usage:

+ +
use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+let mut it = memmem::rfind_iter(haystack, b"foo");
+assert_eq!(Some(16), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(0), it.next());
+assert_eq!(None, it.next());
+
\ No newline at end of file diff --git a/memchr/memmem/index.html b/memchr/memmem/index.html new file mode 100644 index 000000000..632143f5a --- /dev/null +++ b/memchr/memmem/index.html @@ -0,0 +1,53 @@ +memchr::memmem - Rust

Module memchr::memmem

source ·
Expand description

This module provides forward and reverse substring search routines.

+

Unlike the standard library’s substring search routines, these work on +arbitrary bytes. For all non-empty needles, these routines will report exactly +the same values as the corresponding routines in the standard library. For +the empty needle, the standard library reports matches only at valid UTF-8 +boundaries, where as these routines will report matches at every position.

+

Other than being able to work on arbitrary bytes, the primary reason to prefer +these routines over the standard library routines is that these will generally +be faster. In some cases, significantly so.

+

Example: iterating over substring matches

+

This example shows how to use find_iter to find occurrences of a substring +in a haystack.

+ +
use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::find_iter(haystack, "foo");
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+

Example: iterating over substring matches in reverse

+

This example shows how to use rfind_iter to find occurrences of a substring +in a haystack starting from the end of the haystack.

+

NOTE: This module does not implement double ended iterators, so reverse +searches aren’t done by calling rev on a forward iterator.

+ +
use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::rfind_iter(haystack, "foo");
+assert_eq!(Some(16), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(0), it.next());
+assert_eq!(None, it.next());
+

Example: repeating a search for the same needle

+

It may be possible for the overhead of constructing a substring searcher to be +measurable in some workloads. In cases where the same needle is used to search +many haystacks, it is possible to do construction once and thus to avoid it for +subsequent searches. This can be done with a Finder (or a FinderRev for +reverse searches).

+ +
use memchr::memmem;
+
+let finder = memmem::Finder::new("foo");
+
+assert_eq!(Some(4), finder.find(b"baz foo quux"));
+assert_eq!(None, finder.find(b"quux baz bar"));
+

Structs

  • An iterator over non-overlapping substring matches.
  • An iterator over non-overlapping substring matches in reverse.
  • A single substring searcher fixed to a particular needle.
  • A builder for constructing non-default forward or reverse memmem finders.
  • A single substring reverse searcher fixed to a particular needle.

Enums

  • Prefilter controls whether heuristics are used to accelerate searching.

Functions

  • Returns the index of the first occurrence of the given needle.
  • Returns an iterator over all non-overlapping occurrences of a substring in +a haystack.
  • Returns the index of the last occurrence of the given needle.
  • Returns a reverse iterator over all non-overlapping occurrences of a +substring in a haystack.
\ No newline at end of file diff --git a/memchr/memmem/searcher/enum.PrefilterConfig.html b/memchr/memmem/searcher/enum.PrefilterConfig.html new file mode 100644 index 000000000..fc6c8d6a7 --- /dev/null +++ b/memchr/memmem/searcher/enum.PrefilterConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../memchr/memmem/enum.Prefilter.html...

+ + + \ No newline at end of file diff --git a/memchr/memmem/sidebar-items.js b/memchr/memmem/sidebar-items.js new file mode 100644 index 000000000..5013bc312 --- /dev/null +++ b/memchr/memmem/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Prefilter"],"fn":["find","find_iter","rfind","rfind_iter"],"struct":["FindIter","FindRevIter","Finder","FinderBuilder","FinderRev"]}; \ No newline at end of file diff --git a/memchr/memmem/struct.FindIter.html b/memchr/memmem/struct.FindIter.html new file mode 100644 index 000000000..e5548e9b2 --- /dev/null +++ b/memchr/memmem/struct.FindIter.html @@ -0,0 +1,198 @@ +FindIter in memchr::memmem - Rust

Struct memchr::memmem::FindIter

source ·
pub struct FindIter<'h, 'n> { /* private fields */ }
Expand description

An iterator over non-overlapping substring matches.

+

Matches are reported by the byte offset at which they begin.

+

'h is the lifetime of the haystack while 'n is the lifetime of the +needle.

+

Implementations§

source§

impl<'h, 'n> FindIter<'h, 'n>

source

pub fn into_owned(self) -> FindIter<'h, 'static>

Convert this iterator into its owned variant, such that it no longer +borrows the finder and needle.

+

If this is already an owned iterator, then this is a no-op. Otherwise, +this copies the needle.

+

This is only available when the alloc feature is enabled.

+

Trait Implementations§

source§

impl<'h, 'n> Debug for FindIter<'h, 'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 'n> Iterator for FindIter<'h, 'n>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 'n> RefUnwindSafe for FindIter<'h, 'n>

§

impl<'h, 'n> Send for FindIter<'h, 'n>

§

impl<'h, 'n> Sync for FindIter<'h, 'n>

§

impl<'h, 'n> Unpin for FindIter<'h, 'n>

§

impl<'h, 'n> UnwindSafe for FindIter<'h, 'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/memmem/struct.FindRevIter.html b/memchr/memmem/struct.FindRevIter.html new file mode 100644 index 000000000..27c9055fc --- /dev/null +++ b/memchr/memmem/struct.FindRevIter.html @@ -0,0 +1,198 @@ +FindRevIter in memchr::memmem - Rust

Struct memchr::memmem::FindRevIter

source ·
pub struct FindRevIter<'h, 'n> { /* private fields */ }
Expand description

An iterator over non-overlapping substring matches in reverse.

+

Matches are reported by the byte offset at which they begin.

+

'h is the lifetime of the haystack while 'n is the lifetime of the +needle.

+

Implementations§

source§

impl<'h, 'n> FindRevIter<'h, 'n>

source

pub fn into_owned(self) -> FindRevIter<'h, 'static>

Convert this iterator into its owned variant, such that it no longer +borrows the finder and needle.

+

If this is already an owned iterator, then this is a no-op. Otherwise, +this copies the needle.

+

This is only available when the std feature is enabled.

+

Trait Implementations§

source§

impl<'h, 'n> Debug for FindRevIter<'h, 'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h, 'n> Iterator for FindRevIter<'h, 'n>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'h, 'n> RefUnwindSafe for FindRevIter<'h, 'n>

§

impl<'h, 'n> Send for FindRevIter<'h, 'n>

§

impl<'h, 'n> Sync for FindRevIter<'h, 'n>

§

impl<'h, 'n> Unpin for FindRevIter<'h, 'n>

§

impl<'h, 'n> UnwindSafe for FindRevIter<'h, 'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/memmem/struct.Finder.html b/memchr/memmem/struct.Finder.html new file mode 100644 index 000000000..ee1870a9d --- /dev/null +++ b/memchr/memmem/struct.Finder.html @@ -0,0 +1,78 @@ +Finder in memchr::memmem - Rust

Struct memchr::memmem::Finder

source ·
pub struct Finder<'n> { /* private fields */ }
Expand description

A single substring searcher fixed to a particular needle.

+

The purpose of this type is to permit callers to construct a substring +searcher that can be used to search haystacks without the overhead of +constructing the searcher in the first place. This is a somewhat niche +concern when it’s necessary to re-use the same needle to search multiple +different haystacks with as little overhead as possible. In general, using +find is good enough, but Finder is useful when you can meaningfully +observe searcher construction time in a profile.

+

When the std feature is enabled, then this type has an into_owned +version which permits building a Finder that is not connected to +the lifetime of its needle.

+

Implementations§

source§

impl<'n> Finder<'n>

source

pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'n B) -> Finder<'n>

Create a new finder for the given needle.

+
source

pub fn find(&self, haystack: &[u8]) -> Option<usize>

Returns the index of the first occurrence of this needle in the given +haystack.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use memchr::memmem::Finder;
+
+let haystack = b"foo bar baz";
+assert_eq!(Some(0), Finder::new("foo").find(haystack));
+assert_eq!(Some(4), Finder::new("bar").find(haystack));
+assert_eq!(None, Finder::new("quux").find(haystack));
+
source

pub fn find_iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> FindIter<'h, 'a>

Returns an iterator over all occurrences of a substring in a haystack.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use memchr::memmem::Finder;
+
+let haystack = b"foo bar foo baz foo";
+let finder = Finder::new(b"foo");
+let mut it = finder.find_iter(haystack);
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+
source

pub fn into_owned(self) -> Finder<'static>

Convert this finder into its owned variant, such that it no longer +borrows the needle.

+

If this is already an owned finder, then this is a no-op. Otherwise, +this copies the needle.

+

This is only available when the alloc feature is enabled.

+
source

pub fn as_ref(&self) -> Finder<'_>

Convert this finder into its borrowed variant.

+

This is primarily useful if your finder is owned and you’d like to +store its borrowed variant in some intermediate data structure.

+

Note that the lifetime parameter of the returned finder is tied to the +lifetime of self, and may be shorter than the 'n lifetime of the +needle itself. Namely, a finder’s needle can be either borrowed or +owned, so the lifetime of the needle returned must necessarily be the +shorter of the two.

+
source

pub fn needle(&self) -> &[u8]

Returns the needle that this finder searches for.

+

Note that the lifetime of the needle returned is tied to the lifetime +of the finder, and may be shorter than the 'n lifetime. Namely, a +finder’s needle can be either borrowed or owned, so the lifetime of the +needle returned must necessarily be the shorter of the two.

+

Trait Implementations§

source§

impl<'n> Clone for Finder<'n>

source§

fn clone(&self) -> Finder<'n>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'n> Debug for Finder<'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'n> RefUnwindSafe for Finder<'n>

§

impl<'n> Send for Finder<'n>

§

impl<'n> Sync for Finder<'n>

§

impl<'n> Unpin for Finder<'n>

§

impl<'n> UnwindSafe for Finder<'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/memmem/struct.FinderBuilder.html b/memchr/memmem/struct.FinderBuilder.html new file mode 100644 index 000000000..c767ca1cc --- /dev/null +++ b/memchr/memmem/struct.FinderBuilder.html @@ -0,0 +1,37 @@ +FinderBuilder in memchr::memmem - Rust
pub struct FinderBuilder { /* private fields */ }
Expand description

A builder for constructing non-default forward or reverse memmem finders.

+

A builder is primarily useful for configuring a substring searcher. +Currently, the only configuration exposed is the ability to disable +heuristic prefilters used to speed up certain searches.

+

Implementations§

source§

impl FinderBuilder

source

pub fn new() -> FinderBuilder

Create a new finder builder with default settings.

+
source

pub fn build_forward<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B +) -> Finder<'n>

Build a forward finder using the given needle from the current +settings.

+
source

pub fn build_forward_with_ranker<'n, R: HeuristicFrequencyRank, B: ?Sized + AsRef<[u8]>>( + &self, + ranker: R, + needle: &'n B +) -> Finder<'n>

Build a forward finder using the given needle and a custom heuristic for +determining the frequency of a given byte in the dataset. +See HeuristicFrequencyRank for more details.

+
source

pub fn build_reverse<'n, B: ?Sized + AsRef<[u8]>>( + &self, + needle: &'n B +) -> FinderRev<'n>

Build a reverse finder using the given needle from the current +settings.

+
source

pub fn prefilter(&mut self, prefilter: Prefilter) -> &mut FinderBuilder

Configure the prefilter setting for the finder.

+

See the documentation for Prefilter for more discussion on why +you might want to configure this.

+

Trait Implementations§

source§

impl Clone for FinderBuilder

source§

fn clone(&self) -> FinderBuilder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FinderBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for FinderBuilder

source§

fn default() -> FinderBuilder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/memmem/struct.FinderRev.html b/memchr/memmem/struct.FinderRev.html new file mode 100644 index 000000000..12b19a660 --- /dev/null +++ b/memchr/memmem/struct.FinderRev.html @@ -0,0 +1,81 @@ +FinderRev in memchr::memmem - Rust

Struct memchr::memmem::FinderRev

source ·
pub struct FinderRev<'n> { /* private fields */ }
Expand description

A single substring reverse searcher fixed to a particular needle.

+

The purpose of this type is to permit callers to construct a substring +searcher that can be used to search haystacks without the overhead of +constructing the searcher in the first place. This is a somewhat niche +concern when it’s necessary to re-use the same needle to search multiple +different haystacks with as little overhead as possible. In general, +using rfind is good enough, but FinderRev is useful when you can +meaningfully observe searcher construction time in a profile.

+

When the std feature is enabled, then this type has an into_owned +version which permits building a FinderRev that is not connected to +the lifetime of its needle.

+

Implementations§

source§

impl<'n> FinderRev<'n>

source

pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'n B) -> FinderRev<'n>

Create a new reverse finder for the given needle.

+
source

pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize>

Returns the index of the last occurrence of this needle in the given +haystack.

+

The haystack may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use memchr::memmem::FinderRev;
+
+let haystack = b"foo bar baz";
+assert_eq!(Some(0), FinderRev::new("foo").rfind(haystack));
+assert_eq!(Some(4), FinderRev::new("bar").rfind(haystack));
+assert_eq!(None, FinderRev::new("quux").rfind(haystack));
+
source

pub fn rfind_iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> FindRevIter<'h, 'a>

Returns a reverse iterator over all occurrences of a substring in a +haystack.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use memchr::memmem::FinderRev;
+
+let haystack = b"foo bar foo baz foo";
+let finder = FinderRev::new(b"foo");
+let mut it = finder.rfind_iter(haystack);
+assert_eq!(Some(16), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(0), it.next());
+assert_eq!(None, it.next());
+
source

pub fn into_owned(self) -> FinderRev<'static>

Convert this finder into its owned variant, such that it no longer +borrows the needle.

+

If this is already an owned finder, then this is a no-op. Otherwise, +this copies the needle.

+

This is only available when the std feature is enabled.

+
source

pub fn as_ref(&self) -> FinderRev<'_>

Convert this finder into its borrowed variant.

+

This is primarily useful if your finder is owned and you’d like to +store its borrowed variant in some intermediate data structure.

+

Note that the lifetime parameter of the returned finder is tied to the +lifetime of self, and may be shorter than the 'n lifetime of the +needle itself. Namely, a finder’s needle can be either borrowed or +owned, so the lifetime of the needle returned must necessarily be the +shorter of the two.

+
source

pub fn needle(&self) -> &[u8]

Returns the needle that this finder searches for.

+

Note that the lifetime of the needle returned is tied to the lifetime +of the finder, and may be shorter than the 'n lifetime. Namely, a +finder’s needle can be either borrowed or owned, so the lifetime of the +needle returned must necessarily be the shorter of the two.

+

Trait Implementations§

source§

impl<'n> Clone for FinderRev<'n>

source§

fn clone(&self) -> FinderRev<'n>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'n> Debug for FinderRev<'n>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'n> RefUnwindSafe for FinderRev<'n>

§

impl<'n> Send for FinderRev<'n>

§

impl<'n> Sync for FinderRev<'n>

§

impl<'n> Unpin for FinderRev<'n>

§

impl<'n> UnwindSafe for FinderRev<'n>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/sidebar-items.js b/memchr/sidebar-items.js new file mode 100644 index 000000000..ae3d26da8 --- /dev/null +++ b/memchr/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["memchr","memchr2","memchr2_iter","memchr3","memchr3_iter","memchr_iter","memrchr","memrchr2","memrchr2_iter","memrchr3","memrchr3_iter","memrchr_iter"],"mod":["arch","memmem"],"struct":["Memchr","Memchr2","Memchr3"]}; \ No newline at end of file diff --git a/memchr/struct.Memchr.html b/memchr/struct.Memchr.html new file mode 100644 index 000000000..2c66b8788 --- /dev/null +++ b/memchr/struct.Memchr.html @@ -0,0 +1,216 @@ +Memchr in memchr - Rust

Struct memchr::Memchr

source ·
pub struct Memchr<'h> { /* private fields */ }
Expand description

An iterator over all occurrences of a single byte in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the memchr_iter or [memrchr_iter] +functions. It can also be created with the Memchr::new method.

+

The lifetime parameter 'h refers to the lifetime of the haystack being +searched.

+

Implementations§

source§

impl<'h> Memchr<'h>

source

pub fn new(needle1: u8, haystack: &'h [u8]) -> Memchr<'h>

Returns an iterator over all occurrences of the needle byte in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl<'h> Clone for Memchr<'h>

source§

fn clone(&self) -> Memchr<'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'h> Debug for Memchr<'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h> DoubleEndedIterator for Memchr<'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'h> Iterator for Memchr<'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'h> FusedIterator for Memchr<'h>

Auto Trait Implementations§

§

impl<'h> RefUnwindSafe for Memchr<'h>

§

impl<'h> Send for Memchr<'h>

§

impl<'h> Sync for Memchr<'h>

§

impl<'h> Unpin for Memchr<'h>

§

impl<'h> UnwindSafe for Memchr<'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/struct.Memchr2.html b/memchr/struct.Memchr2.html new file mode 100644 index 000000000..5f09ac15d --- /dev/null +++ b/memchr/struct.Memchr2.html @@ -0,0 +1,217 @@ +Memchr2 in memchr - Rust

Struct memchr::Memchr2

source ·
pub struct Memchr2<'h> { /* private fields */ }
Expand description

An iterator over all occurrences of two possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the memchr2_iter or [memrchr2_iter] +functions. It can also be created with the Memchr2::new method.

+

The lifetime parameter 'h refers to the lifetime of the haystack being +searched.

+

Implementations§

source§

impl<'h> Memchr2<'h>

source

pub fn new(needle1: u8, needle2: u8, haystack: &'h [u8]) -> Memchr2<'h>

Returns an iterator over all occurrences of the needle bytes in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl<'h> Clone for Memchr2<'h>

source§

fn clone(&self) -> Memchr2<'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'h> Debug for Memchr2<'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h> DoubleEndedIterator for Memchr2<'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'h> Iterator for Memchr2<'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'h> FusedIterator for Memchr2<'h>

Auto Trait Implementations§

§

impl<'h> RefUnwindSafe for Memchr2<'h>

§

impl<'h> Send for Memchr2<'h>

§

impl<'h> Sync for Memchr2<'h>

§

impl<'h> Unpin for Memchr2<'h>

§

impl<'h> UnwindSafe for Memchr2<'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/memchr/struct.Memchr3.html b/memchr/struct.Memchr3.html new file mode 100644 index 000000000..a1053a1f3 --- /dev/null +++ b/memchr/struct.Memchr3.html @@ -0,0 +1,222 @@ +Memchr3 in memchr - Rust

Struct memchr::Memchr3

source ·
pub struct Memchr3<'h> { /* private fields */ }
Expand description

An iterator over all occurrences of three possible bytes in a haystack.

+

This iterator implements DoubleEndedIterator, which means it can also be +used to find occurrences in reverse order.

+

This iterator is created by the memchr2_iter or [memrchr2_iter] +functions. It can also be created with the Memchr3::new method.

+

The lifetime parameter 'h refers to the lifetime of the haystack being +searched.

+

Implementations§

source§

impl<'h> Memchr3<'h>

source

pub fn new( + needle1: u8, + needle2: u8, + needle3: u8, + haystack: &'h [u8] +) -> Memchr3<'h>

Returns an iterator over all occurrences of the needle bytes in the +given haystack.

+

The iterator returned implements DoubleEndedIterator. This means it +can also be used to find occurrences in reverse order.

+

Trait Implementations§

source§

impl<'h> Clone for Memchr3<'h>

source§

fn clone(&self) -> Memchr3<'h>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'h> Debug for Memchr3<'h>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'h> DoubleEndedIterator for Memchr3<'h>

source§

fn next_back(&mut self) -> Option<usize>

Removes and returns an element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.37.0 · source§

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element from the end of the iterator. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes +elements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single, +final value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
source§

impl<'h> Iterator for Memchr3<'h>

§

type Item = usize

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<usize>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn partition_in_place<'a, T, P>(self, predicate: P) -> usizewhere + T: 'a, + Self: Sized + DoubleEndedIterator<Item = &'a mut T>, + P: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (iter_partition_in_place)
Reorders the elements of this iterator in-place according to the given predicate, +such that all those that return true precede all those that return false. +Returns the number of true elements found. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn rev(self) -> Rev<Self>where + Self: Sized + DoubleEndedIterator,

Reverses an iterator’s direction. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'h> FusedIterator for Memchr3<'h>

Auto Trait Implementations§

§

impl<'h> RefUnwindSafe for Memchr3<'h>

§

impl<'h> Send for Memchr3<'h>

§

impl<'h> Sync for Memchr3<'h>

§

impl<'h> Unpin for Memchr3<'h>

§

impl<'h> UnwindSafe for Memchr3<'h>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/all.html b/roe/all.html new file mode 100644 index 000000000..77e27c424 --- /dev/null +++ b/roe/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Functions

\ No newline at end of file diff --git a/roe/ascii/lowercase/fn.make_ascii_lowercase.html b/roe/ascii/lowercase/fn.make_ascii_lowercase.html new file mode 100644 index 000000000..73fb06c72 --- /dev/null +++ b/roe/ascii/lowercase/fn.make_ascii_lowercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.make_ascii_lowercase.html...

+ + + \ No newline at end of file diff --git a/roe/ascii/lowercase/fn.to_ascii_lowercase.html b/roe/ascii/lowercase/fn.to_ascii_lowercase.html new file mode 100644 index 000000000..5b38530d4 --- /dev/null +++ b/roe/ascii/lowercase/fn.to_ascii_lowercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.to_ascii_lowercase.html...

+ + + \ No newline at end of file diff --git a/roe/ascii/titlecase/fn.make_ascii_titlecase.html b/roe/ascii/titlecase/fn.make_ascii_titlecase.html new file mode 100644 index 000000000..b9f98e5c2 --- /dev/null +++ b/roe/ascii/titlecase/fn.make_ascii_titlecase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.make_ascii_titlecase.html...

+ + + \ No newline at end of file diff --git a/roe/ascii/titlecase/fn.to_ascii_titlecase.html b/roe/ascii/titlecase/fn.to_ascii_titlecase.html new file mode 100644 index 000000000..97a2850d2 --- /dev/null +++ b/roe/ascii/titlecase/fn.to_ascii_titlecase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.to_ascii_titlecase.html...

+ + + \ No newline at end of file diff --git a/roe/ascii/uppercase/fn.make_ascii_uppercase.html b/roe/ascii/uppercase/fn.make_ascii_uppercase.html new file mode 100644 index 000000000..63b87efd7 --- /dev/null +++ b/roe/ascii/uppercase/fn.make_ascii_uppercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.make_ascii_uppercase.html...

+ + + \ No newline at end of file diff --git a/roe/ascii/uppercase/fn.to_ascii_uppercase.html b/roe/ascii/uppercase/fn.to_ascii_uppercase.html new file mode 100644 index 000000000..d244df5b0 --- /dev/null +++ b/roe/ascii/uppercase/fn.to_ascii_uppercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../roe/fn.to_ascii_uppercase.html...

+ + + \ No newline at end of file diff --git a/roe/enum.LowercaseMode.html b/roe/enum.LowercaseMode.html new file mode 100644 index 000000000..534acb236 --- /dev/null +++ b/roe/enum.LowercaseMode.html @@ -0,0 +1,51 @@ +LowercaseMode in roe - Rust

Enum roe::LowercaseMode

source ·
pub enum LowercaseMode {
+    Full,
+    Ascii,
+    Turkic,
+    Lithuanian,
+    Fold,
+}
Expand description

Options to configure the behavior of lowercase.

+

Which letters exactly are replaced, and by which other letters, depends on +the given options.

+

See individual variants for a description of the available behaviors.

+

If you’re not sure which mode to choose, LowercaseMode::Full is a a good +default.

+

Variants§

§

Full

Full Unicode case mapping, suitable for most languages.

+

See the Turkic and Lithuanian variants for exceptions.

+

Context-dependent case mapping as described in Table 3-14 of the Unicode +standard is currently not supported.

+
§

Ascii

Only the ASCII region, i.e. the characters 'A'..='Z' and 'a'..='z', +are affected.

+

This option cannot be combined with any other option.

+
§

Turkic

Full Unicode case mapping, adapted for Turkic languages (Turkish, +Azerbaijani, …).

+

This means that upper case I is mapped to lower case dotless i, and so +on.

+
§

Lithuanian

Currently, just full Unicode case mapping.

+

In the future, full Unicode case mapping adapted for Lithuanian (keeping +the dot on the lower case i even if there is an accent on top).

+
§

Fold

Unicode case folding, which is more far-reaching than Unicode case +mapping.

+

This option currently cannot be combined with any other option (i.e. +there is currently no variant for turkic languages).

+

Trait Implementations§

source§

impl Clone for LowercaseMode

source§

fn clone(&self) -> LowercaseMode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for LowercaseMode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for LowercaseMode

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl FromStr for LowercaseMode

§

type Err = InvalidCaseMappingMode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for LowercaseMode

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for LowercaseMode

source§

fn cmp(&self, other: &LowercaseMode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<LowercaseMode> for LowercaseMode

source§

fn eq(&self, other: &LowercaseMode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<LowercaseMode> for LowercaseMode

source§

fn partial_cmp(&self, other: &LowercaseMode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryFrom<&[u8]> for LowercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: &[u8]) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&str> for LowercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: &str) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Option<&[u8]>> for LowercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: Option<&[u8]>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Option<&str>> for LowercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: Option<&str>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for LowercaseMode

source§

impl Eq for LowercaseMode

source§

impl StructuralEq for LowercaseMode

source§

impl StructuralPartialEq for LowercaseMode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/enum.UppercaseMode.html b/roe/enum.UppercaseMode.html new file mode 100644 index 000000000..8dd63a239 --- /dev/null +++ b/roe/enum.UppercaseMode.html @@ -0,0 +1,46 @@ +UppercaseMode in roe - Rust

Enum roe::UppercaseMode

source ·
pub enum UppercaseMode {
+    Full,
+    Ascii,
+    Turkic,
+    Lithuanian,
+}
Expand description

Options to configure the behavior of uppercase.

+

Which letters exactly are replaced, and by which other letters, depends on +the given options.

+

See individual variants for a description of the available behaviors.

+

If you’re not sure which mode to choose, UppercaseMode::Full is a a good +default.

+

Variants§

§

Full

Full Unicode case mapping, suitable for most languages.

+

See the Turkic and Lithuanian variants for exceptions.

+

Context-dependent case mapping as described in Table 3-14 of the Unicode +standard is currently not supported.

+
§

Ascii

Only the ASCII region, i.e. the characters 'A'..='Z' and 'a'..='z', +are affected.

+

This option cannot be combined with any other option.

+
§

Turkic

Full Unicode case mapping, adapted for Turkic languages (Turkish, +Azerbaijani, …).

+

This means that upper case I is mapped to lower case dotless i, and so +on.

+
§

Lithuanian

Currently, just full Unicode case mapping.

+

In the future, full Unicode case mapping adapted for Lithuanian (keeping +the dot on the lower case i even if there is an accent on top).

+

Trait Implementations§

source§

impl Clone for UppercaseMode

source§

fn clone(&self) -> UppercaseMode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for UppercaseMode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for UppercaseMode

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl FromStr for UppercaseMode

§

type Err = InvalidCaseMappingMode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for UppercaseMode

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for UppercaseMode

source§

fn cmp(&self, other: &UppercaseMode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<UppercaseMode> for UppercaseMode

source§

fn eq(&self, other: &UppercaseMode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<UppercaseMode> for UppercaseMode

source§

fn partial_cmp(&self, other: &UppercaseMode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryFrom<&[u8]> for UppercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: &[u8]) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<&str> for UppercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: &str) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Option<&[u8]>> for UppercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: Option<&[u8]>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Option<&str>> for UppercaseMode

§

type Error = InvalidCaseMappingMode

The type returned in the event of a conversion error.
source§

fn try_from(value: Option<&str>) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for UppercaseMode

source§

impl Eq for UppercaseMode

source§

impl StructuralEq for UppercaseMode

source§

impl StructuralPartialEq for UppercaseMode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/fn.lowercase.html b/roe/fn.lowercase.html new file mode 100644 index 000000000..b76295009 --- /dev/null +++ b/roe/fn.lowercase.html @@ -0,0 +1,11 @@ +lowercase in roe - Rust

Function roe::lowercase

source ·
pub fn lowercase(slice: &[u8], options: LowercaseMode) -> Lowercase<'_> 
Expand description

Returns an iterator that yields a copy of the bytes in the given slice with +all uppercase letters replaced with their lowercase counterparts.

+

This function treats the given slice as a conventionally UTF-8 string. +UTF-8 byte sequences are converted to their Unicode lowercase equivalents. +Invalid UTF-8 byte sequences are yielded as is.

+

The case mapping mode is determined by the given LowercaseMode. See its +documentation for details on the available case mapping modes.

+

Panics

+

Not all LowercaseModes are currently implemented. This function will +panic if the caller supplies Turkic or case folding lowercasing mode.

+
\ No newline at end of file diff --git a/roe/fn.make_ascii_lowercase.html b/roe/fn.make_ascii_lowercase.html new file mode 100644 index 000000000..21d19ffd8 --- /dev/null +++ b/roe/fn.make_ascii_lowercase.html @@ -0,0 +1,16 @@ +make_ascii_lowercase in roe - Rust

Function roe::make_ascii_lowercase

source ·
pub fn make_ascii_lowercase<T: AsMut<[u8]>>(slice: &mut T)
Expand description

Converts the given slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are +unchanged.

+

This function can be used to implement String#downcase! for ASCII +strings in Ruby.

+

To return a new lowercased value without modifying the existing one, use to_ascii_lowercase. +This function is analogous <[u8]>::make_ascii_lowercase.

+

Examples

+
let mut buf = *b"ABCxyz";
+make_ascii_lowercase(&mut buf);
+assert_eq!(buf, *b"abcxyz");
+
+let mut buf = *b"1234%&*";
+make_ascii_lowercase(&mut buf);
+assert_eq!(buf, *b"1234%&*");
+
\ No newline at end of file diff --git a/roe/fn.make_ascii_titlecase.html b/roe/fn.make_ascii_titlecase.html new file mode 100644 index 000000000..6f5a9d560 --- /dev/null +++ b/roe/fn.make_ascii_titlecase.html @@ -0,0 +1,28 @@ +make_ascii_titlecase in roe - Rust

Function roe::make_ascii_titlecase

source ·
pub fn make_ascii_titlecase<T: AsMut<[u8]>>(slice: &mut T)
Expand description

Converts the given slice to its ASCII title case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’ in the first byte; +subsequent bytes with ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’; +non-ASCII letters are unchanged.

+

This function can be used to implement String#capitalize! for ASCII +strings in Ruby.

+

To return a new titlecased value without modifying the existing one, use to_ascii_titlecase.

+

Examples

+
let mut buf = *b"ABCxyz";
+make_ascii_titlecase(&mut buf);
+assert_eq!(buf, *b"Abcxyz");
+
+let mut buf = *b"1234%&*";
+make_ascii_titlecase(&mut buf);
+assert_eq!(buf, *b"1234%&*");
+
+let mut buf = *b"ABC1234%&*";
+make_ascii_titlecase(&mut buf);
+assert_eq!(buf, *b"Abc1234%&*");
+
+let mut buf = *b"1234%&*abcXYZ";
+make_ascii_titlecase(&mut buf);
+assert_eq!(buf, *b"1234%&*abcxyz");
+
+let mut buf = *b"ABC, XYZ";
+make_ascii_titlecase(&mut buf);
+assert_eq!(buf, *b"Abc, xyz");
+
\ No newline at end of file diff --git a/roe/fn.make_ascii_uppercase.html b/roe/fn.make_ascii_uppercase.html new file mode 100644 index 000000000..4a5297e4e --- /dev/null +++ b/roe/fn.make_ascii_uppercase.html @@ -0,0 +1,16 @@ +make_ascii_uppercase in roe - Rust

Function roe::make_ascii_uppercase

source ·
pub fn make_ascii_uppercase<T: AsMut<[u8]>>(slice: &mut T)
Expand description

Converts the given slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, but non-ASCII letters are +unchanged.

+

This function can be used to implement String#upcase! for ASCII strings +in Ruby.

+

To return a new uppercased value without modifying the existing one, use to_ascii_uppercase. +This function is analogous to <[u8]>::make_ascii_uppercase.

+

Examples

+
let mut buf = *b"ABCxyz";
+make_ascii_uppercase(&mut buf);
+assert_eq!(buf, *b"ABCXYZ");
+
+let mut buf = *b"1234%&*";
+make_ascii_uppercase(&mut buf);
+assert_eq!(buf, *b"1234%&*");
+
\ No newline at end of file diff --git a/roe/fn.to_ascii_lowercase.html b/roe/fn.to_ascii_lowercase.html new file mode 100644 index 000000000..78726e97d --- /dev/null +++ b/roe/fn.to_ascii_lowercase.html @@ -0,0 +1,12 @@ +to_ascii_lowercase in roe - Rust

Function roe::to_ascii_lowercase

source ·
pub fn to_ascii_lowercase<T: AsRef<[u8]>>(slice: T) -> Vec<u8>
Available on crate feature alloc only.
Expand description

Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are +unchanged.

+

This function can be used to implement String#downcase and +Symbol#downcase for ASCII strings in Ruby.

+

To lowercase the value in-place, use make_ascii_lowercase. This function +is analogous to <[u8]>::to_ascii_lowercase.

+

Examples

+
assert_eq!(to_ascii_lowercase("ABCxyz"), &b"abcxyz"[..]);
+assert_eq!(to_ascii_lowercase("1234%&*"), &b"1234%&*"[..]);
+
\ No newline at end of file diff --git a/roe/fn.to_ascii_titlecase.html b/roe/fn.to_ascii_titlecase.html new file mode 100644 index 000000000..28207cbe5 --- /dev/null +++ b/roe/fn.to_ascii_titlecase.html @@ -0,0 +1,15 @@ +to_ascii_titlecase in roe - Rust

Function roe::to_ascii_titlecase

source ·
pub fn to_ascii_titlecase<T: AsRef<[u8]>>(slice: T) -> Vec<u8>
Available on crate feature alloc only.
Expand description

Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII title case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’ in the first byte; +subsequent bytes with ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’; +non-ASCII letters are unchanged.

+

This function can be used to implement String#capitalize and +Symbol#capitalize for ASCII strings in Ruby.

+

To titlecase the value in-place, use make_ascii_titlecase.

+

Examples

+
assert_eq!(to_ascii_titlecase("ABCxyz"), &b"Abcxyz"[..]);
+assert_eq!(to_ascii_titlecase("1234%&*"), &b"1234%&*"[..]);
+assert_eq!(to_ascii_titlecase("ABC1234%&*"), &b"Abc1234%&*"[..]);
+assert_eq!(to_ascii_titlecase("1234%&*abcXYZ"), &b"1234%&*abcxyz"[..]);
+assert_eq!(to_ascii_titlecase("ABC, XYZ"), &b"Abc, xyz"[..]);
+
\ No newline at end of file diff --git a/roe/fn.to_ascii_uppercase.html b/roe/fn.to_ascii_uppercase.html new file mode 100644 index 000000000..39833229b --- /dev/null +++ b/roe/fn.to_ascii_uppercase.html @@ -0,0 +1,12 @@ +to_ascii_uppercase in roe - Rust

Function roe::to_ascii_uppercase

source ·
pub fn to_ascii_uppercase<T: AsRef<[u8]>>(slice: T) -> Vec<u8>
Available on crate feature alloc only.
Expand description

Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, but non-ASCII letters are +unchanged.

+

This function can be used to implement String#upcase and +Symbol#upcase for ASCII strings in Ruby.

+

To uppercase the value in-place, use make_ascii_uppercase. This function +is analogous to <[u8]>::to_ascii_uppercase.

+

Examples

+
assert_eq!(to_ascii_uppercase("ABCxyz"), &b"ABCXYZ"[..]);
+assert_eq!(to_ascii_uppercase("1234%&*"), &b"1234%&*"[..]);
+
\ No newline at end of file diff --git a/roe/fn.uppercase.html b/roe/fn.uppercase.html new file mode 100644 index 000000000..0deeede0d --- /dev/null +++ b/roe/fn.uppercase.html @@ -0,0 +1,11 @@ +uppercase in roe - Rust

Function roe::uppercase

source ·
pub fn uppercase(slice: &[u8], options: UppercaseMode) -> Uppercase<'_> 
Expand description

Returns an iterator that yields a copy of the bytes in the given slice with +all lowercase letters replaced with their uppercase counterparts.

+

This function treats the given slice as a conventionally UTF-8 string. +UTF-8 byte sequences are converted to their Unicode uppercase equivalents. +Invalid UTF-8 byte sequences are yielded as is.

+

The case mapping mode is determined by the given UppercaseMode. See its +documentation for details on the available case mapping modes.

+

Panics

+

Not all UppercaseModes are currently implemented. This function will +panic if the caller supplies Turkic uppercasing mode.

+
\ No newline at end of file diff --git a/roe/index.html b/roe/index.html new file mode 100644 index 000000000..bbbc40b82 --- /dev/null +++ b/roe/index.html @@ -0,0 +1,49 @@ +roe - Rust

Crate roe

source ·
Expand description

This crate provides Unicode case mapping routines and iterators for +conventionally UTF-8 binary strings.

+

Unicode case mapping or case conversion can be used to transform the +characters in a string. To quote the Unicode FAQ:

+
+

Case mapping or case conversion is a process whereby strings are converted +to a particular form—uppercase, lowercase, or titlecase—possibly for +display to the user.

+
+

This crate is currently a work in progress. When the API is complete, Roe +will support lowercase, uppercase, titlecase, and case folding iterators for +conventionally UTF-8 byte slices.

+

Roe will implement support for full, Turkic, ASCII, and case folding +transforms.

+

Usage

+

You can convert case like:

+ +
assert_eq!(
+    roe::lowercase(b"Artichoke Ruby", LowercaseMode::Ascii).collect::<Vec<_>>(),
+    b"artichoke ruby"
+);
+assert_eq!(
+    roe::uppercase("Αύριο".as_bytes(), UppercaseMode::Full).collect::<Vec<_>>(),
+    "ΑΎΡΙΟ".as_bytes()
+);
+

Roe provides fast path routines that assume the byte slice is ASCII-only.

+

Crate Features

+

Roe is no_std compatible with an optional dependency on the alloc +crate.

+

Roe has several Cargo features, all of which are enabled by default:

+
    +
  • std - Adds a dependency on std, the Rust Standard Library. This +feature enables std::error::Error implementations on error types in +this crate. Enabling the std feature also enables the alloc +feature.
  • +
  • alloc - Adds a dependency on alloc, the Rust allocation and +collections library. This feature enables APIs that allocate String or +Vec.
  • +
+

Structs

Enums

Functions

  • Returns an iterator that yields a copy of the bytes in the given slice with +all uppercase letters replaced with their lowercase counterparts.
  • Converts the given slice to its ASCII lower case equivalent in-place.
  • Converts the given slice to its ASCII title case equivalent in-place.
  • Converts the given slice to its ASCII upper case equivalent in-place.
  • Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII lower case equivalent.
  • Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII title case equivalent.
  • Returns a vector containing a copy of the given slice where each byte is +mapped to its ASCII upper case equivalent.
  • Returns an iterator that yields a copy of the bytes in the given slice with +all lowercase letters replaced with their uppercase counterparts.
\ No newline at end of file diff --git a/roe/lowercase/struct.Lowercase.html b/roe/lowercase/struct.Lowercase.html new file mode 100644 index 000000000..4da6200bc --- /dev/null +++ b/roe/lowercase/struct.Lowercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../roe/struct.Lowercase.html...

+ + + \ No newline at end of file diff --git a/roe/sidebar-items.js b/roe/sidebar-items.js new file mode 100644 index 000000000..fb522411d --- /dev/null +++ b/roe/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["LowercaseMode","UppercaseMode"],"fn":["lowercase","make_ascii_lowercase","make_ascii_titlecase","make_ascii_uppercase","to_ascii_lowercase","to_ascii_titlecase","to_ascii_uppercase","uppercase"],"struct":["InvalidCaseMappingMode","Lowercase","Uppercase"]}; \ No newline at end of file diff --git a/roe/struct.InvalidCaseMappingMode.html b/roe/struct.InvalidCaseMappingMode.html new file mode 100644 index 000000000..51e2d63f9 --- /dev/null +++ b/roe/struct.InvalidCaseMappingMode.html @@ -0,0 +1,38 @@ +InvalidCaseMappingMode in roe - Rust
pub struct InvalidCaseMappingMode { /* private fields */ }
Expand description

Error that indicates a failure to parse a LowercaseMode or +UppercaseMode.

+

This error corresponds to the Ruby ArgumentError Exception class.

+

Examples

+
let err = InvalidCaseMappingMode::new();
+assert_eq!(err.message(), "invalid option");
+
+let mode: Result<LowercaseMode, InvalidCaseMappingMode> = "full".try_into();
+

Implementations§

source§

impl InvalidCaseMappingMode

source

pub const fn new() -> Self

Construct a new InvalidCaseMappingMode error.

+
Examples
+
const ERR: InvalidCaseMappingMode = InvalidCaseMappingMode::new();
+assert_eq!(ERR.message(), "invalid option");
+
source

pub const fn message(self) -> &'static str

Retrieve the error message associated with this InvalidCaseMappingMode.

+
Examples
+
const MESSAGE: &str = InvalidCaseMappingMode::new().message();
+assert_eq!(MESSAGE, "invalid option");
+

Trait Implementations§

source§

impl Clone for InvalidCaseMappingMode

source§

fn clone(&self) -> InvalidCaseMappingMode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for InvalidCaseMappingMode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for InvalidCaseMappingMode

source§

fn default() -> InvalidCaseMappingMode

Returns the “default value” for a type. Read more
source§

impl Display for InvalidCaseMappingMode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for InvalidCaseMappingMode

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl Hash for InvalidCaseMappingMode

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for InvalidCaseMappingMode

source§

fn cmp(&self, other: &InvalidCaseMappingMode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<InvalidCaseMappingMode> for InvalidCaseMappingMode

source§

fn eq(&self, other: &InvalidCaseMappingMode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<InvalidCaseMappingMode> for InvalidCaseMappingMode

source§

fn partial_cmp(&self, other: &InvalidCaseMappingMode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for InvalidCaseMappingMode

source§

impl Eq for InvalidCaseMappingMode

source§

impl StructuralEq for InvalidCaseMappingMode

source§

impl StructuralPartialEq for InvalidCaseMappingMode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/struct.Lowercase.html b/roe/struct.Lowercase.html new file mode 100644 index 000000000..b152a472c --- /dev/null +++ b/roe/struct.Lowercase.html @@ -0,0 +1,243 @@ +Lowercase in roe - Rust

Struct roe::Lowercase

source ·
pub struct Lowercase<'a> { /* private fields */ }
Expand description

An iterator that yields the lowercase equivalent of a conventionally UTF-8 +byte string.

+

This iterator yields bytes.

+

This struct is created by the lowercase function. See its documentation +for more.

+

Implementations§

source§

impl<'a> Lowercase<'a>

source

pub const fn new() -> Self

Create a new, empty lowercase iterator.

+
Examples
+
let mut lowercase = Lowercase::new();
+assert_eq!(lowercase.next(), None);
+
source

pub const fn with_slice(slice: &'a [u8]) -> Self

Create a new lowercase iterator with the given byte slice using full +Unicode case mapping.

+
Examples
+
let mut lowercase = Lowercase::with_slice(b"abcXYZ");
+assert_eq!(lowercase.next(), Some(b'a'));
+assert_eq!(lowercase.next(), Some(b'b'));
+assert_eq!(lowercase.next(), Some(b'c'));
+assert_eq!(lowercase.next(), Some(b'x'));
+assert_eq!(lowercase.next(), Some(b'y'));
+assert_eq!(lowercase.next(), Some(b'z'));
+assert_eq!(lowercase.next(), None);
+

Non-ASCII characters are case mapped:

+ +
let lowercase = Lowercase::with_slice("Αύριο".as_bytes());
+assert_eq!(lowercase.collect::<Vec<_>>(), "αύριο".as_bytes());
+

Invalid UTF-8 bytes are yielded as is without impacting Unicode +characters:

+ +
let mut s = "Αύριο".to_string().into_bytes();
+s.extend(b"\xFF\xFE");
+let lowercase = Lowercase::with_slice(s.as_slice());
+
+let mut expected = "αύριο".to_string().into_bytes();
+expected.extend(b"\xFF\xFE");
+assert_eq!(lowercase.collect::<Vec<_>>(), expected);
+
source

pub const fn with_ascii_slice(slice: &'a [u8]) -> Self

Create a new lowercase iterator with the given byte slice using ASCII +case mapping.

+
Examples
+
let mut lowercase = Lowercase::with_ascii_slice(b"abcXYZ");
+assert_eq!(lowercase.next(), Some(b'a'));
+assert_eq!(lowercase.next(), Some(b'b'));
+assert_eq!(lowercase.next(), Some(b'c'));
+assert_eq!(lowercase.next(), Some(b'x'));
+assert_eq!(lowercase.next(), Some(b'y'));
+assert_eq!(lowercase.next(), Some(b'z'));
+assert_eq!(lowercase.next(), None);
+

Non-ASCII characters are ignored:

+ +
let lowercase = Lowercase::with_ascii_slice("Αύριο".as_bytes());
+assert_eq!(lowercase.collect::<Vec<_>>(), "Αύριο".as_bytes());
+

Invalid UTF-8 bytes are yielded as is without impacting ASCII bytes:

+ +
let lowercase = Lowercase::with_ascii_slice(b"abc\xFF\xFEXYZ");
+assert_eq!(lowercase.collect::<Vec<_>>(), b"abc\xFF\xFExyz");
+

Trait Implementations§

source§

impl<'a> Clone for Lowercase<'a>

source§

fn clone(&self) -> Lowercase<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Lowercase<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Iterator for Lowercase<'a>

§

type Item = u8

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for Lowercase<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Lowercase<'a>

§

impl<'a> Send for Lowercase<'a>

§

impl<'a> Sync for Lowercase<'a>

§

impl<'a> Unpin for Lowercase<'a>

§

impl<'a> UnwindSafe for Lowercase<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/struct.Uppercase.html b/roe/struct.Uppercase.html new file mode 100644 index 000000000..fde1ce9ae --- /dev/null +++ b/roe/struct.Uppercase.html @@ -0,0 +1,243 @@ +Uppercase in roe - Rust

Struct roe::Uppercase

source ·
pub struct Uppercase<'a> { /* private fields */ }
Expand description

An iterator that yields the uppercase equivalent of a conventionally UTF-8 +byte string.

+

This iterator yields bytes.

+

This struct is created by the uppercase function. See its documentation +for more.

+

Implementations§

source§

impl<'a> Uppercase<'a>

source

pub const fn new() -> Self

Create a new, empty uppercase iterator.

+
Examples
+
let mut uppercase = Uppercase::new();
+assert_eq!(uppercase.next(), None);
+
source

pub const fn with_slice(slice: &'a [u8]) -> Self

Create a new uppercase iterator with the given byte slice using full +Unicode case mapping.

+
Examples
+
let mut uppercase = Uppercase::with_slice(b"abcXYZ");
+assert_eq!(uppercase.next(), Some(b'A'));
+assert_eq!(uppercase.next(), Some(b'B'));
+assert_eq!(uppercase.next(), Some(b'C'));
+assert_eq!(uppercase.next(), Some(b'X'));
+assert_eq!(uppercase.next(), Some(b'Y'));
+assert_eq!(uppercase.next(), Some(b'Z'));
+assert_eq!(uppercase.next(), None);
+

Non-ASCII characters are case mapped:

+ +
let uppercase = Uppercase::with_slice("Αύριο".as_bytes());
+assert_eq!(uppercase.collect::<Vec<_>>(), "ΑΎΡΙΟ".as_bytes());
+

Invalid UTF-8 bytes are yielded as is without impacting Unicode +characters:

+ +
let mut s = "Αύριο".to_string().into_bytes();
+s.extend(b"\xFF\xFE");
+let uppercase = Uppercase::with_slice(s.as_slice());
+
+let mut expected = "ΑΎΡΙΟ".to_string().into_bytes();
+expected.extend(b"\xFF\xFE");
+assert_eq!(uppercase.collect::<Vec<_>>(), expected);
+
source

pub const fn with_ascii_slice(slice: &'a [u8]) -> Self

Create a new uppercase iterator with the given byte slice using ASCII +case mapping.

+
Examples
+
let mut uppercase = Uppercase::with_ascii_slice(b"abcXYZ");
+assert_eq!(uppercase.next(), Some(b'A'));
+assert_eq!(uppercase.next(), Some(b'B'));
+assert_eq!(uppercase.next(), Some(b'C'));
+assert_eq!(uppercase.next(), Some(b'X'));
+assert_eq!(uppercase.next(), Some(b'Y'));
+assert_eq!(uppercase.next(), Some(b'Z'));
+assert_eq!(uppercase.next(), None);
+

Non-ASCII characters are ignored:

+ +
let uppercase = Uppercase::with_ascii_slice("Αύριο".as_bytes());
+assert_eq!(uppercase.collect::<Vec<_>>(), "Αύριο".as_bytes());
+

Invalid UTF-8 bytes are yielded as is without impacting ASCII bytes:

+ +
let uppercase = Uppercase::with_ascii_slice(b"abc\xFF\xFEXYZ");
+assert_eq!(uppercase.collect::<Vec<_>>(), b"ABC\xFF\xFEXYZ");
+

Trait Implementations§

source§

impl<'a> Clone for Uppercase<'a>

source§

fn clone(&self) -> Uppercase<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for Uppercase<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Iterator for Uppercase<'a>

§

type Item = u8

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn count(self) -> usize

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl<'a> FusedIterator for Uppercase<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Uppercase<'a>

§

impl<'a> Send for Uppercase<'a>

§

impl<'a> Sync for Uppercase<'a>

§

impl<'a> Unpin for Uppercase<'a>

§

impl<'a> UnwindSafe for Uppercase<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/roe/uppercase/struct.Uppercase.html b/roe/uppercase/struct.Uppercase.html new file mode 100644 index 000000000..1e07043ce --- /dev/null +++ b/roe/uppercase/struct.Uppercase.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../roe/struct.Uppercase.html...

+ + + \ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 000000000..5a2a50163 --- /dev/null +++ b/search-index.js @@ -0,0 +1,7 @@ +var searchIndex = JSON.parse('{\ +"bstr":{"doc":"A byte string library.","t":"FDIDDDDDDDDDDDDDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL","n":["B","BStr","ByteSlice","Bytes","CharIndices","Chars","EscapeBytes","FieldsWith","Find","FindReverse","Finder","FinderReverse","Lines","LinesWithTerminator","Split","SplitN","SplitNReverse","SplitReverse","Utf8Chunk","Utf8Chunks","Utf8Error","as_bstr","as_bstr","as_bstr_mut","as_bstr_mut","as_bytes","as_bytes","as_bytes","as_bytes","as_bytes","as_mut","as_ref","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","bytes","bytes","char_indices","char_indices","chars","chars","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","contains_str","contains_str","decode_last_utf8","decode_utf8","default","default","deref","deref_mut","ends_with_str","ends_with_str","eq","eq","eq","eq","eq","eq","error_len","escape_bytes","escape_bytes","fields_with","fields_with","find","find","find","find_byte","find_byte","find_byteset","find_byteset","find_char","find_char","find_iter","find_iter","find_non_ascii_byte","find_non_ascii_byte","find_not_byteset","find_not_byteset","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","hash","incomplete","index","index","index","index","index","index","index","index_mut","index_mut","index_mut","index_mut","index_mut","index_mut","index_mut","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","invalid","is_ascii","is_ascii","is_utf8","is_utf8","last_byte","last_byte","len","lines","lines","lines_with_terminator","lines_with_terminator","make_ascii_lowercase","make_ascii_lowercase","make_ascii_uppercase","make_ascii_uppercase","needle","needle","new","new","new","next","next","next","next","next","next","next","next","next","next","next","next","next","next","next_back","next_back","next_back","next_back","next_back","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","reverse_bytes","reverse_bytes","reverse_chars","reverse_chars","rfind","rfind","rfind","rfind_byte","rfind_byte","rfind_byteset","rfind_byteset","rfind_char","rfind_char","rfind_iter","rfind_iter","rfind_not_byteset","rfind_not_byteset","rsplit_once_str","rsplit_once_str","rsplit_str","rsplit_str","rsplitn_str","rsplitn_str","size_hint","size_hint","split_once_str","split_once_str","split_str","split_str","splitn_str","splitn_str","starts_with_str","starts_with_str","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_str","to_str","to_str_unchecked","to_str_unchecked","to_string","to_string","to_string","trim_end_with","trim_end_with","trim_start_with","trim_start_with","trim_with","trim_with","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","utf8_chunks","utf8_chunks","valid","valid_up_to"],"q":[[0,"bstr"],[386,"core::marker"],[387,"core::convert"],[388,"core::cmp"],[389,"core::option"],[390,"core::ops::function"],[391,"core::fmt"],[392,"core::fmt"],[393,"core::ops::range"],[394,"core::ops::range"],[395,"alloc::string"],[396,"core::any"]],"d":["A short-hand constructor for building a &[u8].","A wrapper for &[u8] that provides convenient string …","A trait that extends &[u8] with string oriented methods.","An iterator over the bytes in a byte string.","An iterator over Unicode scalar values in a byte string …","An iterator over Unicode scalar values in a byte string.","An iterator of char values that represent an escaping of …","An iterator over fields in the byte string, separated by a …","An iterator over non-overlapping substring matches.","An iterator over non-overlapping substring matches in …","A single substring searcher fixed to a particular needle.","A single substring reverse searcher fixed to a particular …","An iterator over all lines in a byte string, without their …","An iterator over all lines in a byte string, including …","An iterator over substrings in a byte string, split by a …","An iterator over at most n substrings in a byte string, …","An iterator over at most n substrings in a byte string, …","An iterator over substrings in a byte string, split by a …","A chunk of valid UTF-8, possibly followed by invalid UTF-8 …","An iterator over chunks of valid UTF-8 in a byte slice.","An error that occurs when UTF-8 decoding fails.","Return this byte slice as a &BStr.","Return this byte slice as a &BStr.","Return this byte slice as a &mut BStr.","Return this byte slice as a &mut BStr.","Views the remaining underlying data as a subslice of the …","Return a copy of the rest of the underlying bytes without …","Return a copy of the rest of the underlying bytes without …","View the underlying data as a subslice of the original …","View the underlying data as a subslice of the original …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns an iterator over the bytes in this byte string.","Returns an iterator over the bytes in this byte string.","Returns an iterator over the Unicode scalar values in this …","Returns an iterator over the Unicode scalar values in this …","Returns an iterator over the Unicode scalar values in this …","Returns an iterator over the Unicode scalar values in this …","","","","","","","","","","","","","","","","","","","","","","Returns true if and only if this byte string contains the …","Returns true if and only if this byte string contains the …","UTF-8 decode a single Unicode scalar value from the end of …","UTF-8 decode a single Unicode scalar value from the …","","","","","Returns true if and only if this byte string has the given …","Returns true if and only if this byte string has the given …","","","","","","","Returns the total number of invalid UTF-8 bytes …","Escapes this byte string into a sequence of char values.","Escapes this byte string into a sequence of char values.","Returns an iterator over the fields in a byte string, …","Returns an iterator over the fields in a byte string, …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of this needle …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of any of the …","Returns the index of the first occurrence of any of the …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of the given …","Returns an iterator of the non-overlapping occurrences of …","Returns an iterator of the non-overlapping occurrences of …","Returns the index of the first non-ASCII byte in this byte …","Returns the index of the first non-ASCII byte in this byte …","Returns the index of the first occurrence of a byte that …","Returns the index of the first occurrence of a byte that …","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns whether the invalid sequence might still become …","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","Returns the (possibly empty) invalid UTF-8 bytes in this …","Returns true if and only if every byte in this byte string …","Returns true if and only if every byte in this byte string …","Returns true if and only if the entire byte string is …","Returns true if and only if the entire byte string is …","Returns the last byte in this byte string, if it’s …","Returns the last byte in this byte string, if it’s …","","An iterator over all lines in a byte string, without their …","An iterator over all lines in a byte string, without their …","An iterator over all lines in a byte string, including …","An iterator over all lines in a byte string, including …","Convert this byte string to its lowercase ASCII equivalent …","Convert this byte string to its lowercase ASCII equivalent …","Convert this byte string to its uppercase ASCII equivalent …","Convert this byte string to its uppercase ASCII equivalent …","Returns the needle that this finder searches for.","Returns the needle that this finder searches for.","Directly creates a BStr slice from anything that can be …","Create a new finder for the given needle.","Create a new reverse finder for the given needle.","","","","","","","","","","","","","","","","","","","","","","","","","Reverse the bytes in this string, in place.","Reverse the bytes in this string, in place.","Reverse the codepoints in this string, in place.","Reverse the codepoints in this string, in place.","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of this needle in …","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of any of the …","Returns the index of the last occurrence of any of the …","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of the given …","Returns an iterator of the non-overlapping occurrences of …","Returns an iterator of the non-overlapping occurrences of …","Returns the index of the last occurrence of a byte that is …","Returns the index of the last occurrence of a byte that is …","Split this byte string at the last occurrence of splitter.","Split this byte string at the last occurrence of splitter.","Returns an iterator over substrings of this byte string, …","Returns an iterator over substrings of this byte string, …","Returns an iterator of at most limit substrings of this …","Returns an iterator of at most limit substrings of this …","","","Split this byte string at the first occurrence of splitter.","Split this byte string at the first occurrence of splitter.","Returns an iterator over substrings of this byte string, …","Returns an iterator over substrings of this byte string, …","Returns an iterator of at most limit substrings of this …","Returns an iterator of at most limit substrings of this …","Returns true if and only if this byte string has the given …","Returns true if and only if this byte string has the given …","","","","","","","","","","","Safely convert this byte string into a &str if it’s …","Safely convert this byte string into a &str if it’s …","Unsafely convert this byte string into a &str, without …","Unsafely convert this byte string into a &str, without …","","","","Return a byte string slice with trailing characters …","Return a byte string slice with trailing characters …","Return a byte string slice with leading characters …","Return a byte string slice with leading characters …","Return a byte string slice with leading and trailing …","Return a byte string slice with leading and trailing …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Iterate over chunks of valid UTF-8.","Iterate over chunks of valid UTF-8.","Returns the (possibly empty) valid UTF-8 bytes in this …","Returns the byte index of the position immediately …"],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,46,46,46,46,6,7,8,9,10,5,5,5,36,5,5,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,36,5,5,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,46,46,46,46,46,46,11,12,13,6,7,8,9,10,14,15,11,12,13,6,7,8,9,10,14,15,5,46,46,0,0,5,5,5,5,46,46,5,5,5,5,5,15,15,46,46,46,46,46,46,12,46,46,46,46,46,46,46,46,46,46,46,46,5,5,11,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,15,36,5,5,5,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,5,36,5,5,5,5,5,5,5,5,5,5,5,5,5,5,36,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,11,25,28,6,23,30,31,32,33,7,8,9,10,14,36,46,46,46,46,46,46,6,46,46,46,46,46,46,46,46,12,13,5,12,13,11,25,28,6,23,30,31,32,33,7,8,9,10,14,6,7,8,9,10,5,5,5,5,5,46,46,46,46,46,46,13,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,6,14,46,46,46,46,46,46,46,46,11,12,13,6,7,8,9,10,14,15,46,46,46,46,5,11,15,46,46,46,46,46,46,36,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,36,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,36,5,11,12,13,25,28,6,23,30,31,32,33,7,8,9,10,14,15,46,46,36,15],"f":[[-1,[[2,[1]]],[3,[4,[[2,[1]]]]]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[-1,5,[]],[-1,5,[]],[-1,5,[]],[-1,5,[]],[6,[[2,[1]]]],[7,[[2,[1]]]],[8,[[2,[1]]]],[9,[[2,[1]]]],[10,[[2,[1]]]],[5,[[2,[1]]]],[5,[[2,[1]]]],[5,5],[-1,-2,[],[]],[5,[[2,[1]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[5,[[2,[1]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,6,[]],[-1,6,[]],[-1,10,[]],[-1,10,[]],[-1,9,[]],[-1,9,[]],[11,11],[12,12],[13,13],[6,6],[7,7],[8,8],[9,9],[10,10],[14,14],[15,15],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[-1,-2],16,[],[]],[[5,5],17],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[-1,[[16,[[20,[19]],21]]],[[4,[[2,[1]]]]]],[-1,[[16,[[20,[19]],21]]],[[4,[[2,[1]]]]]],[[],5],[[],5],[5,[[2,[1]]]],[5,[[2,[1]]]],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[[5,5],18],[[5,22],18],[[5,22],18],[[5,[2,[1]]],18],[[5,[2,[1]]],18],[[15,15],18],[15,[[20,[21]]]],[-1,11,[]],[-1,11,[]],[[-1,-2],[[23,[-2]]],[],24],[[-1,-2],[[23,[-2]]],[],24],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[12,-1],[[20,[21]]],[[4,[[2,[1]]]]]],[[-1,1],[[20,[21]]],[]],[[-1,1],[[20,[21]]],[]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,19],[[20,[21]]],[]],[[-1,19],[[20,[21]]],[]],[[-1,-2],25,[],[3,[4,[[2,[1]]]]]],[[-1,-2],25,[],[3,[4,[[2,[1]]]]]],[-1,[[20,[21]]],[]],[-1,[[20,[21]]],[]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[5,26],27],[[5,26],27],[[11,26],27],[[11,26],27],[[12,26],27],[[13,26],27],[[25,26],27],[[28,26],27],[[6,26],27],[[[23,[-1]],26],27,29],[[30,26],27],[[31,26],27],[[32,26],27],[[33,26],27],[[7,26],27],[[8,26],27],[[9,26],27],[[10,26],27],[[14,26],27],[[15,26],27],[[15,26],27],[-1,-1,[]],[[[2,[1]]],5],[[[34,[1]]],5],[22,5],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[[5,-1],16,35],[36,18],[[5,[37,[21]]],5],[[5,[38,[21]]],5],[[5,39],5],[[5,[40,[21]]],5],[[5,21],1],[[5,[41,[21]]],5],[[5,[42,[21]]],5],[[5,[42,[21]]],5],[[5,[37,[21]]],5],[[5,39],5],[[5,[41,[21]]],5],[[5,21],1],[[5,[38,[21]]],5],[[5,[40,[21]]],5],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[36,[[2,[1]]]],[-1,18,[]],[-1,18,[]],[-1,18,[]],[-1,18,[]],[-1,[[20,[1]]],[]],[-1,[[20,[1]]],[]],[6,21],[-1,7,[]],[-1,7,[]],[-1,8,[]],[-1,8,[]],[-1,16,[]],[-1,16,[]],[-1,16,[]],[-1,16,[]],[12,[[2,[1]]]],[13,[[2,[1]]]],[-1,5,[3,[4,[[2,[1]]]]]],[-1,12,[3,[4,[[2,[1]]]]]],[-1,13,[3,[4,[[2,[1]]]]]],[11,[[20,[19]]]],[25,[[20,[21]]]],[28,[[20,[21]]]],[6,[[20,[1]]]],[[[23,[-1]]],[[20,[[2,[1]]]]],24],[30,[[20,[[2,[1]]]]]],[31,[[20,[[2,[1]]]]]],[32,[[20,[[2,[1]]]]]],[33,[[20,[[2,[1]]]]]],[7,[[20,[[2,[1]]]]]],[8,[[20,[[2,[1]]]]]],[9,[[20,[19]]]],[10,[[20,[[16,[21,21,19]]]]]],[14,[[20,[36]]]],[6,[[20,[1]]]],[7,20],[8,20],[9,[[20,[19]]]],[10,[[20,[[16,[21,21,19]]]]]],[[5,[2,[1]]],[[20,[17]]]],[[5,5],[[20,[17]]]],[[5,22],[[20,[17]]]],[[5,[2,[1]]],[[20,[17]]]],[[5,22],[[20,[17]]]],[-1,16,[]],[-1,16,[]],[-1,16,[]],[-1,16,[]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[13,-1],[[20,[21]]],[[4,[[2,[1]]]]]],[[-1,1],[[20,[21]]],[]],[[-1,1],[[20,[21]]],[]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,19],[[20,[21]]],[]],[[-1,19],[[20,[21]]],[]],[[-1,-2],28,[],[3,[4,[[2,[1]]]]]],[[-1,-2],28,[],[3,[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[21]]],[],[[4,[[2,[1]]]]]],[[-1,-2],[[20,[[16,[[2,[1]],[2,[1]]]]]]],[],[3,[4,[[2,[1]]]]]],[[-1,-2],[[20,[[16,[[2,[1]],[2,[1]]]]]]],[],[3,[4,[[2,[1]]]]]],[[-1,-2],31,[],[3,[4,[[2,[1]]]]]],[[-1,-2],31,[],[3,[4,[[2,[1]]]]]],[[-1,21,-2],33,[],[3,[4,[[2,[1]]]]]],[[-1,21,-2],33,[],[3,[4,[[2,[1]]]]]],[6,[[16,[21,[20,[21]]]]]],[14,[[16,[21,[20,[21]]]]]],[[-1,-2],[[20,[[16,[[2,[1]],[2,[1]]]]]]],[],[3,[4,[[2,[1]]]]]],[[-1,-2],[[20,[[16,[[2,[1]],[2,[1]]]]]]],[],[3,[4,[[2,[1]]]]]],[[-1,-2],30,[],[3,[4,[[2,[1]]]]]],[[-1,-2],30,[],[3,[4,[[2,[1]]]]]],[[-1,21,-2],32,[],[3,[4,[[2,[1]]]]]],[[-1,21,-2],32,[],[3,[4,[[2,[1]]]]]],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[[-1,-2],18,[],[[4,[[2,[1]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[43,[22,15]]],[]],[-1,[[43,[22,15]]],[]],[-1,22,[]],[-1,22,[]],[-1,44,[]],[-1,44,[]],[-1,44,[]],[[-1,-2],[[2,[1]]],[],24],[[-1,-2],[[2,[1]]],[],24],[[-1,-2],[[2,[1]]],[],24],[[-1,-2],[[2,[1]]],[],24],[[-1,-2],[[2,[1]]],[],24],[[-1,-2],[[2,[1]]],[],24],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,[[43,[-2]]],[],[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,45,[]],[-1,14,[]],[-1,14,[]],[36,22],[15,21]],"c":[],"p":[[15,"u8"],[15,"slice"],[8,"Sized",386],[8,"AsRef",387],[3,"BStr",0],[3,"Bytes",0],[3,"Lines",0],[3,"LinesWithTerminator",0],[3,"Chars",0],[3,"CharIndices",0],[3,"EscapeBytes",0],[3,"Finder",0],[3,"FinderReverse",0],[3,"Utf8Chunks",0],[3,"Utf8Error",0],[15,"tuple"],[4,"Ordering",388],[15,"bool"],[15,"char"],[4,"Option",389],[15,"usize"],[15,"str"],[3,"FieldsWith",0],[8,"FnMut",390],[3,"Find",0],[3,"Formatter",391],[6,"Result",391],[3,"FindReverse",0],[8,"Debug",391],[3,"Split",0],[3,"SplitReverse",0],[3,"SplitN",0],[3,"SplitNReverse",0],[15,"array"],[8,"Hasher",392],[3,"Utf8Chunk",0],[3,"Range",393],[3,"RangeTo",393],[3,"RangeFull",393],[3,"RangeFrom",393],[3,"RangeInclusive",393],[3,"RangeToInclusive",393],[4,"Result",394],[3,"String",395],[3,"TypeId",396],[8,"ByteSlice",0]],"b":[[31,"impl-AsRef%3C%5Bu8%5D%3E-for-BStr"],[32,"impl-AsRef%3CBStr%3E-for-BStr"],[104,"impl-Default-for-%26BStr"],[105,"impl-Default-for-%26mut+BStr"],[110,"impl-PartialEq-for-BStr"],[111,"impl-PartialEq%3Cstr%3E-for-BStr"],[112,"impl-PartialEq%3C%26str%3E-for-BStr"],[113,"impl-PartialEq%3C%26%5Bu8%5D%3E-for-BStr"],[114,"impl-PartialEq%3C%5Bu8%5D%3E-for-BStr"],[136,"impl-Debug-for-BStr"],[137,"impl-Display-for-BStr"],[138,"impl-Debug-for-EscapeBytes%3C\'a%3E"],[139,"impl-Display-for-EscapeBytes%3C\'a%3E"],[155,"impl-Debug-for-Utf8Error"],[156,"impl-Display-for-Utf8Error"],[158,"impl-From%3C%26%5Bu8%5D%3E-for-%26BStr"],[159,"impl-From%3C%26%5Bu8;+N%5D%3E-for-%26BStr"],[160,"impl-From%3C%26str%3E-for-%26BStr"],[180,"impl-Index%3CRange%3Cusize%3E%3E-for-BStr"],[181,"impl-Index%3CRangeTo%3Cusize%3E%3E-for-BStr"],[182,"impl-Index%3CRangeFull%3E-for-BStr"],[183,"impl-Index%3CRangeFrom%3Cusize%3E%3E-for-BStr"],[184,"impl-Index%3Cusize%3E-for-BStr"],[185,"impl-Index%3CRangeInclusive%3Cusize%3E%3E-for-BStr"],[186,"impl-Index%3CRangeToInclusive%3Cusize%3E%3E-for-BStr"],[187,"impl-IndexMut%3CRangeToInclusive%3Cusize%3E%3E-for-BStr"],[188,"impl-IndexMut%3CRange%3Cusize%3E%3E-for-BStr"],[189,"impl-IndexMut%3CRangeFull%3E-for-BStr"],[190,"impl-IndexMut%3CRangeInclusive%3Cusize%3E%3E-for-BStr"],[191,"impl-IndexMut%3Cusize%3E-for-BStr"],[192,"impl-IndexMut%3CRangeTo%3Cusize%3E%3E-for-BStr"],[193,"impl-IndexMut%3CRangeFrom%3Cusize%3E%3E-for-BStr"],[266,"impl-PartialOrd%3C%26%5Bu8%5D%3E-for-BStr"],[267,"impl-PartialOrd-for-BStr"],[268,"impl-PartialOrd%3C%26str%3E-for-BStr"],[269,"impl-PartialOrd%3C%5Bu8%5D%3E-for-BStr"],[270,"impl-PartialOrd%3Cstr%3E-for-BStr"]]},\ +"memchr":{"doc":"This library provides heavily optimized routines for …","t":"DDDALLLLLLLLLLLLLLLLLLLLLLLLLFFFFFFAFFFFFFLLLLLLLLLLLLLLLLLLLLLLLLAAFFFFAAAAADDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDIDLLLLLLLLLLLLLLLLLLLLKLLLLLLLLLLLDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLDLLLLLLLLLLDDLLLLLLLLLLLLLLLLLLLLLLLLLLAAAADDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDLLLLLLLLLLLLLLLLLLAADDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDLLLLLLLLLLLLLLLLLLNDDDDDNELLLLLLLLLLLLLLLLLLLLLLLLLLLFLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLFLLLLLLLLLLLLLLLLLLLLLLLL","n":["Memchr","Memchr2","Memchr3","arch","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","count","fmt","fmt","fmt","from","from","from","into","into","into","into_iter","into_iter","into_iter","memchr","memchr2","memchr2_iter","memchr3","memchr3_iter","memchr_iter","memmem","memrchr","memrchr2","memrchr2_iter","memrchr3","memrchr3_iter","memrchr_iter","new","new","new","next","next","next","next_back","next_back","next_back","size_hint","size_hint","size_hint","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","all","x86_64","is_equal","is_equal_raw","is_prefix","is_suffix","memchr","packedpair","rabinkarp","shiftor","twoway","One","OneIter","Three","ThreeIter","Two","TwoIter","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","count","count","count_raw","find","find","find","find_raw","find_raw","find_raw","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","into_iter","into_iter","into_iter","iter","iter","iter","new","new","new","next","next","next","next_back","next_back","next_back","rfind","rfind","rfind","rfind_raw","rfind_raw","rfind_raw","size_hint","size_hint","size_hint","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","Finder","HeuristicFrequencyRank","Pair","borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","find_prefilter","fmt","fmt","from","from","index1","index2","into","into","new","new","pair","rank","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","with_indices","with_pair","with_ranker","Finder","FinderRev","borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","find","find_raw","fmt","fmt","from","from","into","into","new","new","rfind","rfind_raw","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","Finder","borrow","borrow_mut","find","fmt","from","into","new","try_from","try_into","type_id","Finder","FinderRev","borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","find","fmt","fmt","from","from","into","into","new","new","rfind","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","avx2","sse2","memchr","packedpair","One","OneIter","Three","ThreeIter","Two","TwoIter","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","count","count","count_raw","find","find","find","find_raw","find_raw","find_raw","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","into_iter","into_iter","into_iter","is_available","is_available","is_available","iter","iter","iter","new","new","new","new_unchecked","new_unchecked","new_unchecked","next","next","next","next_back","next_back","next_back","rfind","rfind","rfind","rfind_raw","rfind_raw","rfind_raw","size_hint","size_hint","size_hint","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","Finder","borrow","borrow_mut","clone","clone_into","find","find_prefilter","fmt","from","into","is_available","min_haystack_len","new","pair","to_owned","try_from","try_into","type_id","with_pair","memchr","packedpair","One","OneIter","Three","ThreeIter","Two","TwoIter","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","count","count","count_raw","find","find","find","find_raw","find_raw","find_raw","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","into_iter","into_iter","into_iter","is_available","is_available","is_available","iter","iter","iter","new","new","new","new_unchecked","new_unchecked","new_unchecked","next","next","next","next_back","next_back","next_back","rfind","rfind","rfind","rfind_raw","rfind_raw","rfind_raw","size_hint","size_hint","size_hint","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","Finder","borrow","borrow_mut","clone","clone_into","find","find_prefilter","fmt","from","into","is_available","min_haystack_len","new","pair","to_owned","try_from","try_into","type_id","with_pair","Auto","FindIter","FindRevIter","Finder","FinderBuilder","FinderRev","None","Prefilter","as_ref","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build_forward","build_forward_with_ranker","build_reverse","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","default","default","find","find","find_iter","find_iter","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","into","into","into","into","into","into","into_iter","into_iter","into_owned","into_owned","into_owned","into_owned","needle","needle","new","new","new","next","next","prefilter","rfind","rfind","rfind_iter","rfind_iter","size_hint","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id"],"q":[[0,"memchr"],[66,"memchr::arch"],[68,"memchr::arch::all"],[77,"memchr::arch::all::memchr"],[182,"memchr::arch::all::packedpair"],[217,"memchr::arch::all::rabinkarp"],[247,"memchr::arch::all::shiftor"],[258,"memchr::arch::all::twoway"],[286,"memchr::arch::x86_64"],[288,"memchr::arch::x86_64::avx2"],[290,"memchr::arch::x86_64::avx2::memchr"],[401,"memchr::arch::x86_64::avx2::packedpair"],[420,"memchr::arch::x86_64::sse2"],[422,"memchr::arch::x86_64::sse2::memchr"],[533,"memchr::arch::x86_64::sse2::packedpair"],[552,"memchr::memmem"],[650,"core::fmt"],[651,"core::fmt"],[652,"core::iter::adapters::rev"],[653,"core::result"],[654,"core::any"],[655,"core::marker"],[656,"core::convert"]],"d":["An iterator over all occurrences of a single byte in a …","An iterator over all occurrences of two possible bytes in …","An iterator over all occurrences of three possible bytes …","A module with low-level architecture dependent routines.","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","Search for the first occurrence of a byte in a slice.","Search for the first occurrence of two possible bytes in a …","Returns an iterator over all occurrences of the needles in …","Search for the first occurrence of three possible bytes in …","Returns an iterator over all occurrences of the needles in …","Returns an iterator over all occurrences of the needle in …","This module provides forward and reverse substring search …","Search for the last occurrence of a byte in a slice.","Search for the last occurrence of two possible bytes in a …","Returns an iterator over all occurrences of the needles in …","Search for the last occurrence of three possible bytes in …","Returns an iterator over all occurrences of the needles in …","Returns an iterator over all occurrences of the needle in …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","","","","","","","","","","","","","","","","","","","","","","Contains architecture independent routines.","Vector algorithms for the x86_64 target.","Compare corresponding bytes in x and y for equality.","Compare n bytes at the given pointers for equality.","Returns true if and only if needle is a prefix of haystack.","Returns true if and only if needle is a suffix of haystack.","Provides architecture independent implementations of memchr…","Provides an architecture independent implementation of the …","An implementation of the Rabin-Karp substring search …","An implementation of the Shift-Or substring search …","An implementation of the Two-Way substring search algorithm…","Finds all occurrences of a single byte in a haystack.","An iterator over all occurrences of a single byte in a …","Finds all occurrences of three bytes in a haystack.","An iterator over all occurrences of three possible bytes …","Finds all occurrences of two bytes in a haystack.","An iterator over all occurrences of two possible bytes in …","","","","","","","","","","","","","","","","","","","","","","","","","Counts all occurrences of this byte in the given haystack.","","Counts all occurrences of this byte in the given haystack …","Return the first occurrence of the needle in the given …","Return the first occurrence of one of the needle bytes in …","Return the first occurrence of one of the needle bytes in …","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of one of the …","Returns an iterator over all occurrences of one of the …","Create a new searcher that finds occurrences of the byte …","Create a new searcher that finds occurrences of the two …","Create a new searcher that finds occurrences of the three …","","","","","","","Return the last occurrence of the needle in the given …","Return the last occurrence of one of the needle bytes in …","Return the last occurrence of one of the needle bytes in …","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","","","","","","","","","","","","","","","","","","","","","","","","","","","","An architecture independent “packed pair” finder.","This trait allows the user to customize the heuristic used …","A pair of byte offsets into a needle to use as a predicate.","","","","","","","","","Run this finder on the given haystack as a prefilter.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the first offset of the pair.","Returns the second offset of the pair.","Calls U::from(self).","Calls U::from(self).","Create a new prefilter that reports possible locations …","Create a new pair of offsets from the given needle.","Returns the pair of offsets (into the needle) used to …","Return the heuristic frequency rank of the given byte. A …","","","","","","","","","Create a new pair using the offsets given for the needle …","Create a new prefilter using the pair given.","Create a new pair of offsets from the given needle and …","A forward substring searcher using the Rabin-Karp …","A reverse substring searcher using the Rabin-Karp …","","","","","","","","","Return the first occurrence of the needle in the haystack …","Like find, but accepts and returns raw pointers.","","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Create a new Rabin-Karp forward searcher for the given …","Create a new Rabin-Karp reverse searcher for the given …","Return the last occurrence of the needle in the haystack …","Like rfind, but accepts and returns raw pointers.","","","","","","","","","A forward substring searcher using the Shift-Or algorithm.","","","Return the first occurrence of the needle given to …","","Returns the argument unchanged.","Calls U::from(self).","Create a new Shift-Or forward searcher for the given needle…","","","","A forward substring searcher that uses the Two-Way …","A reverse substring searcher that uses the Two-Way …","","","","","","","","","Returns the first occurrence of needle in the given …","","","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Create a searcher that finds occurrences of the given …","Create a searcher that finds occurrences of the given …","Returns the last occurrence of needle in the given haystack…","","","","","","","","","Algorithms for the x86_64 target using 256-bit vectors via …","Algorithms for the x86_64 target using 128-bit vectors via …","This module defines 256-bit vector implementations of …","A 256-bit vector implementation of the “packed pair” …","Finds all occurrences of a single byte in a haystack.","An iterator over all occurrences of a single byte in a …","Finds all occurrences of three bytes in a haystack.","An iterator over all occurrences of three possible bytes …","Finds all occurrences of two bytes in a haystack.","An iterator over all occurrences of two possible bytes in …","","","","","","","","","","","","","","","","","","","","","","","","","Counts all occurrences of this byte in the given haystack.","","Counts all occurrences of this byte in the given haystack …","Return the first occurrence of one of the needle bytes in …","Return the first occurrence of one of the needle bytes in …","Return the first occurrence of one of the needle bytes in …","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","Returns true when this implementation is available in the …","Returns true when this implementation is available in the …","Returns true when this implementation is available in the …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new finder specific to AVX2 vectors and routines …","Create a new finder specific to AVX2 vectors and routines …","Create a new finder specific to AVX2 vectors and routines …","","","","","","","Return the last occurrence of one of the needle bytes in …","Return the last occurrence of one of the needle bytes in …","Return the last occurrence of one of the needle bytes in …","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","","","","","","","","","","","","","","","","","","","","","","","","","","","","A “packed pair” finder that uses 256-bit vector …","","","","","Execute a search using AVX2 vectors and routines.","Run this finder on the given haystack as a prefilter.","","Returns the argument unchanged.","Calls U::from(self).","Returns true when this implementation is available in the …","Returns the minimum haystack length that this Finder can …","Create a new pair searcher. The searcher returned can …","Returns the pair of offsets (into the needle) used to …","","","","","Create a new “packed pair” finder using the pair of …","This module defines 128-bit vector implementations of …","A 128-bit vector implementation of the “packed pair” …","Finds all occurrences of a single byte in a haystack.","An iterator over all occurrences of a single byte in a …","Finds all occurrences of three bytes in a haystack.","An iterator over all occurrences of three possible bytes …","Finds all occurrences of two bytes in a haystack.","An iterator over all occurrences of two possible bytes in …","","","","","","","","","","","","","","","","","","","","","","","","","Counts all occurrences of this byte in the given haystack.","","Counts all occurrences of this byte in the given haystack …","Return the first occurrence of one of the needle bytes in …","Return the first occurrence of one of the needle bytes in …","Return the first occurrence of one of the needle bytes in …","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","Like find, but accepts and returns raw pointers.","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","Returns true when this implementation is available in the …","Returns true when this implementation is available in the …","Returns true when this implementation is available in the …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","Returns an iterator over all occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new searcher that finds occurrences of the needle …","Create a new finder specific to SSE2 vectors and routines …","Create a new finder specific to SSE2 vectors and routines …","Create a new finder specific to SSE2 vectors and routines …","","","","","","","Return the last occurrence of one of the needle bytes in …","Return the last occurrence of one of the needle bytes in …","Return the last occurrence of one of the needle bytes in …","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","Like rfind, but accepts and returns raw pointers.","","","","","","","","","","","","","","","","","","","","","","","","","","","","A “packed pair” finder that uses 128-bit vector …","","","","","Execute a search using SSE2 vectors and routines.","Run this finder on the given haystack as a prefilter.","","Returns the argument unchanged.","Calls U::from(self).","Returns true when this implementation is available in the …","Returns the minimum haystack length that this Finder can …","Create a new pair searcher. The searcher returned can …","Returns the pair of offsets (into the needle) used to …","","","","","Create a new “packed pair” finder using the pair of …","Automatically detect whether a heuristic prefilter should …","An iterator over non-overlapping substring matches.","An iterator over non-overlapping substring matches in …","A single substring searcher fixed to a particular needle.","A builder for constructing non-default forward or reverse …","A single substring reverse searcher fixed to a particular …","Never used a prefilter in substring search.","Prefilter controls whether heuristics are used to …","Convert this finder into its borrowed variant.","Convert this finder into its borrowed variant.","","","","","","","","","","","","","Build a forward finder using the given needle from the …","Build a forward finder using the given needle and a custom …","Build a reverse finder using the given needle from the …","","","","","","","","","","","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of this needle …","Returns an iterator over all non-overlapping occurrences …","Returns an iterator over all occurrences of a substring in …","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Convert this iterator into its owned variant, such that it …","Convert this iterator into its owned variant, such that it …","Convert this finder into its owned variant, such that it …","Convert this finder into its owned variant, such that it …","Returns the needle that this finder searches for.","Returns the needle that this finder searches for.","Create a new finder for the given needle.","Create a new reverse finder for the given needle.","Create a new finder builder with default settings.","","","Configure the prefilter setting for the finder.","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of this needle in …","Returns a reverse iterator over all non-overlapping …","Returns a reverse iterator over all occurrences of a …","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,0,0,0,1,2,3,1,2,3,1,2,3,1,2,3,1,1,2,3,1,2,3,1,2,3,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,16,17,18,19,20,15,16,17,18,19,20,15,16,17,18,19,20,15,16,17,18,19,20,15,16,15,15,17,19,15,17,19,15,16,17,18,19,20,15,16,17,18,19,20,15,16,17,18,19,20,16,18,20,15,17,19,15,17,19,16,18,20,16,18,20,15,17,19,15,17,19,16,18,20,15,16,17,18,19,20,15,16,17,18,19,20,15,16,17,18,19,20,15,16,17,18,19,20,0,0,0,21,22,21,22,21,22,21,22,21,21,22,21,22,22,22,21,22,21,22,21,23,21,22,21,22,21,22,21,22,22,21,22,0,0,24,25,24,25,24,25,24,25,24,24,24,25,24,25,24,25,24,25,25,25,24,25,24,25,24,25,24,25,0,26,26,26,26,26,26,26,26,26,26,0,0,27,28,27,28,27,28,27,28,27,27,28,27,28,27,28,27,28,28,27,28,27,28,27,28,27,28,0,0,0,0,0,0,0,0,0,0,29,30,31,32,33,34,29,30,31,32,33,34,29,30,31,32,33,34,29,30,31,32,33,34,29,30,29,29,31,33,29,31,33,29,30,31,32,33,34,29,30,31,32,33,34,29,30,31,32,33,34,30,32,34,29,31,33,29,31,33,29,31,33,29,31,33,30,32,34,30,32,34,29,31,33,29,31,33,30,32,34,29,30,31,32,33,34,29,30,31,32,33,34,29,30,31,32,33,34,29,30,31,32,33,34,0,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,0,0,0,0,0,0,0,0,36,37,38,39,40,41,36,37,38,39,40,41,36,37,38,39,40,41,36,37,38,39,40,41,36,37,36,36,38,40,36,38,40,36,37,38,39,40,41,36,37,38,39,40,41,36,37,38,39,40,41,37,39,41,36,38,40,36,38,40,36,38,40,36,38,40,37,39,41,37,39,41,36,38,40,36,38,40,37,39,41,36,37,38,39,40,41,36,37,38,39,40,41,36,37,38,39,40,41,36,37,38,39,40,41,0,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,48,0,0,0,0,0,48,0,43,44,48,49,50,43,44,45,48,49,50,43,44,45,45,45,45,48,43,44,45,48,43,44,45,48,45,0,43,0,43,48,49,50,43,44,45,48,49,50,43,44,45,48,49,50,43,44,45,49,50,49,50,43,44,43,44,43,44,45,49,50,45,0,44,0,44,49,48,43,44,45,48,49,50,43,44,45,48,49,50,43,44,45,48,49,50,43,44,45],"f":[0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[1,1],[2,2],[3,3],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[1,5],[[1,6],7],[[2,6],7],[[3,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[8,[9,[8]]],[[10,[5]]]],[[8,8,[9,[8]]],[[10,[5]]]],[[8,8,[9,[8]]],2],[[8,8,8,[9,[8]]],[[10,[5]]]],[[8,8,8,[9,[8]]],3],[[8,[9,[8]]],1],0,[[8,[9,[8]]],[[10,[5]]]],[[8,8,[9,[8]]],[[10,[5]]]],[[8,8,[9,[8]]],[[11,[2]]]],[[8,8,8,[9,[8]]],[[10,[5]]]],[[8,8,8,[9,[8]]],[[11,[3]]]],[[8,[9,[8]]],[[11,[1]]]],[[8,[9,[8]]],1],[[8,8,[9,[8]]],2],[[8,8,8,[9,[8]]],3],[1,[[10,[5]]]],[2,[[10,[5]]]],[3,[[10,[5]]]],[1,[[10,[5]]]],[2,[[10,[5]]]],[3,[[10,[5]]]],[1,[[4,[5,[10,[5]]]]]],[2,[[4,[5,[10,[5]]]]]],[3,[[4,[5,[10,[5]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],0,0,[[[9,[8]],[9,[8]]],14],[[8,8,5],14],[[[9,[8]],[9,[8]]],14],[[[9,[8]],[9,[8]]],14],0,0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[15,15],[16,16],[17,17],[18,18],[19,19],[20,20],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[15,[9,[8]]],5],[16,5],[[15,8,8],5],[[15,[9,[8]]],[[10,[5]]]],[[17,[9,[8]]],[[10,[5]]]],[[19,[9,[8]]],[[10,[5]]]],[[15,8,8],[[10,[8]]]],[[17,8,8],[[10,[8]]]],[[19,8,8],[[10,[8]]]],[[15,6],7],[[16,6],7],[[17,6],7],[[18,6],7],[[19,6],7],[[20,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[15,[9,[8]]],16],[[17,[9,[8]]],18],[[19,[9,[8]]],20],[8,15],[[8,8],17],[[8,8,8],19],[16,[[10,[5]]]],[18,[[10,[5]]]],[20,[[10,[5]]]],[16,[[10,[5]]]],[18,[[10,[5]]]],[20,[[10,[5]]]],[[15,[9,[8]]],[[10,[5]]]],[[17,[9,[8]]],[[10,[5]]]],[[19,[9,[8]]],[[10,[5]]]],[[15,8,8],[[10,[8]]]],[[17,8,8],[[10,[8]]]],[[19,8,8],[[10,[8]]]],[16,[[4,[5,[10,[5]]]]]],[18,[[4,[5,[10,[5]]]]]],[20,[[4,[5,[10,[5]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[21,21],[22,22],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[21,[9,[8]]],[[10,[5]]]],[[21,6],7],[[22,6],7],[-1,-1,[]],[-1,-1,[]],[22,8],[22,8],[-1,-2,[],[]],[-1,-2,[],[]],[[[9,[8]]],[[10,[21]]]],[[[9,[8]]],[[10,[22]]]],[21,22],[[-1,8],8,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[[[9,[8]],8,8],[[10,[22]]]],[[[9,[8]],22],[[10,[21]]]],[[[9,[8]],-1],[[10,[22]]],23],0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[24,24],[25,25],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[24,[9,[8]],[9,[8]]],[[10,[5]]]],[[24,8,8,8,8],[[10,[8]]]],[[24,6],7],[[25,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[9,[8]]],24],[[[9,[8]]],25],[[25,[9,[8]],[9,[8]]],[[10,[5]]]],[[25,8,8,8,8],[[10,[8]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[[26,[9,[8]]],[[10,[5]]]],[[26,6],7],[-1,-1,[]],[-1,-2,[],[]],[[[9,[8]]],[[10,[26]]]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[27,27],[28,28],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[27,[9,[8]],[9,[8]]],[[10,[5]]]],[[27,6],7],[[28,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[9,[8]]],27],[[[9,[8]]],28],[[28,[9,[8]],[9,[8]]],[[10,[5]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[29,29],[30,30],[31,31],[32,32],[33,33],[34,34],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[29,[9,[8]]],5],[30,5],[[29,8,8],5],[[29,[9,[8]]],[[10,[5]]]],[[31,[9,[8]]],[[10,[5]]]],[[33,[9,[8]]],[[10,[5]]]],[[29,8,8],[[10,[8]]]],[[31,8,8],[[10,[8]]]],[[33,8,8],[[10,[8]]]],[[29,6],7],[[30,6],7],[[31,6],7],[[32,6],7],[[33,6],7],[[34,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],14],[[],14],[[],14],[[29,[9,[8]]],30],[[31,[9,[8]]],32],[[33,[9,[8]]],34],[8,[[10,[29]]]],[[8,8],[[10,[31]]]],[[8,8,8],[[10,[33]]]],[8,29],[[8,8],31],[[8,8,8],33],[30,[[10,[5]]]],[32,[[10,[5]]]],[34,[[10,[5]]]],[30,[[10,[5]]]],[32,[[10,[5]]]],[34,[[10,[5]]]],[[29,[9,[8]]],[[10,[5]]]],[[31,[9,[8]]],[[10,[5]]]],[[33,[9,[8]]],[[10,[5]]]],[[29,8,8],[[10,[8]]]],[[31,8,8],[[10,[8]]]],[[33,8,8],[[10,[8]]]],[30,[[4,[5,[10,[5]]]]]],[32,[[4,[5,[10,[5]]]]]],[34,[[4,[5,[10,[5]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[35,35],[[-1,-2],4,[],[]],[[35,[9,[8]],[9,[8]]],[[10,[5]]]],[[35,[9,[8]]],[[10,[5]]]],[[35,6],7],[-1,-1,[]],[-1,-2,[],[]],[[],14],[35,5],[[[9,[8]]],[[10,[35]]]],[35,22],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[[[9,[8]],22],[[10,[35]]]],0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[36,36],[37,37],[38,38],[39,39],[40,40],[41,41],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[36,[9,[8]]],5],[37,5],[[36,8,8],5],[[36,[9,[8]]],[[10,[5]]]],[[38,[9,[8]]],[[10,[5]]]],[[40,[9,[8]]],[[10,[5]]]],[[36,8,8],[[10,[8]]]],[[38,8,8],[[10,[8]]]],[[40,8,8],[[10,[8]]]],[[36,6],7],[[37,6],7],[[38,6],7],[[39,6],7],[[40,6],7],[[41,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[],14],[[],14],[[],14],[[36,[9,[8]]],37],[[38,[9,[8]]],39],[[40,[9,[8]]],41],[8,[[10,[36]]]],[[8,8],[[10,[38]]]],[[8,8,8],[[10,[40]]]],[8,36],[[8,8],38],[[8,8,8],40],[37,[[10,[5]]]],[39,[[10,[5]]]],[41,[[10,[5]]]],[37,[[10,[5]]]],[39,[[10,[5]]]],[41,[[10,[5]]]],[[36,[9,[8]]],[[10,[5]]]],[[38,[9,[8]]],[[10,[5]]]],[[40,[9,[8]]],[[10,[5]]]],[[36,8,8],[[10,[8]]]],[[38,8,8],[[10,[8]]]],[[40,8,8],[[10,[8]]]],[37,[[4,[5,[10,[5]]]]]],[39,[[4,[5,[10,[5]]]]]],[41,[[4,[5,[10,[5]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],0,[-1,-2,[],[]],[-1,-2,[],[]],[42,42],[[-1,-2],4,[],[]],[[42,[9,[8]],[9,[8]]],[[10,[5]]]],[[42,[9,[8]]],[[10,[5]]]],[[42,6],7],[-1,-1,[]],[-1,-2,[],[]],[[],14],[42,5],[[[9,[8]]],[[10,[42]]]],[42,22],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[[[9,[8]],22],[[10,[42]]]],0,0,0,0,0,0,0,0,[43,43],[44,44],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[45,-1],43,[46,[47,[[9,[8]]]]]],[[45,-1,-2],43,23,[46,[47,[[9,[8]]]]]],[[45,-1],44,[46,[47,[[9,[8]]]]]],[48,48],[43,43],[44,44],[45,45],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[-1,-2],4,[],[]],[[],48],[[],45],[[[9,[8]],[9,[8]]],[[10,[5]]]],[[43,[9,[8]]],[[10,[5]]]],[[[9,[8]],-1],49,[46,[47,[[9,[8]]]]]],[[43,[9,[8]]],49],[[48,6],7],[[49,6],7],[[50,6],7],[[43,6],7],[[44,6],7],[[45,6],7],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[49,49],[50,50],[43,43],[44,44],[43,[[9,[8]]]],[44,[[9,[8]]]],[-1,43,[46,[47,[[9,[8]]]]]],[-1,44,[46,[47,[[9,[8]]]]]],[[],45],[49,[[10,[5]]]],[50,[[10,[5]]]],[[45,48],45],[[[9,[8]],[9,[8]]],[[10,[5]]]],[[44,-1],[[10,[5]]],[[47,[[9,[8]]]]]],[[[9,[8]],-1],50,[46,[47,[[9,[8]]]]]],[[44,[9,[8]]],50],[49,[[4,[5,[10,[5]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,[[12,[-2]]],[],[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]],[-1,13,[]]],"c":[],"p":[[3,"Memchr",0],[3,"Memchr2",0],[3,"Memchr3",0],[15,"tuple"],[15,"usize"],[3,"Formatter",650],[6,"Result",650],[15,"u8"],[15,"slice"],[4,"Option",651],[3,"Rev",652],[4,"Result",653],[3,"TypeId",654],[15,"bool"],[3,"One",77],[3,"OneIter",77],[3,"Two",77],[3,"TwoIter",77],[3,"Three",77],[3,"ThreeIter",77],[3,"Finder",182],[3,"Pair",182],[8,"HeuristicFrequencyRank",182],[3,"Finder",217],[3,"FinderRev",217],[3,"Finder",247],[3,"Finder",258],[3,"FinderRev",258],[3,"One",290],[3,"OneIter",290],[3,"Two",290],[3,"TwoIter",290],[3,"Three",290],[3,"ThreeIter",290],[3,"Finder",401],[3,"One",422],[3,"OneIter",422],[3,"Two",422],[3,"TwoIter",422],[3,"Three",422],[3,"ThreeIter",422],[3,"Finder",533],[3,"Finder",552],[3,"FinderRev",552],[3,"FinderBuilder",552],[8,"Sized",655],[8,"AsRef",656],[4,"Prefilter",552],[3,"FindIter",552],[3,"FindRevIter",552]],"b":[]},\ +"roe":{"doc":"This crate provides Unicode case mapping routines and …","t":"NNNNNDNNDENNDELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFFFLLLLLLLLLLLFFFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLLLL","n":["Ascii","Ascii","Fold","Full","Full","InvalidCaseMappingMode","Lithuanian","Lithuanian","Lowercase","LowercaseMode","Turkic","Turkic","Uppercase","UppercaseMode","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","count","count","default","default","default","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_str","from_str","hash","hash","hash","into","into","into","into","into","into_iter","into_iter","lowercase","make_ascii_lowercase","make_ascii_titlecase","make_ascii_uppercase","message","new","new","new","next","next","partial_cmp","partial_cmp","partial_cmp","size_hint","size_hint","to_ascii_lowercase","to_ascii_titlecase","to_ascii_uppercase","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","uppercase","with_ascii_slice","with_ascii_slice","with_slice","with_slice"],"q":[[0,"roe"],[120,"core::cmp"],[121,"core::fmt"],[122,"core::fmt"],[123,"core::hash"],[124,"core::convert"],[125,"core::option"],[126,"alloc::vec"],[127,"core::convert"],[128,"core::any"]],"d":["Only the ASCII region, i.e. the characters 'A'..='Z' and …","Only the ASCII region, i.e. the characters 'A'..='Z' and …","Unicode case folding, which is more far-reaching than …","Full Unicode case mapping, suitable for most languages.","Full Unicode case mapping, suitable for most languages.","Error that indicates a failure to parse a LowercaseMode or …","Currently, just full Unicode case mapping.","Currently, just full Unicode case mapping.","An iterator that yields the lowercase equivalent of a …","Options to configure the behavior of lowercase.","Full Unicode case mapping, adapted for Turkic languages …","Full Unicode case mapping, adapted for Turkic languages …","An iterator that yields the uppercase equivalent of a …","Options to configure the behavior of uppercase.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Returns an iterator that yields a copy of the bytes in the …","Converts the given slice to its ASCII lower case …","Converts the given slice to its ASCII title case …","Converts the given slice to its ASCII upper case …","Retrieve the error message associated with this …","Create a new, empty lowercase iterator.","Create a new, empty uppercase iterator.","Construct a new InvalidCaseMappingMode error.","","","","","","","","Returns a vector containing a copy of the given slice …","Returns a vector containing a copy of the given slice …","Returns a vector containing a copy of the given slice …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns an iterator that yields a copy of the bytes in the …","Create a new lowercase iterator with the given byte slice …","Create a new uppercase iterator with the given byte slice …","Create a new lowercase iterator with the given byte slice …","Create a new uppercase iterator with the given byte slice …"],"i":[4,5,4,4,5,0,4,5,0,0,4,5,0,0,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,3,4,5,1,2,3,4,5,3,4,5,1,2,3,3,4,5,1,2,3,4,5,4,5,3,4,5,1,2,3,4,5,1,2,0,0,0,0,3,1,2,3,1,2,3,4,5,1,2,0,0,0,1,2,3,4,5,3,1,2,3,4,4,4,4,4,5,5,5,5,5,1,2,3,4,5,1,2,3,4,5,0,1,2,1,2],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[1,1],[2,2],[3,3],[4,4],[5,5],[[-1,-2],6,[],[]],[[-1,-2],6,[],[]],[[-1,-2],6,[],[]],[[-1,-2],6,[],[]],[[-1,-2],6,[],[]],[[3,3],7],[[4,4],7],[[5,5],7],[1,8],[2,8],[[],3],[[],4],[[],5],[[3,3],9],[[4,4],9],[[5,5],9],[[1,10],11],[[2,10],11],[[3,10],11],[[3,10],11],[[4,10],11],[[5,10],11],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[12,[[13,[4]]]],[12,[[13,[5]]]],[[3,-1],6,14],[[4,-1],6,14],[[5,-1],6,14],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[[[16,[15]],4],1],[-1,6,[[17,[[16,[15]]]]]],[-1,6,[[17,[[16,[15]]]]]],[-1,6,[[17,[[16,[15]]]]]],[3,12],[[],1],[[],2],[[],3],[1,18],[2,18],[[3,3],[[18,[7]]]],[[4,4],[[18,[7]]]],[[5,5],[[18,[7]]]],[1,[[6,[8,[18,[8]]]]]],[2,[[6,[8,[18,[8]]]]]],[-1,[[19,[15]]],[[20,[[16,[15]]]]]],[-1,[[19,[15]]],[[20,[[16,[15]]]]]],[-1,[[19,[15]]],[[20,[[16,[15]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,21,[]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[[[18,[[16,[15]]]]],[[13,[4]]]],[[[18,[12]]],[[13,[4]]]],[-1,[[13,[-2]]],[],[]],[[[16,[15]]],[[13,[4]]]],[12,[[13,[4]]]],[-1,[[13,[-2]]],[],[]],[[[18,[[16,[15]]]]],[[13,[5]]]],[12,[[13,[5]]]],[[[18,[12]]],[[13,[5]]]],[[[16,[15]]],[[13,[5]]]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[-1,[[13,[-2]]],[],[]],[-1,22,[]],[-1,22,[]],[-1,22,[]],[-1,22,[]],[-1,22,[]],[[[16,[15]],5],2],[[[16,[15]]],1],[[[16,[15]]],2],[[[16,[15]]],1],[[[16,[15]]],2]],"c":[],"p":[[3,"Lowercase",0],[3,"Uppercase",0],[3,"InvalidCaseMappingMode",0],[4,"LowercaseMode",0],[4,"UppercaseMode",0],[15,"tuple"],[4,"Ordering",120],[15,"usize"],[15,"bool"],[3,"Formatter",121],[6,"Result",121],[15,"str"],[4,"Result",122],[8,"Hasher",123],[15,"u8"],[15,"slice"],[8,"AsMut",124],[4,"Option",125],[3,"Vec",126],[8,"AsRef",124],[3,"String",127],[3,"TypeId",128]],"b":[[47,"impl-Debug-for-InvalidCaseMappingMode"],[48,"impl-Display-for-InvalidCaseMappingMode"],[95,"impl-TryFrom%3COption%3C%26%5Bu8%5D%3E%3E-for-LowercaseMode"],[96,"impl-TryFrom%3COption%3C%26str%3E%3E-for-LowercaseMode"],[98,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-LowercaseMode"],[99,"impl-TryFrom%3C%26str%3E-for-LowercaseMode"],[101,"impl-TryFrom%3COption%3C%26%5Bu8%5D%3E%3E-for-UppercaseMode"],[102,"impl-TryFrom%3C%26str%3E-for-UppercaseMode"],[103,"impl-TryFrom%3COption%3C%26str%3E%3E-for-UppercaseMode"],[104,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-UppercaseMode"]]}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/settings.html b/settings.html new file mode 100644 index 000000000..aced12316 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 000000000..a1685f44f --- /dev/null +++ b/src-files.js @@ -0,0 +1,6 @@ +var srcIndex = JSON.parse('{\ +"bstr":["",[["byteset",[],["mod.rs","scalar.rs"]]],["ascii.rs","bstr.rs","escape_bytes.rs","ext_slice.rs","impls.rs","lib.rs","utf8.rs"]],\ +"memchr":["",[["arch",[["all",[["packedpair",[],["default_rank.rs","mod.rs"]]],["memchr.rs","mod.rs","rabinkarp.rs","shiftor.rs","twoway.rs"]],["generic",[],["memchr.rs","mod.rs","packedpair.rs"]],["x86_64",[["avx2",[],["memchr.rs","mod.rs","packedpair.rs"]],["sse2",[],["memchr.rs","mod.rs","packedpair.rs"]]],["memchr.rs","mod.rs"]]],["mod.rs"]],["memmem",[],["mod.rs","searcher.rs"]]],["cow.rs","ext.rs","lib.rs","macros.rs","memchr.rs","vector.rs"]],\ +"roe":["",[["ascii",[],["lowercase.rs","titlecase.rs","uppercase.rs"]],["lowercase",[],["ascii.rs","full.rs"]],["uppercase",[],["ascii.rs","full.rs"]]],["ascii.rs","lib.rs","lowercase.rs","uppercase.rs"]]\ +}'); +createSrcSidebar(); diff --git a/src/bstr/ascii.rs.html b/src/bstr/ascii.rs.html new file mode 100644 index 000000000..71e4fdb33 --- /dev/null +++ b/src/bstr/ascii.rs.html @@ -0,0 +1,675 @@ +ascii.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+
// The following ~400 lines of code exists for exactly one purpose, which is
+// to optimize this code:
+//
+//     byte_slice.iter().position(|&b| b > 0x7F).unwrap_or(byte_slice.len())
+//
+// Yes... Overengineered is a word that comes to mind, but this is effectively
+// a very similar problem to memchr, and virtually nobody has been able to
+// resist optimizing the crap out of that (except for perhaps the BSD and MUSL
+// folks). In particular, this routine makes a very common case (ASCII) very
+// fast, which seems worth it. We do stop short of adding AVX variants of the
+// code below in order to retain our sanity and also to avoid needing to deal
+// with runtime target feature detection. RESIST!
+//
+// In order to understand the SIMD version below, it would be good to read this
+// comment describing how my memchr routine works:
+// https://github.com/BurntSushi/rust-memchr/blob/b0a29f267f4a7fad8ffcc8fe8377a06498202883/src/x86/sse2.rs#L19-L106
+//
+// The primary difference with memchr is that for ASCII, we can do a bit less
+// work. In particular, we don't need to detect the presence of a specific
+// byte, but rather, whether any byte has its most significant bit set. That
+// means we can effectively skip the _mm_cmpeq_epi8 step and jump straight to
+// _mm_movemask_epi8.
+
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+const USIZE_BYTES: usize = core::mem::size_of::<usize>();
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+const FALLBACK_LOOP_SIZE: usize = 2 * USIZE_BYTES;
+
+// This is a mask where the most significant bit of each byte in the usize
+// is set. We test this bit to determine whether a character is ASCII or not.
+// Namely, a single byte is regarded as an ASCII codepoint if and only if it's
+// most significant bit is not set.
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+const ASCII_MASK_U64: u64 = 0x8080808080808080;
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+const ASCII_MASK: usize = ASCII_MASK_U64 as usize;
+
+/// Returns the index of the first non ASCII byte in the given slice.
+///
+/// If slice only contains ASCII bytes, then the length of the slice is
+/// returned.
+pub fn first_non_ascii_byte(slice: &[u8]) -> usize {
+    #[cfg(any(miri, not(target_arch = "x86_64")))]
+    {
+        first_non_ascii_byte_fallback(slice)
+    }
+
+    #[cfg(all(not(miri), target_arch = "x86_64"))]
+    {
+        first_non_ascii_byte_sse2(slice)
+    }
+}
+
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+fn first_non_ascii_byte_fallback(slice: &[u8]) -> usize {
+    let align = USIZE_BYTES - 1;
+    let start_ptr = slice.as_ptr();
+    let end_ptr = slice[slice.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    unsafe {
+        if slice.len() < USIZE_BYTES {
+            return first_non_ascii_byte_slow(start_ptr, end_ptr, ptr);
+        }
+
+        let chunk = read_unaligned_usize(ptr);
+        let mask = chunk & ASCII_MASK;
+        if mask != 0 {
+            return first_non_ascii_byte_mask(mask);
+        }
+
+        ptr = ptr_add(ptr, USIZE_BYTES - (start_ptr as usize & align));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(ptr_sub(end_ptr, USIZE_BYTES) >= start_ptr);
+        if slice.len() >= FALLBACK_LOOP_SIZE {
+            while ptr <= ptr_sub(end_ptr, FALLBACK_LOOP_SIZE) {
+                debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+                let a = *(ptr as *const usize);
+                let b = *(ptr_add(ptr, USIZE_BYTES) as *const usize);
+                if (a | b) & ASCII_MASK != 0 {
+                    // What a kludge. We wrap the position finding code into
+                    // a non-inlineable function, which makes the codegen in
+                    // the tight loop above a bit better by avoiding a
+                    // couple extra movs. We pay for it by two additional
+                    // stores, but only in the case of finding a non-ASCII
+                    // byte.
+                    #[inline(never)]
+                    unsafe fn findpos(
+                        start_ptr: *const u8,
+                        ptr: *const u8,
+                    ) -> usize {
+                        let a = *(ptr as *const usize);
+                        let b = *(ptr_add(ptr, USIZE_BYTES) as *const usize);
+
+                        let mut at = sub(ptr, start_ptr);
+                        let maska = a & ASCII_MASK;
+                        if maska != 0 {
+                            return at + first_non_ascii_byte_mask(maska);
+                        }
+
+                        at += USIZE_BYTES;
+                        let maskb = b & ASCII_MASK;
+                        debug_assert!(maskb != 0);
+                        return at + first_non_ascii_byte_mask(maskb);
+                    }
+                    return findpos(start_ptr, ptr);
+                }
+                ptr = ptr_add(ptr, FALLBACK_LOOP_SIZE);
+            }
+        }
+        first_non_ascii_byte_slow(start_ptr, end_ptr, ptr)
+    }
+}
+
+#[cfg(all(not(miri), target_arch = "x86_64"))]
+fn first_non_ascii_byte_sse2(slice: &[u8]) -> usize {
+    use core::arch::x86_64::*;
+
+    const VECTOR_SIZE: usize = core::mem::size_of::<__m128i>();
+    const VECTOR_ALIGN: usize = VECTOR_SIZE - 1;
+    const VECTOR_LOOP_SIZE: usize = 4 * VECTOR_SIZE;
+
+    let start_ptr = slice.as_ptr();
+    let end_ptr = slice[slice.len()..].as_ptr();
+    let mut ptr = start_ptr;
+
+    unsafe {
+        if slice.len() < VECTOR_SIZE {
+            return first_non_ascii_byte_slow(start_ptr, end_ptr, ptr);
+        }
+
+        let chunk = _mm_loadu_si128(ptr as *const __m128i);
+        let mask = _mm_movemask_epi8(chunk);
+        if mask != 0 {
+            return mask.trailing_zeros() as usize;
+        }
+
+        ptr = ptr.add(VECTOR_SIZE - (start_ptr as usize & VECTOR_ALIGN));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(end_ptr.sub(VECTOR_SIZE) >= start_ptr);
+        if slice.len() >= VECTOR_LOOP_SIZE {
+            while ptr <= ptr_sub(end_ptr, VECTOR_LOOP_SIZE) {
+                debug_assert_eq!(0, (ptr as usize) % VECTOR_SIZE);
+
+                let a = _mm_load_si128(ptr as *const __m128i);
+                let b = _mm_load_si128(ptr.add(VECTOR_SIZE) as *const __m128i);
+                let c =
+                    _mm_load_si128(ptr.add(2 * VECTOR_SIZE) as *const __m128i);
+                let d =
+                    _mm_load_si128(ptr.add(3 * VECTOR_SIZE) as *const __m128i);
+
+                let or1 = _mm_or_si128(a, b);
+                let or2 = _mm_or_si128(c, d);
+                let or3 = _mm_or_si128(or1, or2);
+                if _mm_movemask_epi8(or3) != 0 {
+                    let mut at = sub(ptr, start_ptr);
+                    let mask = _mm_movemask_epi8(a);
+                    if mask != 0 {
+                        return at + mask.trailing_zeros() as usize;
+                    }
+
+                    at += VECTOR_SIZE;
+                    let mask = _mm_movemask_epi8(b);
+                    if mask != 0 {
+                        return at + mask.trailing_zeros() as usize;
+                    }
+
+                    at += VECTOR_SIZE;
+                    let mask = _mm_movemask_epi8(c);
+                    if mask != 0 {
+                        return at + mask.trailing_zeros() as usize;
+                    }
+
+                    at += VECTOR_SIZE;
+                    let mask = _mm_movemask_epi8(d);
+                    debug_assert!(mask != 0);
+                    return at + mask.trailing_zeros() as usize;
+                }
+                ptr = ptr_add(ptr, VECTOR_LOOP_SIZE);
+            }
+        }
+        while ptr <= end_ptr.sub(VECTOR_SIZE) {
+            debug_assert!(sub(end_ptr, ptr) >= VECTOR_SIZE);
+
+            let chunk = _mm_loadu_si128(ptr as *const __m128i);
+            let mask = _mm_movemask_epi8(chunk);
+            if mask != 0 {
+                return sub(ptr, start_ptr) + mask.trailing_zeros() as usize;
+            }
+            ptr = ptr.add(VECTOR_SIZE);
+        }
+        first_non_ascii_byte_slow(start_ptr, end_ptr, ptr)
+    }
+}
+
+#[inline(always)]
+unsafe fn first_non_ascii_byte_slow(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    mut ptr: *const u8,
+) -> usize {
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr);
+
+    while ptr < end_ptr {
+        if *ptr > 0x7F {
+            return sub(ptr, start_ptr);
+        }
+        ptr = ptr.offset(1);
+    }
+    sub(end_ptr, start_ptr)
+}
+
+/// Compute the position of the first ASCII byte in the given mask.
+///
+/// The mask should be computed by `chunk & ASCII_MASK`, where `chunk` is
+/// 8 contiguous bytes of the slice being checked where *at least* one of those
+/// bytes is not an ASCII byte.
+///
+/// The position returned is always in the inclusive range [0, 7].
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+fn first_non_ascii_byte_mask(mask: usize) -> usize {
+    #[cfg(target_endian = "little")]
+    {
+        mask.trailing_zeros() as usize / 8
+    }
+    #[cfg(target_endian = "big")]
+    {
+        mask.leading_zeros() as usize / 8
+    }
+}
+
+/// Increment the given pointer by the given amount.
+unsafe fn ptr_add(ptr: *const u8, amt: usize) -> *const u8 {
+    debug_assert!(amt < ::core::isize::MAX as usize);
+    ptr.offset(amt as isize)
+}
+
+/// Decrement the given pointer by the given amount.
+unsafe fn ptr_sub(ptr: *const u8, amt: usize) -> *const u8 {
+    debug_assert!(amt < ::core::isize::MAX as usize);
+    ptr.offset((amt as isize).wrapping_neg())
+}
+
+#[cfg(any(test, miri, not(target_arch = "x86_64")))]
+unsafe fn read_unaligned_usize(ptr: *const u8) -> usize {
+    use core::ptr;
+
+    let mut n: usize = 0;
+    ptr::copy_nonoverlapping(ptr, &mut n as *mut _ as *mut u8, USIZE_BYTES);
+    n
+}
+
+/// Subtract `b` from `a` and return the difference. `a` should be greater than
+/// or equal to `b`.
+fn sub(a: *const u8, b: *const u8) -> usize {
+    debug_assert!(a >= b);
+    (a as usize) - (b as usize)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    // Our testing approach here is to try and exhaustively test every case.
+    // This includes the position at which a non-ASCII byte occurs in addition
+    // to the alignment of the slice that we're searching.
+
+    #[test]
+    fn positive_fallback_forward() {
+        for i in 0..517 {
+            let s = "a".repeat(i);
+            assert_eq!(
+                i,
+                first_non_ascii_byte_fallback(s.as_bytes()),
+                "i: {:?}, len: {:?}, s: {:?}",
+                i,
+                s.len(),
+                s
+            );
+        }
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    #[cfg(not(miri))]
+    fn positive_sse2_forward() {
+        for i in 0..517 {
+            let b = "a".repeat(i).into_bytes();
+            assert_eq!(b.len(), first_non_ascii_byte_sse2(&b));
+        }
+    }
+
+    #[test]
+    #[cfg(not(miri))]
+    fn negative_fallback_forward() {
+        for i in 0..517 {
+            for align in 0..65 {
+                let mut s = "a".repeat(i);
+                s.push_str("☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃");
+                let s = s.get(align..).unwrap_or("");
+                assert_eq!(
+                    i.saturating_sub(align),
+                    first_non_ascii_byte_fallback(s.as_bytes()),
+                    "i: {:?}, align: {:?}, len: {:?}, s: {:?}",
+                    i,
+                    align,
+                    s.len(),
+                    s
+                );
+            }
+        }
+    }
+
+    #[test]
+    #[cfg(target_arch = "x86_64")]
+    #[cfg(not(miri))]
+    fn negative_sse2_forward() {
+        for i in 0..517 {
+            for align in 0..65 {
+                let mut s = "a".repeat(i);
+                s.push_str("☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃");
+                let s = s.get(align..).unwrap_or("");
+                assert_eq!(
+                    i.saturating_sub(align),
+                    first_non_ascii_byte_sse2(s.as_bytes()),
+                    "i: {:?}, align: {:?}, len: {:?}, s: {:?}",
+                    i,
+                    align,
+                    s.len(),
+                    s
+                );
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/bstr.rs.html b/src/bstr/bstr.rs.html new file mode 100644 index 000000000..6dd9a5262 --- /dev/null +++ b/src/bstr/bstr.rs.html @@ -0,0 +1,201 @@ +bstr.rs - source
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
+
use core::mem;
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+/// A wrapper for `&[u8]` that provides convenient string oriented trait impls.
+///
+/// If you need ownership or a growable byte string buffer, then use
+/// [`BString`](struct.BString.html).
+///
+/// Using a `&BStr` is just like using a `&[u8]`, since `BStr`
+/// implements `Deref` to `[u8]`. So all methods available on `[u8]`
+/// are also available on `BStr`.
+///
+/// # Representation
+///
+/// A `&BStr` has the same representation as a `&str`. That is, a `&BStr` is
+/// a fat pointer which consists of a pointer to some bytes and a length.
+///
+/// # Trait implementations
+///
+/// The `BStr` type has a number of trait implementations, and in particular,
+/// defines equality and ordinal comparisons between `&BStr`, `&str` and
+/// `&[u8]` for convenience.
+///
+/// The `Debug` implementation for `BStr` shows its bytes as a normal string.
+/// For invalid UTF-8, hex escape sequences are used.
+///
+/// The `Display` implementation behaves as if `BStr` were first lossily
+/// converted to a `str`. Invalid UTF-8 bytes are substituted with the Unicode
+/// replacement codepoint, which looks like this: �.
+#[derive(Hash)]
+#[repr(transparent)]
+pub struct BStr {
+    pub(crate) bytes: [u8],
+}
+
+impl BStr {
+    /// Directly creates a `BStr` slice from anything that can be converted
+    /// to a byte slice.
+    ///
+    /// This is very similar to the [`B`](crate::B) function, except this
+    /// returns a `&BStr` instead of a `&[u8]`.
+    ///
+    /// This is a cost-free conversion.
+    ///
+    /// # Example
+    ///
+    /// You can create `BStr`'s from byte arrays, byte slices or even string
+    /// slices:
+    ///
+    /// ```
+    /// use bstr::BStr;
+    ///
+    /// let a = BStr::new(b"abc");
+    /// let b = BStr::new(&b"abc"[..]);
+    /// let c = BStr::new("abc");
+    ///
+    /// assert_eq!(a, b);
+    /// assert_eq!(a, c);
+    /// ```
+    #[inline]
+    pub fn new<'a, B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> &'a BStr {
+        BStr::from_bytes(bytes.as_ref())
+    }
+
+    #[inline]
+    pub(crate) fn new_mut<B: ?Sized + AsMut<[u8]>>(
+        bytes: &mut B,
+    ) -> &mut BStr {
+        BStr::from_bytes_mut(bytes.as_mut())
+    }
+
+    #[inline]
+    pub(crate) fn from_bytes(slice: &[u8]) -> &BStr {
+        unsafe { mem::transmute(slice) }
+    }
+
+    #[inline]
+    pub(crate) fn from_bytes_mut(slice: &mut [u8]) -> &mut BStr {
+        unsafe { mem::transmute(slice) }
+    }
+
+    #[inline]
+    #[cfg(feature = "alloc")]
+    pub(crate) fn from_boxed_bytes(slice: Box<[u8]>) -> Box<BStr> {
+        unsafe { Box::from_raw(Box::into_raw(slice) as _) }
+    }
+
+    #[inline]
+    #[cfg(feature = "alloc")]
+    pub(crate) fn into_boxed_bytes(slice: Box<BStr>) -> Box<[u8]> {
+        unsafe { Box::from_raw(Box::into_raw(slice) as _) }
+    }
+
+    #[inline]
+    pub(crate) fn as_bytes(&self) -> &[u8] {
+        &self.bytes
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/byteset/mod.rs.html b/src/bstr/byteset/mod.rs.html new file mode 100644 index 000000000..d755dc31b --- /dev/null +++ b/src/bstr/byteset/mod.rs.html @@ -0,0 +1,231 @@ +mod.rs - source
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
+
use memchr::{memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3};
+
+mod scalar;
+
+#[inline]
+fn build_table(byteset: &[u8]) -> [u8; 256] {
+    let mut table = [0u8; 256];
+    for &b in byteset {
+        table[b as usize] = 1;
+    }
+    table
+}
+
+#[inline]
+pub(crate) fn find(haystack: &[u8], byteset: &[u8]) -> Option<usize> {
+    match byteset.len() {
+        0 => return None,
+        1 => memchr(byteset[0], haystack),
+        2 => memchr2(byteset[0], byteset[1], haystack),
+        3 => memchr3(byteset[0], byteset[1], byteset[2], haystack),
+        _ => {
+            let table = build_table(byteset);
+            scalar::forward_search_bytes(haystack, |b| table[b as usize] != 0)
+        }
+    }
+}
+
+#[inline]
+pub(crate) fn rfind(haystack: &[u8], byteset: &[u8]) -> Option<usize> {
+    match byteset.len() {
+        0 => return None,
+        1 => memrchr(byteset[0], haystack),
+        2 => memrchr2(byteset[0], byteset[1], haystack),
+        3 => memrchr3(byteset[0], byteset[1], byteset[2], haystack),
+        _ => {
+            let table = build_table(byteset);
+            scalar::reverse_search_bytes(haystack, |b| table[b as usize] != 0)
+        }
+    }
+}
+
+#[inline]
+pub(crate) fn find_not(haystack: &[u8], byteset: &[u8]) -> Option<usize> {
+    if haystack.is_empty() {
+        return None;
+    }
+    match byteset.len() {
+        0 => return Some(0),
+        1 => scalar::inv_memchr(byteset[0], haystack),
+        2 => scalar::forward_search_bytes(haystack, |b| {
+            b != byteset[0] && b != byteset[1]
+        }),
+        3 => scalar::forward_search_bytes(haystack, |b| {
+            b != byteset[0] && b != byteset[1] && b != byteset[2]
+        }),
+        _ => {
+            let table = build_table(byteset);
+            scalar::forward_search_bytes(haystack, |b| table[b as usize] == 0)
+        }
+    }
+}
+#[inline]
+pub(crate) fn rfind_not(haystack: &[u8], byteset: &[u8]) -> Option<usize> {
+    if haystack.is_empty() {
+        return None;
+    }
+    match byteset.len() {
+        0 => return Some(haystack.len() - 1),
+        1 => scalar::inv_memrchr(byteset[0], haystack),
+        2 => scalar::reverse_search_bytes(haystack, |b| {
+            b != byteset[0] && b != byteset[1]
+        }),
+        3 => scalar::reverse_search_bytes(haystack, |b| {
+            b != byteset[0] && b != byteset[1] && b != byteset[2]
+        }),
+        _ => {
+            let table = build_table(byteset);
+            scalar::reverse_search_bytes(haystack, |b| table[b as usize] == 0)
+        }
+    }
+}
+
+#[cfg(all(test, feature = "std", not(miri)))]
+mod tests {
+    quickcheck::quickcheck! {
+        fn qc_byteset_forward_matches_naive(
+            haystack: Vec<u8>,
+            needles: Vec<u8>
+        ) -> bool {
+            super::find(&haystack, &needles)
+                == haystack.iter().position(|b| needles.contains(b))
+        }
+        fn qc_byteset_backwards_matches_naive(
+            haystack: Vec<u8>,
+            needles: Vec<u8>
+        ) -> bool {
+            super::rfind(&haystack, &needles)
+                == haystack.iter().rposition(|b| needles.contains(b))
+        }
+        fn qc_byteset_forward_not_matches_naive(
+            haystack: Vec<u8>,
+            needles: Vec<u8>
+        ) -> bool {
+            super::find_not(&haystack, &needles)
+                == haystack.iter().position(|b| !needles.contains(b))
+        }
+        fn qc_byteset_backwards_not_matches_naive(
+            haystack: Vec<u8>,
+            needles: Vec<u8>
+        ) -> bool {
+            super::rfind_not(&haystack, &needles)
+                == haystack.iter().rposition(|b| !needles.contains(b))
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/byteset/scalar.rs.html b/src/bstr/byteset/scalar.rs.html new file mode 100644 index 000000000..6fde0b6f1 --- /dev/null +++ b/src/bstr/byteset/scalar.rs.html @@ -0,0 +1,611 @@ +scalar.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+
// This is adapted from `fallback.rs` from rust-memchr. It's modified to return
+// the 'inverse' query of memchr, e.g. finding the first byte not in the
+// provided set. This is simple for the 1-byte case.
+
+use core::{cmp, usize};
+
+const USIZE_BYTES: usize = core::mem::size_of::<usize>();
+
+// The number of bytes to loop at in one iteration of memchr/memrchr.
+const LOOP_SIZE: usize = 2 * USIZE_BYTES;
+
+/// Repeat the given byte into a word size number. That is, every 8 bits
+/// is equivalent to the given byte. For example, if `b` is `\x4E` or
+/// `01001110` in binary, then the returned value on a 32-bit system would be:
+/// `01001110_01001110_01001110_01001110`.
+#[inline(always)]
+fn repeat_byte(b: u8) -> usize {
+    (b as usize) * (usize::MAX / 255)
+}
+
+pub fn inv_memchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let confirm = |byte| byte != n1;
+    let loop_size = cmp::min(LOOP_SIZE, haystack.len());
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+
+    unsafe {
+        let end_ptr = haystack.as_ptr().add(haystack.len());
+        let mut ptr = start_ptr;
+
+        if haystack.len() < USIZE_BYTES {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr);
+        if (chunk ^ vn1) != 0 {
+            return forward_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = ptr.add(USIZE_BYTES - (start_ptr as usize & align));
+        debug_assert!(ptr > start_ptr);
+        debug_assert!(end_ptr.sub(USIZE_BYTES) >= start_ptr);
+        while loop_size == LOOP_SIZE && ptr <= end_ptr.sub(loop_size) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let a = *(ptr as *const usize);
+            let b = *(ptr.add(USIZE_BYTES) as *const usize);
+            let eqa = (a ^ vn1) != 0;
+            let eqb = (b ^ vn1) != 0;
+            if eqa || eqb {
+                break;
+            }
+            ptr = ptr.add(LOOP_SIZE);
+        }
+        forward_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+/// Return the last index not matching the byte `x` in `text`.
+pub fn inv_memrchr(n1: u8, haystack: &[u8]) -> Option<usize> {
+    let vn1 = repeat_byte(n1);
+    let confirm = |byte| byte != n1;
+    let loop_size = cmp::min(LOOP_SIZE, haystack.len());
+    let align = USIZE_BYTES - 1;
+    let start_ptr = haystack.as_ptr();
+
+    unsafe {
+        let end_ptr = haystack.as_ptr().add(haystack.len());
+        let mut ptr = end_ptr;
+
+        if haystack.len() < USIZE_BYTES {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        let chunk = read_unaligned_usize(ptr.sub(USIZE_BYTES));
+        if (chunk ^ vn1) != 0 {
+            return reverse_search(start_ptr, end_ptr, ptr, confirm);
+        }
+
+        ptr = ptr.sub(end_ptr as usize & align);
+        debug_assert!(start_ptr <= ptr && ptr <= end_ptr);
+        while loop_size == LOOP_SIZE && ptr >= start_ptr.add(loop_size) {
+            debug_assert_eq!(0, (ptr as usize) % USIZE_BYTES);
+
+            let a = *(ptr.sub(2 * USIZE_BYTES) as *const usize);
+            let b = *(ptr.sub(1 * USIZE_BYTES) as *const usize);
+            let eqa = (a ^ vn1) != 0;
+            let eqb = (b ^ vn1) != 0;
+            if eqa || eqb {
+                break;
+            }
+            ptr = ptr.sub(loop_size);
+        }
+        reverse_search(start_ptr, end_ptr, ptr, confirm)
+    }
+}
+
+#[inline(always)]
+unsafe fn forward_search<F: Fn(u8) -> bool>(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    mut ptr: *const u8,
+    confirm: F,
+) -> Option<usize> {
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr);
+
+    while ptr < end_ptr {
+        if confirm(*ptr) {
+            return Some(sub(ptr, start_ptr));
+        }
+        ptr = ptr.offset(1);
+    }
+    None
+}
+
+#[inline(always)]
+unsafe fn reverse_search<F: Fn(u8) -> bool>(
+    start_ptr: *const u8,
+    end_ptr: *const u8,
+    mut ptr: *const u8,
+    confirm: F,
+) -> Option<usize> {
+    debug_assert!(start_ptr <= ptr);
+    debug_assert!(ptr <= end_ptr);
+
+    while ptr > start_ptr {
+        ptr = ptr.offset(-1);
+        if confirm(*ptr) {
+            return Some(sub(ptr, start_ptr));
+        }
+    }
+    None
+}
+
+unsafe fn read_unaligned_usize(ptr: *const u8) -> usize {
+    (ptr as *const usize).read_unaligned()
+}
+
+/// Subtract `b` from `a` and return the difference. `a` should be greater than
+/// or equal to `b`.
+fn sub(a: *const u8, b: *const u8) -> usize {
+    debug_assert!(a >= b);
+    (a as usize) - (b as usize)
+}
+
+/// Safe wrapper around `forward_search`
+#[inline]
+pub(crate) fn forward_search_bytes<F: Fn(u8) -> bool>(
+    s: &[u8],
+    confirm: F,
+) -> Option<usize> {
+    unsafe {
+        let start = s.as_ptr();
+        let end = start.add(s.len());
+        forward_search(start, end, start, confirm)
+    }
+}
+
+/// Safe wrapper around `reverse_search`
+#[inline]
+pub(crate) fn reverse_search_bytes<F: Fn(u8) -> bool>(
+    s: &[u8],
+    confirm: F,
+) -> Option<usize> {
+    unsafe {
+        let start = s.as_ptr();
+        let end = start.add(s.len());
+        reverse_search(start, end, end, confirm)
+    }
+}
+
+#[cfg(all(test, feature = "std"))]
+mod tests {
+    use super::{inv_memchr, inv_memrchr};
+
+    // search string, search byte, inv_memchr result, inv_memrchr result.
+    // these are expanded into a much larger set of tests in build_tests
+    const TESTS: &[(&[u8], u8, usize, usize)] = &[
+        (b"z", b'a', 0, 0),
+        (b"zz", b'a', 0, 1),
+        (b"aza", b'a', 1, 1),
+        (b"zaz", b'a', 0, 2),
+        (b"zza", b'a', 0, 1),
+        (b"zaa", b'a', 0, 0),
+        (b"zzz", b'a', 0, 2),
+    ];
+
+    type TestCase = (Vec<u8>, u8, Option<(usize, usize)>);
+
+    fn build_tests() -> Vec<TestCase> {
+        #[cfg(not(miri))]
+        const MAX_PER: usize = 515;
+        #[cfg(miri)]
+        const MAX_PER: usize = 10;
+
+        let mut result = vec![];
+        for &(search, byte, fwd_pos, rev_pos) in TESTS {
+            result.push((search.to_vec(), byte, Some((fwd_pos, rev_pos))));
+            for i in 1..MAX_PER {
+                // add a bunch of copies of the search byte to the end.
+                let mut suffixed: Vec<u8> = search.into();
+                suffixed.extend(std::iter::repeat(byte).take(i));
+                result.push((suffixed, byte, Some((fwd_pos, rev_pos))));
+
+                // add a bunch of copies of the search byte to the start.
+                let mut prefixed: Vec<u8> =
+                    std::iter::repeat(byte).take(i).collect();
+                prefixed.extend(search);
+                result.push((
+                    prefixed,
+                    byte,
+                    Some((fwd_pos + i, rev_pos + i)),
+                ));
+
+                // add a bunch of copies of the search byte to both ends.
+                let mut surrounded: Vec<u8> =
+                    std::iter::repeat(byte).take(i).collect();
+                surrounded.extend(search);
+                surrounded.extend(std::iter::repeat(byte).take(i));
+                result.push((
+                    surrounded,
+                    byte,
+                    Some((fwd_pos + i, rev_pos + i)),
+                ));
+            }
+        }
+
+        // build non-matching tests for several sizes
+        for i in 0..MAX_PER {
+            result.push((
+                std::iter::repeat(b'\0').take(i).collect(),
+                b'\0',
+                None,
+            ));
+        }
+
+        result
+    }
+
+    #[test]
+    fn test_inv_memchr() {
+        use crate::{ByteSlice, B};
+
+        #[cfg(not(miri))]
+        const MAX_OFFSET: usize = 130;
+        #[cfg(miri)]
+        const MAX_OFFSET: usize = 13;
+
+        for (search, byte, matching) in build_tests() {
+            assert_eq!(
+                inv_memchr(byte, &search),
+                matching.map(|m| m.0),
+                "inv_memchr when searching for {:?} in {:?}",
+                byte as char,
+                // better printing
+                B(&search).as_bstr(),
+            );
+            assert_eq!(
+                inv_memrchr(byte, &search),
+                matching.map(|m| m.1),
+                "inv_memrchr when searching for {:?} in {:?}",
+                byte as char,
+                // better printing
+                B(&search).as_bstr(),
+            );
+            // Test a rather large number off offsets for potential alignment
+            // issues.
+            for offset in 1..MAX_OFFSET {
+                if offset >= search.len() {
+                    break;
+                }
+                // If this would cause us to shift the results off the end,
+                // skip it so that we don't have to recompute them.
+                if let Some((f, r)) = matching {
+                    if offset > f || offset > r {
+                        break;
+                    }
+                }
+                let realigned = &search[offset..];
+
+                let forward_pos = matching.map(|m| m.0 - offset);
+                let reverse_pos = matching.map(|m| m.1 - offset);
+
+                assert_eq!(
+                    inv_memchr(byte, &realigned),
+                    forward_pos,
+                    "inv_memchr when searching (realigned by {}) for {:?} in {:?}",
+                    offset,
+                    byte as char,
+                    realigned.as_bstr(),
+                );
+                assert_eq!(
+                    inv_memrchr(byte, &realigned),
+                    reverse_pos,
+                    "inv_memrchr when searching (realigned by {}) for {:?} in {:?}",
+                    offset,
+                    byte as char,
+                    realigned.as_bstr(),
+                );
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/escape_bytes.rs.html b/src/bstr/escape_bytes.rs.html new file mode 100644 index 000000000..1573467a8 --- /dev/null +++ b/src/bstr/escape_bytes.rs.html @@ -0,0 +1,903 @@ +escape_bytes.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+
/// An iterator of `char` values that represent an escaping of arbitrary bytes.
+///
+/// The lifetime parameter `'a` refers to the lifetime of the bytes being
+/// escaped.
+///
+/// This iterator is created by the
+/// [`ByteSlice::escape_bytes`](crate::ByteSlice::escape_bytes) method.
+#[derive(Clone, Debug)]
+pub struct EscapeBytes<'a> {
+    remaining: &'a [u8],
+    state: EscapeState,
+}
+
+impl<'a> EscapeBytes<'a> {
+    pub(crate) fn new(bytes: &'a [u8]) -> EscapeBytes {
+        EscapeBytes { remaining: bytes, state: EscapeState::Start }
+    }
+}
+
+impl<'a> Iterator for EscapeBytes<'a> {
+    type Item = char;
+
+    #[inline]
+    fn next(&mut self) -> Option<char> {
+        use self::EscapeState::*;
+
+        match self.state {
+            Start => {
+                let byte = match crate::decode_utf8(self.remaining) {
+                    (None, 0) => return None,
+                    // If we see invalid UTF-8 or ASCII, then we always just
+                    // peel one byte off. If it's printable ASCII, we'll pass
+                    // it through as-is below. Otherwise, below, it will get
+                    // escaped in some way.
+                    (None, _) | (Some(_), 1) => {
+                        let byte = self.remaining[0];
+                        self.remaining = &self.remaining[1..];
+                        byte
+                    }
+                    // For any valid UTF-8 that is not ASCII, we pass it
+                    // through as-is. We don't do any Unicode escaping.
+                    (Some(ch), size) => {
+                        self.remaining = &self.remaining[size..];
+                        return Some(ch);
+                    }
+                };
+                self.state = match byte {
+                    0x21..=0x5B | 0x5D..=0x7E => {
+                        return Some(char::from(byte))
+                    }
+                    b'\0' => SpecialEscape('0'),
+                    b'\n' => SpecialEscape('n'),
+                    b'\r' => SpecialEscape('r'),
+                    b'\t' => SpecialEscape('t'),
+                    b'\\' => SpecialEscape('\\'),
+                    _ => HexEscapeX(byte),
+                };
+                Some('\\')
+            }
+            SpecialEscape(ch) => {
+                self.state = Start;
+                Some(ch)
+            }
+            HexEscapeX(byte) => {
+                self.state = HexEscapeHighNybble(byte);
+                Some('x')
+            }
+            HexEscapeHighNybble(byte) => {
+                self.state = HexEscapeLowNybble(byte);
+                let nybble = byte >> 4;
+                Some(hexdigit_to_char(nybble))
+            }
+            HexEscapeLowNybble(byte) => {
+                self.state = Start;
+                let nybble = byte & 0xF;
+                Some(hexdigit_to_char(nybble))
+            }
+        }
+    }
+}
+
+impl<'a> core::fmt::Display for EscapeBytes<'a> {
+    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+        use core::fmt::Write;
+        for ch in self.clone() {
+            f.write_char(ch)?;
+        }
+        Ok(())
+    }
+}
+
+/// The state used by the FSM in the escaping iterator.
+#[derive(Clone, Debug)]
+enum EscapeState {
+    /// Read and remove the next byte from 'remaining'. If 'remaining' is
+    /// empty, then return None. Otherwise, escape the byte according to the
+    /// following rules or emit it as-is.
+    ///
+    /// If it's \n, \r, \t, \\ or \0, then emit a '\' and set the current
+    /// state to 'SpecialEscape(n | r | t | \ | 0)'. Otherwise, if the 'byte'
+    /// is not in [\x21-\x5B\x5D-\x7E], then emit a '\' and set the state to
+    /// to 'HexEscapeX(byte)'.
+    Start,
+    /// Emit the given codepoint as is. This assumes '\' has just been emitted.
+    /// Then set the state to 'Start'.
+    SpecialEscape(char),
+    /// Emit the 'x' part of a hex escape. This assumes '\' has just been
+    /// emitted. Then set the state to 'HexEscapeHighNybble(byte)'.
+    HexEscapeX(u8),
+    /// Emit the high nybble of the byte as a hexadecimal digit. This
+    /// assumes '\x' has just been emitted. Then set the state to
+    /// 'HexEscapeLowNybble(byte)'.
+    HexEscapeHighNybble(u8),
+    /// Emit the low nybble of the byte as a hexadecimal digit. This assume
+    /// '\xZ' has just been emitted, where 'Z' is the high nybble of this byte.
+    /// Then set the state to 'Start'.
+    HexEscapeLowNybble(u8),
+}
+
+/// An iterator of `u8` values that represent an unescaping of a sequence of
+/// codepoints.
+///
+/// The type parameter `I` refers to the iterator of codepoints that is
+/// unescaped.
+///
+/// Currently this iterator is not exposed in the crate API, and instead all
+/// we expose is a `ByteVec::unescape` method. Which of course requires an
+/// alloc. That's the most convenient form of this, but in theory, we could
+/// expose this for core-only use cases too. I'm just not quite sure what the
+/// API should be.
+#[derive(Clone, Debug)]
+#[cfg(feature = "alloc")]
+pub(crate) struct UnescapeBytes<I> {
+    it: I,
+    state: UnescapeState,
+}
+
+#[cfg(feature = "alloc")]
+impl<I: Iterator<Item = char>> UnescapeBytes<I> {
+    pub(crate) fn new<T: IntoIterator<IntoIter = I>>(
+        t: T,
+    ) -> UnescapeBytes<I> {
+        UnescapeBytes { it: t.into_iter(), state: UnescapeState::Start }
+    }
+}
+
+#[cfg(feature = "alloc")]
+impl<I: Iterator<Item = char>> Iterator for UnescapeBytes<I> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<u8> {
+        use self::UnescapeState::*;
+
+        loop {
+            match self.state {
+                Start => {
+                    let ch = self.it.next()?;
+                    match ch {
+                        '\\' => {
+                            self.state = Escape;
+                        }
+                        ch => {
+                            self.state = UnescapeState::bytes(&[], ch);
+                        }
+                    }
+                }
+                Bytes { buf, mut cur, len } => {
+                    let byte = buf[cur];
+                    cur += 1;
+                    if cur >= len {
+                        self.state = Start;
+                    } else {
+                        self.state = Bytes { buf, cur, len };
+                    }
+                    return Some(byte);
+                }
+                Escape => {
+                    let ch = match self.it.next() {
+                        Some(ch) => ch,
+                        None => {
+                            self.state = Start;
+                            // Incomplete escape sequences unescape as
+                            // themselves.
+                            return Some(b'\\');
+                        }
+                    };
+                    match ch {
+                        '0' => {
+                            self.state = Start;
+                            return Some(b'\x00');
+                        }
+                        '\\' => {
+                            self.state = Start;
+                            return Some(b'\\');
+                        }
+                        'r' => {
+                            self.state = Start;
+                            return Some(b'\r');
+                        }
+                        'n' => {
+                            self.state = Start;
+                            return Some(b'\n');
+                        }
+                        't' => {
+                            self.state = Start;
+                            return Some(b'\t');
+                        }
+                        'x' => {
+                            self.state = HexFirst;
+                        }
+                        ch => {
+                            // An invalid escape sequence unescapes as itself.
+                            self.state = UnescapeState::bytes(&[b'\\'], ch);
+                        }
+                    }
+                }
+                HexFirst => {
+                    let ch = match self.it.next() {
+                        Some(ch) => ch,
+                        None => {
+                            // An incomplete escape sequence unescapes as
+                            // itself.
+                            self.state = UnescapeState::bytes_raw(&[b'x']);
+                            return Some(b'\\');
+                        }
+                    };
+                    match ch {
+                        '0'..='9' | 'A'..='F' | 'a'..='f' => {
+                            self.state = HexSecond(ch);
+                        }
+                        ch => {
+                            // An invalid escape sequence unescapes as itself.
+                            self.state = UnescapeState::bytes(&[b'x'], ch);
+                            return Some(b'\\');
+                        }
+                    }
+                }
+                HexSecond(first) => {
+                    let second = match self.it.next() {
+                        Some(ch) => ch,
+                        None => {
+                            // An incomplete escape sequence unescapes as
+                            // itself.
+                            self.state = UnescapeState::bytes(&[b'x'], first);
+                            return Some(b'\\');
+                        }
+                    };
+                    match second {
+                        '0'..='9' | 'A'..='F' | 'a'..='f' => {
+                            self.state = Start;
+                            let hinybble = char_to_hexdigit(first);
+                            let lonybble = char_to_hexdigit(second);
+                            let byte = hinybble << 4 | lonybble;
+                            return Some(byte);
+                        }
+                        ch => {
+                            // An invalid escape sequence unescapes as itself.
+                            self.state =
+                                UnescapeState::bytes2(&[b'x'], first, ch);
+                            return Some(b'\\');
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+/// The state used by the FSM in the unescaping iterator.
+#[derive(Clone, Debug)]
+#[cfg(feature = "alloc")]
+enum UnescapeState {
+    /// The start state. Look for an escape sequence, otherwise emit the next
+    /// codepoint as-is.
+    Start,
+    /// Emit the byte at `buf[cur]`.
+    ///
+    /// This state should never be created when `cur >= len`. That is, when
+    /// this state is visited, it is assumed that `cur < len`.
+    Bytes { buf: [u8; 11], cur: usize, len: usize },
+    /// This state is entered after a `\` is seen.
+    Escape,
+    /// This state is entered after a `\x` is seen.
+    HexFirst,
+    /// This state is entered after a `\xN` is seen, where `N` is in
+    /// `[0-9A-Fa-f]`. The given codepoint corresponds to `N`.
+    HexSecond(char),
+}
+
+#[cfg(feature = "alloc")]
+impl UnescapeState {
+    /// Create a new `Bytes` variant with the given slice.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `bytes.len() > 11`.
+    fn bytes_raw(bytes: &[u8]) -> UnescapeState {
+        // This can be increased, you just need to make sure 'buf' in the
+        // 'Bytes' state has enough room.
+        assert!(bytes.len() <= 11, "no more than 11 bytes allowed");
+        let mut buf = [0; 11];
+        buf[..bytes.len()].copy_from_slice(bytes);
+        UnescapeState::Bytes { buf, cur: 0, len: bytes.len() }
+    }
+
+    /// Create a new `Bytes` variant with the prefix byte slice, followed by
+    /// the UTF-8 encoding of the given char.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `prefix.len() > 3`.
+    fn bytes(prefix: &[u8], ch: char) -> UnescapeState {
+        // This can be increased, you just need to make sure 'buf' in the
+        // 'Bytes' state has enough room.
+        assert!(prefix.len() <= 3, "no more than 3 bytes allowed");
+        let mut buf = [0; 11];
+        buf[..prefix.len()].copy_from_slice(prefix);
+        let chlen = ch.encode_utf8(&mut buf[prefix.len()..]).len();
+        UnescapeState::Bytes { buf, cur: 0, len: prefix.len() + chlen }
+    }
+
+    /// Create a new `Bytes` variant with the prefix byte slice, followed by
+    /// the UTF-8 encoding of `ch1` and then `ch2`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `prefix.len() > 3`.
+    fn bytes2(prefix: &[u8], ch1: char, ch2: char) -> UnescapeState {
+        // This can be increased, you just need to make sure 'buf' in the
+        // 'Bytes' state has enough room.
+        assert!(prefix.len() <= 3, "no more than 3 bytes allowed");
+        let mut buf = [0; 11];
+        buf[..prefix.len()].copy_from_slice(prefix);
+        let len1 = ch1.encode_utf8(&mut buf[prefix.len()..]).len();
+        let len2 = ch2.encode_utf8(&mut buf[prefix.len() + len1..]).len();
+        UnescapeState::Bytes { buf, cur: 0, len: prefix.len() + len1 + len2 }
+    }
+}
+
+/// Convert the given codepoint to its corresponding hexadecimal digit.
+///
+/// # Panics
+///
+/// This panics if `ch` is not in `[0-9A-Fa-f]`.
+#[cfg(feature = "alloc")]
+fn char_to_hexdigit(ch: char) -> u8 {
+    u8::try_from(ch.to_digit(16).unwrap()).unwrap()
+}
+
+/// Convert the given hexadecimal digit to its corresponding codepoint.
+///
+/// # Panics
+///
+/// This panics when `digit > 15`.
+fn hexdigit_to_char(digit: u8) -> char {
+    char::from_digit(u32::from(digit), 16).unwrap().to_ascii_uppercase()
+}
+
+#[cfg(all(test, feature = "std"))]
+mod tests {
+    use crate::BString;
+
+    use super::*;
+
+    #[allow(non_snake_case)]
+    fn B<B: AsRef<[u8]>>(bytes: B) -> BString {
+        BString::from(bytes.as_ref())
+    }
+
+    fn e<B: AsRef<[u8]>>(bytes: B) -> String {
+        EscapeBytes::new(bytes.as_ref()).to_string()
+    }
+
+    fn u(string: &str) -> BString {
+        UnescapeBytes::new(string.chars()).collect()
+    }
+
+    #[test]
+    fn escape() {
+        assert_eq!(r"a", e(br"a"));
+        assert_eq!(r"\\x61", e(br"\x61"));
+        assert_eq!(r"a", e(b"\x61"));
+        assert_eq!(r"~", e(b"\x7E"));
+        assert_eq!(r"\x7F", e(b"\x7F"));
+
+        assert_eq!(r"\n", e(b"\n"));
+        assert_eq!(r"\r", e(b"\r"));
+        assert_eq!(r"\t", e(b"\t"));
+        assert_eq!(r"\\", e(b"\\"));
+        assert_eq!(r"\0", e(b"\0"));
+        assert_eq!(r"\0", e(b"\x00"));
+
+        assert_eq!(r"\x88", e(b"\x88"));
+        assert_eq!(r"\x8F", e(b"\x8F"));
+        assert_eq!(r"\xF8", e(b"\xF8"));
+        assert_eq!(r"\xFF", e(b"\xFF"));
+
+        assert_eq!(r"\xE2", e(b"\xE2"));
+        assert_eq!(r"\xE2\x98", e(b"\xE2\x98"));
+        assert_eq!(r"☃", e(b"\xE2\x98\x83"));
+
+        assert_eq!(r"\xF0", e(b"\xF0"));
+        assert_eq!(r"\xF0\x9F", e(b"\xF0\x9F"));
+        assert_eq!(r"\xF0\x9F\x92", e(b"\xF0\x9F\x92"));
+        assert_eq!(r"💩", e(b"\xF0\x9F\x92\xA9"));
+    }
+
+    #[test]
+    fn unescape() {
+        assert_eq!(B(r"a"), u(r"a"));
+        assert_eq!(B(r"\x61"), u(r"\\x61"));
+        assert_eq!(B(r"a"), u(r"\x61"));
+        assert_eq!(B(r"~"), u(r"\x7E"));
+        assert_eq!(B(b"\x7F"), u(r"\x7F"));
+
+        assert_eq!(B(b"\n"), u(r"\n"));
+        assert_eq!(B(b"\r"), u(r"\r"));
+        assert_eq!(B(b"\t"), u(r"\t"));
+        assert_eq!(B(b"\\"), u(r"\\"));
+        assert_eq!(B(b"\0"), u(r"\0"));
+        assert_eq!(B(b"\0"), u(r"\x00"));
+
+        assert_eq!(B(b"\x88"), u(r"\x88"));
+        assert_eq!(B(b"\x8F"), u(r"\x8F"));
+        assert_eq!(B(b"\xF8"), u(r"\xF8"));
+        assert_eq!(B(b"\xFF"), u(r"\xFF"));
+
+        assert_eq!(B(b"\xE2"), u(r"\xE2"));
+        assert_eq!(B(b"\xE2\x98"), u(r"\xE2\x98"));
+        assert_eq!(B("☃"), u(r"\xE2\x98\x83"));
+
+        assert_eq!(B(b"\xF0"), u(r"\xf0"));
+        assert_eq!(B(b"\xF0\x9F"), u(r"\xf0\x9f"));
+        assert_eq!(B(b"\xF0\x9F\x92"), u(r"\xf0\x9f\x92"));
+        assert_eq!(B("💩"), u(r"\xf0\x9f\x92\xa9"));
+    }
+
+    #[test]
+    fn unescape_weird() {
+        assert_eq!(B(b"\\"), u(r"\"));
+        assert_eq!(B(b"\\"), u(r"\\"));
+        assert_eq!(B(b"\\x"), u(r"\x"));
+        assert_eq!(B(b"\\xA"), u(r"\xA"));
+
+        assert_eq!(B(b"\\xZ"), u(r"\xZ"));
+        assert_eq!(B(b"\\xZZ"), u(r"\xZZ"));
+        assert_eq!(B(b"\\i"), u(r"\i"));
+        assert_eq!(B(b"\\u"), u(r"\u"));
+        assert_eq!(B(b"\\u{2603}"), u(r"\u{2603}"));
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/ext_slice.rs.html b/src/bstr/ext_slice.rs.html new file mode 100644 index 000000000..b583c2421 --- /dev/null +++ b/src/bstr/ext_slice.rs.html @@ -0,0 +1,7741 @@ +ext_slice.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+2452
+2453
+2454
+2455
+2456
+2457
+2458
+2459
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+2470
+2471
+2472
+2473
+2474
+2475
+2476
+2477
+2478
+2479
+2480
+2481
+2482
+2483
+2484
+2485
+2486
+2487
+2488
+2489
+2490
+2491
+2492
+2493
+2494
+2495
+2496
+2497
+2498
+2499
+2500
+2501
+2502
+2503
+2504
+2505
+2506
+2507
+2508
+2509
+2510
+2511
+2512
+2513
+2514
+2515
+2516
+2517
+2518
+2519
+2520
+2521
+2522
+2523
+2524
+2525
+2526
+2527
+2528
+2529
+2530
+2531
+2532
+2533
+2534
+2535
+2536
+2537
+2538
+2539
+2540
+2541
+2542
+2543
+2544
+2545
+2546
+2547
+2548
+2549
+2550
+2551
+2552
+2553
+2554
+2555
+2556
+2557
+2558
+2559
+2560
+2561
+2562
+2563
+2564
+2565
+2566
+2567
+2568
+2569
+2570
+2571
+2572
+2573
+2574
+2575
+2576
+2577
+2578
+2579
+2580
+2581
+2582
+2583
+2584
+2585
+2586
+2587
+2588
+2589
+2590
+2591
+2592
+2593
+2594
+2595
+2596
+2597
+2598
+2599
+2600
+2601
+2602
+2603
+2604
+2605
+2606
+2607
+2608
+2609
+2610
+2611
+2612
+2613
+2614
+2615
+2616
+2617
+2618
+2619
+2620
+2621
+2622
+2623
+2624
+2625
+2626
+2627
+2628
+2629
+2630
+2631
+2632
+2633
+2634
+2635
+2636
+2637
+2638
+2639
+2640
+2641
+2642
+2643
+2644
+2645
+2646
+2647
+2648
+2649
+2650
+2651
+2652
+2653
+2654
+2655
+2656
+2657
+2658
+2659
+2660
+2661
+2662
+2663
+2664
+2665
+2666
+2667
+2668
+2669
+2670
+2671
+2672
+2673
+2674
+2675
+2676
+2677
+2678
+2679
+2680
+2681
+2682
+2683
+2684
+2685
+2686
+2687
+2688
+2689
+2690
+2691
+2692
+2693
+2694
+2695
+2696
+2697
+2698
+2699
+2700
+2701
+2702
+2703
+2704
+2705
+2706
+2707
+2708
+2709
+2710
+2711
+2712
+2713
+2714
+2715
+2716
+2717
+2718
+2719
+2720
+2721
+2722
+2723
+2724
+2725
+2726
+2727
+2728
+2729
+2730
+2731
+2732
+2733
+2734
+2735
+2736
+2737
+2738
+2739
+2740
+2741
+2742
+2743
+2744
+2745
+2746
+2747
+2748
+2749
+2750
+2751
+2752
+2753
+2754
+2755
+2756
+2757
+2758
+2759
+2760
+2761
+2762
+2763
+2764
+2765
+2766
+2767
+2768
+2769
+2770
+2771
+2772
+2773
+2774
+2775
+2776
+2777
+2778
+2779
+2780
+2781
+2782
+2783
+2784
+2785
+2786
+2787
+2788
+2789
+2790
+2791
+2792
+2793
+2794
+2795
+2796
+2797
+2798
+2799
+2800
+2801
+2802
+2803
+2804
+2805
+2806
+2807
+2808
+2809
+2810
+2811
+2812
+2813
+2814
+2815
+2816
+2817
+2818
+2819
+2820
+2821
+2822
+2823
+2824
+2825
+2826
+2827
+2828
+2829
+2830
+2831
+2832
+2833
+2834
+2835
+2836
+2837
+2838
+2839
+2840
+2841
+2842
+2843
+2844
+2845
+2846
+2847
+2848
+2849
+2850
+2851
+2852
+2853
+2854
+2855
+2856
+2857
+2858
+2859
+2860
+2861
+2862
+2863
+2864
+2865
+2866
+2867
+2868
+2869
+2870
+2871
+2872
+2873
+2874
+2875
+2876
+2877
+2878
+2879
+2880
+2881
+2882
+2883
+2884
+2885
+2886
+2887
+2888
+2889
+2890
+2891
+2892
+2893
+2894
+2895
+2896
+2897
+2898
+2899
+2900
+2901
+2902
+2903
+2904
+2905
+2906
+2907
+2908
+2909
+2910
+2911
+2912
+2913
+2914
+2915
+2916
+2917
+2918
+2919
+2920
+2921
+2922
+2923
+2924
+2925
+2926
+2927
+2928
+2929
+2930
+2931
+2932
+2933
+2934
+2935
+2936
+2937
+2938
+2939
+2940
+2941
+2942
+2943
+2944
+2945
+2946
+2947
+2948
+2949
+2950
+2951
+2952
+2953
+2954
+2955
+2956
+2957
+2958
+2959
+2960
+2961
+2962
+2963
+2964
+2965
+2966
+2967
+2968
+2969
+2970
+2971
+2972
+2973
+2974
+2975
+2976
+2977
+2978
+2979
+2980
+2981
+2982
+2983
+2984
+2985
+2986
+2987
+2988
+2989
+2990
+2991
+2992
+2993
+2994
+2995
+2996
+2997
+2998
+2999
+3000
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3008
+3009
+3010
+3011
+3012
+3013
+3014
+3015
+3016
+3017
+3018
+3019
+3020
+3021
+3022
+3023
+3024
+3025
+3026
+3027
+3028
+3029
+3030
+3031
+3032
+3033
+3034
+3035
+3036
+3037
+3038
+3039
+3040
+3041
+3042
+3043
+3044
+3045
+3046
+3047
+3048
+3049
+3050
+3051
+3052
+3053
+3054
+3055
+3056
+3057
+3058
+3059
+3060
+3061
+3062
+3063
+3064
+3065
+3066
+3067
+3068
+3069
+3070
+3071
+3072
+3073
+3074
+3075
+3076
+3077
+3078
+3079
+3080
+3081
+3082
+3083
+3084
+3085
+3086
+3087
+3088
+3089
+3090
+3091
+3092
+3093
+3094
+3095
+3096
+3097
+3098
+3099
+3100
+3101
+3102
+3103
+3104
+3105
+3106
+3107
+3108
+3109
+3110
+3111
+3112
+3113
+3114
+3115
+3116
+3117
+3118
+3119
+3120
+3121
+3122
+3123
+3124
+3125
+3126
+3127
+3128
+3129
+3130
+3131
+3132
+3133
+3134
+3135
+3136
+3137
+3138
+3139
+3140
+3141
+3142
+3143
+3144
+3145
+3146
+3147
+3148
+3149
+3150
+3151
+3152
+3153
+3154
+3155
+3156
+3157
+3158
+3159
+3160
+3161
+3162
+3163
+3164
+3165
+3166
+3167
+3168
+3169
+3170
+3171
+3172
+3173
+3174
+3175
+3176
+3177
+3178
+3179
+3180
+3181
+3182
+3183
+3184
+3185
+3186
+3187
+3188
+3189
+3190
+3191
+3192
+3193
+3194
+3195
+3196
+3197
+3198
+3199
+3200
+3201
+3202
+3203
+3204
+3205
+3206
+3207
+3208
+3209
+3210
+3211
+3212
+3213
+3214
+3215
+3216
+3217
+3218
+3219
+3220
+3221
+3222
+3223
+3224
+3225
+3226
+3227
+3228
+3229
+3230
+3231
+3232
+3233
+3234
+3235
+3236
+3237
+3238
+3239
+3240
+3241
+3242
+3243
+3244
+3245
+3246
+3247
+3248
+3249
+3250
+3251
+3252
+3253
+3254
+3255
+3256
+3257
+3258
+3259
+3260
+3261
+3262
+3263
+3264
+3265
+3266
+3267
+3268
+3269
+3270
+3271
+3272
+3273
+3274
+3275
+3276
+3277
+3278
+3279
+3280
+3281
+3282
+3283
+3284
+3285
+3286
+3287
+3288
+3289
+3290
+3291
+3292
+3293
+3294
+3295
+3296
+3297
+3298
+3299
+3300
+3301
+3302
+3303
+3304
+3305
+3306
+3307
+3308
+3309
+3310
+3311
+3312
+3313
+3314
+3315
+3316
+3317
+3318
+3319
+3320
+3321
+3322
+3323
+3324
+3325
+3326
+3327
+3328
+3329
+3330
+3331
+3332
+3333
+3334
+3335
+3336
+3337
+3338
+3339
+3340
+3341
+3342
+3343
+3344
+3345
+3346
+3347
+3348
+3349
+3350
+3351
+3352
+3353
+3354
+3355
+3356
+3357
+3358
+3359
+3360
+3361
+3362
+3363
+3364
+3365
+3366
+3367
+3368
+3369
+3370
+3371
+3372
+3373
+3374
+3375
+3376
+3377
+3378
+3379
+3380
+3381
+3382
+3383
+3384
+3385
+3386
+3387
+3388
+3389
+3390
+3391
+3392
+3393
+3394
+3395
+3396
+3397
+3398
+3399
+3400
+3401
+3402
+3403
+3404
+3405
+3406
+3407
+3408
+3409
+3410
+3411
+3412
+3413
+3414
+3415
+3416
+3417
+3418
+3419
+3420
+3421
+3422
+3423
+3424
+3425
+3426
+3427
+3428
+3429
+3430
+3431
+3432
+3433
+3434
+3435
+3436
+3437
+3438
+3439
+3440
+3441
+3442
+3443
+3444
+3445
+3446
+3447
+3448
+3449
+3450
+3451
+3452
+3453
+3454
+3455
+3456
+3457
+3458
+3459
+3460
+3461
+3462
+3463
+3464
+3465
+3466
+3467
+3468
+3469
+3470
+3471
+3472
+3473
+3474
+3475
+3476
+3477
+3478
+3479
+3480
+3481
+3482
+3483
+3484
+3485
+3486
+3487
+3488
+3489
+3490
+3491
+3492
+3493
+3494
+3495
+3496
+3497
+3498
+3499
+3500
+3501
+3502
+3503
+3504
+3505
+3506
+3507
+3508
+3509
+3510
+3511
+3512
+3513
+3514
+3515
+3516
+3517
+3518
+3519
+3520
+3521
+3522
+3523
+3524
+3525
+3526
+3527
+3528
+3529
+3530
+3531
+3532
+3533
+3534
+3535
+3536
+3537
+3538
+3539
+3540
+3541
+3542
+3543
+3544
+3545
+3546
+3547
+3548
+3549
+3550
+3551
+3552
+3553
+3554
+3555
+3556
+3557
+3558
+3559
+3560
+3561
+3562
+3563
+3564
+3565
+3566
+3567
+3568
+3569
+3570
+3571
+3572
+3573
+3574
+3575
+3576
+3577
+3578
+3579
+3580
+3581
+3582
+3583
+3584
+3585
+3586
+3587
+3588
+3589
+3590
+3591
+3592
+3593
+3594
+3595
+3596
+3597
+3598
+3599
+3600
+3601
+3602
+3603
+3604
+3605
+3606
+3607
+3608
+3609
+3610
+3611
+3612
+3613
+3614
+3615
+3616
+3617
+3618
+3619
+3620
+3621
+3622
+3623
+3624
+3625
+3626
+3627
+3628
+3629
+3630
+3631
+3632
+3633
+3634
+3635
+3636
+3637
+3638
+3639
+3640
+3641
+3642
+3643
+3644
+3645
+3646
+3647
+3648
+3649
+3650
+3651
+3652
+3653
+3654
+3655
+3656
+3657
+3658
+3659
+3660
+3661
+3662
+3663
+3664
+3665
+3666
+3667
+3668
+3669
+3670
+3671
+3672
+3673
+3674
+3675
+3676
+3677
+3678
+3679
+3680
+3681
+3682
+3683
+3684
+3685
+3686
+3687
+3688
+3689
+3690
+3691
+3692
+3693
+3694
+3695
+3696
+3697
+3698
+3699
+3700
+3701
+3702
+3703
+3704
+3705
+3706
+3707
+3708
+3709
+3710
+3711
+3712
+3713
+3714
+3715
+3716
+3717
+3718
+3719
+3720
+3721
+3722
+3723
+3724
+3725
+3726
+3727
+3728
+3729
+3730
+3731
+3732
+3733
+3734
+3735
+3736
+3737
+3738
+3739
+3740
+3741
+3742
+3743
+3744
+3745
+3746
+3747
+3748
+3749
+3750
+3751
+3752
+3753
+3754
+3755
+3756
+3757
+3758
+3759
+3760
+3761
+3762
+3763
+3764
+3765
+3766
+3767
+3768
+3769
+3770
+3771
+3772
+3773
+3774
+3775
+3776
+3777
+3778
+3779
+3780
+3781
+3782
+3783
+3784
+3785
+3786
+3787
+3788
+3789
+3790
+3791
+3792
+3793
+3794
+3795
+3796
+3797
+3798
+3799
+3800
+3801
+3802
+3803
+3804
+3805
+3806
+3807
+3808
+3809
+3810
+3811
+3812
+3813
+3814
+3815
+3816
+3817
+3818
+3819
+3820
+3821
+3822
+3823
+3824
+3825
+3826
+3827
+3828
+3829
+3830
+3831
+3832
+3833
+3834
+3835
+3836
+3837
+3838
+3839
+3840
+3841
+3842
+3843
+3844
+3845
+3846
+3847
+3848
+3849
+3850
+3851
+3852
+3853
+3854
+3855
+3856
+3857
+3858
+3859
+3860
+3861
+3862
+3863
+3864
+3865
+3866
+3867
+3868
+3869
+3870
+
use core::{iter, slice, str};
+
+#[cfg(all(feature = "alloc", feature = "unicode"))]
+use alloc::vec;
+#[cfg(feature = "alloc")]
+use alloc::{borrow::Cow, string::String, vec::Vec};
+
+#[cfg(feature = "std")]
+use std::{ffi::OsStr, path::Path};
+
+use memchr::{memchr, memmem, memrchr};
+
+use crate::escape_bytes::EscapeBytes;
+#[cfg(feature = "alloc")]
+use crate::ext_vec::ByteVec;
+#[cfg(feature = "unicode")]
+use crate::unicode::{
+    whitespace_len_fwd, whitespace_len_rev, GraphemeIndices, Graphemes,
+    SentenceIndices, Sentences, WordIndices, Words, WordsWithBreakIndices,
+    WordsWithBreaks,
+};
+use crate::{
+    ascii,
+    bstr::BStr,
+    byteset,
+    utf8::{self, CharIndices, Chars, Utf8Chunks, Utf8Error},
+};
+
+/// A short-hand constructor for building a `&[u8]`.
+///
+/// This idiosyncratic constructor is useful for concisely building byte string
+/// slices. Its primary utility is in conveniently writing byte string literals
+/// in a uniform way. For example, consider this code that does not compile:
+///
+/// ```ignore
+/// let strs = vec![b"a", b"xy"];
+/// ```
+///
+/// The above code doesn't compile because the type of the byte string literal
+/// `b"a"` is `&'static [u8; 1]`, and the type of `b"xy"` is
+/// `&'static [u8; 2]`. Since their types aren't the same, they can't be stored
+/// in the same `Vec`. (This is dissimilar from normal Unicode string slices,
+/// where both `"a"` and `"xy"` have the same type of `&'static str`.)
+///
+/// One way of getting the above code to compile is to convert byte strings to
+/// slices. You might try this:
+///
+/// ```ignore
+/// let strs = vec![&b"a", &b"xy"];
+/// ```
+///
+/// But this just creates values with type `& &'static [u8; 1]` and
+/// `& &'static [u8; 2]`. Instead, you need to force the issue like so:
+///
+/// ```
+/// let strs = vec![&b"a"[..], &b"xy"[..]];
+/// // or
+/// let strs = vec![b"a".as_ref(), b"xy".as_ref()];
+/// ```
+///
+/// But neither of these are particularly convenient to type, especially when
+/// it's something as common as a string literal. Thus, this constructor
+/// permits writing the following instead:
+///
+/// ```
+/// use bstr::B;
+///
+/// let strs = vec![B("a"), B(b"xy")];
+/// ```
+///
+/// Notice that this also lets you mix and match both string literals and byte
+/// string literals. This can be quite convenient!
+#[allow(non_snake_case)]
+#[inline]
+pub fn B<'a, B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> &'a [u8] {
+    bytes.as_ref()
+}
+
+impl ByteSlice for [u8] {
+    #[inline]
+    fn as_bytes(&self) -> &[u8] {
+        self
+    }
+
+    #[inline]
+    fn as_bytes_mut(&mut self) -> &mut [u8] {
+        self
+    }
+}
+
+impl<const N: usize> ByteSlice for [u8; N] {
+    #[inline]
+    fn as_bytes(&self) -> &[u8] {
+        self
+    }
+
+    #[inline]
+    fn as_bytes_mut(&mut self) -> &mut [u8] {
+        self
+    }
+}
+
+/// Ensure that callers cannot implement `ByteSlice` by making an
+/// umplementable trait its super trait.
+mod private {
+    pub trait Sealed {}
+}
+impl private::Sealed for [u8] {}
+impl<const N: usize> private::Sealed for [u8; N] {}
+
+/// A trait that extends `&[u8]` with string oriented methods.
+///
+/// This trait is sealed and cannot be implemented outside of `bstr`.
+pub trait ByteSlice: private::Sealed {
+    /// A method for accessing the raw bytes of this type. This is always a
+    /// no-op and callers shouldn't care about it. This only exists for making
+    /// the extension trait work.
+    #[doc(hidden)]
+    fn as_bytes(&self) -> &[u8];
+
+    /// A method for accessing the raw bytes of this type, mutably. This is
+    /// always a no-op and callers shouldn't care about it. This only exists
+    /// for making the extension trait work.
+    #[doc(hidden)]
+    fn as_bytes_mut(&mut self) -> &mut [u8];
+
+    /// Return this byte slice as a `&BStr`.
+    ///
+    /// Use `&BStr` is useful because of its `fmt::Debug` representation
+    /// and various other trait implementations (such as `PartialEq` and
+    /// `PartialOrd`). In particular, the `Debug` implementation for `BStr`
+    /// shows its bytes as a normal string. For invalid UTF-8, hex escape
+    /// sequences are used.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// println!("{:?}", b"foo\xFFbar".as_bstr());
+    /// ```
+    #[inline]
+    fn as_bstr(&self) -> &BStr {
+        BStr::new(self.as_bytes())
+    }
+
+    /// Return this byte slice as a `&mut BStr`.
+    ///
+    /// Use `&mut BStr` is useful because of its `fmt::Debug` representation
+    /// and various other trait implementations (such as `PartialEq` and
+    /// `PartialOrd`). In particular, the `Debug` implementation for `BStr`
+    /// shows its bytes as a normal string. For invalid UTF-8, hex escape
+    /// sequences are used.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut bytes = *b"foo\xFFbar";
+    /// println!("{:?}", &mut bytes.as_bstr_mut());
+    /// ```
+    #[inline]
+    fn as_bstr_mut(&mut self) -> &mut BStr {
+        BStr::new_mut(self.as_bytes_mut())
+    }
+
+    /// Create an immutable byte string from an OS string slice.
+    ///
+    /// When the underlying bytes of OS strings are accessible, then this
+    /// always succeeds and is zero cost. Otherwise, this returns `None` if the
+    /// given OS string is not valid UTF-8. (For example, when the underlying
+    /// bytes are inaccessible on Windows, file paths are allowed to be a
+    /// sequence of arbitrary 16-bit integers. Not all such sequences can be
+    /// transcoded to valid UTF-8.)
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::ffi::OsStr;
+    ///
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// let bs = <[u8]>::from_os_str(os_str).expect("should be valid UTF-8");
+    /// assert_eq!(bs, B("foo"));
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn from_os_str(os_str: &OsStr) -> Option<&[u8]> {
+        #[cfg(unix)]
+        #[inline]
+        fn imp(os_str: &OsStr) -> Option<&[u8]> {
+            use std::os::unix::ffi::OsStrExt;
+
+            Some(os_str.as_bytes())
+        }
+
+        #[cfg(not(unix))]
+        #[inline]
+        fn imp(os_str: &OsStr) -> Option<&[u8]> {
+            os_str.to_str().map(|s| s.as_bytes())
+        }
+
+        imp(os_str)
+    }
+
+    /// Create an immutable byte string from a file path.
+    ///
+    /// When the underlying bytes of paths are accessible, then this always
+    /// succeeds and is zero cost. Otherwise, this returns `None` if the given
+    /// path is not valid UTF-8. (For example, when the underlying bytes are
+    /// inaccessible on Windows, file paths are allowed to be a sequence of
+    /// arbitrary 16-bit integers. Not all such sequences can be transcoded to
+    /// valid UTF-8.)
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let path = Path::new("foo");
+    /// let bs = <[u8]>::from_path(path).expect("should be valid UTF-8");
+    /// assert_eq!(bs, B("foo"));
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn from_path(path: &Path) -> Option<&[u8]> {
+        Self::from_os_str(path.as_os_str())
+    }
+
+    /// Safely convert this byte string into a `&str` if it's valid UTF-8.
+    ///
+    /// If this byte string is not valid UTF-8, then an error is returned. The
+    /// error returned indicates the first invalid byte found and the length
+    /// of the error.
+    ///
+    /// In cases where a lossy conversion to `&str` is acceptable, then use one
+    /// of the [`to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy) or
+    /// [`to_str_lossy_into`](trait.ByteSlice.html#method.to_str_lossy_into)
+    /// methods.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// # #[cfg(feature = "alloc")] {
+    /// use bstr::{B, ByteSlice, ByteVec};
+    ///
+    /// # fn example() -> Result<(), bstr::Utf8Error> {
+    /// let s = B("☃βツ").to_str()?;
+    /// assert_eq!("☃βツ", s);
+    ///
+    /// let mut bstring = <Vec<u8>>::from("☃βツ");
+    /// bstring.push(b'\xFF');
+    /// let err = bstring.to_str().unwrap_err();
+    /// assert_eq!(8, err.valid_up_to());
+    /// # Ok(()) }; example().unwrap()
+    /// # }
+    /// ```
+    #[inline]
+    fn to_str(&self) -> Result<&str, Utf8Error> {
+        utf8::validate(self.as_bytes()).map(|_| {
+            // SAFETY: This is safe because of the guarantees provided by
+            // utf8::validate.
+            unsafe { str::from_utf8_unchecked(self.as_bytes()) }
+        })
+    }
+
+    /// Unsafely convert this byte string into a `&str`, without checking for
+    /// valid UTF-8.
+    ///
+    /// # Safety
+    ///
+    /// Callers *must* ensure that this byte string is valid UTF-8 before
+    /// calling this method. Converting a byte string into a `&str` that is
+    /// not valid UTF-8 is considered undefined behavior.
+    ///
+    /// This routine is useful in performance sensitive contexts where the
+    /// UTF-8 validity of the byte string is already known and it is
+    /// undesirable to pay the cost of an additional UTF-8 validation check
+    /// that [`to_str`](trait.ByteSlice.html#method.to_str) performs.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// // SAFETY: This is safe because string literals are guaranteed to be
+    /// // valid UTF-8 by the Rust compiler.
+    /// let s = unsafe { B("☃βツ").to_str_unchecked() };
+    /// assert_eq!("☃βツ", s);
+    /// ```
+    #[inline]
+    unsafe fn to_str_unchecked(&self) -> &str {
+        str::from_utf8_unchecked(self.as_bytes())
+    }
+
+    /// Convert this byte string to a valid UTF-8 string by replacing invalid
+    /// UTF-8 bytes with the Unicode replacement codepoint (`U+FFFD`).
+    ///
+    /// If the byte string is already valid UTF-8, then no copying or
+    /// allocation is performed and a borrrowed string slice is returned. If
+    /// the byte string is not valid UTF-8, then an owned string buffer is
+    /// returned with invalid bytes replaced by the replacement codepoint.
+    ///
+    /// This method uses the "substitution of maximal subparts" (Unicode
+    /// Standard, Chapter 3, Section 9) strategy for inserting the replacement
+    /// codepoint. Specifically, a replacement codepoint is inserted whenever a
+    /// byte is found that cannot possibly lead to a valid code unit sequence.
+    /// If there were previous bytes that represented a prefix of a well-formed
+    /// code unit sequence, then all of those bytes are substituted with a
+    /// single replacement codepoint. The "substitution of maximal subparts"
+    /// strategy is the same strategy used by
+    /// [W3C's Encoding standard](https://www.w3.org/TR/encoding/).
+    /// For a more precise description of the maximal subpart strategy, see
+    /// the Unicode Standard, Chapter 3, Section 9. See also
+    /// [Public Review Issue #121](https://www.unicode.org/review/pr-121.html).
+    ///
+    /// N.B. Rust's standard library also appears to use the same strategy,
+    /// but it does not appear to be an API guarantee.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::borrow::Cow;
+    ///
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut bstring = <Vec<u8>>::from("☃βツ");
+    /// assert_eq!(Cow::Borrowed("☃βツ"), bstring.to_str_lossy());
+    ///
+    /// // Add a byte that makes the sequence invalid.
+    /// bstring.push(b'\xFF');
+    /// assert_eq!(Cow::Borrowed("☃βツ\u{FFFD}"), bstring.to_str_lossy());
+    /// ```
+    ///
+    /// This demonstrates the "maximal subpart" substitution logic.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// // \x61 is the ASCII codepoint for 'a'.
+    /// // \xF1\x80\x80 is a valid 3-byte code unit prefix.
+    /// // \xE1\x80 is a valid 2-byte code unit prefix.
+    /// // \xC2 is a valid 1-byte code unit prefix.
+    /// // \x62 is the ASCII codepoint for 'b'.
+    /// //
+    /// // In sum, each of the prefixes is replaced by a single replacement
+    /// // codepoint since none of the prefixes are properly completed. This
+    /// // is in contrast to other strategies that might insert a replacement
+    /// // codepoint for every single byte.
+    /// let bs = B(b"\x61\xF1\x80\x80\xE1\x80\xC2\x62");
+    /// assert_eq!("a\u{FFFD}\u{FFFD}\u{FFFD}b", bs.to_str_lossy());
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn to_str_lossy(&self) -> Cow<'_, str> {
+        match utf8::validate(self.as_bytes()) {
+            Ok(()) => {
+                // SAFETY: This is safe because of the guarantees provided by
+                // utf8::validate.
+                unsafe {
+                    Cow::Borrowed(str::from_utf8_unchecked(self.as_bytes()))
+                }
+            }
+            Err(err) => {
+                let mut lossy = String::with_capacity(self.as_bytes().len());
+                let (valid, after) =
+                    self.as_bytes().split_at(err.valid_up_to());
+                // SAFETY: This is safe because utf8::validate guarantees
+                // that all of `valid` is valid UTF-8.
+                lossy.push_str(unsafe { str::from_utf8_unchecked(valid) });
+                lossy.push_str("\u{FFFD}");
+                if let Some(len) = err.error_len() {
+                    after[len..].to_str_lossy_into(&mut lossy);
+                }
+                Cow::Owned(lossy)
+            }
+        }
+    }
+
+    /// Copy the contents of this byte string into the given owned string
+    /// buffer, while replacing invalid UTF-8 code unit sequences with the
+    /// Unicode replacement codepoint (`U+FFFD`).
+    ///
+    /// This method uses the same "substitution of maximal subparts" strategy
+    /// for inserting the replacement codepoint as the
+    /// [`to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy) method.
+    ///
+    /// This routine is useful for amortizing allocation. However, unlike
+    /// `to_str_lossy`, this routine will _always_ copy the contents of this
+    /// byte string into the destination buffer, even if this byte string is
+    /// valid UTF-8.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::borrow::Cow;
+    ///
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut bstring = <Vec<u8>>::from("☃βツ");
+    /// // Add a byte that makes the sequence invalid.
+    /// bstring.push(b'\xFF');
+    ///
+    /// let mut dest = String::new();
+    /// bstring.to_str_lossy_into(&mut dest);
+    /// assert_eq!("☃βツ\u{FFFD}", dest);
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn to_str_lossy_into(&self, dest: &mut String) {
+        let mut bytes = self.as_bytes();
+        dest.reserve(bytes.len());
+        loop {
+            match utf8::validate(bytes) {
+                Ok(()) => {
+                    // SAFETY: This is safe because utf8::validate guarantees
+                    // that all of `bytes` is valid UTF-8.
+                    dest.push_str(unsafe { str::from_utf8_unchecked(bytes) });
+                    break;
+                }
+                Err(err) => {
+                    let (valid, after) = bytes.split_at(err.valid_up_to());
+                    // SAFETY: This is safe because utf8::validate guarantees
+                    // that all of `valid` is valid UTF-8.
+                    dest.push_str(unsafe { str::from_utf8_unchecked(valid) });
+                    dest.push_str("\u{FFFD}");
+                    match err.error_len() {
+                        None => break,
+                        Some(len) => bytes = &after[len..],
+                    }
+                }
+            }
+        }
+    }
+
+    /// Create an OS string slice from this byte string.
+    ///
+    /// When OS strings can be constructed from arbitrary byte sequences, this
+    /// always succeeds and is zero cost. Otherwise, this returns a UTF-8
+    /// decoding error if this byte string is not valid UTF-8. (For example,
+    /// assuming the representation of `OsStr` is opaque on Windows, file paths
+    /// are allowed to be a sequence of arbitrary 16-bit integers. There is
+    /// no obvious mapping from an arbitrary sequence of 8-bit integers to an
+    /// arbitrary sequence of 16-bit integers. If the representation of `OsStr`
+    /// is even opened up, then this will convert any sequence of bytes to an
+    /// `OsStr` without cost.)
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let os_str = b"foo".to_os_str().expect("should be valid UTF-8");
+    /// assert_eq!(os_str, "foo");
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn to_os_str(&self) -> Result<&OsStr, Utf8Error> {
+        #[cfg(unix)]
+        #[inline]
+        fn imp(bytes: &[u8]) -> Result<&OsStr, Utf8Error> {
+            use std::os::unix::ffi::OsStrExt;
+
+            Ok(OsStr::from_bytes(bytes))
+        }
+
+        #[cfg(not(unix))]
+        #[inline]
+        fn imp(bytes: &[u8]) -> Result<&OsStr, Utf8Error> {
+            bytes.to_str().map(OsStr::new)
+        }
+
+        imp(self.as_bytes())
+    }
+
+    /// Lossily create an OS string slice from this byte string.
+    ///
+    /// When OS strings can be constructed from arbitrary byte sequences, this
+    /// is zero cost and always returns a slice. Otherwise, this will perform a
+    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
+    /// the Unicode replacement codepoint.
+    ///
+    /// Note that this can prevent the correct roundtripping of file paths when
+    /// the representation of `OsStr` is opaque.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let os_str = b"foo\xFFbar".to_os_str_lossy();
+    /// assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn to_os_str_lossy(&self) -> Cow<'_, OsStr> {
+        #[cfg(unix)]
+        #[inline]
+        fn imp(bytes: &[u8]) -> Cow<'_, OsStr> {
+            use std::os::unix::ffi::OsStrExt;
+
+            Cow::Borrowed(OsStr::from_bytes(bytes))
+        }
+
+        #[cfg(not(unix))]
+        #[inline]
+        fn imp(bytes: &[u8]) -> Cow<OsStr> {
+            use std::ffi::OsString;
+
+            match bytes.to_str_lossy() {
+                Cow::Borrowed(x) => Cow::Borrowed(OsStr::new(x)),
+                Cow::Owned(x) => Cow::Owned(OsString::from(x)),
+            }
+        }
+
+        imp(self.as_bytes())
+    }
+
+    /// Create a path slice from this byte string.
+    ///
+    /// When paths can be constructed from arbitrary byte sequences, this
+    /// always succeeds and is zero cost. Otherwise, this returns a UTF-8
+    /// decoding error if this byte string is not valid UTF-8. (For example,
+    /// assuming the representation of `Path` is opaque on Windows, file paths
+    /// are allowed to be a sequence of arbitrary 16-bit integers. There is
+    /// no obvious mapping from an arbitrary sequence of 8-bit integers to an
+    /// arbitrary sequence of 16-bit integers. If the representation of `Path`
+    /// is even opened up, then this will convert any sequence of bytes to an
+    /// `Path` without cost.)
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let path = b"foo".to_path().expect("should be valid UTF-8");
+    /// assert_eq!(path.as_os_str(), "foo");
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn to_path(&self) -> Result<&Path, Utf8Error> {
+        self.to_os_str().map(Path::new)
+    }
+
+    /// Lossily create a path slice from this byte string.
+    ///
+    /// When paths can be constructed from arbitrary byte sequences, this is
+    /// zero cost and always returns a slice. Otherwise, this will perform a
+    /// UTF-8 check and lossily convert this byte string into valid UTF-8 using
+    /// the Unicode replacement codepoint.
+    ///
+    /// Note that this can prevent the correct roundtripping of file paths when
+    /// the representation of `Path` is opaque.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"foo\xFFbar";
+    /// let path = bs.to_path_lossy();
+    /// assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
+    /// ```
+    #[cfg(feature = "std")]
+    #[inline]
+    fn to_path_lossy(&self) -> Cow<'_, Path> {
+        use std::path::PathBuf;
+
+        match self.to_os_str_lossy() {
+            Cow::Borrowed(x) => Cow::Borrowed(Path::new(x)),
+            Cow::Owned(x) => Cow::Owned(PathBuf::from(x)),
+        }
+    }
+
+    /// Create a new byte string by repeating this byte string `n` times.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if the capacity of the new byte string would
+    /// overflow.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(b"foo".repeatn(4), B("foofoofoofoo"));
+    /// assert_eq!(b"foo".repeatn(0), B(""));
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn repeatn(&self, n: usize) -> Vec<u8> {
+        self.as_bytes().repeat(n)
+    }
+
+    /// Returns true if and only if this byte string contains the given needle.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert!(b"foo bar".contains_str("foo"));
+    /// assert!(b"foo bar".contains_str("bar"));
+    /// assert!(!b"foo".contains_str("foobar"));
+    /// ```
+    #[inline]
+    fn contains_str<B: AsRef<[u8]>>(&self, needle: B) -> bool {
+        self.find(needle).is_some()
+    }
+
+    /// Returns true if and only if this byte string has the given prefix.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert!(b"foo bar".starts_with_str("foo"));
+    /// assert!(!b"foo bar".starts_with_str("bar"));
+    /// assert!(!b"foo".starts_with_str("foobar"));
+    /// ```
+    #[inline]
+    fn starts_with_str<B: AsRef<[u8]>>(&self, prefix: B) -> bool {
+        self.as_bytes().starts_with(prefix.as_ref())
+    }
+
+    /// Returns true if and only if this byte string has the given suffix.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert!(b"foo bar".ends_with_str("bar"));
+    /// assert!(!b"foo bar".ends_with_str("foo"));
+    /// assert!(!b"bar".ends_with_str("foobar"));
+    /// ```
+    #[inline]
+    fn ends_with_str<B: AsRef<[u8]>>(&self, suffix: B) -> bool {
+        self.as_bytes().ends_with(suffix.as_ref())
+    }
+
+    /// Returns the index of the first occurrence of the given needle.
+    ///
+    /// The needle may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// Note that if you're are searching for the same needle in many
+    /// different small haystacks, it may be faster to initialize a
+    /// [`Finder`](struct.Finder.html) once, and reuse it for each search.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo bar baz";
+    /// assert_eq!(Some(0), s.find("foo"));
+    /// assert_eq!(Some(4), s.find("bar"));
+    /// assert_eq!(None, s.find("quux"));
+    /// ```
+    #[inline]
+    fn find<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
+        Finder::new(needle.as_ref()).find(self.as_bytes())
+    }
+
+    /// Returns the index of the last occurrence of the given needle.
+    ///
+    /// The needle may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// Note that if you're are searching for the same needle in many
+    /// different small haystacks, it may be faster to initialize a
+    /// [`FinderReverse`](struct.FinderReverse.html) once, and reuse it for
+    /// each search.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo bar baz";
+    /// assert_eq!(Some(0), s.rfind("foo"));
+    /// assert_eq!(Some(4), s.rfind("bar"));
+    /// assert_eq!(Some(8), s.rfind("ba"));
+    /// assert_eq!(None, s.rfind("quux"));
+    /// ```
+    #[inline]
+    fn rfind<B: AsRef<[u8]>>(&self, needle: B) -> Option<usize> {
+        FinderReverse::new(needle.as_ref()).rfind(self.as_bytes())
+    }
+
+    /// Returns an iterator of the non-overlapping occurrences of the given
+    /// needle. The iterator yields byte offset positions indicating the start
+    /// of each match.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo bar foo foo quux foo";
+    /// let matches: Vec<usize> = s.find_iter("foo").collect();
+    /// assert_eq!(matches, vec![0, 8, 12, 21]);
+    /// ```
+    ///
+    /// An empty string matches at every position, including the position
+    /// immediately following the last byte:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let matches: Vec<usize> = b"foo".find_iter("").collect();
+    /// assert_eq!(matches, vec![0, 1, 2, 3]);
+    ///
+    /// let matches: Vec<usize> = b"".find_iter("").collect();
+    /// assert_eq!(matches, vec![0]);
+    /// ```
+    #[inline]
+    fn find_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        needle: &'n B,
+    ) -> Find<'h, 'n> {
+        Find::new(self.as_bytes(), needle.as_ref())
+    }
+
+    /// Returns an iterator of the non-overlapping occurrences of the given
+    /// needle in reverse. The iterator yields byte offset positions indicating
+    /// the start of each match.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo bar foo foo quux foo";
+    /// let matches: Vec<usize> = s.rfind_iter("foo").collect();
+    /// assert_eq!(matches, vec![21, 12, 8, 0]);
+    /// ```
+    ///
+    /// An empty string matches at every position, including the position
+    /// immediately following the last byte:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let matches: Vec<usize> = b"foo".rfind_iter("").collect();
+    /// assert_eq!(matches, vec![3, 2, 1, 0]);
+    ///
+    /// let matches: Vec<usize> = b"".rfind_iter("").collect();
+    /// assert_eq!(matches, vec![0]);
+    /// ```
+    #[inline]
+    fn rfind_iter<'h, 'n, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        needle: &'n B,
+    ) -> FindReverse<'h, 'n> {
+        FindReverse::new(self.as_bytes(), needle.as_ref())
+    }
+
+    /// Returns the index of the first occurrence of the given byte. If the
+    /// byte does not occur in this byte string, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(Some(10), b"foo bar baz".find_byte(b'z'));
+    /// assert_eq!(None, b"foo bar baz".find_byte(b'y'));
+    /// ```
+    #[inline]
+    fn find_byte(&self, byte: u8) -> Option<usize> {
+        memchr(byte, self.as_bytes())
+    }
+
+    /// Returns the index of the last occurrence of the given byte. If the
+    /// byte does not occur in this byte string, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(Some(10), b"foo bar baz".rfind_byte(b'z'));
+    /// assert_eq!(None, b"foo bar baz".rfind_byte(b'y'));
+    /// ```
+    #[inline]
+    fn rfind_byte(&self, byte: u8) -> Option<usize> {
+        memrchr(byte, self.as_bytes())
+    }
+
+    /// Returns the index of the first occurrence of the given codepoint.
+    /// If the codepoint does not occur in this byte string, then `None` is
+    /// returned.
+    ///
+    /// Note that if one searches for the replacement codepoint, `\u{FFFD}`,
+    /// then only explicit occurrences of that encoding will be found. Invalid
+    /// UTF-8 sequences will not be matched.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(Some(10), b"foo bar baz".find_char('z'));
+    /// assert_eq!(Some(4), B("αβγγδ").find_char('γ'));
+    /// assert_eq!(None, b"foo bar baz".find_char('y'));
+    /// ```
+    #[inline]
+    fn find_char(&self, ch: char) -> Option<usize> {
+        self.find(ch.encode_utf8(&mut [0; 4]))
+    }
+
+    /// Returns the index of the last occurrence of the given codepoint.
+    /// If the codepoint does not occur in this byte string, then `None` is
+    /// returned.
+    ///
+    /// Note that if one searches for the replacement codepoint, `\u{FFFD}`,
+    /// then only explicit occurrences of that encoding will be found. Invalid
+    /// UTF-8 sequences will not be matched.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(Some(10), b"foo bar baz".rfind_char('z'));
+    /// assert_eq!(Some(6), B("αβγγδ").rfind_char('γ'));
+    /// assert_eq!(None, b"foo bar baz".rfind_char('y'));
+    /// ```
+    #[inline]
+    fn rfind_char(&self, ch: char) -> Option<usize> {
+        self.rfind(ch.encode_utf8(&mut [0; 4]))
+    }
+
+    /// Returns the index of the first occurrence of any of the bytes in the
+    /// provided set.
+    ///
+    /// The `byteset` may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
+    /// note that passing a `&str` which contains multibyte characters may not
+    /// behave as you expect: each byte in the `&str` is treated as an
+    /// individual member of the byte set.
+    ///
+    /// Note that order is irrelevant for the `byteset` parameter, and
+    /// duplicate bytes present in its body are ignored.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the set of bytes and the haystack. That is, this
+    /// runs in `O(byteset.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(b"foo bar baz".find_byteset(b"zr"), Some(6));
+    /// assert_eq!(b"foo baz bar".find_byteset(b"bzr"), Some(4));
+    /// assert_eq!(None, b"foo baz bar".find_byteset(b"\t\n"));
+    /// // The empty byteset never matches.
+    /// assert_eq!(None, b"abc".find_byteset(b""));
+    /// assert_eq!(None, b"".find_byteset(b""));
+    /// ```
+    #[inline]
+    fn find_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
+        byteset::find(self.as_bytes(), byteset.as_ref())
+    }
+
+    /// Returns the index of the first occurrence of a byte that is not a
+    /// member of the provided set.
+    ///
+    /// The `byteset` may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
+    /// note that passing a `&str` which contains multibyte characters may not
+    /// behave as you expect: each byte in the `&str` is treated as an
+    /// individual member of the byte set.
+    ///
+    /// Note that order is irrelevant for the `byteset` parameter, and
+    /// duplicate bytes present in its body are ignored.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the set of bytes and the haystack. That is, this
+    /// runs in `O(byteset.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(b"foo bar baz".find_not_byteset(b"fo "), Some(4));
+    /// assert_eq!(b"\t\tbaz bar".find_not_byteset(b" \t\r\n"), Some(2));
+    /// assert_eq!(b"foo\nbaz\tbar".find_not_byteset(b"\t\n"), Some(0));
+    /// // The negation of the empty byteset matches everything.
+    /// assert_eq!(Some(0), b"abc".find_not_byteset(b""));
+    /// // But an empty string never contains anything.
+    /// assert_eq!(None, b"".find_not_byteset(b""));
+    /// ```
+    #[inline]
+    fn find_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
+        byteset::find_not(self.as_bytes(), byteset.as_ref())
+    }
+
+    /// Returns the index of the last occurrence of any of the bytes in the
+    /// provided set.
+    ///
+    /// The `byteset` may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
+    /// note that passing a `&str` which contains multibyte characters may not
+    /// behave as you expect: each byte in the `&str` is treated as an
+    /// individual member of the byte set.
+    ///
+    /// Note that order is irrelevant for the `byteset` parameter, and duplicate
+    /// bytes present in its body are ignored.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the set of bytes and the haystack. That is, this
+    /// runs in `O(byteset.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(b"foo bar baz".rfind_byteset(b"agb"), Some(9));
+    /// assert_eq!(b"foo baz bar".rfind_byteset(b"rabz "), Some(10));
+    /// assert_eq!(b"foo baz bar".rfind_byteset(b"\n123"), None);
+    /// ```
+    #[inline]
+    fn rfind_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
+        byteset::rfind(self.as_bytes(), byteset.as_ref())
+    }
+
+    /// Returns the index of the last occurrence of a byte that is not a member
+    /// of the provided set.
+    ///
+    /// The `byteset` may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`, but
+    /// note that passing a `&str` which contains multibyte characters may not
+    /// behave as you expect: each byte in the `&str` is treated as an
+    /// individual member of the byte set.
+    ///
+    /// Note that order is irrelevant for the `byteset` parameter, and
+    /// duplicate bytes present in its body are ignored.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the set of bytes and the haystack. That is, this
+    /// runs in `O(byteset.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(b"foo bar baz,\t".rfind_not_byteset(b",\t"), Some(10));
+    /// assert_eq!(b"foo baz bar".rfind_not_byteset(b"rabz "), Some(2));
+    /// assert_eq!(None, b"foo baz bar".rfind_not_byteset(b"barfoz "));
+    /// ```
+    #[inline]
+    fn rfind_not_byteset<B: AsRef<[u8]>>(&self, byteset: B) -> Option<usize> {
+        byteset::rfind_not(self.as_bytes(), byteset.as_ref())
+    }
+
+    /// Returns an iterator over the fields in a byte string, separated
+    /// by contiguous whitespace (according to the Unicode property
+    /// `White_Space`).
+    ///
+    /// # Example
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("  foo\tbar\t\u{2003}\nquux   \n");
+    /// let fields: Vec<&[u8]> = s.fields().collect();
+    /// assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
+    /// ```
+    ///
+    /// A byte string consisting of just whitespace yields no elements:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(0, B("  \n\t\u{2003}\n  \t").fields().count());
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn fields(&self) -> Fields<'_> {
+        Fields::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the fields in a byte string, separated by
+    /// contiguous codepoints satisfying the given predicate.
+    ///
+    /// If this byte string is not valid UTF-8, then the given closure will
+    /// be called with a Unicode replacement codepoint when invalid UTF-8
+    /// bytes are seen.
+    ///
+    /// # Example
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"123foo999999bar1quux123456";
+    /// let fields: Vec<&[u8]> = s.fields_with(|c| c.is_numeric()).collect();
+    /// assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
+    /// ```
+    ///
+    /// A byte string consisting of all codepoints satisfying the predicate
+    /// yields no elements:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(0, b"1911354563".fields_with(|c| c.is_numeric()).count());
+    /// ```
+    #[inline]
+    fn fields_with<F: FnMut(char) -> bool>(&self, f: F) -> FieldsWith<'_, F> {
+        FieldsWith::new(self.as_bytes(), f)
+    }
+
+    /// Returns an iterator over substrings of this byte string, separated
+    /// by the given byte string. Each element yielded is guaranteed not to
+    /// include the splitter substring.
+    ///
+    /// The splitter may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"Mary had a little lamb".split_str(" ").collect();
+    /// assert_eq!(x, vec![
+    ///     B("Mary"), B("had"), B("a"), B("little"), B("lamb"),
+    /// ]);
+    ///
+    /// let x: Vec<&[u8]> = b"".split_str("X").collect();
+    /// assert_eq!(x, vec![b""]);
+    ///
+    /// let x: Vec<&[u8]> = b"lionXXtigerXleopard".split_str("X").collect();
+    /// assert_eq!(x, vec![B("lion"), B(""), B("tiger"), B("leopard")]);
+    ///
+    /// let x: Vec<&[u8]> = b"lion::tiger::leopard".split_str("::").collect();
+    /// assert_eq!(x, vec![B("lion"), B("tiger"), B("leopard")]);
+    /// ```
+    ///
+    /// If a string contains multiple contiguous separators, you will end up
+    /// with empty strings yielded by the iterator:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"||||a||b|c".split_str("|").collect();
+    /// assert_eq!(x, vec![
+    ///     B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+    /// ]);
+    ///
+    /// let x: Vec<&[u8]> = b"(///)".split_str("/").collect();
+    /// assert_eq!(x, vec![B("("), B(""), B(""), B(")")]);
+    /// ```
+    ///
+    /// Separators at the start or end of a string are neighbored by empty
+    /// strings.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"010".split_str("0").collect();
+    /// assert_eq!(x, vec![B(""), B("1"), B("")]);
+    /// ```
+    ///
+    /// When the empty string is used as a separator, it splits every **byte**
+    /// in the byte string, along with the beginning and end of the byte
+    /// string.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"rust".split_str("").collect();
+    /// assert_eq!(x, vec![
+    ///     B(""), B("r"), B("u"), B("s"), B("t"), B(""),
+    /// ]);
+    ///
+    /// // Splitting by an empty string is not UTF-8 aware. Elements yielded
+    /// // may not be valid UTF-8!
+    /// let x: Vec<&[u8]> = B("☃").split_str("").collect();
+    /// assert_eq!(x, vec![
+    ///     B(""), B(b"\xE2"), B(b"\x98"), B(b"\x83"), B(""),
+    /// ]);
+    /// ```
+    ///
+    /// Contiguous separators, especially whitespace, can lead to possibly
+    /// surprising behavior. For example, this code is correct:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"    a  b c".split_str(" ").collect();
+    /// assert_eq!(x, vec![
+    ///     B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+    /// ]);
+    /// ```
+    ///
+    /// It does *not* give you `["a", "b", "c"]`. For that behavior, use
+    /// [`fields`](#method.fields) instead.
+    #[inline]
+    fn split_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        splitter: &'s B,
+    ) -> Split<'h, 's> {
+        Split::new(self.as_bytes(), splitter.as_ref())
+    }
+
+    /// Returns an iterator over substrings of this byte string, separated by
+    /// the given byte string, in reverse. Each element yielded is guaranteed
+    /// not to include the splitter substring.
+    ///
+    /// The splitter may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> =
+    ///     b"Mary had a little lamb".rsplit_str(" ").collect();
+    /// assert_eq!(x, vec![
+    ///     B("lamb"), B("little"), B("a"), B("had"), B("Mary"),
+    /// ]);
+    ///
+    /// let x: Vec<&[u8]> = b"".rsplit_str("X").collect();
+    /// assert_eq!(x, vec![b""]);
+    ///
+    /// let x: Vec<&[u8]> = b"lionXXtigerXleopard".rsplit_str("X").collect();
+    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B(""), B("lion")]);
+    ///
+    /// let x: Vec<&[u8]> = b"lion::tiger::leopard".rsplit_str("::").collect();
+    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B("lion")]);
+    /// ```
+    ///
+    /// If a string contains multiple contiguous separators, you will end up
+    /// with empty strings yielded by the iterator:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"||||a||b|c".rsplit_str("|").collect();
+    /// assert_eq!(x, vec![
+    ///     B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+    /// ]);
+    ///
+    /// let x: Vec<&[u8]> = b"(///)".rsplit_str("/").collect();
+    /// assert_eq!(x, vec![B(")"), B(""), B(""), B("(")]);
+    /// ```
+    ///
+    /// Separators at the start or end of a string are neighbored by empty
+    /// strings.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"010".rsplit_str("0").collect();
+    /// assert_eq!(x, vec![B(""), B("1"), B("")]);
+    /// ```
+    ///
+    /// When the empty string is used as a separator, it splits every **byte**
+    /// in the byte string, along with the beginning and end of the byte
+    /// string.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"rust".rsplit_str("").collect();
+    /// assert_eq!(x, vec![
+    ///     B(""), B("t"), B("s"), B("u"), B("r"), B(""),
+    /// ]);
+    ///
+    /// // Splitting by an empty string is not UTF-8 aware. Elements yielded
+    /// // may not be valid UTF-8!
+    /// let x: Vec<&[u8]> = B("☃").rsplit_str("").collect();
+    /// assert_eq!(x, vec![B(""), B(b"\x83"), B(b"\x98"), B(b"\xE2"), B("")]);
+    /// ```
+    ///
+    /// Contiguous separators, especially whitespace, can lead to possibly
+    /// surprising behavior. For example, this code is correct:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<&[u8]> = b"    a  b c".rsplit_str(" ").collect();
+    /// assert_eq!(x, vec![
+    ///     B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+    /// ]);
+    /// ```
+    ///
+    /// It does *not* give you `["a", "b", "c"]`.
+    #[inline]
+    fn rsplit_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        splitter: &'s B,
+    ) -> SplitReverse<'h, 's> {
+        SplitReverse::new(self.as_bytes(), splitter.as_ref())
+    }
+
+    /// Split this byte string at the first occurrence of `splitter`.
+    ///
+    /// If the `splitter` is found in the byte string, returns a tuple
+    /// containing the parts of the string before and after the first occurrence
+    /// of `splitter` respectively. Otherwise, if there are no occurrences of
+    /// `splitter` in the byte string, returns `None`.
+    ///
+    /// The splitter may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// If you need to split on the *last* instance of a delimiter instead, see
+    /// the [`ByteSlice::rsplit_once_str`](#method.rsplit_once_str) method .
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(
+    ///     B("foo,bar").split_once_str(","),
+    ///     Some((B("foo"), B("bar"))),
+    /// );
+    /// assert_eq!(
+    ///     B("foo,bar,baz").split_once_str(","),
+    ///     Some((B("foo"), B("bar,baz"))),
+    /// );
+    /// assert_eq!(B("foo").split_once_str(","), None);
+    /// assert_eq!(B("foo,").split_once_str(b","), Some((B("foo"), B(""))));
+    /// assert_eq!(B(",foo").split_once_str(b","), Some((B(""), B("foo"))));
+    /// ```
+    #[inline]
+    fn split_once_str<'a, B: ?Sized + AsRef<[u8]>>(
+        &'a self,
+        splitter: &B,
+    ) -> Option<(&'a [u8], &'a [u8])> {
+        let bytes = self.as_bytes();
+        let splitter = splitter.as_ref();
+        let start = Finder::new(splitter).find(bytes)?;
+        let end = start + splitter.len();
+        Some((&bytes[..start], &bytes[end..]))
+    }
+
+    /// Split this byte string at the last occurrence of `splitter`.
+    ///
+    /// If the `splitter` is found in the byte string, returns a tuple
+    /// containing the parts of the string before and after the last occurrence
+    /// of `splitter`, respectively. Otherwise, if there are no occurrences of
+    /// `splitter` in the byte string, returns `None`.
+    ///
+    /// The splitter may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// If you need to split on the *first* instance of a delimiter instead, see
+    /// the [`ByteSlice::split_once_str`](#method.split_once_str) method.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(
+    ///     B("foo,bar").rsplit_once_str(","),
+    ///     Some((B("foo"), B("bar"))),
+    /// );
+    /// assert_eq!(
+    ///     B("foo,bar,baz").rsplit_once_str(","),
+    ///     Some((B("foo,bar"), B("baz"))),
+    /// );
+    /// assert_eq!(B("foo").rsplit_once_str(","), None);
+    /// assert_eq!(B("foo,").rsplit_once_str(b","), Some((B("foo"), B(""))));
+    /// assert_eq!(B(",foo").rsplit_once_str(b","), Some((B(""), B("foo"))));
+    /// ```
+    #[inline]
+    fn rsplit_once_str<'a, B: ?Sized + AsRef<[u8]>>(
+        &'a self,
+        splitter: &B,
+    ) -> Option<(&'a [u8], &'a [u8])> {
+        let bytes = self.as_bytes();
+        let splitter = splitter.as_ref();
+        let start = FinderReverse::new(splitter).rfind(bytes)?;
+        let end = start + splitter.len();
+        Some((&bytes[..start], &bytes[end..]))
+    }
+
+    /// Returns an iterator of at most `limit` substrings of this byte string,
+    /// separated by the given byte string. If `limit` substrings are yielded,
+    /// then the last substring will contain the remainder of this byte string.
+    ///
+    /// The needle may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<_> = b"Mary had a little lamb".splitn_str(3, " ").collect();
+    /// assert_eq!(x, vec![B("Mary"), B("had"), B("a little lamb")]);
+    ///
+    /// let x: Vec<_> = b"".splitn_str(3, "X").collect();
+    /// assert_eq!(x, vec![b""]);
+    ///
+    /// let x: Vec<_> = b"lionXXtigerXleopard".splitn_str(3, "X").collect();
+    /// assert_eq!(x, vec![B("lion"), B(""), B("tigerXleopard")]);
+    ///
+    /// let x: Vec<_> = b"lion::tiger::leopard".splitn_str(2, "::").collect();
+    /// assert_eq!(x, vec![B("lion"), B("tiger::leopard")]);
+    ///
+    /// let x: Vec<_> = b"abcXdef".splitn_str(1, "X").collect();
+    /// assert_eq!(x, vec![B("abcXdef")]);
+    ///
+    /// let x: Vec<_> = b"abcdef".splitn_str(2, "X").collect();
+    /// assert_eq!(x, vec![B("abcdef")]);
+    ///
+    /// let x: Vec<_> = b"abcXdef".splitn_str(0, "X").collect();
+    /// assert!(x.is_empty());
+    /// ```
+    #[inline]
+    fn splitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        limit: usize,
+        splitter: &'s B,
+    ) -> SplitN<'h, 's> {
+        SplitN::new(self.as_bytes(), splitter.as_ref(), limit)
+    }
+
+    /// Returns an iterator of at most `limit` substrings of this byte string,
+    /// separated by the given byte string, in reverse. If `limit` substrings
+    /// are yielded, then the last substring will contain the remainder of this
+    /// byte string.
+    ///
+    /// The needle may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let x: Vec<_> =
+    ///     b"Mary had a little lamb".rsplitn_str(3, " ").collect();
+    /// assert_eq!(x, vec![B("lamb"), B("little"), B("Mary had a")]);
+    ///
+    /// let x: Vec<_> = b"".rsplitn_str(3, "X").collect();
+    /// assert_eq!(x, vec![b""]);
+    ///
+    /// let x: Vec<_> = b"lionXXtigerXleopard".rsplitn_str(3, "X").collect();
+    /// assert_eq!(x, vec![B("leopard"), B("tiger"), B("lionX")]);
+    ///
+    /// let x: Vec<_> = b"lion::tiger::leopard".rsplitn_str(2, "::").collect();
+    /// assert_eq!(x, vec![B("leopard"), B("lion::tiger")]);
+    ///
+    /// let x: Vec<_> = b"abcXdef".rsplitn_str(1, "X").collect();
+    /// assert_eq!(x, vec![B("abcXdef")]);
+    ///
+    /// let x: Vec<_> = b"abcdef".rsplitn_str(2, "X").collect();
+    /// assert_eq!(x, vec![B("abcdef")]);
+    ///
+    /// let x: Vec<_> = b"abcXdef".rsplitn_str(0, "X").collect();
+    /// assert!(x.is_empty());
+    /// ```
+    #[inline]
+    fn rsplitn_str<'h, 's, B: ?Sized + AsRef<[u8]>>(
+        &'h self,
+        limit: usize,
+        splitter: &'s B,
+    ) -> SplitNReverse<'h, 's> {
+        SplitNReverse::new(self.as_bytes(), splitter.as_ref(), limit)
+    }
+
+    /// Replace all matches of the given needle with the given replacement, and
+    /// the result as a new `Vec<u8>`.
+    ///
+    /// This routine is useful as a convenience. If you need to reuse an
+    /// allocation, use [`replace_into`](#method.replace_into) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"this is old".replace("old", "new");
+    /// assert_eq!(s, "this is new".as_bytes());
+    /// ```
+    ///
+    /// When the pattern doesn't match:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"this is old".replace("nada nada", "limonada");
+    /// assert_eq!(s, "this is old".as_bytes());
+    /// ```
+    ///
+    /// When the needle is an empty string:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo".replace("", "Z");
+    /// assert_eq!(s, "ZfZoZoZ".as_bytes());
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn replace<N: AsRef<[u8]>, R: AsRef<[u8]>>(
+        &self,
+        needle: N,
+        replacement: R,
+    ) -> Vec<u8> {
+        let mut dest = Vec::with_capacity(self.as_bytes().len());
+        self.replace_into(needle, replacement, &mut dest);
+        dest
+    }
+
+    /// Replace up to `limit` matches of the given needle with the given
+    /// replacement, and the result as a new `Vec<u8>`.
+    ///
+    /// This routine is useful as a convenience. If you need to reuse an
+    /// allocation, use [`replacen_into`](#method.replacen_into) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foofoo".replacen("o", "z", 2);
+    /// assert_eq!(s, "fzzfoo".as_bytes());
+    /// ```
+    ///
+    /// When the pattern doesn't match:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foofoo".replacen("a", "z", 2);
+    /// assert_eq!(s, "foofoo".as_bytes());
+    /// ```
+    ///
+    /// When the needle is an empty string:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo".replacen("", "Z", 2);
+    /// assert_eq!(s, "ZfZoo".as_bytes());
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn replacen<N: AsRef<[u8]>, R: AsRef<[u8]>>(
+        &self,
+        needle: N,
+        replacement: R,
+        limit: usize,
+    ) -> Vec<u8> {
+        let mut dest = Vec::with_capacity(self.as_bytes().len());
+        self.replacen_into(needle, replacement, limit, &mut dest);
+        dest
+    }
+
+    /// Replace all matches of the given needle with the given replacement,
+    /// and write the result into the provided `Vec<u8>`.
+    ///
+    /// This does **not** clear `dest` before writing to it.
+    ///
+    /// This routine is useful for reusing allocation. For a more convenient
+    /// API, use [`replace`](#method.replace) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"this is old";
+    ///
+    /// let mut dest = vec![];
+    /// s.replace_into("old", "new", &mut dest);
+    /// assert_eq!(dest, "this is new".as_bytes());
+    /// ```
+    ///
+    /// When the pattern doesn't match:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"this is old";
+    ///
+    /// let mut dest = vec![];
+    /// s.replace_into("nada nada", "limonada", &mut dest);
+    /// assert_eq!(dest, "this is old".as_bytes());
+    /// ```
+    ///
+    /// When the needle is an empty string:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo";
+    ///
+    /// let mut dest = vec![];
+    /// s.replace_into("", "Z", &mut dest);
+    /// assert_eq!(dest, "ZfZoZoZ".as_bytes());
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn replace_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
+        &self,
+        needle: N,
+        replacement: R,
+        dest: &mut Vec<u8>,
+    ) {
+        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
+
+        let mut last = 0;
+        for start in self.find_iter(needle) {
+            dest.push_str(&self.as_bytes()[last..start]);
+            dest.push_str(replacement);
+            last = start + needle.len();
+        }
+        dest.push_str(&self.as_bytes()[last..]);
+    }
+
+    /// Replace up to `limit` matches of the given needle with the given
+    /// replacement, and write the result into the provided `Vec<u8>`.
+    ///
+    /// This does **not** clear `dest` before writing to it.
+    ///
+    /// This routine is useful for reusing allocation. For a more convenient
+    /// API, use [`replacen`](#method.replacen) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foofoo";
+    ///
+    /// let mut dest = vec![];
+    /// s.replacen_into("o", "z", 2, &mut dest);
+    /// assert_eq!(dest, "fzzfoo".as_bytes());
+    /// ```
+    ///
+    /// When the pattern doesn't match:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foofoo";
+    ///
+    /// let mut dest = vec![];
+    /// s.replacen_into("a", "z", 2, &mut dest);
+    /// assert_eq!(dest, "foofoo".as_bytes());
+    /// ```
+    ///
+    /// When the needle is an empty string:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foo";
+    ///
+    /// let mut dest = vec![];
+    /// s.replacen_into("", "Z", 2, &mut dest);
+    /// assert_eq!(dest, "ZfZoo".as_bytes());
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn replacen_into<N: AsRef<[u8]>, R: AsRef<[u8]>>(
+        &self,
+        needle: N,
+        replacement: R,
+        limit: usize,
+        dest: &mut Vec<u8>,
+    ) {
+        let (needle, replacement) = (needle.as_ref(), replacement.as_ref());
+
+        let mut last = 0;
+        for start in self.find_iter(needle).take(limit) {
+            dest.push_str(&self.as_bytes()[last..start]);
+            dest.push_str(replacement);
+            last = start + needle.len();
+        }
+        dest.push_str(&self.as_bytes()[last..]);
+    }
+
+    /// Returns an iterator over the bytes in this byte string.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"foobar";
+    /// let bytes: Vec<u8> = bs.bytes().collect();
+    /// assert_eq!(bytes, bs);
+    /// ```
+    #[inline]
+    fn bytes(&self) -> Bytes<'_> {
+        Bytes { it: self.as_bytes().iter() }
+    }
+
+    /// Returns an iterator over the Unicode scalar values in this byte string.
+    /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint
+    /// is yielded instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+    /// let chars: Vec<char> = bs.chars().collect();
+    /// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+    /// ```
+    ///
+    /// Codepoints can also be iterated over in reverse:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+    /// let chars: Vec<char> = bs.chars().rev().collect();
+    /// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+    /// ```
+    #[inline]
+    fn chars(&self) -> Chars<'_> {
+        Chars::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the Unicode scalar values in this byte string
+    /// along with their starting and ending byte index positions. If invalid
+    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
+    /// instead.
+    ///
+    /// Note that this is slightly different from the `CharIndices` iterator
+    /// provided by the standard library. Aside from working on possibly
+    /// invalid UTF-8, this iterator provides both the corresponding starting
+    /// and ending byte indices of each codepoint yielded. The ending position
+    /// is necessary to slice the original byte string when invalid UTF-8 bytes
+    /// are converted into a Unicode replacement codepoint, since a single
+    /// replacement codepoint can substitute anywhere from 1 to 3 invalid bytes
+    /// (inclusive).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+    /// let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
+    /// assert_eq!(chars, vec![
+    ///     (0, 3, '☃'),
+    ///     (3, 4, '\u{FFFD}'),
+    ///     (4, 8, '𝞃'),
+    ///     (8, 10, '\u{FFFD}'),
+    ///     (10, 11, 'a'),
+    /// ]);
+    /// ```
+    ///
+    /// Codepoints can also be iterated over in reverse:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+    /// let chars: Vec<(usize, usize, char)> = bs
+    ///     .char_indices()
+    ///     .rev()
+    ///     .collect();
+    /// assert_eq!(chars, vec![
+    ///     (10, 11, 'a'),
+    ///     (8, 10, '\u{FFFD}'),
+    ///     (4, 8, '𝞃'),
+    ///     (3, 4, '\u{FFFD}'),
+    ///     (0, 3, '☃'),
+    /// ]);
+    /// ```
+    #[inline]
+    fn char_indices(&self) -> CharIndices<'_> {
+        CharIndices::new(self.as_bytes())
+    }
+
+    /// Iterate over chunks of valid UTF-8.
+    ///
+    /// The iterator returned yields chunks of valid UTF-8 separated by invalid
+    /// UTF-8 bytes, if they exist. Invalid UTF-8 bytes are always 1-3 bytes,
+    /// which are determined via the "substitution of maximal subparts"
+    /// strategy described in the docs for the
+    /// [`ByteSlice::to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy)
+    /// method.
+    ///
+    /// # Examples
+    ///
+    /// This example shows how to gather all valid and invalid chunks from a
+    /// byte slice:
+    ///
+    /// ```
+    /// use bstr::{ByteSlice, Utf8Chunk};
+    ///
+    /// let bytes = b"foo\xFD\xFEbar\xFF";
+    ///
+    /// let (mut valid_chunks, mut invalid_chunks) = (vec![], vec![]);
+    /// for chunk in bytes.utf8_chunks() {
+    ///     if !chunk.valid().is_empty() {
+    ///         valid_chunks.push(chunk.valid());
+    ///     }
+    ///     if !chunk.invalid().is_empty() {
+    ///         invalid_chunks.push(chunk.invalid());
+    ///     }
+    /// }
+    ///
+    /// assert_eq!(valid_chunks, vec!["foo", "bar"]);
+    /// assert_eq!(invalid_chunks, vec![b"\xFD", b"\xFE", b"\xFF"]);
+    /// ```
+    #[inline]
+    fn utf8_chunks(&self) -> Utf8Chunks<'_> {
+        Utf8Chunks { bytes: self.as_bytes() }
+    }
+
+    /// Returns an iterator over the grapheme clusters in this byte string.
+    /// If invalid UTF-8 is encountered, then the Unicode replacement codepoint
+    /// is yielded instead.
+    ///
+    /// # Examples
+    ///
+    /// This example shows how multiple codepoints can combine to form a
+    /// single grapheme cluster:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+    /// let graphemes: Vec<&str> = bs.graphemes().collect();
+    /// assert_eq!(vec!["à̖", "🇺🇸"], graphemes);
+    /// ```
+    ///
+    /// This shows that graphemes can be iterated over in reverse:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+    /// let graphemes: Vec<&str> = bs.graphemes().rev().collect();
+    /// assert_eq!(vec!["🇺🇸", "à̖"], graphemes);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn graphemes(&self) -> Graphemes<'_> {
+        Graphemes::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the grapheme clusters in this byte string
+    /// along with their starting and ending byte index positions. If invalid
+    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
+    /// instead.
+    ///
+    /// # Examples
+    ///
+    /// This example shows how to get the byte offsets of each individual
+    /// grapheme cluster:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+    /// let graphemes: Vec<(usize, usize, &str)> =
+    ///     bs.grapheme_indices().collect();
+    /// assert_eq!(vec![(0, 5, "à̖"), (5, 13, "🇺🇸")], graphemes);
+    /// ```
+    ///
+    /// This example shows what happens when invalid UTF-8 is encountered. Note
+    /// that the offsets are valid indices into the original string, and do
+    /// not necessarily correspond to the length of the `&str` returned!
+    ///
+    /// ```
+    /// # #[cfg(all(feature = "alloc"))] {
+    /// use bstr::{ByteSlice, ByteVec};
+    ///
+    /// let mut bytes = vec![];
+    /// bytes.push_str("a\u{0300}\u{0316}");
+    /// bytes.push(b'\xFF');
+    /// bytes.push_str("\u{1F1FA}\u{1F1F8}");
+    ///
+    /// let graphemes: Vec<(usize, usize, &str)> =
+    ///     bytes.grapheme_indices().collect();
+    /// assert_eq!(
+    ///     graphemes,
+    ///     vec![(0, 5, "à̖"), (5, 6, "\u{FFFD}"), (6, 14, "🇺🇸")]
+    /// );
+    /// # }
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn grapheme_indices(&self) -> GraphemeIndices<'_> {
+        GraphemeIndices::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the words in this byte string. If invalid
+    /// UTF-8 is encountered, then the Unicode replacement codepoint is yielded
+    /// instead.
+    ///
+    /// This is similar to
+    /// [`words_with_breaks`](trait.ByteSlice.html#method.words_with_breaks),
+    /// except it only returns elements that contain a "word" character. A word
+    /// character is defined by UTS #18 (Annex C) to be the combination of the
+    /// `Alphabetic` and `Join_Control` properties, along with the
+    /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general
+    /// categories.
+    ///
+    /// Since words are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
+    /// let words: Vec<&str> = bs.words().collect();
+    /// assert_eq!(words, vec![
+    ///     "The", "quick", "brown", "fox", "can't",
+    ///     "jump", "32.3", "feet", "right",
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn words(&self) -> Words<'_> {
+        Words::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the words in this byte string along with
+    /// their starting and ending byte index positions.
+    ///
+    /// This is similar to
+    /// [`words_with_break_indices`](trait.ByteSlice.html#method.words_with_break_indices),
+    /// except it only returns elements that contain a "word" character. A word
+    /// character is defined by UTS #18 (Annex C) to be the combination of the
+    /// `Alphabetic` and `Join_Control` properties, along with the
+    /// `Decimal_Number`, `Mark` and `Connector_Punctuation` general
+    /// categories.
+    ///
+    /// Since words are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// This example shows how to get the byte offsets of each individual
+    /// word:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"can't jump 32.3 feet";
+    /// let words: Vec<(usize, usize, &str)> = bs.word_indices().collect();
+    /// assert_eq!(words, vec![
+    ///     (0, 5, "can't"),
+    ///     (6, 10, "jump"),
+    ///     (11, 15, "32.3"),
+    ///     (16, 20, "feet"),
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn word_indices(&self) -> WordIndices<'_> {
+        WordIndices::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the words in this byte string, along with
+    /// all breaks between the words. Concatenating all elements yielded by
+    /// the iterator results in the original string (modulo Unicode replacement
+    /// codepoint substitutions if invalid UTF-8 is encountered).
+    ///
+    /// Since words are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
+    /// let words: Vec<&str> = bs.words_with_breaks().collect();
+    /// assert_eq!(words, vec![
+    ///     "The", " ", "quick", " ", "(", "\"", "brown", "\"", ")",
+    ///     " ", "fox", " ", "can't", " ", "jump", " ", "32.3", " ", "feet",
+    ///     ",", " ", "right", "?",
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn words_with_breaks(&self) -> WordsWithBreaks<'_> {
+        WordsWithBreaks::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the words and their byte offsets in this
+    /// byte string, along with all breaks between the words. Concatenating
+    /// all elements yielded by the iterator results in the original string
+    /// (modulo Unicode replacement codepoint substitutions if invalid UTF-8 is
+    /// encountered).
+    ///
+    /// Since words are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// This example shows how to get the byte offsets of each individual
+    /// word:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"can't jump 32.3 feet";
+    /// let words: Vec<(usize, usize, &str)> =
+    ///     bs.words_with_break_indices().collect();
+    /// assert_eq!(words, vec![
+    ///     (0, 5, "can't"),
+    ///     (5, 6, " "),
+    ///     (6, 10, "jump"),
+    ///     (10, 11, " "),
+    ///     (11, 15, "32.3"),
+    ///     (15, 16, " "),
+    ///     (16, 20, "feet"),
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn words_with_break_indices(&self) -> WordsWithBreakIndices<'_> {
+        WordsWithBreakIndices::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the sentences in this byte string.
+    ///
+    /// Typically, a sentence will include its trailing punctuation and
+    /// whitespace. Concatenating all elements yielded by the iterator
+    /// results in the original string (modulo Unicode replacement codepoint
+    /// substitutions if invalid UTF-8 is encountered).
+    ///
+    /// Since sentences are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"I want this. Not that. Right now.";
+    /// let sentences: Vec<&str> = bs.sentences().collect();
+    /// assert_eq!(sentences, vec![
+    ///     "I want this. ",
+    ///     "Not that. ",
+    ///     "Right now.",
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn sentences(&self) -> Sentences<'_> {
+        Sentences::new(self.as_bytes())
+    }
+
+    /// Returns an iterator over the sentences in this byte string along with
+    /// their starting and ending byte index positions.
+    ///
+    /// Typically, a sentence will include its trailing punctuation and
+    /// whitespace. Concatenating all elements yielded by the iterator
+    /// results in the original string (modulo Unicode replacement codepoint
+    /// substitutions if invalid UTF-8 is encountered).
+    ///
+    /// Since sentences are made up of one or more codepoints, this iterator
+    /// yields `&str` elements. When invalid UTF-8 is encountered, replacement
+    /// codepoints are [substituted](index.html#handling-of-invalid-utf-8).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let bs = b"I want this. Not that. Right now.";
+    /// let sentences: Vec<(usize, usize, &str)> =
+    ///     bs.sentence_indices().collect();
+    /// assert_eq!(sentences, vec![
+    ///     (0, 13, "I want this. "),
+    ///     (13, 23, "Not that. "),
+    ///     (23, 33, "Right now."),
+    /// ]);
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn sentence_indices(&self) -> SentenceIndices<'_> {
+        SentenceIndices::new(self.as_bytes())
+    }
+
+    /// An iterator over all lines in a byte string, without their
+    /// terminators.
+    ///
+    /// For this iterator, the only line terminators recognized are `\r\n` and
+    /// `\n`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"\
+    /// foo
+    ///
+    /// bar\r
+    /// baz
+    ///
+    ///
+    /// quux";
+    /// let lines: Vec<&[u8]> = s.lines().collect();
+    /// assert_eq!(lines, vec![
+    ///     B("foo"), B(""), B("bar"), B("baz"), B(""), B(""), B("quux"),
+    /// ]);
+    /// ```
+    #[inline]
+    fn lines(&self) -> Lines<'_> {
+        Lines::new(self.as_bytes())
+    }
+
+    /// An iterator over all lines in a byte string, including their
+    /// terminators.
+    ///
+    /// For this iterator, the only line terminator recognized is `\n`. (Since
+    /// line terminators are included, this also handles `\r\n` line endings.)
+    ///
+    /// Line terminators are only included if they are present in the original
+    /// byte string. For example, the last line in a byte string may not end
+    /// with a line terminator.
+    ///
+    /// Concatenating all elements yielded by this iterator is guaranteed to
+    /// yield the original byte string.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"\
+    /// foo
+    ///
+    /// bar\r
+    /// baz
+    ///
+    ///
+    /// quux";
+    /// let lines: Vec<&[u8]> = s.lines_with_terminator().collect();
+    /// assert_eq!(lines, vec![
+    ///     B("foo\n"),
+    ///     B("\n"),
+    ///     B("bar\r\n"),
+    ///     B("baz\n"),
+    ///     B("\n"),
+    ///     B("\n"),
+    ///     B("quux"),
+    /// ]);
+    /// ```
+    #[inline]
+    fn lines_with_terminator(&self) -> LinesWithTerminator<'_> {
+        LinesWithTerminator::new(self.as_bytes())
+    }
+
+    /// Return a byte string slice with leading and trailing whitespace
+    /// removed.
+    ///
+    /// Whitespace is defined according to the terms of the `White_Space`
+    /// Unicode property.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(" foo\tbar\t\u{2003}\n");
+    /// assert_eq!(s.trim(), B("foo\tbar"));
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn trim(&self) -> &[u8] {
+        self.trim_start().trim_end()
+    }
+
+    /// Return a byte string slice with leading whitespace removed.
+    ///
+    /// Whitespace is defined according to the terms of the `White_Space`
+    /// Unicode property.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(" foo\tbar\t\u{2003}\n");
+    /// assert_eq!(s.trim_start(), B("foo\tbar\t\u{2003}\n"));
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn trim_start(&self) -> &[u8] {
+        let start = whitespace_len_fwd(self.as_bytes());
+        &self.as_bytes()[start..]
+    }
+
+    /// Return a byte string slice with trailing whitespace removed.
+    ///
+    /// Whitespace is defined according to the terms of the `White_Space`
+    /// Unicode property.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(" foo\tbar\t\u{2003}\n");
+    /// assert_eq!(s.trim_end(), B(" foo\tbar"));
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn trim_end(&self) -> &[u8] {
+        let end = whitespace_len_rev(self.as_bytes());
+        &self.as_bytes()[..end]
+    }
+
+    /// Return a byte string slice with leading and trailing characters
+    /// satisfying the given predicate removed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"123foo5bar789";
+    /// assert_eq!(s.trim_with(|c| c.is_numeric()), B("foo5bar"));
+    /// ```
+    #[inline]
+    fn trim_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
+        self.trim_start_with(&mut trim).trim_end_with(&mut trim)
+    }
+
+    /// Return a byte string slice with leading characters satisfying the given
+    /// predicate removed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"123foo5bar789";
+    /// assert_eq!(s.trim_start_with(|c| c.is_numeric()), B("foo5bar789"));
+    /// ```
+    #[inline]
+    fn trim_start_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
+        for (s, _, ch) in self.char_indices() {
+            if !trim(ch) {
+                return &self.as_bytes()[s..];
+            }
+        }
+        b""
+    }
+
+    /// Return a byte string slice with trailing characters satisfying the
+    /// given predicate removed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"123foo5bar789";
+    /// assert_eq!(s.trim_end_with(|c| c.is_numeric()), B("123foo5bar"));
+    /// ```
+    #[inline]
+    fn trim_end_with<F: FnMut(char) -> bool>(&self, mut trim: F) -> &[u8] {
+        for (_, e, ch) in self.char_indices().rev() {
+            if !trim(ch) {
+                return &self.as_bytes()[..e];
+            }
+        }
+        b""
+    }
+
+    /// Returns a new `Vec<u8>` containing the lowercase equivalent of this
+    /// byte string.
+    ///
+    /// In this case, lowercase is defined according to the `Lowercase` Unicode
+    /// property.
+    ///
+    /// If invalid UTF-8 is seen, or if a character has no lowercase variant,
+    /// then it is written to the given buffer unchanged.
+    ///
+    /// Note that some characters in this byte string may expand into multiple
+    /// characters when changing the case, so the number of bytes written to
+    /// the given byte string may not be equivalent to the number of bytes in
+    /// this byte string.
+    ///
+    /// If you'd like to reuse an allocation for performance reasons, then use
+    /// [`to_lowercase_into`](#method.to_lowercase_into) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("HELLO Β");
+    /// assert_eq!("hello β".as_bytes(), s.to_lowercase().as_bytes());
+    /// ```
+    ///
+    /// Scripts without case are not changed:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("农历新年");
+    /// assert_eq!("农历新年".as_bytes(), s.to_lowercase().as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+    /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s.to_lowercase().as_bytes());
+    /// ```
+    #[cfg(all(feature = "alloc", feature = "unicode"))]
+    #[inline]
+    fn to_lowercase(&self) -> Vec<u8> {
+        let mut buf = vec![];
+        self.to_lowercase_into(&mut buf);
+        buf
+    }
+
+    /// Writes the lowercase equivalent of this byte string into the given
+    /// buffer. The buffer is not cleared before written to.
+    ///
+    /// In this case, lowercase is defined according to the `Lowercase`
+    /// Unicode property.
+    ///
+    /// If invalid UTF-8 is seen, or if a character has no lowercase variant,
+    /// then it is written to the given buffer unchanged.
+    ///
+    /// Note that some characters in this byte string may expand into multiple
+    /// characters when changing the case, so the number of bytes written to
+    /// the given byte string may not be equivalent to the number of bytes in
+    /// this byte string.
+    ///
+    /// If you don't need to amortize allocation and instead prefer
+    /// convenience, then use [`to_lowercase`](#method.to_lowercase) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("HELLO Β");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_lowercase_into(&mut buf);
+    /// assert_eq!("hello β".as_bytes(), buf.as_bytes());
+    /// ```
+    ///
+    /// Scripts without case are not changed:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("农历新年");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_lowercase_into(&mut buf);
+    /// assert_eq!("农历新年".as_bytes(), buf.as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_lowercase_into(&mut buf);
+    /// assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), buf.as_bytes());
+    /// ```
+    #[cfg(all(feature = "alloc", feature = "unicode"))]
+    #[inline]
+    fn to_lowercase_into(&self, buf: &mut Vec<u8>) {
+        // TODO: This is the best we can do given what std exposes I think.
+        // If we roll our own case handling, then we might be able to do this
+        // a bit faster. We shouldn't roll our own case handling unless we
+        // need to, e.g., for doing caseless matching or case folding.
+
+        // TODO(BUG): This doesn't handle any special casing rules.
+
+        buf.reserve(self.as_bytes().len());
+        for (s, e, ch) in self.char_indices() {
+            if ch == '\u{FFFD}' {
+                buf.push_str(&self.as_bytes()[s..e]);
+            } else if ch.is_ascii() {
+                buf.push_char(ch.to_ascii_lowercase());
+            } else {
+                for upper in ch.to_lowercase() {
+                    buf.push_char(upper);
+                }
+            }
+        }
+    }
+
+    /// Returns a new `Vec<u8>` containing the ASCII lowercase equivalent of
+    /// this byte string.
+    ///
+    /// In this case, lowercase is only defined in ASCII letters. Namely, the
+    /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged.
+    /// In particular, the length of the byte string returned is always
+    /// equivalent to the length of this byte string.
+    ///
+    /// If you'd like to reuse an allocation for performance reasons, then use
+    /// [`make_ascii_lowercase`](#method.make_ascii_lowercase) to perform
+    /// the conversion in place.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("HELLO Β");
+    /// assert_eq!("hello Β".as_bytes(), s.to_ascii_lowercase().as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+    /// assert_eq!(s.to_ascii_lowercase(), B(b"foo\xFFbar\xE2\x98baz"));
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn to_ascii_lowercase(&self) -> Vec<u8> {
+        self.as_bytes().to_ascii_lowercase()
+    }
+
+    /// Convert this byte string to its lowercase ASCII equivalent in place.
+    ///
+    /// In this case, lowercase is only defined in ASCII letters. Namely, the
+    /// letters `A-Z` are converted to `a-z`. All other bytes remain unchanged.
+    ///
+    /// If you don't need to do the conversion in
+    /// place and instead prefer convenience, then use
+    /// [`to_ascii_lowercase`](#method.to_ascii_lowercase) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("HELLO Β");
+    /// s.make_ascii_lowercase();
+    /// assert_eq!(s, "hello Β".as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// # #[cfg(feature = "alloc")] {
+    /// use bstr::{B, ByteSlice, ByteVec};
+    ///
+    /// let mut s = <Vec<u8>>::from_slice(b"FOO\xFFBAR\xE2\x98BAZ");
+    /// s.make_ascii_lowercase();
+    /// assert_eq!(s, B(b"foo\xFFbar\xE2\x98baz"));
+    /// # }
+    /// ```
+    #[inline]
+    fn make_ascii_lowercase(&mut self) {
+        self.as_bytes_mut().make_ascii_lowercase();
+    }
+
+    /// Returns a new `Vec<u8>` containing the uppercase equivalent of this
+    /// byte string.
+    ///
+    /// In this case, uppercase is defined according to the `Uppercase`
+    /// Unicode property.
+    ///
+    /// If invalid UTF-8 is seen, or if a character has no uppercase variant,
+    /// then it is written to the given buffer unchanged.
+    ///
+    /// Note that some characters in this byte string may expand into multiple
+    /// characters when changing the case, so the number of bytes written to
+    /// the given byte string may not be equivalent to the number of bytes in
+    /// this byte string.
+    ///
+    /// If you'd like to reuse an allocation for performance reasons, then use
+    /// [`to_uppercase_into`](#method.to_uppercase_into) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("hello β");
+    /// assert_eq!(s.to_uppercase(), B("HELLO Β"));
+    /// ```
+    ///
+    /// Scripts without case are not changed:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("农历新年");
+    /// assert_eq!(s.to_uppercase(), B("农历新年"));
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"foo\xFFbar\xE2\x98baz");
+    /// assert_eq!(s.to_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
+    /// ```
+    #[cfg(all(feature = "alloc", feature = "unicode"))]
+    #[inline]
+    fn to_uppercase(&self) -> Vec<u8> {
+        let mut buf = vec![];
+        self.to_uppercase_into(&mut buf);
+        buf
+    }
+
+    /// Writes the uppercase equivalent of this byte string into the given
+    /// buffer. The buffer is not cleared before written to.
+    ///
+    /// In this case, uppercase is defined according to the `Uppercase`
+    /// Unicode property.
+    ///
+    /// If invalid UTF-8 is seen, or if a character has no uppercase variant,
+    /// then it is written to the given buffer unchanged.
+    ///
+    /// Note that some characters in this byte string may expand into multiple
+    /// characters when changing the case, so the number of bytes written to
+    /// the given byte string may not be equivalent to the number of bytes in
+    /// this byte string.
+    ///
+    /// If you don't need to amortize allocation and instead prefer
+    /// convenience, then use [`to_uppercase`](#method.to_uppercase) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("hello β");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_uppercase_into(&mut buf);
+    /// assert_eq!(buf, B("HELLO Β"));
+    /// ```
+    ///
+    /// Scripts without case are not changed:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("农历新年");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_uppercase_into(&mut buf);
+    /// assert_eq!(buf, B("农历新年"));
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"foo\xFFbar\xE2\x98baz");
+    ///
+    /// let mut buf = vec![];
+    /// s.to_uppercase_into(&mut buf);
+    /// assert_eq!(buf, B(b"FOO\xFFBAR\xE2\x98BAZ"));
+    /// ```
+    #[cfg(all(feature = "alloc", feature = "unicode"))]
+    #[inline]
+    fn to_uppercase_into(&self, buf: &mut Vec<u8>) {
+        // TODO: This is the best we can do given what std exposes I think.
+        // If we roll our own case handling, then we might be able to do this
+        // a bit faster. We shouldn't roll our own case handling unless we
+        // need to, e.g., for doing caseless matching or case folding.
+        buf.reserve(self.as_bytes().len());
+        for (s, e, ch) in self.char_indices() {
+            if ch == '\u{FFFD}' {
+                buf.push_str(&self.as_bytes()[s..e]);
+            } else if ch.is_ascii() {
+                buf.push_char(ch.to_ascii_uppercase());
+            } else {
+                for upper in ch.to_uppercase() {
+                    buf.push_char(upper);
+                }
+            }
+        }
+    }
+
+    /// Returns a new `Vec<u8>` containing the ASCII uppercase equivalent of
+    /// this byte string.
+    ///
+    /// In this case, uppercase is only defined in ASCII letters. Namely, the
+    /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged.
+    /// In particular, the length of the byte string returned is always
+    /// equivalent to the length of this byte string.
+    ///
+    /// If you'd like to reuse an allocation for performance reasons, then use
+    /// [`make_ascii_uppercase`](#method.make_ascii_uppercase) to perform
+    /// the conversion in place.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B("hello β");
+    /// assert_eq!(s.to_ascii_uppercase(), B("HELLO β"));
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = B(b"foo\xFFbar\xE2\x98baz");
+    /// assert_eq!(s.to_ascii_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
+    /// ```
+    #[cfg(feature = "alloc")]
+    #[inline]
+    fn to_ascii_uppercase(&self) -> Vec<u8> {
+        self.as_bytes().to_ascii_uppercase()
+    }
+
+    /// Convert this byte string to its uppercase ASCII equivalent in place.
+    ///
+    /// In this case, uppercase is only defined in ASCII letters. Namely, the
+    /// letters `a-z` are converted to `A-Z`. All other bytes remain unchanged.
+    ///
+    /// If you don't need to do the conversion in
+    /// place and instead prefer convenience, then use
+    /// [`to_ascii_uppercase`](#method.to_ascii_uppercase) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let mut s = <Vec<u8>>::from("hello β");
+    /// s.make_ascii_uppercase();
+    /// assert_eq!(s, B("HELLO β"));
+    /// ```
+    ///
+    /// Invalid UTF-8 remains as is:
+    ///
+    /// ```
+    /// # #[cfg(feature = "alloc")] {
+    /// use bstr::{B, ByteSlice, ByteVec};
+    ///
+    /// let mut s = <Vec<u8>>::from_slice(b"foo\xFFbar\xE2\x98baz");
+    /// s.make_ascii_uppercase();
+    /// assert_eq!(s, B(b"FOO\xFFBAR\xE2\x98BAZ"));
+    /// # }
+    /// ```
+    #[inline]
+    fn make_ascii_uppercase(&mut self) {
+        self.as_bytes_mut().make_ascii_uppercase();
+    }
+
+    /// Escapes this byte string into a sequence of `char` values.
+    ///
+    /// When the sequence of `char` values is concatenated into a string, the
+    /// result is always valid UTF-8. Any unprintable or invalid UTF-8 in this
+    /// byte string are escaped using using `\xNN` notation. Moreover, the
+    /// characters `\0`, `\r`, `\n`, `\t` and `\` are escaped as well.
+    ///
+    /// This is useful when one wants to get a human readable view of the raw
+    /// bytes that is also valid UTF-8.
+    ///
+    /// The iterator returned implements the `Display` trait. So one can do
+    /// `b"foo\xFFbar".escape_bytes().to_string()` to get a `String` with its
+    /// bytes escaped.
+    ///
+    /// The dual of this function is [`ByteVec::unescape_bytes`].
+    ///
+    /// Note that this is similar to, but not equivalent to the `Debug`
+    /// implementation on [`BStr`] and [`BString`]. The `Debug` implementations
+    /// also use the debug representation for all Unicode codepoints. However,
+    /// this escaping routine only escapes individual bytes. All Unicode
+    /// codepoints above `U+007F` are passed through unchanged without any
+    /// escaping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #[cfg(feature = "alloc")] {
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert_eq!(r"foo\xFFbar", b"foo\xFFbar".escape_bytes().to_string());
+    /// assert_eq!(r"foo\nbar", b"foo\nbar".escape_bytes().to_string());
+    /// assert_eq!(r"foo\tbar", b"foo\tbar".escape_bytes().to_string());
+    /// assert_eq!(r"foo\\bar", b"foo\\bar".escape_bytes().to_string());
+    /// assert_eq!(r"foo☃bar", B("foo☃bar").escape_bytes().to_string());
+    /// # }
+    /// ```
+    #[inline]
+    fn escape_bytes(&self) -> EscapeBytes<'_> {
+        EscapeBytes::new(self.as_bytes())
+    }
+
+    /// Reverse the bytes in this string, in place.
+    ///
+    /// This is not necessarily a well formed operation! For example, if this
+    /// byte string contains valid UTF-8 that isn't ASCII, then reversing the
+    /// string will likely result in invalid UTF-8 and otherwise non-sensical
+    /// content.
+    ///
+    /// Note that this is equivalent to the generic `[u8]::reverse` method.
+    /// This method is provided to permit callers to explicitly differentiate
+    /// between reversing bytes, codepoints and graphemes.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("hello");
+    /// s.reverse_bytes();
+    /// assert_eq!(s, "olleh".as_bytes());
+    /// ```
+    #[inline]
+    fn reverse_bytes(&mut self) {
+        self.as_bytes_mut().reverse();
+    }
+
+    /// Reverse the codepoints in this string, in place.
+    ///
+    /// If this byte string is valid UTF-8, then its reversal by codepoint
+    /// is also guaranteed to be valid UTF-8.
+    ///
+    /// This operation is equivalent to the following, but without allocating:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("foo☃bar");
+    ///
+    /// let mut chars: Vec<char> = s.chars().collect();
+    /// chars.reverse();
+    ///
+    /// let reversed: String = chars.into_iter().collect();
+    /// assert_eq!(reversed, "rab☃oof");
+    /// ```
+    ///
+    /// Note that this is not necessarily a well formed operation. For example,
+    /// if this byte string contains grapheme clusters with more than one
+    /// codepoint, then those grapheme clusters will not necessarily be
+    /// preserved. If you'd like to preserve grapheme clusters, then use
+    /// [`reverse_graphemes`](#method.reverse_graphemes) instead.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("foo☃bar");
+    /// s.reverse_chars();
+    /// assert_eq!(s, "rab☃oof".as_bytes());
+    /// ```
+    ///
+    /// This example shows that not all reversals lead to a well formed string.
+    /// For example, in this case, combining marks are used to put accents over
+    /// some letters, and those accent marks must appear after the codepoints
+    /// they modify.
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let mut s = <Vec<u8>>::from("résumé");
+    /// s.reverse_chars();
+    /// assert_eq!(s, B(b"\xCC\x81emus\xCC\x81er"));
+    /// ```
+    ///
+    /// A word of warning: the above example relies on the fact that
+    /// `résumé` is in decomposed normal form, which means there are separate
+    /// codepoints for the accents above `e`. If it is instead in composed
+    /// normal form, then the example works:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let mut s = <Vec<u8>>::from("résumé");
+    /// s.reverse_chars();
+    /// assert_eq!(s, B("émusér"));
+    /// ```
+    ///
+    /// The point here is to be cautious and not assume that just because
+    /// `reverse_chars` works in one case, that it therefore works in all
+    /// cases.
+    #[inline]
+    fn reverse_chars(&mut self) {
+        let mut i = 0;
+        loop {
+            let (_, size) = utf8::decode(&self.as_bytes()[i..]);
+            if size == 0 {
+                break;
+            }
+            if size > 1 {
+                self.as_bytes_mut()[i..i + size].reverse_bytes();
+            }
+            i += size;
+        }
+        self.reverse_bytes();
+    }
+
+    /// Reverse the graphemes in this string, in place.
+    ///
+    /// If this byte string is valid UTF-8, then its reversal by grapheme
+    /// is also guaranteed to be valid UTF-8.
+    ///
+    /// This operation is equivalent to the following, but without allocating:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("foo☃bar");
+    ///
+    /// let mut graphemes: Vec<&str> = s.graphemes().collect();
+    /// graphemes.reverse();
+    ///
+    /// let reversed = graphemes.concat();
+    /// assert_eq!(reversed, "rab☃oof");
+    /// ```
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("foo☃bar");
+    /// s.reverse_graphemes();
+    /// assert_eq!(s, "rab☃oof".as_bytes());
+    /// ```
+    ///
+    /// This example shows how this correctly handles grapheme clusters,
+    /// unlike `reverse_chars`.
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut s = <Vec<u8>>::from("résumé");
+    /// s.reverse_graphemes();
+    /// assert_eq!(s, "émusér".as_bytes());
+    /// ```
+    #[cfg(feature = "unicode")]
+    #[inline]
+    fn reverse_graphemes(&mut self) {
+        use crate::unicode::decode_grapheme;
+
+        let mut i = 0;
+        loop {
+            let (_, size) = decode_grapheme(&self.as_bytes()[i..]);
+            if size == 0 {
+                break;
+            }
+            if size > 1 {
+                self.as_bytes_mut()[i..i + size].reverse_bytes();
+            }
+            i += size;
+        }
+        self.reverse_bytes();
+    }
+
+    /// Returns true if and only if every byte in this byte string is ASCII.
+    ///
+    /// ASCII is an encoding that defines 128 codepoints. A byte corresponds to
+    /// an ASCII codepoint if and only if it is in the inclusive range
+    /// `[0, 127]`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert!(B("abc").is_ascii());
+    /// assert!(!B("☃βツ").is_ascii());
+    /// assert!(!B(b"\xFF").is_ascii());
+    /// ```
+    #[inline]
+    fn is_ascii(&self) -> bool {
+        ascii::first_non_ascii_byte(self.as_bytes()) == self.as_bytes().len()
+    }
+
+    /// Returns true if and only if the entire byte string is valid UTF-8.
+    ///
+    /// If you need location information about where a byte string's first
+    /// invalid UTF-8 byte is, then use the [`to_str`](#method.to_str) method.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// assert!(B("abc").is_utf8());
+    /// assert!(B("☃βツ").is_utf8());
+    /// // invalid bytes
+    /// assert!(!B(b"abc\xFF").is_utf8());
+    /// // surrogate encoding
+    /// assert!(!B(b"\xED\xA0\x80").is_utf8());
+    /// // incomplete sequence
+    /// assert!(!B(b"\xF0\x9D\x9Ca").is_utf8());
+    /// // overlong sequence
+    /// assert!(!B(b"\xF0\x82\x82\xAC").is_utf8());
+    /// ```
+    #[inline]
+    fn is_utf8(&self) -> bool {
+        utf8::validate(self.as_bytes()).is_ok()
+    }
+
+    /// Returns the last byte in this byte string, if it's non-empty. If this
+    /// byte string is empty, this returns `None`.
+    ///
+    /// Note that this is like the generic `[u8]::last`, except this returns
+    /// the byte by value instead of a reference to the byte.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// assert_eq!(Some(b'z'), b"baz".last_byte());
+    /// assert_eq!(None, b"".last_byte());
+    /// ```
+    #[inline]
+    fn last_byte(&self) -> Option<u8> {
+        let bytes = self.as_bytes();
+        bytes.get(bytes.len().saturating_sub(1)).map(|&b| b)
+    }
+
+    /// Returns the index of the first non-ASCII byte in this byte string (if
+    /// any such indices exist). Specifically, it returns the index of the
+    /// first byte with a value greater than or equal to `0x80`.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{ByteSlice, B};
+    ///
+    /// assert_eq!(Some(3), b"abc\xff".find_non_ascii_byte());
+    /// assert_eq!(None, b"abcde".find_non_ascii_byte());
+    /// assert_eq!(Some(0), B("😀").find_non_ascii_byte());
+    /// ```
+    #[inline]
+    fn find_non_ascii_byte(&self) -> Option<usize> {
+        let index = ascii::first_non_ascii_byte(self.as_bytes());
+        if index == self.as_bytes().len() {
+            None
+        } else {
+            Some(index)
+        }
+    }
+}
+
+/// A single substring searcher fixed to a particular needle.
+///
+/// The purpose of this type is to permit callers to construct a substring
+/// searcher that can be used to search haystacks without the overhead of
+/// constructing the searcher in the first place. This is a somewhat niche
+/// concern when it's necessary to re-use the same needle to search multiple
+/// different haystacks with as little overhead as possible. In general, using
+/// [`ByteSlice::find`](trait.ByteSlice.html#method.find)
+/// or
+/// [`ByteSlice::find_iter`](trait.ByteSlice.html#method.find_iter)
+/// is good enough, but `Finder` is useful when you can meaningfully observe
+/// searcher construction time in a profile.
+///
+/// When the `std` feature is enabled, then this type has an `into_owned`
+/// version which permits building a `Finder` that is not connected to the
+/// lifetime of its needle.
+#[derive(Clone, Debug)]
+pub struct Finder<'a>(memmem::Finder<'a>);
+
+impl<'a> Finder<'a> {
+    /// Create a new finder for the given needle.
+    #[inline]
+    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> Finder<'a> {
+        Finder(memmem::Finder::new(needle.as_ref()))
+    }
+
+    /// Convert this finder into its owned variant, such that it no longer
+    /// borrows the needle.
+    ///
+    /// If this is already an owned finder, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `alloc` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> Finder<'static> {
+        Finder(self.0.into_owned())
+    }
+
+    /// Returns the needle that this finder searches for.
+    ///
+    /// Note that the lifetime of the needle returned is tied to the lifetime
+    /// of the finder, and may be shorter than the `'a` lifetime. Namely, a
+    /// finder's needle can be either borrowed or owned, so the lifetime of the
+    /// needle returned must necessarily be the shorter of the two.
+    #[inline]
+    pub fn needle(&self) -> &[u8] {
+        self.0.needle()
+    }
+
+    /// Returns the index of the first occurrence of this needle in the given
+    /// haystack.
+    ///
+    /// The haystack may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::Finder;
+    ///
+    /// let haystack = "foo bar baz";
+    /// assert_eq!(Some(0), Finder::new("foo").find(haystack));
+    /// assert_eq!(Some(4), Finder::new("bar").find(haystack));
+    /// assert_eq!(None, Finder::new("quux").find(haystack));
+    /// ```
+    #[inline]
+    pub fn find<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
+        self.0.find(haystack.as_ref())
+    }
+}
+
+/// A single substring reverse searcher fixed to a particular needle.
+///
+/// The purpose of this type is to permit callers to construct a substring
+/// searcher that can be used to search haystacks without the overhead of
+/// constructing the searcher in the first place. This is a somewhat niche
+/// concern when it's necessary to re-use the same needle to search multiple
+/// different haystacks with as little overhead as possible. In general, using
+/// [`ByteSlice::rfind`](trait.ByteSlice.html#method.rfind)
+/// or
+/// [`ByteSlice::rfind_iter`](trait.ByteSlice.html#method.rfind_iter)
+/// is good enough, but `FinderReverse` is useful when you can meaningfully
+/// observe searcher construction time in a profile.
+///
+/// When the `std` feature is enabled, then this type has an `into_owned`
+/// version which permits building a `FinderReverse` that is not connected to
+/// the lifetime of its needle.
+#[derive(Clone, Debug)]
+pub struct FinderReverse<'a>(memmem::FinderRev<'a>);
+
+impl<'a> FinderReverse<'a> {
+    /// Create a new reverse finder for the given needle.
+    #[inline]
+    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'a B) -> FinderReverse<'a> {
+        FinderReverse(memmem::FinderRev::new(needle.as_ref()))
+    }
+
+    /// Convert this finder into its owned variant, such that it no longer
+    /// borrows the needle.
+    ///
+    /// If this is already an owned finder, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `alloc` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> FinderReverse<'static> {
+        FinderReverse(self.0.into_owned())
+    }
+
+    /// Returns the needle that this finder searches for.
+    ///
+    /// Note that the lifetime of the needle returned is tied to the lifetime
+    /// of this finder, and may be shorter than the `'a` lifetime. Namely,
+    /// a finder's needle can be either borrowed or owned, so the lifetime of
+    /// the needle returned must necessarily be the shorter of the two.
+    #[inline]
+    pub fn needle(&self) -> &[u8] {
+        self.0.needle()
+    }
+
+    /// Returns the index of the last occurrence of this needle in the given
+    /// haystack.
+    ///
+    /// The haystack may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::FinderReverse;
+    ///
+    /// let haystack = "foo bar baz";
+    /// assert_eq!(Some(0), FinderReverse::new("foo").rfind(haystack));
+    /// assert_eq!(Some(4), FinderReverse::new("bar").rfind(haystack));
+    /// assert_eq!(None, FinderReverse::new("quux").rfind(haystack));
+    /// ```
+    #[inline]
+    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
+        self.0.rfind(haystack.as_ref())
+    }
+}
+
+/// An iterator over non-overlapping substring matches.
+///
+/// Matches are reported by the byte offset at which they begin.
+///
+/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
+/// needle.
+#[derive(Debug)]
+pub struct Find<'h, 'n> {
+    it: memmem::FindIter<'h, 'n>,
+    haystack: &'h [u8],
+    needle: &'n [u8],
+}
+
+impl<'h, 'n> Find<'h, 'n> {
+    fn new(haystack: &'h [u8], needle: &'n [u8]) -> Find<'h, 'n> {
+        Find { it: memmem::find_iter(haystack, needle), haystack, needle }
+    }
+}
+
+impl<'h, 'n> Iterator for Find<'h, 'n> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        self.it.next()
+    }
+}
+
+/// An iterator over non-overlapping substring matches in reverse.
+///
+/// Matches are reported by the byte offset at which they begin.
+///
+/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
+/// needle.
+#[derive(Debug)]
+pub struct FindReverse<'h, 'n> {
+    it: memmem::FindRevIter<'h, 'n>,
+    haystack: &'h [u8],
+    needle: &'n [u8],
+}
+
+impl<'h, 'n> FindReverse<'h, 'n> {
+    fn new(haystack: &'h [u8], needle: &'n [u8]) -> FindReverse<'h, 'n> {
+        FindReverse {
+            it: memmem::rfind_iter(haystack, needle),
+            haystack,
+            needle,
+        }
+    }
+
+    fn haystack(&self) -> &'h [u8] {
+        self.haystack
+    }
+
+    fn needle(&self) -> &'n [u8] {
+        self.needle
+    }
+}
+
+impl<'h, 'n> Iterator for FindReverse<'h, 'n> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        self.it.next()
+    }
+}
+
+/// An iterator over the bytes in a byte string.
+///
+/// `'a` is the lifetime of the byte string being traversed.
+#[derive(Clone, Debug)]
+pub struct Bytes<'a> {
+    it: slice::Iter<'a, u8>,
+}
+
+impl<'a> Bytes<'a> {
+    /// Views the remaining underlying data as a subslice of the original data.
+    /// This has the same lifetime as the original slice,
+    /// and so the iterator can continue to be used while this exists.
+    #[inline]
+    pub fn as_bytes(&self) -> &'a [u8] {
+        self.it.as_slice()
+    }
+}
+
+impl<'a> Iterator for Bytes<'a> {
+    type Item = u8;
+
+    #[inline]
+    fn next(&mut self) -> Option<u8> {
+        self.it.next().map(|&b| b)
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a> DoubleEndedIterator for Bytes<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<u8> {
+        self.it.next_back().map(|&b| b)
+    }
+}
+
+impl<'a> ExactSizeIterator for Bytes<'a> {
+    #[inline]
+    fn len(&self) -> usize {
+        self.it.len()
+    }
+}
+
+impl<'a> iter::FusedIterator for Bytes<'a> {}
+
+/// An iterator over the fields in a byte string, separated by whitespace.
+///
+/// Whitespace for this iterator is defined by the Unicode property
+/// `White_Space`.
+///
+/// This iterator splits on contiguous runs of whitespace, such that the fields
+/// in `foo\t\t\n  \nbar` are `foo` and `bar`.
+///
+/// `'a` is the lifetime of the byte string being split.
+#[cfg(feature = "unicode")]
+#[derive(Debug)]
+pub struct Fields<'a> {
+    it: FieldsWith<'a, fn(char) -> bool>,
+}
+
+#[cfg(feature = "unicode")]
+impl<'a> Fields<'a> {
+    fn new(bytes: &'a [u8]) -> Fields<'a> {
+        Fields { it: bytes.fields_with(|ch| ch.is_whitespace()) }
+    }
+}
+
+#[cfg(feature = "unicode")]
+impl<'a> Iterator for Fields<'a> {
+    type Item = &'a [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [u8]> {
+        self.it.next()
+    }
+}
+
+/// An iterator over fields in the byte string, separated by a predicate over
+/// codepoints.
+///
+/// This iterator splits a byte string based on its predicate function such
+/// that the elements returned are separated by contiguous runs of codepoints
+/// for which the predicate returns true.
+///
+/// `'a` is the lifetime of the byte string being split, while `F` is the type
+/// of the predicate, i.e., `FnMut(char) -> bool`.
+#[derive(Debug)]
+pub struct FieldsWith<'a, F> {
+    f: F,
+    bytes: &'a [u8],
+    chars: CharIndices<'a>,
+}
+
+impl<'a, F: FnMut(char) -> bool> FieldsWith<'a, F> {
+    fn new(bytes: &'a [u8], f: F) -> FieldsWith<'a, F> {
+        FieldsWith { f, bytes, chars: bytes.char_indices() }
+    }
+}
+
+impl<'a, F: FnMut(char) -> bool> Iterator for FieldsWith<'a, F> {
+    type Item = &'a [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [u8]> {
+        let (start, mut end);
+        loop {
+            match self.chars.next() {
+                None => return None,
+                Some((s, e, ch)) => {
+                    if !(self.f)(ch) {
+                        start = s;
+                        end = e;
+                        break;
+                    }
+                }
+            }
+        }
+        while let Some((_, e, ch)) = self.chars.next() {
+            if (self.f)(ch) {
+                break;
+            }
+            end = e;
+        }
+        Some(&self.bytes[start..end])
+    }
+}
+
+/// An iterator over substrings in a byte string, split by a separator.
+///
+/// `'h` is the lifetime of the byte string being split (the haystack), while
+/// `'s` is the lifetime of the byte string doing the splitting.
+#[derive(Debug)]
+pub struct Split<'h, 's> {
+    finder: Find<'h, 's>,
+    /// The end position of the previous match of our splitter. The element
+    /// we yield corresponds to the substring starting at `last` up to the
+    /// beginning of the next match of the splitter.
+    last: usize,
+    /// Only set when iteration is complete. A corner case here is when a
+    /// splitter is matched at the end of the haystack. At that point, we still
+    /// need to yield an empty string following it.
+    done: bool,
+}
+
+impl<'h, 's> Split<'h, 's> {
+    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> Split<'h, 's> {
+        let finder = haystack.find_iter(splitter);
+        Split { finder, last: 0, done: false }
+    }
+}
+
+impl<'h, 's> Iterator for Split<'h, 's> {
+    type Item = &'h [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'h [u8]> {
+        let haystack = self.finder.haystack;
+        match self.finder.next() {
+            Some(start) => {
+                let next = &haystack[self.last..start];
+                self.last = start + self.finder.needle.len();
+                Some(next)
+            }
+            None => {
+                if self.last >= haystack.len() {
+                    if !self.done {
+                        self.done = true;
+                        Some(b"")
+                    } else {
+                        None
+                    }
+                } else {
+                    let s = &haystack[self.last..];
+                    self.last = haystack.len();
+                    self.done = true;
+                    Some(s)
+                }
+            }
+        }
+    }
+}
+
+/// An iterator over substrings in a byte string, split by a separator, in
+/// reverse.
+///
+/// `'h` is the lifetime of the byte string being split (the haystack), while
+/// `'s` is the lifetime of the byte string doing the splitting.
+#[derive(Debug)]
+pub struct SplitReverse<'h, 's> {
+    finder: FindReverse<'h, 's>,
+    /// The end position of the previous match of our splitter. The element
+    /// we yield corresponds to the substring starting at `last` up to the
+    /// beginning of the next match of the splitter.
+    last: usize,
+    /// Only set when iteration is complete. A corner case here is when a
+    /// splitter is matched at the end of the haystack. At that point, we still
+    /// need to yield an empty string following it.
+    done: bool,
+}
+
+impl<'h, 's> SplitReverse<'h, 's> {
+    fn new(haystack: &'h [u8], splitter: &'s [u8]) -> SplitReverse<'h, 's> {
+        let finder = haystack.rfind_iter(splitter);
+        SplitReverse { finder, last: haystack.len(), done: false }
+    }
+}
+
+impl<'h, 's> Iterator for SplitReverse<'h, 's> {
+    type Item = &'h [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'h [u8]> {
+        let haystack = self.finder.haystack();
+        match self.finder.next() {
+            Some(start) => {
+                let nlen = self.finder.needle().len();
+                let next = &haystack[start + nlen..self.last];
+                self.last = start;
+                Some(next)
+            }
+            None => {
+                if self.last == 0 {
+                    if !self.done {
+                        self.done = true;
+                        Some(b"")
+                    } else {
+                        None
+                    }
+                } else {
+                    let s = &haystack[..self.last];
+                    self.last = 0;
+                    self.done = true;
+                    Some(s)
+                }
+            }
+        }
+    }
+}
+
+/// An iterator over at most `n` substrings in a byte string, split by a
+/// separator.
+///
+/// `'h` is the lifetime of the byte string being split (the haystack), while
+/// `'s` is the lifetime of the byte string doing the splitting.
+#[derive(Debug)]
+pub struct SplitN<'h, 's> {
+    split: Split<'h, 's>,
+    limit: usize,
+    count: usize,
+}
+
+impl<'h, 's> SplitN<'h, 's> {
+    fn new(
+        haystack: &'h [u8],
+        splitter: &'s [u8],
+        limit: usize,
+    ) -> SplitN<'h, 's> {
+        let split = haystack.split_str(splitter);
+        SplitN { split, limit, count: 0 }
+    }
+}
+
+impl<'h, 's> Iterator for SplitN<'h, 's> {
+    type Item = &'h [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'h [u8]> {
+        self.count += 1;
+        if self.count > self.limit || self.split.done {
+            None
+        } else if self.count == self.limit {
+            Some(&self.split.finder.haystack[self.split.last..])
+        } else {
+            self.split.next()
+        }
+    }
+}
+
+/// An iterator over at most `n` substrings in a byte string, split by a
+/// separator, in reverse.
+///
+/// `'h` is the lifetime of the byte string being split (the haystack), while
+/// `'s` is the lifetime of the byte string doing the splitting.
+#[derive(Debug)]
+pub struct SplitNReverse<'h, 's> {
+    split: SplitReverse<'h, 's>,
+    limit: usize,
+    count: usize,
+}
+
+impl<'h, 's> SplitNReverse<'h, 's> {
+    fn new(
+        haystack: &'h [u8],
+        splitter: &'s [u8],
+        limit: usize,
+    ) -> SplitNReverse<'h, 's> {
+        let split = haystack.rsplit_str(splitter);
+        SplitNReverse { split, limit, count: 0 }
+    }
+}
+
+impl<'h, 's> Iterator for SplitNReverse<'h, 's> {
+    type Item = &'h [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'h [u8]> {
+        self.count += 1;
+        if self.count > self.limit || self.split.done {
+            None
+        } else if self.count == self.limit {
+            Some(&self.split.finder.haystack()[..self.split.last])
+        } else {
+            self.split.next()
+        }
+    }
+}
+
+/// An iterator over all lines in a byte string, without their terminators.
+///
+/// For this iterator, the only line terminators recognized are `\r\n` and
+/// `\n`.
+///
+/// `'a` is the lifetime of the byte string being iterated over.
+#[derive(Clone, Debug)]
+pub struct Lines<'a> {
+    it: LinesWithTerminator<'a>,
+}
+
+impl<'a> Lines<'a> {
+    fn new(bytes: &'a [u8]) -> Lines<'a> {
+        Lines { it: LinesWithTerminator::new(bytes) }
+    }
+
+    /// Return a copy of the rest of the underlying bytes without affecting the
+    /// iterator itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"\
+    /// foo
+    /// bar\r
+    /// baz";
+    /// let mut lines = s.lines();
+    /// assert_eq!(lines.next(), Some(B("foo")));
+    /// assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
+    /// ```
+    pub fn as_bytes(&self) -> &'a [u8] {
+        self.it.bytes
+    }
+}
+
+impl<'a> Iterator for Lines<'a> {
+    type Item = &'a [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [u8]> {
+        Some(trim_last_terminator(self.it.next()?))
+    }
+}
+
+impl<'a> DoubleEndedIterator for Lines<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        Some(trim_last_terminator(self.it.next_back()?))
+    }
+}
+
+impl<'a> iter::FusedIterator for Lines<'a> {}
+
+/// An iterator over all lines in a byte string, including their terminators.
+///
+/// For this iterator, the only line terminator recognized is `\n`. (Since
+/// line terminators are included, this also handles `\r\n` line endings.)
+///
+/// Line terminators are only included if they are present in the original
+/// byte string. For example, the last line in a byte string may not end with
+/// a line terminator.
+///
+/// Concatenating all elements yielded by this iterator is guaranteed to yield
+/// the original byte string.
+///
+/// `'a` is the lifetime of the byte string being iterated over.
+#[derive(Clone, Debug)]
+pub struct LinesWithTerminator<'a> {
+    bytes: &'a [u8],
+}
+
+impl<'a> LinesWithTerminator<'a> {
+    fn new(bytes: &'a [u8]) -> LinesWithTerminator<'a> {
+        LinesWithTerminator { bytes }
+    }
+
+    /// Return a copy of the rest of the underlying bytes without affecting the
+    /// iterator itself.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use bstr::{B, ByteSlice};
+    ///
+    /// let s = b"\
+    /// foo
+    /// bar\r
+    /// baz";
+    /// let mut lines = s.lines_with_terminator();
+    /// assert_eq!(lines.next(), Some(B("foo\n")));
+    /// assert_eq!(lines.as_bytes(), B("bar\r\nbaz"));
+    /// ```
+    pub fn as_bytes(&self) -> &'a [u8] {
+        self.bytes
+    }
+}
+
+impl<'a> Iterator for LinesWithTerminator<'a> {
+    type Item = &'a [u8];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [u8]> {
+        match self.bytes.find_byte(b'\n') {
+            None if self.bytes.is_empty() => None,
+            None => {
+                let line = self.bytes;
+                self.bytes = b"";
+                Some(line)
+            }
+            Some(end) => {
+                let line = &self.bytes[..end + 1];
+                self.bytes = &self.bytes[end + 1..];
+                Some(line)
+            }
+        }
+    }
+}
+
+impl<'a> DoubleEndedIterator for LinesWithTerminator<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<Self::Item> {
+        let end = self.bytes.len().checked_sub(1)?;
+        match self.bytes[..end].rfind_byte(b'\n') {
+            None => {
+                let line = self.bytes;
+                self.bytes = b"";
+                Some(line)
+            }
+            Some(end) => {
+                let line = &self.bytes[end + 1..];
+                self.bytes = &self.bytes[..end + 1];
+                Some(line)
+            }
+        }
+    }
+}
+
+impl<'a> iter::FusedIterator for LinesWithTerminator<'a> {}
+
+fn trim_last_terminator(mut s: &[u8]) -> &[u8] {
+    if s.last_byte() == Some(b'\n') {
+        s = &s[..s.len() - 1];
+        if s.last_byte() == Some(b'\r') {
+            s = &s[..s.len() - 1];
+        }
+    }
+    s
+}
+
+#[cfg(all(test, feature = "std"))]
+mod tests {
+    use crate::{
+        ext_slice::{ByteSlice, Lines, LinesWithTerminator, B},
+        tests::LOSSY_TESTS,
+    };
+
+    #[test]
+    fn to_str_lossy() {
+        for (i, &(expected, input)) in LOSSY_TESTS.iter().enumerate() {
+            let got = B(input).to_str_lossy();
+            assert_eq!(
+                expected.as_bytes(),
+                got.as_bytes(),
+                "to_str_lossy(ith: {:?}, given: {:?})",
+                i,
+                input,
+            );
+
+            let mut got = String::new();
+            B(input).to_str_lossy_into(&mut got);
+            assert_eq!(
+                expected.as_bytes(),
+                got.as_bytes(),
+                "to_str_lossy_into",
+            );
+
+            let got = String::from_utf8_lossy(input);
+            assert_eq!(expected.as_bytes(), got.as_bytes(), "std");
+        }
+    }
+
+    #[test]
+    fn lines_iteration() {
+        macro_rules! t {
+            ($it:expr, $forward:expr) => {
+                let mut res: Vec<&[u8]> = Vec::from($forward);
+                assert_eq!($it.collect::<Vec<_>>(), res);
+                res.reverse();
+                assert_eq!($it.rev().collect::<Vec<_>>(), res);
+            };
+        }
+
+        t!(Lines::new(b""), []);
+        t!(LinesWithTerminator::new(b""), []);
+
+        t!(Lines::new(b"\n"), [B("")]);
+        t!(Lines::new(b"\r\n"), [B("")]);
+        t!(LinesWithTerminator::new(b"\n"), [B("\n")]);
+
+        t!(Lines::new(b"a"), [B("a")]);
+        t!(LinesWithTerminator::new(b"a"), [B("a")]);
+
+        t!(Lines::new(b"abc"), [B("abc")]);
+        t!(LinesWithTerminator::new(b"abc"), [B("abc")]);
+
+        t!(Lines::new(b"abc\n"), [B("abc")]);
+        t!(Lines::new(b"abc\r\n"), [B("abc")]);
+        t!(LinesWithTerminator::new(b"abc\n"), [B("abc\n")]);
+
+        t!(Lines::new(b"abc\n\n"), [B("abc"), B("")]);
+        t!(LinesWithTerminator::new(b"abc\n\n"), [B("abc\n"), B("\n")]);
+
+        t!(Lines::new(b"abc\n\ndef"), [B("abc"), B(""), B("def")]);
+        t!(
+            LinesWithTerminator::new(b"abc\n\ndef"),
+            [B("abc\n"), B("\n"), B("def")]
+        );
+
+        t!(Lines::new(b"abc\n\ndef\n"), [B("abc"), B(""), B("def")]);
+        t!(
+            LinesWithTerminator::new(b"abc\n\ndef\n"),
+            [B("abc\n"), B("\n"), B("def\n")]
+        );
+
+        t!(Lines::new(b"\na\nb\n"), [B(""), B("a"), B("b")]);
+        t!(
+            LinesWithTerminator::new(b"\na\nb\n"),
+            [B("\n"), B("a\n"), B("b\n")]
+        );
+
+        t!(Lines::new(b"\n\n\n"), [B(""), B(""), B("")]);
+        t!(LinesWithTerminator::new(b"\n\n\n"), [B("\n"), B("\n"), B("\n")]);
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/impls.rs.html b/src/bstr/impls.rs.html new file mode 100644 index 000000000..25ca31bcc --- /dev/null +++ b/src/bstr/impls.rs.html @@ -0,0 +1,2457 @@ +impls.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+
macro_rules! impl_partial_eq {
+    ($lhs:ty, $rhs:ty) => {
+        impl<'a, 'b> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool {
+                let other: &[u8] = other.as_ref();
+                PartialEq::eq(self.as_bytes(), other)
+            }
+        }
+
+        impl<'a, 'b> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool {
+                let this: &[u8] = self.as_ref();
+                PartialEq::eq(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+#[cfg(feature = "alloc")]
+macro_rules! impl_partial_eq_cow {
+    ($lhs:ty, $rhs:ty) => {
+        impl<'a, 'b> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool {
+                let other: &[u8] = (&**other).as_ref();
+                PartialEq::eq(self.as_bytes(), other)
+            }
+        }
+
+        impl<'a, 'b> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool {
+                let this: &[u8] = (&**other).as_ref();
+                PartialEq::eq(this, self.as_bytes())
+            }
+        }
+    };
+}
+
+macro_rules! impl_partial_ord {
+    ($lhs:ty, $rhs:ty) => {
+        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
+                let other: &[u8] = other.as_ref();
+                PartialOrd::partial_cmp(self.as_bytes(), other)
+            }
+        }
+
+        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
+                let this: &[u8] = self.as_ref();
+                PartialOrd::partial_cmp(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+#[cfg(feature = "alloc")]
+mod bstring {
+    use core::{
+        cmp::Ordering, convert::TryFrom, fmt, iter::FromIterator, ops,
+    };
+
+    use alloc::{
+        borrow::{Borrow, BorrowMut, Cow, ToOwned},
+        string::String,
+        vec,
+        vec::Vec,
+    };
+
+    use crate::{
+        bstr::BStr, bstring::BString, ext_slice::ByteSlice, ext_vec::ByteVec,
+    };
+
+    impl fmt::Display for BString {
+        #[inline]
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            fmt::Display::fmt(self.as_bstr(), f)
+        }
+    }
+
+    impl fmt::Debug for BString {
+        #[inline]
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            fmt::Debug::fmt(self.as_bstr(), f)
+        }
+    }
+
+    impl ops::Deref for BString {
+        type Target = Vec<u8>;
+
+        #[inline]
+        fn deref(&self) -> &Vec<u8> {
+            self.as_vec()
+        }
+    }
+
+    impl ops::DerefMut for BString {
+        #[inline]
+        fn deref_mut(&mut self) -> &mut Vec<u8> {
+            self.as_vec_mut()
+        }
+    }
+
+    impl AsRef<[u8]> for BString {
+        #[inline]
+        fn as_ref(&self) -> &[u8] {
+            self.as_bytes()
+        }
+    }
+
+    impl AsRef<BStr> for BString {
+        #[inline]
+        fn as_ref(&self) -> &BStr {
+            self.as_bstr()
+        }
+    }
+
+    impl AsMut<[u8]> for BString {
+        #[inline]
+        fn as_mut(&mut self) -> &mut [u8] {
+            self.as_bytes_mut()
+        }
+    }
+
+    impl AsMut<BStr> for BString {
+        #[inline]
+        fn as_mut(&mut self) -> &mut BStr {
+            self.as_mut_bstr()
+        }
+    }
+
+    impl Borrow<[u8]> for BString {
+        #[inline]
+        fn borrow(&self) -> &[u8] {
+            self.as_bytes()
+        }
+    }
+
+    impl Borrow<BStr> for BString {
+        #[inline]
+        fn borrow(&self) -> &BStr {
+            self.as_bstr()
+        }
+    }
+
+    impl Borrow<BStr> for Vec<u8> {
+        #[inline]
+        fn borrow(&self) -> &BStr {
+            self.as_slice().as_bstr()
+        }
+    }
+
+    impl Borrow<BStr> for String {
+        #[inline]
+        fn borrow(&self) -> &BStr {
+            self.as_bytes().as_bstr()
+        }
+    }
+
+    impl BorrowMut<[u8]> for BString {
+        #[inline]
+        fn borrow_mut(&mut self) -> &mut [u8] {
+            self.as_bytes_mut()
+        }
+    }
+
+    impl BorrowMut<BStr> for BString {
+        #[inline]
+        fn borrow_mut(&mut self) -> &mut BStr {
+            self.as_mut_bstr()
+        }
+    }
+
+    impl BorrowMut<BStr> for Vec<u8> {
+        #[inline]
+        fn borrow_mut(&mut self) -> &mut BStr {
+            BStr::new_mut(self.as_mut_slice())
+        }
+    }
+
+    impl ToOwned for BStr {
+        type Owned = BString;
+
+        #[inline]
+        fn to_owned(&self) -> BString {
+            BString::from(self)
+        }
+    }
+
+    impl Default for BString {
+        fn default() -> BString {
+            BString::from(vec![])
+        }
+    }
+
+    impl<'a, const N: usize> From<&'a [u8; N]> for BString {
+        #[inline]
+        fn from(s: &'a [u8; N]) -> BString {
+            BString::from(&s[..])
+        }
+    }
+
+    impl<const N: usize> From<[u8; N]> for BString {
+        #[inline]
+        fn from(s: [u8; N]) -> BString {
+            BString::from(&s[..])
+        }
+    }
+
+    impl<'a> From<&'a [u8]> for BString {
+        #[inline]
+        fn from(s: &'a [u8]) -> BString {
+            BString::from(s.to_vec())
+        }
+    }
+
+    impl From<Vec<u8>> for BString {
+        #[inline]
+        fn from(s: Vec<u8>) -> BString {
+            BString::new(s)
+        }
+    }
+
+    impl From<BString> for Vec<u8> {
+        #[inline]
+        fn from(s: BString) -> Vec<u8> {
+            s.into_vec()
+        }
+    }
+
+    impl<'a> From<&'a str> for BString {
+        #[inline]
+        fn from(s: &'a str) -> BString {
+            BString::from(s.as_bytes().to_vec())
+        }
+    }
+
+    impl From<String> for BString {
+        #[inline]
+        fn from(s: String) -> BString {
+            BString::from(s.into_bytes())
+        }
+    }
+
+    impl<'a> From<&'a BStr> for BString {
+        #[inline]
+        fn from(s: &'a BStr) -> BString {
+            BString::from(s.bytes.to_vec())
+        }
+    }
+
+    impl<'a> From<BString> for Cow<'a, BStr> {
+        #[inline]
+        fn from(s: BString) -> Cow<'a, BStr> {
+            Cow::Owned(s)
+        }
+    }
+
+    impl TryFrom<BString> for String {
+        type Error = crate::FromUtf8Error;
+
+        #[inline]
+        fn try_from(s: BString) -> Result<String, crate::FromUtf8Error> {
+            s.into_vec().into_string()
+        }
+    }
+
+    impl<'a> TryFrom<&'a BString> for &'a str {
+        type Error = crate::Utf8Error;
+
+        #[inline]
+        fn try_from(s: &'a BString) -> Result<&'a str, crate::Utf8Error> {
+            s.as_bytes().to_str()
+        }
+    }
+
+    impl FromIterator<char> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> BString {
+            BString::from(iter.into_iter().collect::<String>())
+        }
+    }
+
+    impl FromIterator<u8> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> BString {
+            BString::from(iter.into_iter().collect::<Vec<u8>>())
+        }
+    }
+
+    impl<'a> FromIterator<&'a str> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> BString {
+            let mut buf = vec![];
+            for b in iter {
+                buf.push_str(b);
+            }
+            BString::from(buf)
+        }
+    }
+
+    impl<'a> FromIterator<&'a [u8]> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> BString {
+            let mut buf = vec![];
+            for b in iter {
+                buf.push_str(b);
+            }
+            BString::from(buf)
+        }
+    }
+
+    impl<'a> FromIterator<&'a BStr> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = &'a BStr>>(iter: T) -> BString {
+            let mut buf = vec![];
+            for b in iter {
+                buf.push_str(b);
+            }
+            BString::from(buf)
+        }
+    }
+
+    impl FromIterator<BString> for BString {
+        #[inline]
+        fn from_iter<T: IntoIterator<Item = BString>>(iter: T) -> BString {
+            let mut buf = vec![];
+            for b in iter {
+                buf.push_str(b);
+            }
+            BString::from(buf)
+        }
+    }
+
+    impl Eq for BString {}
+
+    impl PartialEq for BString {
+        #[inline]
+        fn eq(&self, other: &BString) -> bool {
+            &self[..] == &other[..]
+        }
+    }
+
+    impl_partial_eq!(BString, Vec<u8>);
+    impl_partial_eq!(BString, [u8]);
+    impl_partial_eq!(BString, &'a [u8]);
+    impl_partial_eq!(BString, String);
+    impl_partial_eq!(BString, str);
+    impl_partial_eq!(BString, &'a str);
+    impl_partial_eq!(BString, BStr);
+    impl_partial_eq!(BString, &'a BStr);
+
+    impl PartialOrd for BString {
+        #[inline]
+        fn partial_cmp(&self, other: &BString) -> Option<Ordering> {
+            PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
+        }
+    }
+
+    impl Ord for BString {
+        #[inline]
+        fn cmp(&self, other: &BString) -> Ordering {
+            self.partial_cmp(other).unwrap()
+        }
+    }
+
+    impl_partial_ord!(BString, Vec<u8>);
+    impl_partial_ord!(BString, [u8]);
+    impl_partial_ord!(BString, &'a [u8]);
+    impl_partial_ord!(BString, String);
+    impl_partial_ord!(BString, str);
+    impl_partial_ord!(BString, &'a str);
+    impl_partial_ord!(BString, BStr);
+    impl_partial_ord!(BString, &'a BStr);
+}
+
+mod bstr {
+    use core::{
+        borrow::{Borrow, BorrowMut},
+        cmp::Ordering,
+        convert::TryFrom,
+        fmt, ops,
+    };
+
+    #[cfg(feature = "alloc")]
+    use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
+
+    use crate::{bstr::BStr, ext_slice::ByteSlice};
+
+    impl fmt::Display for BStr {
+        #[inline]
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            /// Write the given bstr (lossily) to the given formatter.
+            fn write_bstr(
+                f: &mut fmt::Formatter<'_>,
+                bstr: &BStr,
+            ) -> Result<(), fmt::Error> {
+                for chunk in bstr.utf8_chunks() {
+                    f.write_str(chunk.valid())?;
+                    if !chunk.invalid().is_empty() {
+                        f.write_str("\u{FFFD}")?;
+                    }
+                }
+                Ok(())
+            }
+
+            /// Write 'num' fill characters to the given formatter.
+            fn write_pads(
+                f: &mut fmt::Formatter<'_>,
+                num: usize,
+            ) -> fmt::Result {
+                let fill = f.fill();
+                for _ in 0..num {
+                    f.write_fmt(format_args!("{}", fill))?;
+                }
+                Ok(())
+            }
+
+            if let Some(align) = f.align() {
+                let width = f.width().unwrap_or(0);
+                let nchars = self.chars().count();
+                let remaining_pads = width.saturating_sub(nchars);
+                match align {
+                    fmt::Alignment::Left => {
+                        write_bstr(f, self)?;
+                        write_pads(f, remaining_pads)?;
+                    }
+                    fmt::Alignment::Right => {
+                        write_pads(f, remaining_pads)?;
+                        write_bstr(f, self)?;
+                    }
+                    fmt::Alignment::Center => {
+                        let half = remaining_pads / 2;
+                        let second_half = if remaining_pads % 2 == 0 {
+                            half
+                        } else {
+                            half + 1
+                        };
+                        write_pads(f, half)?;
+                        write_bstr(f, self)?;
+                        write_pads(f, second_half)?;
+                    }
+                }
+                Ok(())
+            } else {
+                write_bstr(f, self)?;
+                Ok(())
+            }
+        }
+    }
+
+    impl fmt::Debug for BStr {
+        #[inline]
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            write!(f, "\"")?;
+            for (s, e, ch) in self.char_indices() {
+                match ch {
+                    '\0' => write!(f, "\\0")?,
+                    '\u{FFFD}' => {
+                        let bytes = self[s..e].as_bytes();
+                        if bytes == b"\xEF\xBF\xBD" {
+                            write!(f, "{}", ch.escape_debug())?;
+                        } else {
+                            for &b in self[s..e].as_bytes() {
+                                write!(f, r"\x{:02X}", b)?;
+                            }
+                        }
+                    }
+                    // ASCII control characters except \0, \n, \r, \t
+                    '\x01'..='\x08'
+                    | '\x0b'
+                    | '\x0c'
+                    | '\x0e'..='\x19'
+                    | '\x7f' => {
+                        write!(f, "\\x{:02x}", ch as u32)?;
+                    }
+                    '\n' | '\r' | '\t' | _ => {
+                        write!(f, "{}", ch.escape_debug())?;
+                    }
+                }
+            }
+            write!(f, "\"")?;
+            Ok(())
+        }
+    }
+
+    impl ops::Deref for BStr {
+        type Target = [u8];
+
+        #[inline]
+        fn deref(&self) -> &[u8] {
+            &self.bytes
+        }
+    }
+
+    impl ops::DerefMut for BStr {
+        #[inline]
+        fn deref_mut(&mut self) -> &mut [u8] {
+            &mut self.bytes
+        }
+    }
+
+    impl ops::Index<usize> for BStr {
+        type Output = u8;
+
+        #[inline]
+        fn index(&self, idx: usize) -> &u8 {
+            &self.as_bytes()[idx]
+        }
+    }
+
+    impl ops::Index<ops::RangeFull> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, _: ops::RangeFull) -> &BStr {
+            self
+        }
+    }
+
+    impl ops::Index<ops::Range<usize>> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, r: ops::Range<usize>) -> &BStr {
+            BStr::new(&self.as_bytes()[r.start..r.end])
+        }
+    }
+
+    impl ops::Index<ops::RangeInclusive<usize>> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr {
+            BStr::new(&self.as_bytes()[*r.start()..=*r.end()])
+        }
+    }
+
+    impl ops::Index<ops::RangeFrom<usize>> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, r: ops::RangeFrom<usize>) -> &BStr {
+            BStr::new(&self.as_bytes()[r.start..])
+        }
+    }
+
+    impl ops::Index<ops::RangeTo<usize>> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, r: ops::RangeTo<usize>) -> &BStr {
+            BStr::new(&self.as_bytes()[..r.end])
+        }
+    }
+
+    impl ops::Index<ops::RangeToInclusive<usize>> for BStr {
+        type Output = BStr;
+
+        #[inline]
+        fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr {
+            BStr::new(&self.as_bytes()[..=r.end])
+        }
+    }
+
+    impl ops::IndexMut<usize> for BStr {
+        #[inline]
+        fn index_mut(&mut self, idx: usize) -> &mut u8 {
+            &mut self.bytes[idx]
+        }
+    }
+
+    impl ops::IndexMut<ops::RangeFull> for BStr {
+        #[inline]
+        fn index_mut(&mut self, _: ops::RangeFull) -> &mut BStr {
+            self
+        }
+    }
+
+    impl ops::IndexMut<ops::Range<usize>> for BStr {
+        #[inline]
+        fn index_mut(&mut self, r: ops::Range<usize>) -> &mut BStr {
+            BStr::from_bytes_mut(&mut self.bytes[r.start..r.end])
+        }
+    }
+
+    impl ops::IndexMut<ops::RangeInclusive<usize>> for BStr {
+        #[inline]
+        fn index_mut(&mut self, r: ops::RangeInclusive<usize>) -> &mut BStr {
+            BStr::from_bytes_mut(&mut self.bytes[*r.start()..=*r.end()])
+        }
+    }
+
+    impl ops::IndexMut<ops::RangeFrom<usize>> for BStr {
+        #[inline]
+        fn index_mut(&mut self, r: ops::RangeFrom<usize>) -> &mut BStr {
+            BStr::from_bytes_mut(&mut self.bytes[r.start..])
+        }
+    }
+
+    impl ops::IndexMut<ops::RangeTo<usize>> for BStr {
+        #[inline]
+        fn index_mut(&mut self, r: ops::RangeTo<usize>) -> &mut BStr {
+            BStr::from_bytes_mut(&mut self.bytes[..r.end])
+        }
+    }
+
+    impl ops::IndexMut<ops::RangeToInclusive<usize>> for BStr {
+        #[inline]
+        fn index_mut(&mut self, r: ops::RangeToInclusive<usize>) -> &mut BStr {
+            BStr::from_bytes_mut(&mut self.bytes[..=r.end])
+        }
+    }
+
+    impl AsRef<[u8]> for BStr {
+        #[inline]
+        fn as_ref(&self) -> &[u8] {
+            self.as_bytes()
+        }
+    }
+
+    impl AsRef<BStr> for BStr {
+        #[inline]
+        fn as_ref(&self) -> &BStr {
+            self
+        }
+    }
+
+    impl AsRef<BStr> for [u8] {
+        #[inline]
+        fn as_ref(&self) -> &BStr {
+            BStr::new(self)
+        }
+    }
+
+    impl AsRef<BStr> for str {
+        #[inline]
+        fn as_ref(&self) -> &BStr {
+            BStr::new(self)
+        }
+    }
+
+    impl AsMut<[u8]> for BStr {
+        #[inline]
+        fn as_mut(&mut self) -> &mut [u8] {
+            &mut self.bytes
+        }
+    }
+
+    impl AsMut<BStr> for [u8] {
+        #[inline]
+        fn as_mut(&mut self) -> &mut BStr {
+            BStr::new_mut(self)
+        }
+    }
+
+    impl Borrow<BStr> for [u8] {
+        #[inline]
+        fn borrow(&self) -> &BStr {
+            self.as_bstr()
+        }
+    }
+
+    impl Borrow<BStr> for str {
+        #[inline]
+        fn borrow(&self) -> &BStr {
+            self.as_bytes().as_bstr()
+        }
+    }
+
+    impl Borrow<[u8]> for BStr {
+        #[inline]
+        fn borrow(&self) -> &[u8] {
+            self.as_bytes()
+        }
+    }
+
+    impl BorrowMut<BStr> for [u8] {
+        #[inline]
+        fn borrow_mut(&mut self) -> &mut BStr {
+            BStr::new_mut(self)
+        }
+    }
+
+    impl BorrowMut<[u8]> for BStr {
+        #[inline]
+        fn borrow_mut(&mut self) -> &mut [u8] {
+            self.as_bytes_mut()
+        }
+    }
+
+    impl<'a> Default for &'a BStr {
+        fn default() -> &'a BStr {
+            BStr::from_bytes(b"")
+        }
+    }
+
+    impl<'a> Default for &'a mut BStr {
+        fn default() -> &'a mut BStr {
+            BStr::from_bytes_mut(&mut [])
+        }
+    }
+
+    impl<'a, const N: usize> From<&'a [u8; N]> for &'a BStr {
+        #[inline]
+        fn from(s: &'a [u8; N]) -> &'a BStr {
+            BStr::from_bytes(s)
+        }
+    }
+
+    impl<'a> From<&'a [u8]> for &'a BStr {
+        #[inline]
+        fn from(s: &'a [u8]) -> &'a BStr {
+            BStr::from_bytes(s)
+        }
+    }
+
+    impl<'a> From<&'a BStr> for &'a [u8] {
+        #[inline]
+        fn from(s: &'a BStr) -> &'a [u8] {
+            BStr::as_bytes(s)
+        }
+    }
+
+    impl<'a> From<&'a str> for &'a BStr {
+        #[inline]
+        fn from(s: &'a str) -> &'a BStr {
+            BStr::from_bytes(s.as_bytes())
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    impl<'a> From<&'a BStr> for Cow<'a, BStr> {
+        #[inline]
+        fn from(s: &'a BStr) -> Cow<'a, BStr> {
+            Cow::Borrowed(s)
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    impl From<Box<[u8]>> for Box<BStr> {
+        #[inline]
+        fn from(s: Box<[u8]>) -> Box<BStr> {
+            BStr::from_boxed_bytes(s)
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    impl From<Box<BStr>> for Box<[u8]> {
+        #[inline]
+        fn from(s: Box<BStr>) -> Box<[u8]> {
+            BStr::into_boxed_bytes(s)
+        }
+    }
+
+    impl<'a> TryFrom<&'a BStr> for &'a str {
+        type Error = crate::Utf8Error;
+
+        #[inline]
+        fn try_from(s: &'a BStr) -> Result<&'a str, crate::Utf8Error> {
+            s.as_bytes().to_str()
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    impl<'a> TryFrom<&'a BStr> for String {
+        type Error = crate::Utf8Error;
+
+        #[inline]
+        fn try_from(s: &'a BStr) -> Result<String, crate::Utf8Error> {
+            Ok(s.as_bytes().to_str()?.into())
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    impl Clone for Box<BStr> {
+        #[inline]
+        fn clone(&self) -> Self {
+            BStr::from_boxed_bytes(self.as_bytes().into())
+        }
+    }
+
+    impl Eq for BStr {}
+
+    impl PartialEq<BStr> for BStr {
+        #[inline]
+        fn eq(&self, other: &BStr) -> bool {
+            self.as_bytes() == other.as_bytes()
+        }
+    }
+
+    impl_partial_eq!(BStr, [u8]);
+    impl_partial_eq!(BStr, &'a [u8]);
+    impl_partial_eq!(BStr, str);
+    impl_partial_eq!(BStr, &'a str);
+
+    #[cfg(feature = "alloc")]
+    impl_partial_eq!(BStr, Vec<u8>);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq!(&'a BStr, Vec<u8>);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq!(BStr, String);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq!(&'a BStr, String);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq_cow!(&'a BStr, Cow<'a, BStr>);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq_cow!(&'a BStr, Cow<'a, str>);
+    #[cfg(feature = "alloc")]
+    impl_partial_eq_cow!(&'a BStr, Cow<'a, [u8]>);
+
+    impl PartialOrd for BStr {
+        #[inline]
+        fn partial_cmp(&self, other: &BStr) -> Option<Ordering> {
+            PartialOrd::partial_cmp(self.as_bytes(), other.as_bytes())
+        }
+    }
+
+    impl Ord for BStr {
+        #[inline]
+        fn cmp(&self, other: &BStr) -> Ordering {
+            self.partial_cmp(other).unwrap()
+        }
+    }
+
+    impl_partial_ord!(BStr, [u8]);
+    impl_partial_ord!(BStr, &'a [u8]);
+    impl_partial_ord!(BStr, str);
+    impl_partial_ord!(BStr, &'a str);
+
+    #[cfg(feature = "alloc")]
+    impl_partial_ord!(BStr, Vec<u8>);
+    #[cfg(feature = "alloc")]
+    impl_partial_ord!(&'a BStr, Vec<u8>);
+    #[cfg(feature = "alloc")]
+    impl_partial_ord!(BStr, String);
+    #[cfg(feature = "alloc")]
+    impl_partial_ord!(&'a BStr, String);
+}
+
+#[cfg(feature = "serde")]
+mod bstr_serde {
+    use core::fmt;
+
+    use serde::{
+        de::Error, de::Visitor, Deserialize, Deserializer, Serialize,
+        Serializer,
+    };
+
+    use crate::bstr::BStr;
+
+    impl Serialize for BStr {
+        #[inline]
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            serializer.serialize_bytes(self.as_bytes())
+        }
+    }
+
+    impl<'a, 'de: 'a> Deserialize<'de> for &'a BStr {
+        #[inline]
+        fn deserialize<D>(deserializer: D) -> Result<&'a BStr, D::Error>
+        where
+            D: Deserializer<'de>,
+        {
+            struct BStrVisitor;
+
+            impl<'de> Visitor<'de> for BStrVisitor {
+                type Value = &'de BStr;
+
+                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str("a borrowed byte string")
+                }
+
+                #[inline]
+                fn visit_borrowed_bytes<E: Error>(
+                    self,
+                    value: &'de [u8],
+                ) -> Result<&'de BStr, E> {
+                    Ok(BStr::new(value))
+                }
+
+                #[inline]
+                fn visit_borrowed_str<E: Error>(
+                    self,
+                    value: &'de str,
+                ) -> Result<&'de BStr, E> {
+                    Ok(BStr::new(value))
+                }
+            }
+
+            deserializer.deserialize_bytes(BStrVisitor)
+        }
+    }
+}
+
+#[cfg(all(feature = "serde", feature = "alloc"))]
+mod bstring_serde {
+    use core::{cmp, fmt};
+
+    use alloc::{boxed::Box, string::String, vec::Vec};
+
+    use serde::{
+        de::Error, de::SeqAccess, de::Visitor, Deserialize, Deserializer,
+        Serialize, Serializer,
+    };
+
+    use crate::{bstr::BStr, bstring::BString};
+
+    impl Serialize for BString {
+        #[inline]
+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+        where
+            S: Serializer,
+        {
+            serializer.serialize_bytes(self.as_bytes())
+        }
+    }
+
+    impl<'de> Deserialize<'de> for BString {
+        #[inline]
+        fn deserialize<D>(deserializer: D) -> Result<BString, D::Error>
+        where
+            D: Deserializer<'de>,
+        {
+            struct BStringVisitor;
+
+            impl<'de> Visitor<'de> for BStringVisitor {
+                type Value = BString;
+
+                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str("a byte string")
+                }
+
+                #[inline]
+                fn visit_seq<V: SeqAccess<'de>>(
+                    self,
+                    mut visitor: V,
+                ) -> Result<BString, V::Error> {
+                    let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
+                    let mut bytes = Vec::with_capacity(len);
+                    while let Some(v) = visitor.next_element()? {
+                        bytes.push(v);
+                    }
+                    Ok(BString::from(bytes))
+                }
+
+                #[inline]
+                fn visit_bytes<E: Error>(
+                    self,
+                    value: &[u8],
+                ) -> Result<BString, E> {
+                    Ok(BString::from(value))
+                }
+
+                #[inline]
+                fn visit_byte_buf<E: Error>(
+                    self,
+                    value: Vec<u8>,
+                ) -> Result<BString, E> {
+                    Ok(BString::from(value))
+                }
+
+                #[inline]
+                fn visit_str<E: Error>(
+                    self,
+                    value: &str,
+                ) -> Result<BString, E> {
+                    Ok(BString::from(value))
+                }
+
+                #[inline]
+                fn visit_string<E: Error>(
+                    self,
+                    value: String,
+                ) -> Result<BString, E> {
+                    Ok(BString::from(value))
+                }
+            }
+
+            deserializer.deserialize_byte_buf(BStringVisitor)
+        }
+    }
+
+    impl<'de> Deserialize<'de> for Box<BStr> {
+        #[inline]
+        fn deserialize<D>(deserializer: D) -> Result<Box<BStr>, D::Error>
+        where
+            D: Deserializer<'de>,
+        {
+            struct BoxedBStrVisitor;
+
+            impl<'de> Visitor<'de> for BoxedBStrVisitor {
+                type Value = Box<BStr>;
+
+                fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    f.write_str("a boxed byte string")
+                }
+
+                #[inline]
+                fn visit_seq<V: SeqAccess<'de>>(
+                    self,
+                    mut visitor: V,
+                ) -> Result<Box<BStr>, V::Error> {
+                    let len = cmp::min(visitor.size_hint().unwrap_or(0), 256);
+                    let mut bytes = Vec::with_capacity(len);
+                    while let Some(v) = visitor.next_element()? {
+                        bytes.push(v);
+                    }
+                    Ok(BStr::from_boxed_bytes(bytes.into_boxed_slice()))
+                }
+
+                #[inline]
+                fn visit_bytes<E: Error>(
+                    self,
+                    value: &[u8],
+                ) -> Result<Box<BStr>, E> {
+                    Ok(BStr::from_boxed_bytes(
+                        value.to_vec().into_boxed_slice(),
+                    ))
+                }
+
+                #[inline]
+                fn visit_byte_buf<E: Error>(
+                    self,
+                    value: Vec<u8>,
+                ) -> Result<Box<BStr>, E> {
+                    Ok(BStr::from_boxed_bytes(value.into_boxed_slice()))
+                }
+
+                #[inline]
+                fn visit_str<E: Error>(
+                    self,
+                    value: &str,
+                ) -> Result<Box<BStr>, E> {
+                    Ok(BStr::from_boxed_bytes(
+                        value.as_bytes().to_vec().into_boxed_slice(),
+                    ))
+                }
+
+                #[inline]
+                fn visit_string<E: Error>(
+                    self,
+                    value: String,
+                ) -> Result<Box<BStr>, E> {
+                    Ok(BStr::from_boxed_bytes(
+                        value.into_bytes().into_boxed_slice(),
+                    ))
+                }
+            }
+
+            deserializer.deserialize_byte_buf(BoxedBStrVisitor)
+        }
+    }
+}
+
+#[cfg(all(test, feature = "std"))]
+mod display {
+    #[cfg(not(miri))]
+    use crate::bstring::BString;
+    use crate::ByteSlice;
+
+    #[test]
+    fn clean() {
+        assert_eq!(&format!("{}", &b"abc".as_bstr()), "abc");
+        assert_eq!(&format!("{}", &b"\xf0\x28\x8c\xbc".as_bstr()), "�(��");
+    }
+
+    #[test]
+    fn width_bigger_than_bstr() {
+        assert_eq!(&format!("{:<7}!", &b"abc".as_bstr()), "abc    !");
+        assert_eq!(&format!("{:>7}!", &b"abc".as_bstr()), "    abc!");
+        assert_eq!(&format!("{:^7}!", &b"abc".as_bstr()), "  abc  !");
+        assert_eq!(&format!("{:^6}!", &b"abc".as_bstr()), " abc  !");
+        assert_eq!(&format!("{:-<7}!", &b"abc".as_bstr()), "abc----!");
+        assert_eq!(&format!("{:->7}!", &b"abc".as_bstr()), "----abc!");
+        assert_eq!(&format!("{:-^7}!", &b"abc".as_bstr()), "--abc--!");
+        assert_eq!(&format!("{:-^6}!", &b"abc".as_bstr()), "-abc--!");
+
+        assert_eq!(
+            &format!("{:<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��   !"
+        );
+        assert_eq!(
+            &format!("{:>7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "   �(��!"
+        );
+        assert_eq!(
+            &format!("{:^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            " �(��  !"
+        );
+        assert_eq!(
+            &format!("{:^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            " �(�� !"
+        );
+
+        assert_eq!(
+            &format!("{:-<7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��---!"
+        );
+        assert_eq!(
+            &format!("{:->7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "---�(��!"
+        );
+        assert_eq!(
+            &format!("{:-^7}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "-�(��--!"
+        );
+        assert_eq!(
+            &format!("{:-^6}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "-�(��-!"
+        );
+    }
+
+    #[test]
+    fn width_lesser_than_bstr() {
+        assert_eq!(&format!("{:<2}!", &b"abc".as_bstr()), "abc!");
+        assert_eq!(&format!("{:>2}!", &b"abc".as_bstr()), "abc!");
+        assert_eq!(&format!("{:^2}!", &b"abc".as_bstr()), "abc!");
+        assert_eq!(&format!("{:-<2}!", &b"abc".as_bstr()), "abc!");
+        assert_eq!(&format!("{:->2}!", &b"abc".as_bstr()), "abc!");
+        assert_eq!(&format!("{:-^2}!", &b"abc".as_bstr()), "abc!");
+
+        assert_eq!(
+            &format!("{:<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:>3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+
+        assert_eq!(
+            &format!("{:-<3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:->3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:-^3}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+        assert_eq!(
+            &format!("{:-^2}!", &b"\xf0\x28\x8c\xbc".as_bstr()),
+            "�(��!"
+        );
+    }
+
+    #[cfg(not(miri))]
+    quickcheck::quickcheck! {
+        fn total_length(bstr: BString) -> bool {
+            let size = bstr.chars().count();
+            format!("{:<1$}", bstr.as_bstr(), size).chars().count() >= size
+        }
+    }
+}
+
+#[cfg(all(test, feature = "alloc"))]
+mod bstring_arbitrary {
+    use crate::bstring::BString;
+
+    use quickcheck::{Arbitrary, Gen};
+
+    impl Arbitrary for BString {
+        fn arbitrary(g: &mut Gen) -> BString {
+            BString::from(Vec::<u8>::arbitrary(g))
+        }
+
+        fn shrink(&self) -> Box<dyn Iterator<Item = BString>> {
+            Box::new(self.as_vec().shrink().map(BString::from))
+        }
+    }
+}
+
+#[test]
+#[cfg(feature = "std")]
+fn test_debug() {
+    use crate::{ByteSlice, B};
+
+    assert_eq!(
+        r#""\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp""#,
+        format!("{:?}", b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp".as_bstr()),
+    );
+
+    // Tests that if the underlying bytes contain the UTF-8 encoding of the
+    // replacement codepoint, then we emit the codepoint just like other
+    // non-printable Unicode characters.
+    assert_eq!(
+        b"\"\\xFF\xEF\xBF\xBD\\xFF\"".as_bstr(),
+        // Before fixing #72, the output here would be:
+        //   \\xFF\\xEF\\xBF\\xBD\\xFF
+        B(&format!("{:?}", b"\xFF\xEF\xBF\xBD\xFF".as_bstr())).as_bstr(),
+    );
+}
+
+// See: https://github.com/BurntSushi/bstr/issues/82
+#[test]
+#[cfg(feature = "std")]
+fn test_cows_regression() {
+    use std::borrow::Cow;
+
+    use crate::ByteSlice;
+
+    let c1 = Cow::from(b"hello bstr".as_bstr());
+    let c2 = b"goodbye bstr".as_bstr();
+    assert_ne!(c1, c2);
+
+    let c3 = Cow::from("hello str");
+    let c4 = "goodbye str";
+    assert_ne!(c3, c4);
+}
+
\ No newline at end of file diff --git a/src/bstr/lib.rs.html b/src/bstr/lib.rs.html new file mode 100644 index 000000000..d141c4d48 --- /dev/null +++ b/src/bstr/lib.rs.html @@ -0,0 +1,941 @@ +lib.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+
/*!
+A byte string library.
+
+Byte strings are just like standard Unicode strings with one very important
+difference: byte strings are only *conventionally* UTF-8 while Rust's standard
+Unicode strings are *guaranteed* to be valid UTF-8. The primary motivation for
+byte strings is for handling arbitrary bytes that are mostly UTF-8.
+
+# Overview
+
+This crate provides two important traits that provide string oriented methods
+on `&[u8]` and `Vec<u8>` types:
+
+* [`ByteSlice`](trait.ByteSlice.html) extends the `[u8]` type with additional
+  string oriented methods.
+* [`ByteVec`](trait.ByteVec.html) extends the `Vec<u8>` type with additional
+  string oriented methods.
+
+Additionally, this crate provides two concrete byte string types that deref to
+`[u8]` and `Vec<u8>`. These are useful for storing byte string types, and come
+with convenient `std::fmt::Debug` implementations:
+
+* [`BStr`](struct.BStr.html) is a byte string slice, analogous to `str`.
+* [`BString`](struct.BString.html) is an owned growable byte string buffer,
+  analogous to `String`.
+
+Additionally, the free function [`B`](fn.B.html) serves as a convenient short
+hand for writing byte string literals.
+
+# Quick examples
+
+Byte strings build on the existing APIs for `Vec<u8>` and `&[u8]`, with
+additional string oriented methods. Operations such as iterating over
+graphemes, searching for substrings, replacing substrings, trimming and case
+conversion are examples of things not provided on the standard library `&[u8]`
+APIs but are provided by this crate. For example, this code iterates over all
+of occurrences of a substring:
+
+```
+use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+
+let mut matches = vec![];
+for start in s.find_iter("foo") {
+    matches.push(start);
+}
+assert_eq!(matches, [0, 8, 12, 21]);
+```
+
+Here's another example showing how to do a search and replace (and also showing
+use of the `B` function):
+
+```
+# #[cfg(feature = "alloc")] {
+use bstr::{B, ByteSlice};
+
+let old = B("foo ☃☃☃ foo foo quux foo");
+let new = old.replace("foo", "hello");
+assert_eq!(new, B("hello ☃☃☃ hello hello quux hello"));
+# }
+```
+
+And here's an example that shows case conversion, even in the presence of
+invalid UTF-8:
+
+```
+# #[cfg(all(feature = "alloc", feature = "unicode"))] {
+use bstr::{ByteSlice, ByteVec};
+
+let mut lower = Vec::from("hello β");
+lower[0] = b'\xFF';
+// lowercase β is uppercased to Β
+assert_eq!(lower.to_uppercase(), b"\xFFELLO \xCE\x92");
+# }
+```
+
+# Convenient debug representation
+
+When working with byte strings, it is often useful to be able to print them
+as if they were byte strings and not sequences of integers. While this crate
+cannot affect the `std::fmt::Debug` implementations for `[u8]` and `Vec<u8>`,
+this crate does provide the `BStr` and `BString` types which have convenient
+`std::fmt::Debug` implementations.
+
+For example, this
+
+```
+use bstr::ByteSlice;
+
+let mut bytes = Vec::from("hello β");
+bytes[0] = b'\xFF';
+
+println!("{:?}", bytes.as_bstr());
+```
+
+will output `"\xFFello β"`.
+
+This example works because the
+[`ByteSlice::as_bstr`](trait.ByteSlice.html#method.as_bstr)
+method converts any `&[u8]` to a `&BStr`.
+
+# When should I use byte strings?
+
+This library reflects my belief that UTF-8 by convention is a better trade
+off in some circumstances than guaranteed UTF-8.
+
+The first time this idea hit me was in the implementation of Rust's regex
+engine. In particular, very little of the internal implementation cares at all
+about searching valid UTF-8 encoded strings. Indeed, internally, the
+implementation converts `&str` from the API to `&[u8]` fairly quickly and
+just deals with raw bytes. UTF-8 match boundaries are then guaranteed by the
+finite state machine itself rather than any specific string type. This makes it
+possible to not only run regexes on `&str` values, but also on `&[u8]` values.
+
+Why would you ever want to run a regex on a `&[u8]` though? Well, `&[u8]` is
+the fundamental way at which one reads data from all sorts of streams, via the
+standard library's [`Read`](https://doc.rust-lang.org/std/io/trait.Read.html)
+trait. In particular, there is no platform independent way to determine whether
+what you're reading from is some binary file or a human readable text file.
+Therefore, if you're writing a program to search files, you probably need to
+deal with `&[u8]` directly unless you're okay with first converting it to a
+`&str` and dropping any bytes that aren't valid UTF-8. (Or otherwise determine
+the encoding---which is often impractical---and perform a transcoding step.)
+Often, the simplest and most robust way to approach this is to simply treat the
+contents of a file as if it were mostly valid UTF-8 and pass through invalid
+UTF-8 untouched. This may not be the most correct approach though!
+
+One case in particular exacerbates these issues, and that's memory mapping
+a file. When you memory map a file, that file may be gigabytes big, but all
+you get is a `&[u8]`. Converting that to a `&str` all in one go is generally
+not a good idea because of the costs associated with doing so, and also
+because it generally causes one to do two passes over the data instead of
+one, which is quite undesirable. It is of course usually possible to do it an
+incremental way by only parsing chunks at a time, but this is often complex to
+do or impractical. For example, many regex engines only accept one contiguous
+sequence of bytes at a time with no way to perform incremental matching.
+
+# `bstr` in public APIs
+
+This library is past version `1` and is expected to remain at version `1` for
+the foreseeable future. Therefore, it is encouraged to put types from `bstr`
+(like `BStr` and `BString`) in your public API if that makes sense for your
+crate.
+
+With that said, in general, it should be possible to avoid putting anything
+in this crate into your public APIs. Namely, you should never need to use the
+`ByteSlice` or `ByteVec` traits as bounds on public APIs, since their only
+purpose is to extend the methods on the concrete types `[u8]` and `Vec<u8>`,
+respectively. Similarly, it should not be necessary to put either the `BStr` or
+`BString` types into public APIs. If you want to use them internally, then they
+can be converted to/from `[u8]`/`Vec<u8>` as needed. The conversions are free.
+
+So while it shouldn't ever be 100% necessary to make `bstr` a public
+dependency, there may be cases where it is convenient to do so. This is an
+explicitly supported use case of `bstr`, and as such, major version releases
+should be exceptionally rare.
+
+
+# Differences with standard strings
+
+The primary difference between `[u8]` and `str` is that the former is
+conventionally UTF-8 while the latter is guaranteed to be UTF-8. The phrase
+"conventionally UTF-8" means that a `[u8]` may contain bytes that do not form
+a valid UTF-8 sequence, but operations defined on the type in this crate are
+generally most useful on valid UTF-8 sequences. For example, iterating over
+Unicode codepoints or grapheme clusters is an operation that is only defined
+on valid UTF-8. Therefore, when invalid UTF-8 is encountered, the Unicode
+replacement codepoint is substituted. Thus, a byte string that is not UTF-8 at
+all is of limited utility when using these crate.
+
+However, not all operations on byte strings are specifically Unicode aware. For
+example, substring search has no specific Unicode semantics ascribed to it. It
+works just as well for byte strings that are completely valid UTF-8 as for byte
+strings that contain no valid UTF-8 at all. Similarly for replacements and
+various other operations that do not need any Unicode specific tailoring.
+
+Aside from the difference in how UTF-8 is handled, the APIs between `[u8]` and
+`str` (and `Vec<u8>` and `String`) are intentionally very similar, including
+maintaining the same behavior for corner cases in things like substring
+splitting. There are, however, some differences:
+
+* Substring search is not done with `matches`, but instead, `find_iter`.
+  In general, this crate does not define any generic
+  [`Pattern`](https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html)
+  infrastructure, and instead prefers adding new methods for different
+  argument types. For example, `matches` can search by a `char` or a `&str`,
+  where as `find_iter` can only search by a byte string. `find_char` can be
+  used for searching by a `char`.
+* Since `SliceConcatExt` in the standard library is unstable, it is not
+  possible to reuse that to implement `join` and `concat` methods. Instead,
+  [`join`](fn.join.html) and [`concat`](fn.concat.html) are provided as free
+  functions that perform a similar task.
+* This library bundles in a few more Unicode operations, such as grapheme,
+  word and sentence iterators. More operations, such as normalization and
+  case folding, may be provided in the future.
+* Some `String`/`str` APIs will panic if a particular index was not on a valid
+  UTF-8 code unit sequence boundary. Conversely, no such checking is performed
+  in this crate, as is consistent with treating byte strings as a sequence of
+  bytes. This means callers are responsible for maintaining a UTF-8 invariant
+  if that's important.
+* Some routines provided by this crate, such as `starts_with_str`, have a
+  `_str` suffix to differentiate them from similar routines already defined
+  on the `[u8]` type. The difference is that `starts_with` requires its
+  parameter to be a `&[u8]`, where as `starts_with_str` permits its parameter
+  to by anything that implements `AsRef<[u8]>`, which is more flexible. This
+  means you can write `bytes.starts_with_str("☃")` instead of
+  `bytes.starts_with("☃".as_bytes())`.
+
+Otherwise, you should find most of the APIs between this crate and the standard
+library string APIs to be very similar, if not identical.
+
+# Handling of invalid UTF-8
+
+Since byte strings are only *conventionally* UTF-8, there is no guarantee
+that byte strings contain valid UTF-8. Indeed, it is perfectly legal for a
+byte string to contain arbitrary bytes. However, since this library defines
+a *string* type, it provides many operations specified by Unicode. These
+operations are typically only defined over codepoints, and thus have no real
+meaning on bytes that are invalid UTF-8 because they do not map to a particular
+codepoint.
+
+For this reason, whenever operations defined only on codepoints are used, this
+library will automatically convert invalid UTF-8 to the Unicode replacement
+codepoint, `U+FFFD`, which looks like this: `�`. For example, an
+[iterator over codepoints](struct.Chars.html) will yield a Unicode
+replacement codepoint whenever it comes across bytes that are not valid UTF-8:
+
+```
+use bstr::ByteSlice;
+
+let bs = b"a\xFF\xFFz";
+let chars: Vec<char> = bs.chars().collect();
+assert_eq!(vec!['a', '\u{FFFD}', '\u{FFFD}', 'z'], chars);
+```
+
+There are a few ways in which invalid bytes can be substituted with a Unicode
+replacement codepoint. One way, not used by this crate, is to replace every
+individual invalid byte with a single replacement codepoint. In contrast, the
+approach this crate uses is called the "substitution of maximal subparts," as
+specified by the Unicode Standard (Chapter 3, Section 9). (This approach is
+also used by [W3C's Encoding Standard](https://www.w3.org/TR/encoding/).) In
+this strategy, a replacement codepoint is inserted whenever a byte is found
+that cannot possibly lead to a valid UTF-8 code unit sequence. If there were
+previous bytes that represented a *prefix* of a well-formed UTF-8 code unit
+sequence, then all of those bytes (up to 3) are substituted with a single
+replacement codepoint. For example:
+
+```
+use bstr::ByteSlice;
+
+let bs = b"a\xF0\x9F\x87z";
+let chars: Vec<char> = bs.chars().collect();
+// The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of them
+// on their own are invalid. Only one replacement codepoint is substituted,
+// which demonstrates the "substitution of maximal subparts" strategy.
+assert_eq!(vec!['a', '\u{FFFD}', 'z'], chars);
+```
+
+If you do need to access the raw bytes for some reason in an iterator like
+`Chars`, then you should use the iterator's "indices" variant, which gives
+the byte offsets containing the invalid UTF-8 bytes that were substituted with
+the replacement codepoint. For example:
+
+```
+use bstr::{B, ByteSlice};
+
+let bs = b"a\xE2\x98z";
+let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
+// Even though the replacement codepoint is encoded as 3 bytes itself, the
+// byte range given here is only two bytes, corresponding to the original
+// raw bytes.
+assert_eq!(vec![(0, 1, 'a'), (1, 3, '\u{FFFD}'), (3, 4, 'z')], chars);
+
+// Thus, getting the original raw bytes is as simple as slicing the original
+// byte string:
+let chars: Vec<&[u8]> = bs.char_indices().map(|(s, e, _)| &bs[s..e]).collect();
+assert_eq!(vec![B("a"), B(b"\xE2\x98"), B("z")], chars);
+```
+
+# File paths and OS strings
+
+One of the premiere features of Rust's standard library is how it handles file
+paths. In particular, it makes it very hard to write incorrect code while
+simultaneously providing a correct cross platform abstraction for manipulating
+file paths. The key challenge that one faces with file paths across platforms
+is derived from the following observations:
+
+* On most Unix-like systems, file paths are an arbitrary sequence of bytes.
+* On Windows, file paths are an arbitrary sequence of 16-bit integers.
+
+(In both cases, certain sequences aren't allowed. For example a `NUL` byte is
+not allowed in either case. But we can ignore this for the purposes of this
+section.)
+
+Byte strings, like the ones provided in this crate, line up really well with
+file paths on Unix like systems, which are themselves just arbitrary sequences
+of bytes. It turns out that if you treat them as "mostly UTF-8," then things
+work out pretty well. On the contrary, byte strings _don't_ really work
+that well on Windows because it's not possible to correctly roundtrip file
+paths between 16-bit integers and something that looks like UTF-8 _without_
+explicitly defining an encoding to do this for you, which is anathema to byte
+strings, which are just bytes.
+
+Rust's standard library elegantly solves this problem by specifying an
+internal encoding for file paths that's only used on Windows called
+[WTF-8](https://simonsapin.github.io/wtf-8/). Its key properties are that they
+permit losslessly roundtripping file paths on Windows by extending UTF-8 to
+support an encoding of surrogate codepoints, while simultaneously supporting
+zero-cost conversion from Rust's Unicode strings to file paths. (Since UTF-8 is
+a proper subset of WTF-8.)
+
+The fundamental point at which the above strategy fails is when you want to
+treat file paths as things that look like strings in a zero cost way. In most
+cases, this is actually the wrong thing to do, but some cases call for it,
+for example, glob or regex matching on file paths. This is because WTF-8 is
+treated as an internal implementation detail, and there is no way to access
+those bytes via a public API. Therefore, such consumers are limited in what
+they can do:
+
+1. One could re-implement WTF-8 and re-encode file paths on Windows to WTF-8
+   by accessing their underlying 16-bit integer representation. Unfortunately,
+   this isn't zero cost (it introduces a second WTF-8 decoding step) and it's
+   not clear this is a good thing to do, since WTF-8 should ideally remain an
+   internal implementation detail. This is roughly the approach taken by the
+   [`os_str_bytes`](https://crates.io/crates/os_str_bytes) crate.
+2. One could instead declare that they will not handle paths on Windows that
+   are not valid UTF-16, and return an error when one is encountered.
+3. Like (2), but instead of returning an error, lossily decode the file path
+   on Windows that isn't valid UTF-16 into UTF-16 by replacing invalid bytes
+   with the Unicode replacement codepoint.
+
+While this library may provide facilities for (1) in the future, currently,
+this library only provides facilities for (2) and (3). In particular, a suite
+of conversion functions are provided that permit converting between byte
+strings, OS strings and file paths. For owned byte strings, they are:
+
+* [`ByteVec::from_os_string`](trait.ByteVec.html#method.from_os_string)
+* [`ByteVec::from_os_str_lossy`](trait.ByteVec.html#method.from_os_str_lossy)
+* [`ByteVec::from_path_buf`](trait.ByteVec.html#method.from_path_buf)
+* [`ByteVec::from_path_lossy`](trait.ByteVec.html#method.from_path_lossy)
+* [`ByteVec::into_os_string`](trait.ByteVec.html#method.into_os_string)
+* [`ByteVec::into_os_string_lossy`](trait.ByteVec.html#method.into_os_string_lossy)
+* [`ByteVec::into_path_buf`](trait.ByteVec.html#method.into_path_buf)
+* [`ByteVec::into_path_buf_lossy`](trait.ByteVec.html#method.into_path_buf_lossy)
+
+For byte string slices, they are:
+
+* [`ByteSlice::from_os_str`](trait.ByteSlice.html#method.from_os_str)
+* [`ByteSlice::from_path`](trait.ByteSlice.html#method.from_path)
+* [`ByteSlice::to_os_str`](trait.ByteSlice.html#method.to_os_str)
+* [`ByteSlice::to_os_str_lossy`](trait.ByteSlice.html#method.to_os_str_lossy)
+* [`ByteSlice::to_path`](trait.ByteSlice.html#method.to_path)
+* [`ByteSlice::to_path_lossy`](trait.ByteSlice.html#method.to_path_lossy)
+
+On Unix, all of these conversions are rigorously zero cost, which gives one
+a way to ergonomically deal with raw file paths exactly as they are using
+normal string-related functions. On Windows, these conversion routines perform
+a UTF-8 check and either return an error or lossily decode the file path
+into valid UTF-8, depending on which function you use. This means that you
+cannot roundtrip all file paths on Windows correctly using these conversion
+routines. However, this may be an acceptable downside since such file paths
+are exceptionally rare. Moreover, roundtripping isn't always necessary, for
+example, if all you're doing is filtering based on file paths.
+
+The reason why using byte strings for this is potentially superior than the
+standard library's approach is that a lot of Rust code is already lossily
+converting file paths to Rust's Unicode strings, which are required to be valid
+UTF-8, and thus contain latent bugs on Unix where paths with invalid UTF-8 are
+not terribly uncommon. If you instead use byte strings, then you're guaranteed
+to write correct code for Unix, at the cost of getting a corner case wrong on
+Windows.
+
+# Cargo features
+
+This crates comes with a few features that control standard library, serde
+and Unicode support.
+
+* `std` - **Enabled** by default. This provides APIs that require the standard
+  library, such as `Vec<u8>` and `PathBuf`. Enabling this feature also enables
+  the `alloc` feature and any other relevant `std` features for dependencies.
+* `alloc` - **Enabled** by default. This provides APIs that require allocations
+  via the `alloc` crate, such as `Vec<u8>`.
+* `unicode` - **Enabled** by default. This provides APIs that require sizable
+  Unicode data compiled into the binary. This includes, but is not limited to,
+  grapheme/word/sentence segmenters. When this is disabled, basic support such
+  as UTF-8 decoding is still included. Note that currently, enabling this
+  feature also requires enabling the `std` feature. It is expected that this
+  limitation will be lifted at some point.
+* `serde` - Enables implementations of serde traits for `BStr`, and also
+  `BString` when `alloc` is enabled.
+*/
+
+#![cfg_attr(not(any(feature = "std", test)), no_std)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+pub use crate::bstr::BStr;
+#[cfg(feature = "alloc")]
+pub use crate::bstring::BString;
+pub use crate::escape_bytes::EscapeBytes;
+#[cfg(feature = "unicode")]
+pub use crate::ext_slice::Fields;
+pub use crate::ext_slice::{
+    ByteSlice, Bytes, FieldsWith, Find, FindReverse, Finder, FinderReverse,
+    Lines, LinesWithTerminator, Split, SplitN, SplitNReverse, SplitReverse, B,
+};
+#[cfg(feature = "alloc")]
+pub use crate::ext_vec::{concat, join, ByteVec, DrainBytes, FromUtf8Error};
+#[cfg(feature = "unicode")]
+pub use crate::unicode::{
+    GraphemeIndices, Graphemes, SentenceIndices, Sentences, WordIndices,
+    Words, WordsWithBreakIndices, WordsWithBreaks,
+};
+pub use crate::utf8::{
+    decode as decode_utf8, decode_last as decode_last_utf8, CharIndices,
+    Chars, Utf8Chunk, Utf8Chunks, Utf8Error,
+};
+
+mod ascii;
+mod bstr;
+#[cfg(feature = "alloc")]
+mod bstring;
+mod byteset;
+mod escape_bytes;
+mod ext_slice;
+#[cfg(feature = "alloc")]
+mod ext_vec;
+mod impls;
+#[cfg(feature = "std")]
+pub mod io;
+#[cfg(all(test, feature = "std"))]
+mod tests;
+#[cfg(feature = "unicode")]
+mod unicode;
+mod utf8;
+
+#[cfg(all(test, feature = "std"))]
+mod apitests {
+    use crate::{
+        bstr::BStr,
+        bstring::BString,
+        ext_slice::{Finder, FinderReverse},
+    };
+
+    #[test]
+    fn oibits() {
+        use std::panic::{RefUnwindSafe, UnwindSafe};
+
+        fn assert_send<T: Send>() {}
+        fn assert_sync<T: Sync>() {}
+        fn assert_unwind_safe<T: RefUnwindSafe + UnwindSafe>() {}
+
+        assert_send::<&BStr>();
+        assert_sync::<&BStr>();
+        assert_unwind_safe::<&BStr>();
+        assert_send::<BString>();
+        assert_sync::<BString>();
+        assert_unwind_safe::<BString>();
+
+        assert_send::<Finder<'_>>();
+        assert_sync::<Finder<'_>>();
+        assert_unwind_safe::<Finder<'_>>();
+        assert_send::<FinderReverse<'_>>();
+        assert_sync::<FinderReverse<'_>>();
+        assert_unwind_safe::<FinderReverse<'_>>();
+    }
+}
+
\ No newline at end of file diff --git a/src/bstr/utf8.rs.html b/src/bstr/utf8.rs.html new file mode 100644 index 000000000..868e660a0 --- /dev/null +++ b/src/bstr/utf8.rs.html @@ -0,0 +1,2739 @@ +utf8.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+
use core::{char, cmp, fmt, str};
+
+#[cfg(feature = "std")]
+use std::error;
+
+use crate::{ascii, bstr::BStr, ext_slice::ByteSlice};
+
+// The UTF-8 decoder provided here is based on the one presented here:
+// https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+//
+// We *could* have done UTF-8 decoding by using a DFA generated by `\p{any}`
+// using regex-automata that is roughly the same size. The real benefit of
+// Hoehrmann's formulation is that the byte class mapping below is manually
+// tailored such that each byte's class doubles as a shift to mask out the
+// bits necessary for constructing the leading bits of each codepoint value
+// from the initial byte.
+//
+// There are some minor differences between this implementation and Hoehrmann's
+// formulation.
+//
+// Firstly, we make REJECT have state ID 0, since it makes the state table
+// itself a little easier to read and is consistent with the notion that 0
+// means "false" or "bad."
+//
+// Secondly, when doing bulk decoding, we add a SIMD accelerated ASCII fast
+// path.
+//
+// Thirdly, we pre-multiply the state IDs to avoid a multiplication instruction
+// in the core decoding loop. (Which is what regex-automata would do by
+// default.)
+//
+// Fourthly, we split the byte class mapping and transition table into two
+// arrays because it's clearer.
+//
+// It is unlikely that this is the fastest way to do UTF-8 decoding, however,
+// it is fairly simple.
+
+const ACCEPT: usize = 12;
+const REJECT: usize = 0;
+
+/// SAFETY: The decode below function relies on the correctness of these
+/// equivalence classes.
+#[cfg_attr(rustfmt, rustfmt::skip)]
+const CLASSES: [u8; 256] = [
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+   8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+];
+
+/// SAFETY: The decode below function relies on the correctness of this state
+/// machine.
+#[cfg_attr(rustfmt, rustfmt::skip)]
+const STATES_FORWARD: &'static [u8] = &[
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  12, 0, 24, 36, 60, 96, 84, 0, 0, 0, 48, 72,
+  0, 12, 0, 0, 0, 0, 0, 12, 0, 12, 0, 0,
+  0, 24, 0, 0, 0, 0, 0, 24, 0, 24, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0,
+  0, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 36, 0, 36, 0, 0,
+  0, 36, 0, 0, 0, 0, 0, 36, 0, 36, 0, 0,
+  0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+];
+
+/// An iterator over Unicode scalar values in a byte string.
+///
+/// When invalid UTF-8 byte sequences are found, they are substituted with the
+/// Unicode replacement codepoint (`U+FFFD`) using the
+/// ["maximal subpart" strategy](https://www.unicode.org/review/pr-121.html).
+///
+/// This iterator is created by the
+/// [`chars`](trait.ByteSlice.html#method.chars) method provided by the
+/// [`ByteSlice`](trait.ByteSlice.html) extension trait for `&[u8]`.
+#[derive(Clone, Debug)]
+pub struct Chars<'a> {
+    bs: &'a [u8],
+}
+
+impl<'a> Chars<'a> {
+    pub(crate) fn new(bs: &'a [u8]) -> Chars<'a> {
+        Chars { bs }
+    }
+
+    /// View the underlying data as a subslice of the original data.
+    ///
+    /// The slice returned has the same lifetime as the original slice, and so
+    /// the iterator can continue to be used while this exists.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut chars = b"abc".chars();
+    ///
+    /// assert_eq!(b"abc", chars.as_bytes());
+    /// chars.next();
+    /// assert_eq!(b"bc", chars.as_bytes());
+    /// chars.next();
+    /// chars.next();
+    /// assert_eq!(b"", chars.as_bytes());
+    /// ```
+    #[inline]
+    pub fn as_bytes(&self) -> &'a [u8] {
+        self.bs
+    }
+}
+
+impl<'a> Iterator for Chars<'a> {
+    type Item = char;
+
+    #[inline]
+    fn next(&mut self) -> Option<char> {
+        let (ch, size) = decode_lossy(self.bs);
+        if size == 0 {
+            return None;
+        }
+        self.bs = &self.bs[size..];
+        Some(ch)
+    }
+}
+
+impl<'a> DoubleEndedIterator for Chars<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<char> {
+        let (ch, size) = decode_last_lossy(self.bs);
+        if size == 0 {
+            return None;
+        }
+        self.bs = &self.bs[..self.bs.len() - size];
+        Some(ch)
+    }
+}
+
+/// An iterator over Unicode scalar values in a byte string and their
+/// byte index positions.
+///
+/// When invalid UTF-8 byte sequences are found, they are substituted with the
+/// Unicode replacement codepoint (`U+FFFD`) using the
+/// ["maximal subpart" strategy](https://www.unicode.org/review/pr-121.html).
+///
+/// Note that this is slightly different from the `CharIndices` iterator
+/// provided by the standard library. Aside from working on possibly invalid
+/// UTF-8, this iterator provides both the corresponding starting and ending
+/// byte indices of each codepoint yielded. The ending position is necessary to
+/// slice the original byte string when invalid UTF-8 bytes are converted into
+/// a Unicode replacement codepoint, since a single replacement codepoint can
+/// substitute anywhere from 1 to 3 invalid bytes (inclusive).
+///
+/// This iterator is created by the
+/// [`char_indices`](trait.ByteSlice.html#method.char_indices) method provided
+/// by the [`ByteSlice`](trait.ByteSlice.html) extension trait for `&[u8]`.
+#[derive(Clone, Debug)]
+pub struct CharIndices<'a> {
+    bs: &'a [u8],
+    forward_index: usize,
+    reverse_index: usize,
+}
+
+impl<'a> CharIndices<'a> {
+    pub(crate) fn new(bs: &'a [u8]) -> CharIndices<'a> {
+        CharIndices { bs, forward_index: 0, reverse_index: bs.len() }
+    }
+
+    /// View the underlying data as a subslice of the original data.
+    ///
+    /// The slice returned has the same lifetime as the original slice, and so
+    /// the iterator can continue to be used while this exists.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let mut it = b"abc".char_indices();
+    ///
+    /// assert_eq!(b"abc", it.as_bytes());
+    /// it.next();
+    /// assert_eq!(b"bc", it.as_bytes());
+    /// it.next();
+    /// it.next();
+    /// assert_eq!(b"", it.as_bytes());
+    /// ```
+    #[inline]
+    pub fn as_bytes(&self) -> &'a [u8] {
+        self.bs
+    }
+}
+
+impl<'a> Iterator for CharIndices<'a> {
+    type Item = (usize, usize, char);
+
+    #[inline]
+    fn next(&mut self) -> Option<(usize, usize, char)> {
+        let index = self.forward_index;
+        let (ch, size) = decode_lossy(self.bs);
+        if size == 0 {
+            return None;
+        }
+        self.bs = &self.bs[size..];
+        self.forward_index += size;
+        Some((index, index + size, ch))
+    }
+}
+
+impl<'a> DoubleEndedIterator for CharIndices<'a> {
+    #[inline]
+    fn next_back(&mut self) -> Option<(usize, usize, char)> {
+        let (ch, size) = decode_last_lossy(self.bs);
+        if size == 0 {
+            return None;
+        }
+        self.bs = &self.bs[..self.bs.len() - size];
+        self.reverse_index -= size;
+        Some((self.reverse_index, self.reverse_index + size, ch))
+    }
+}
+
+impl<'a> ::core::iter::FusedIterator for CharIndices<'a> {}
+
+/// An iterator over chunks of valid UTF-8 in a byte slice.
+///
+/// See [`utf8_chunks`](trait.ByteSlice.html#method.utf8_chunks).
+#[derive(Clone, Debug)]
+pub struct Utf8Chunks<'a> {
+    pub(super) bytes: &'a [u8],
+}
+
+/// A chunk of valid UTF-8, possibly followed by invalid UTF-8 bytes.
+///
+/// This is yielded by the
+/// [`Utf8Chunks`](struct.Utf8Chunks.html)
+/// iterator, which can be created via the
+/// [`ByteSlice::utf8_chunks`](trait.ByteSlice.html#method.utf8_chunks)
+/// method.
+///
+/// The `'a` lifetime parameter corresponds to the lifetime of the bytes that
+/// are being iterated over.
+#[cfg_attr(test, derive(Debug, PartialEq))]
+pub struct Utf8Chunk<'a> {
+    /// A valid UTF-8 piece, at the start, end, or between invalid UTF-8 bytes.
+    ///
+    /// This is empty between adjacent invalid UTF-8 byte sequences.
+    valid: &'a str,
+    /// A sequence of invalid UTF-8 bytes.
+    ///
+    /// Can only be empty in the last chunk.
+    ///
+    /// Should be replaced by a single unicode replacement character, if not
+    /// empty.
+    invalid: &'a BStr,
+    /// Indicates whether the invalid sequence could've been valid if there
+    /// were more bytes.
+    ///
+    /// Can only be true in the last chunk.
+    incomplete: bool,
+}
+
+impl<'a> Utf8Chunk<'a> {
+    /// Returns the (possibly empty) valid UTF-8 bytes in this chunk.
+    ///
+    /// This may be empty if there are consecutive sequences of invalid UTF-8
+    /// bytes.
+    #[inline]
+    pub fn valid(&self) -> &'a str {
+        self.valid
+    }
+
+    /// Returns the (possibly empty) invalid UTF-8 bytes in this chunk that
+    /// immediately follow the valid UTF-8 bytes in this chunk.
+    ///
+    /// This is only empty when this chunk corresponds to the last chunk in
+    /// the original bytes.
+    ///
+    /// The maximum length of this slice is 3. That is, invalid UTF-8 byte
+    /// sequences greater than 1 always correspond to a valid _prefix_ of
+    /// a valid UTF-8 encoded codepoint. This corresponds to the "substitution
+    /// of maximal subparts" strategy that is described in more detail in the
+    /// docs for the
+    /// [`ByteSlice::to_str_lossy`](trait.ByteSlice.html#method.to_str_lossy)
+    /// method.
+    #[inline]
+    pub fn invalid(&self) -> &'a [u8] {
+        self.invalid.as_bytes()
+    }
+
+    /// Returns whether the invalid sequence might still become valid if more
+    /// bytes are added.
+    ///
+    /// Returns true if the end of the input was reached unexpectedly,
+    /// without encountering an unexpected byte.
+    ///
+    /// This can only be the case for the last chunk.
+    #[inline]
+    pub fn incomplete(&self) -> bool {
+        self.incomplete
+    }
+}
+
+impl<'a> Iterator for Utf8Chunks<'a> {
+    type Item = Utf8Chunk<'a>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Utf8Chunk<'a>> {
+        if self.bytes.is_empty() {
+            return None;
+        }
+        match validate(self.bytes) {
+            Ok(()) => {
+                let valid = self.bytes;
+                self.bytes = &[];
+                Some(Utf8Chunk {
+                    // SAFETY: This is safe because of the guarantees provided
+                    // by utf8::validate.
+                    valid: unsafe { str::from_utf8_unchecked(valid) },
+                    invalid: [].as_bstr(),
+                    incomplete: false,
+                })
+            }
+            Err(e) => {
+                let (valid, rest) = self.bytes.split_at(e.valid_up_to());
+                // SAFETY: This is safe because of the guarantees provided by
+                // utf8::validate.
+                let valid = unsafe { str::from_utf8_unchecked(valid) };
+                let (invalid_len, incomplete) = match e.error_len() {
+                    Some(n) => (n, false),
+                    None => (rest.len(), true),
+                };
+                let (invalid, rest) = rest.split_at(invalid_len);
+                self.bytes = rest;
+                Some(Utf8Chunk {
+                    valid,
+                    invalid: invalid.as_bstr(),
+                    incomplete,
+                })
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.bytes.is_empty() {
+            (0, Some(0))
+        } else {
+            (1, Some(self.bytes.len()))
+        }
+    }
+}
+
+impl<'a> ::core::iter::FusedIterator for Utf8Chunks<'a> {}
+
+/// An error that occurs when UTF-8 decoding fails.
+///
+/// This error occurs when attempting to convert a non-UTF-8 byte
+/// string to a Rust string that must be valid UTF-8. For example,
+/// [`to_str`](trait.ByteSlice.html#method.to_str) is one such method.
+///
+/// # Example
+///
+/// This example shows what happens when a given byte sequence is invalid,
+/// but ends with a sequence that is a possible prefix of valid UTF-8.
+///
+/// ```
+/// use bstr::{B, ByteSlice};
+///
+/// let s = B(b"foobar\xF1\x80\x80");
+/// let err = s.to_str().unwrap_err();
+/// assert_eq!(err.valid_up_to(), 6);
+/// assert_eq!(err.error_len(), None);
+/// ```
+///
+/// This example shows what happens when a given byte sequence contains
+/// invalid UTF-8.
+///
+/// ```
+/// use bstr::ByteSlice;
+///
+/// let s = b"foobar\xF1\x80\x80quux";
+/// let err = s.to_str().unwrap_err();
+/// assert_eq!(err.valid_up_to(), 6);
+/// // The error length reports the maximum number of bytes that correspond to
+/// // a valid prefix of a UTF-8 encoded codepoint.
+/// assert_eq!(err.error_len(), Some(3));
+///
+/// // In contrast to the above which contains a single invalid prefix,
+/// // consider the case of multiple individual bytes that are never valid
+/// // prefixes. Note how the value of error_len changes!
+/// let s = b"foobar\xFF\xFFquux";
+/// let err = s.to_str().unwrap_err();
+/// assert_eq!(err.valid_up_to(), 6);
+/// assert_eq!(err.error_len(), Some(1));
+///
+/// // The fact that it's an invalid prefix does not change error_len even
+/// // when it immediately precedes the end of the string.
+/// let s = b"foobar\xFF";
+/// let err = s.to_str().unwrap_err();
+/// assert_eq!(err.valid_up_to(), 6);
+/// assert_eq!(err.error_len(), Some(1));
+/// ```
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Utf8Error {
+    valid_up_to: usize,
+    error_len: Option<usize>,
+}
+
+impl Utf8Error {
+    /// Returns the byte index of the position immediately following the last
+    /// valid UTF-8 byte.
+    ///
+    /// # Example
+    ///
+    /// This examples shows how `valid_up_to` can be used to retrieve a
+    /// possibly empty prefix that is guaranteed to be valid UTF-8:
+    ///
+    /// ```
+    /// use bstr::ByteSlice;
+    ///
+    /// let s = b"foobar\xF1\x80\x80quux";
+    /// let err = s.to_str().unwrap_err();
+    ///
+    /// // This is guaranteed to never panic.
+    /// let string = s[..err.valid_up_to()].to_str().unwrap();
+    /// assert_eq!(string, "foobar");
+    /// ```
+    #[inline]
+    pub fn valid_up_to(&self) -> usize {
+        self.valid_up_to
+    }
+
+    /// Returns the total number of invalid UTF-8 bytes immediately following
+    /// the position returned by `valid_up_to`. This value is always at least
+    /// `1`, but can be up to `3` if bytes form a valid prefix of some UTF-8
+    /// encoded codepoint.
+    ///
+    /// If the end of the original input was found before a valid UTF-8 encoded
+    /// codepoint could be completed, then this returns `None`. This is useful
+    /// when processing streams, where a `None` value signals that more input
+    /// might be needed.
+    #[inline]
+    pub fn error_len(&self) -> Option<usize> {
+        self.error_len
+    }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Utf8Error {
+    fn description(&self) -> &str {
+        "invalid UTF-8"
+    }
+}
+
+impl fmt::Display for Utf8Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "invalid UTF-8 found at byte offset {}", self.valid_up_to)
+    }
+}
+
+/// Returns OK if and only if the given slice is completely valid UTF-8.
+///
+/// If the slice isn't valid UTF-8, then an error is returned that explains
+/// the first location at which invalid UTF-8 was detected.
+pub fn validate(slice: &[u8]) -> Result<(), Utf8Error> {
+    // The fast path for validating UTF-8. It steps through a UTF-8 automaton
+    // and uses a SIMD accelerated ASCII fast path on x86_64. If an error is
+    // detected, it backs up and runs the slower version of the UTF-8 automaton
+    // to determine correct error information.
+    fn fast(slice: &[u8]) -> Result<(), Utf8Error> {
+        let mut state = ACCEPT;
+        let mut i = 0;
+
+        while i < slice.len() {
+            let b = slice[i];
+
+            // ASCII fast path. If we see two consecutive ASCII bytes, then try
+            // to validate as much ASCII as possible very quickly.
+            if state == ACCEPT
+                && b <= 0x7F
+                && slice.get(i + 1).map_or(false, |&b| b <= 0x7F)
+            {
+                i += ascii::first_non_ascii_byte(&slice[i..]);
+                continue;
+            }
+
+            state = step(state, b);
+            if state == REJECT {
+                return Err(find_valid_up_to(slice, i));
+            }
+            i += 1;
+        }
+        if state != ACCEPT {
+            Err(find_valid_up_to(slice, slice.len()))
+        } else {
+            Ok(())
+        }
+    }
+
+    // Given the first position at which a UTF-8 sequence was determined to be
+    // invalid, return an error that correctly reports the position at which
+    // the last complete UTF-8 sequence ends.
+    #[inline(never)]
+    fn find_valid_up_to(slice: &[u8], rejected_at: usize) -> Utf8Error {
+        // In order to find the last valid byte, we need to back up an amount
+        // that guarantees every preceding byte is part of a valid UTF-8
+        // code unit sequence. To do this, we simply locate the last leading
+        // byte that occurs before rejected_at.
+        let mut backup = rejected_at.saturating_sub(1);
+        while backup > 0 && !is_leading_or_invalid_utf8_byte(slice[backup]) {
+            backup -= 1;
+        }
+        let upto = cmp::min(slice.len(), rejected_at.saturating_add(1));
+        let mut err = slow(&slice[backup..upto]).unwrap_err();
+        err.valid_up_to += backup;
+        err
+    }
+
+    // Like top-level UTF-8 decoding, except it correctly reports a UTF-8 error
+    // when an invalid sequence is found. This is split out from validate so
+    // that the fast path doesn't need to keep track of the position of the
+    // last valid UTF-8 byte. In particular, tracking this requires checking
+    // for an ACCEPT state on each byte, which degrades throughput pretty
+    // badly.
+    fn slow(slice: &[u8]) -> Result<(), Utf8Error> {
+        let mut state = ACCEPT;
+        let mut valid_up_to = 0;
+        for (i, &b) in slice.iter().enumerate() {
+            state = step(state, b);
+            if state == ACCEPT {
+                valid_up_to = i + 1;
+            } else if state == REJECT {
+                // Our error length must always be at least 1.
+                let error_len = Some(cmp::max(1, i - valid_up_to));
+                return Err(Utf8Error { valid_up_to, error_len });
+            }
+        }
+        if state != ACCEPT {
+            Err(Utf8Error { valid_up_to, error_len: None })
+        } else {
+            Ok(())
+        }
+    }
+
+    // Advance to the next state given the current state and current byte.
+    fn step(state: usize, b: u8) -> usize {
+        let class = CLASSES[b as usize];
+        // SAFETY: This is safe because 'class' is always <=11 and 'state' is
+        // always <=96. Therefore, the maximal index is 96+11 = 107, where
+        // STATES_FORWARD.len() = 108 such that every index is guaranteed to be
+        // valid by construction of the state machine and the byte equivalence
+        // classes.
+        unsafe {
+            *STATES_FORWARD.get_unchecked(state + class as usize) as usize
+        }
+    }
+
+    fast(slice)
+}
+
+/// UTF-8 decode a single Unicode scalar value from the beginning of a slice.
+///
+/// When successful, the corresponding Unicode scalar value is returned along
+/// with the number of bytes it was encoded with. The number of bytes consumed
+/// for a successful decode is always between 1 and 4, inclusive.
+///
+/// When unsuccessful, `None` is returned along with the number of bytes that
+/// make up a maximal prefix of a valid UTF-8 code unit sequence. In this case,
+/// the number of bytes consumed is always between 0 and 3, inclusive, where
+/// 0 is only returned when `slice` is empty.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use bstr::decode_utf8;
+///
+/// // Decoding a valid codepoint.
+/// let (ch, size) = decode_utf8(b"\xE2\x98\x83");
+/// assert_eq!(Some('☃'), ch);
+/// assert_eq!(3, size);
+///
+/// // Decoding an incomplete codepoint.
+/// let (ch, size) = decode_utf8(b"\xE2\x98");
+/// assert_eq!(None, ch);
+/// assert_eq!(2, size);
+/// ```
+///
+/// This example shows how to iterate over all codepoints in UTF-8 encoded
+/// bytes, while replacing invalid UTF-8 sequences with the replacement
+/// codepoint:
+///
+/// ```
+/// use bstr::{B, decode_utf8};
+///
+/// let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+/// let mut chars = vec![];
+/// while !bytes.is_empty() {
+///     let (ch, size) = decode_utf8(bytes);
+///     bytes = &bytes[size..];
+///     chars.push(ch.unwrap_or('\u{FFFD}'));
+/// }
+/// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+/// ```
+#[inline]
+pub fn decode<B: AsRef<[u8]>>(slice: B) -> (Option<char>, usize) {
+    let slice = slice.as_ref();
+    match slice.get(0) {
+        None => return (None, 0),
+        Some(&b) if b <= 0x7F => return (Some(b as char), 1),
+        _ => {}
+    }
+
+    let (mut state, mut cp, mut i) = (ACCEPT, 0, 0);
+    while i < slice.len() {
+        decode_step(&mut state, &mut cp, slice[i]);
+        i += 1;
+
+        if state == ACCEPT {
+            // SAFETY: This is safe because `decode_step` guarantees that
+            // `cp` is a valid Unicode scalar value in an ACCEPT state.
+            let ch = unsafe { char::from_u32_unchecked(cp) };
+            return (Some(ch), i);
+        } else if state == REJECT {
+            // At this point, we always want to advance at least one byte.
+            return (None, cmp::max(1, i.saturating_sub(1)));
+        }
+    }
+    (None, i)
+}
+
+/// Lossily UTF-8 decode a single Unicode scalar value from the beginning of a
+/// slice.
+///
+/// When successful, the corresponding Unicode scalar value is returned along
+/// with the number of bytes it was encoded with. The number of bytes consumed
+/// for a successful decode is always between 1 and 4, inclusive.
+///
+/// When unsuccessful, the Unicode replacement codepoint (`U+FFFD`) is returned
+/// along with the number of bytes that make up a maximal prefix of a valid
+/// UTF-8 code unit sequence. In this case, the number of bytes consumed is
+/// always between 0 and 3, inclusive, where 0 is only returned when `slice` is
+/// empty.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```ignore
+/// use bstr::decode_utf8_lossy;
+///
+/// // Decoding a valid codepoint.
+/// let (ch, size) = decode_utf8_lossy(b"\xE2\x98\x83");
+/// assert_eq!('☃', ch);
+/// assert_eq!(3, size);
+///
+/// // Decoding an incomplete codepoint.
+/// let (ch, size) = decode_utf8_lossy(b"\xE2\x98");
+/// assert_eq!('\u{FFFD}', ch);
+/// assert_eq!(2, size);
+/// ```
+///
+/// This example shows how to iterate over all codepoints in UTF-8 encoded
+/// bytes, while replacing invalid UTF-8 sequences with the replacement
+/// codepoint:
+///
+/// ```ignore
+/// use bstr::{B, decode_utf8_lossy};
+///
+/// let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+/// let mut chars = vec![];
+/// while !bytes.is_empty() {
+///     let (ch, size) = decode_utf8_lossy(bytes);
+///     bytes = &bytes[size..];
+///     chars.push(ch);
+/// }
+/// assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+/// ```
+#[inline]
+pub fn decode_lossy<B: AsRef<[u8]>>(slice: B) -> (char, usize) {
+    match decode(slice) {
+        (Some(ch), size) => (ch, size),
+        (None, size) => ('\u{FFFD}', size),
+    }
+}
+
+/// UTF-8 decode a single Unicode scalar value from the end of a slice.
+///
+/// When successful, the corresponding Unicode scalar value is returned along
+/// with the number of bytes it was encoded with. The number of bytes consumed
+/// for a successful decode is always between 1 and 4, inclusive.
+///
+/// When unsuccessful, `None` is returned along with the number of bytes that
+/// make up a maximal prefix of a valid UTF-8 code unit sequence. In this case,
+/// the number of bytes consumed is always between 0 and 3, inclusive, where
+/// 0 is only returned when `slice` is empty.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use bstr::decode_last_utf8;
+///
+/// // Decoding a valid codepoint.
+/// let (ch, size) = decode_last_utf8(b"\xE2\x98\x83");
+/// assert_eq!(Some('☃'), ch);
+/// assert_eq!(3, size);
+///
+/// // Decoding an incomplete codepoint.
+/// let (ch, size) = decode_last_utf8(b"\xE2\x98");
+/// assert_eq!(None, ch);
+/// assert_eq!(2, size);
+/// ```
+///
+/// This example shows how to iterate over all codepoints in UTF-8 encoded
+/// bytes in reverse, while replacing invalid UTF-8 sequences with the
+/// replacement codepoint:
+///
+/// ```
+/// use bstr::{B, decode_last_utf8};
+///
+/// let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+/// let mut chars = vec![];
+/// while !bytes.is_empty() {
+///     let (ch, size) = decode_last_utf8(bytes);
+///     bytes = &bytes[..bytes.len()-size];
+///     chars.push(ch.unwrap_or('\u{FFFD}'));
+/// }
+/// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+/// ```
+#[inline]
+pub fn decode_last<B: AsRef<[u8]>>(slice: B) -> (Option<char>, usize) {
+    // TODO: We could implement this by reversing the UTF-8 automaton, but for
+    // now, we do it the slow way by using the forward automaton.
+
+    let slice = slice.as_ref();
+    if slice.is_empty() {
+        return (None, 0);
+    }
+    let mut start = slice.len() - 1;
+    let limit = slice.len().saturating_sub(4);
+    while start > limit && !is_leading_or_invalid_utf8_byte(slice[start]) {
+        start -= 1;
+    }
+    let (ch, size) = decode(&slice[start..]);
+    // If we didn't consume all of the bytes, then that means there's at least
+    // one stray byte that never occurs in a valid code unit prefix, so we can
+    // advance by one byte.
+    if start + size != slice.len() {
+        (None, 1)
+    } else {
+        (ch, size)
+    }
+}
+
+/// Lossily UTF-8 decode a single Unicode scalar value from the end of a slice.
+///
+/// When successful, the corresponding Unicode scalar value is returned along
+/// with the number of bytes it was encoded with. The number of bytes consumed
+/// for a successful decode is always between 1 and 4, inclusive.
+///
+/// When unsuccessful, the Unicode replacement codepoint (`U+FFFD`) is returned
+/// along with the number of bytes that make up a maximal prefix of a valid
+/// UTF-8 code unit sequence. In this case, the number of bytes consumed is
+/// always between 0 and 3, inclusive, where 0 is only returned when `slice` is
+/// empty.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```ignore
+/// use bstr::decode_last_utf8_lossy;
+///
+/// // Decoding a valid codepoint.
+/// let (ch, size) = decode_last_utf8_lossy(b"\xE2\x98\x83");
+/// assert_eq!('☃', ch);
+/// assert_eq!(3, size);
+///
+/// // Decoding an incomplete codepoint.
+/// let (ch, size) = decode_last_utf8_lossy(b"\xE2\x98");
+/// assert_eq!('\u{FFFD}', ch);
+/// assert_eq!(2, size);
+/// ```
+///
+/// This example shows how to iterate over all codepoints in UTF-8 encoded
+/// bytes in reverse, while replacing invalid UTF-8 sequences with the
+/// replacement codepoint:
+///
+/// ```ignore
+/// use bstr::decode_last_utf8_lossy;
+///
+/// let mut bytes = B(b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61");
+/// let mut chars = vec![];
+/// while !bytes.is_empty() {
+///     let (ch, size) = decode_last_utf8_lossy(bytes);
+///     bytes = &bytes[..bytes.len()-size];
+///     chars.push(ch);
+/// }
+/// assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+/// ```
+#[inline]
+pub fn decode_last_lossy<B: AsRef<[u8]>>(slice: B) -> (char, usize) {
+    match decode_last(slice) {
+        (Some(ch), size) => (ch, size),
+        (None, size) => ('\u{FFFD}', size),
+    }
+}
+
+/// SAFETY: The decode function relies on state being equal to ACCEPT only if
+/// cp is a valid Unicode scalar value.
+#[inline]
+pub fn decode_step(state: &mut usize, cp: &mut u32, b: u8) {
+    let class = CLASSES[b as usize];
+    if *state == ACCEPT {
+        *cp = (0xFF >> class) & (b as u32);
+    } else {
+        *cp = (b as u32 & 0b111111) | (*cp << 6);
+    }
+    *state = STATES_FORWARD[*state + class as usize] as usize;
+}
+
+/// Returns true if and only if the given byte is either a valid leading UTF-8
+/// byte, or is otherwise an invalid byte that can never appear anywhere in a
+/// valid UTF-8 sequence.
+fn is_leading_or_invalid_utf8_byte(b: u8) -> bool {
+    // In the ASCII case, the most significant bit is never set. The leading
+    // byte of a 2/3/4-byte sequence always has the top two most significant
+    // bits set. For bytes that can never appear anywhere in valid UTF-8, this
+    // also returns true, since every such byte has its two most significant
+    // bits set:
+    //
+    //     \xC0 :: 11000000
+    //     \xC1 :: 11000001
+    //     \xF5 :: 11110101
+    //     \xF6 :: 11110110
+    //     \xF7 :: 11110111
+    //     \xF8 :: 11111000
+    //     \xF9 :: 11111001
+    //     \xFA :: 11111010
+    //     \xFB :: 11111011
+    //     \xFC :: 11111100
+    //     \xFD :: 11111101
+    //     \xFE :: 11111110
+    //     \xFF :: 11111111
+    (b & 0b1100_0000) != 0b1000_0000
+}
+
+#[cfg(all(test, feature = "std"))]
+mod tests {
+    use std::char;
+
+    use crate::{
+        ext_slice::{ByteSlice, B},
+        tests::LOSSY_TESTS,
+        utf8::{self, Utf8Error},
+    };
+
+    fn utf8e(valid_up_to: usize) -> Utf8Error {
+        Utf8Error { valid_up_to, error_len: None }
+    }
+
+    fn utf8e2(valid_up_to: usize, error_len: usize) -> Utf8Error {
+        Utf8Error { valid_up_to, error_len: Some(error_len) }
+    }
+
+    #[test]
+    #[cfg(not(miri))]
+    fn validate_all_codepoints() {
+        for i in 0..(0x10FFFF + 1) {
+            let cp = match char::from_u32(i) {
+                None => continue,
+                Some(cp) => cp,
+            };
+            let mut buf = [0; 4];
+            let s = cp.encode_utf8(&mut buf);
+            assert_eq!(Ok(()), utf8::validate(s.as_bytes()));
+        }
+    }
+
+    #[test]
+    fn validate_multiple_codepoints() {
+        assert_eq!(Ok(()), utf8::validate(b"abc"));
+        assert_eq!(Ok(()), utf8::validate(b"a\xE2\x98\x83a"));
+        assert_eq!(Ok(()), utf8::validate(b"a\xF0\x9D\x9C\xB7a"));
+        assert_eq!(Ok(()), utf8::validate(b"\xE2\x98\x83\xF0\x9D\x9C\xB7",));
+        assert_eq!(
+            Ok(()),
+            utf8::validate(b"a\xE2\x98\x83a\xF0\x9D\x9C\xB7a",)
+        );
+        assert_eq!(
+            Ok(()),
+            utf8::validate(b"\xEF\xBF\xBD\xE2\x98\x83\xEF\xBF\xBD",)
+        );
+    }
+
+    #[test]
+    fn validate_errors() {
+        // single invalid byte
+        assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xFF"));
+        // single invalid byte after ASCII
+        assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xFF"));
+        // single invalid byte after 2 byte sequence
+        assert_eq!(Err(utf8e2(2, 1)), utf8::validate(b"\xCE\xB2\xFF"));
+        // single invalid byte after 3 byte sequence
+        assert_eq!(Err(utf8e2(3, 1)), utf8::validate(b"\xE2\x98\x83\xFF"));
+        // single invalid byte after 4 byte sequence
+        assert_eq!(Err(utf8e2(4, 1)), utf8::validate(b"\xF0\x9D\x9D\xB1\xFF"));
+
+        // An invalid 2-byte sequence with a valid 1-byte prefix.
+        assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xCE\xF0"));
+        // An invalid 3-byte sequence with a valid 2-byte prefix.
+        assert_eq!(Err(utf8e2(0, 2)), utf8::validate(b"\xE2\x98\xF0"));
+        // An invalid 4-byte sequence with a valid 3-byte prefix.
+        assert_eq!(Err(utf8e2(0, 3)), utf8::validate(b"\xF0\x9D\x9D\xF0"));
+
+        // An overlong sequence. Should be \xE2\x82\xAC, but we encode the
+        // same codepoint value in 4 bytes. This not only tests that we reject
+        // overlong sequences, but that we get valid_up_to correct.
+        assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xF0\x82\x82\xAC"));
+        assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xF0\x82\x82\xAC"));
+        assert_eq!(
+            Err(utf8e2(3, 1)),
+            utf8::validate(b"\xE2\x98\x83\xF0\x82\x82\xAC",)
+        );
+
+        // Check that encoding a surrogate codepoint using the UTF-8 scheme
+        // fails validation.
+        assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xED\xA0\x80"));
+        assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xED\xA0\x80"));
+        assert_eq!(
+            Err(utf8e2(3, 1)),
+            utf8::validate(b"\xE2\x98\x83\xED\xA0\x80",)
+        );
+
+        // Check that an incomplete 2-byte sequence fails.
+        assert_eq!(Err(utf8e2(0, 1)), utf8::validate(b"\xCEa"));
+        assert_eq!(Err(utf8e2(1, 1)), utf8::validate(b"a\xCEa"));
+        assert_eq!(
+            Err(utf8e2(3, 1)),
+            utf8::validate(b"\xE2\x98\x83\xCE\xE2\x98\x83",)
+        );
+        // Check that an incomplete 3-byte sequence fails.
+        assert_eq!(Err(utf8e2(0, 2)), utf8::validate(b"\xE2\x98a"));
+        assert_eq!(Err(utf8e2(1, 2)), utf8::validate(b"a\xE2\x98a"));
+        assert_eq!(
+            Err(utf8e2(3, 2)),
+            utf8::validate(b"\xE2\x98\x83\xE2\x98\xE2\x98\x83",)
+        );
+        // Check that an incomplete 4-byte sequence fails.
+        assert_eq!(Err(utf8e2(0, 3)), utf8::validate(b"\xF0\x9D\x9Ca"));
+        assert_eq!(Err(utf8e2(1, 3)), utf8::validate(b"a\xF0\x9D\x9Ca"));
+        assert_eq!(
+            Err(utf8e2(4, 3)),
+            utf8::validate(b"\xF0\x9D\x9C\xB1\xF0\x9D\x9C\xE2\x98\x83",)
+        );
+        assert_eq!(
+            Err(utf8e2(6, 3)),
+            utf8::validate(b"foobar\xF1\x80\x80quux",)
+        );
+
+        // Check that an incomplete (EOF) 2-byte sequence fails.
+        assert_eq!(Err(utf8e(0)), utf8::validate(b"\xCE"));
+        assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xCE"));
+        assert_eq!(Err(utf8e(3)), utf8::validate(b"\xE2\x98\x83\xCE"));
+        // Check that an incomplete (EOF) 3-byte sequence fails.
+        assert_eq!(Err(utf8e(0)), utf8::validate(b"\xE2\x98"));
+        assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xE2\x98"));
+        assert_eq!(Err(utf8e(3)), utf8::validate(b"\xE2\x98\x83\xE2\x98"));
+        // Check that an incomplete (EOF) 4-byte sequence fails.
+        assert_eq!(Err(utf8e(0)), utf8::validate(b"\xF0\x9D\x9C"));
+        assert_eq!(Err(utf8e(1)), utf8::validate(b"a\xF0\x9D\x9C"));
+        assert_eq!(
+            Err(utf8e(4)),
+            utf8::validate(b"\xF0\x9D\x9C\xB1\xF0\x9D\x9C",)
+        );
+
+        // Test that we errors correct even after long valid sequences. This
+        // checks that our "backup" logic for detecting errors is correct.
+        assert_eq!(
+            Err(utf8e2(8, 1)),
+            utf8::validate(b"\xe2\x98\x83\xce\xb2\xe3\x83\x84\xFF",)
+        );
+    }
+
+    #[test]
+    fn decode_valid() {
+        fn d(mut s: &str) -> Vec<char> {
+            let mut chars = vec![];
+            while !s.is_empty() {
+                let (ch, size) = utf8::decode(s.as_bytes());
+                s = &s[size..];
+                chars.push(ch.unwrap());
+            }
+            chars
+        }
+
+        assert_eq!(vec!['☃'], d("☃"));
+        assert_eq!(vec!['☃', '☃'], d("☃☃"));
+        assert_eq!(vec!['α', 'β', 'γ', 'δ', 'ε'], d("αβγδε"));
+        assert_eq!(vec!['☃', '⛄', '⛇'], d("☃⛄⛇"));
+        assert_eq!(vec!['𝗮', '𝗯', '𝗰', '𝗱', '𝗲'], d("𝗮𝗯𝗰𝗱𝗲"));
+    }
+
+    #[test]
+    fn decode_invalid() {
+        let (ch, size) = utf8::decode(b"");
+        assert_eq!(None, ch);
+        assert_eq!(0, size);
+
+        let (ch, size) = utf8::decode(b"\xFF");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode(b"\xCE\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode(b"\xE2\x98\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode(b"\xF0\x9D\x9D");
+        assert_eq!(None, ch);
+        assert_eq!(3, size);
+
+        let (ch, size) = utf8::decode(b"\xF0\x9D\x9D\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(3, size);
+
+        let (ch, size) = utf8::decode(b"\xF0\x82\x82\xAC");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode(b"\xED\xA0\x80");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode(b"\xCEa");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode(b"\xE2\x98a");
+        assert_eq!(None, ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode(b"\xF0\x9D\x9Ca");
+        assert_eq!(None, ch);
+        assert_eq!(3, size);
+    }
+
+    #[test]
+    fn decode_lossy() {
+        let (ch, size) = utf8::decode_lossy(b"");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(0, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xFF");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xCE\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xE2\x98\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xF0\x9D\x9D\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(3, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xF0\x82\x82\xAC");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xED\xA0\x80");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xCEa");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xE2\x98a");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_lossy(b"\xF0\x9D\x9Ca");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(3, size);
+    }
+
+    #[test]
+    fn decode_last_valid() {
+        fn d(mut s: &str) -> Vec<char> {
+            let mut chars = vec![];
+            while !s.is_empty() {
+                let (ch, size) = utf8::decode_last(s.as_bytes());
+                s = &s[..s.len() - size];
+                chars.push(ch.unwrap());
+            }
+            chars
+        }
+
+        assert_eq!(vec!['☃'], d("☃"));
+        assert_eq!(vec!['☃', '☃'], d("☃☃"));
+        assert_eq!(vec!['ε', 'δ', 'γ', 'β', 'α'], d("αβγδε"));
+        assert_eq!(vec!['⛇', '⛄', '☃'], d("☃⛄⛇"));
+        assert_eq!(vec!['𝗲', '𝗱', '𝗰', '𝗯', '𝗮'], d("𝗮𝗯𝗰𝗱𝗲"));
+    }
+
+    #[test]
+    fn decode_last_invalid() {
+        let (ch, size) = utf8::decode_last(b"");
+        assert_eq!(None, ch);
+        assert_eq!(0, size);
+
+        let (ch, size) = utf8::decode_last(b"\xFF");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xCE\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xCE");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xE2\x98\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xE2\x98");
+        assert_eq!(None, ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_last(b"\xF0\x9D\x9D\xF0");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xF0\x9D\x9D");
+        assert_eq!(None, ch);
+        assert_eq!(3, size);
+
+        let (ch, size) = utf8::decode_last(b"\xF0\x82\x82\xAC");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xED\xA0\x80");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xED\xA0");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"\xED");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"a\xCE");
+        assert_eq!(None, ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last(b"a\xE2\x98");
+        assert_eq!(None, ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_last(b"a\xF0\x9D\x9C");
+        assert_eq!(None, ch);
+        assert_eq!(3, size);
+    }
+
+    #[test]
+    fn decode_last_lossy() {
+        let (ch, size) = utf8::decode_last_lossy(b"");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(0, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xFF");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xCE\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xCE");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xE2\x98\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xE2\x98");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xF0\x9D\x9D\xF0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xF0\x9D\x9D");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(3, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xF0\x82\x82\xAC");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xED\xA0\x80");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xED\xA0");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"\xED");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"a\xCE");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(1, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"a\xE2\x98");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(2, size);
+
+        let (ch, size) = utf8::decode_last_lossy(b"a\xF0\x9D\x9C");
+        assert_eq!('\u{FFFD}', ch);
+        assert_eq!(3, size);
+    }
+
+    #[test]
+    fn chars() {
+        for (i, &(expected, input)) in LOSSY_TESTS.iter().enumerate() {
+            let got: String = B(input).chars().collect();
+            assert_eq!(
+                expected, got,
+                "chars(ith: {:?}, given: {:?})",
+                i, input,
+            );
+            let got: String =
+                B(input).char_indices().map(|(_, _, ch)| ch).collect();
+            assert_eq!(
+                expected, got,
+                "char_indices(ith: {:?}, given: {:?})",
+                i, input,
+            );
+
+            let expected: String = expected.chars().rev().collect();
+
+            let got: String = B(input).chars().rev().collect();
+            assert_eq!(
+                expected, got,
+                "chars.rev(ith: {:?}, given: {:?})",
+                i, input,
+            );
+            let got: String =
+                B(input).char_indices().rev().map(|(_, _, ch)| ch).collect();
+            assert_eq!(
+                expected, got,
+                "char_indices.rev(ith: {:?}, given: {:?})",
+                i, input,
+            );
+        }
+    }
+
+    #[test]
+    fn utf8_chunks() {
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xC0" };
+        assert_eq!(
+            (c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xC0".as_bstr(),
+                    incomplete: false,
+                }),
+                None,
+            )
+        );
+
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xFF\xFF" };
+        assert_eq!(
+            (c.next(), c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xFF".as_bstr(),
+                    incomplete: false,
+                }),
+                Some(utf8::Utf8Chunk {
+                    valid: "",
+                    invalid: b"\xFF".as_bstr(),
+                    incomplete: false,
+                }),
+                None,
+            )
+        );
+
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xD0" };
+        assert_eq!(
+            (c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xD0".as_bstr(),
+                    incomplete: true,
+                }),
+                None,
+            )
+        );
+
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xD0456" };
+        assert_eq!(
+            (c.next(), c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xD0".as_bstr(),
+                    incomplete: false,
+                }),
+                Some(utf8::Utf8Chunk {
+                    valid: "456",
+                    invalid: b"".as_bstr(),
+                    incomplete: false,
+                }),
+                None,
+            )
+        );
+
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xE2\x98" };
+        assert_eq!(
+            (c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xE2\x98".as_bstr(),
+                    incomplete: true,
+                }),
+                None,
+            )
+        );
+
+        let mut c = utf8::Utf8Chunks { bytes: b"123\xF4\x8F\xBF" };
+        assert_eq!(
+            (c.next(), c.next()),
+            (
+                Some(utf8::Utf8Chunk {
+                    valid: "123",
+                    invalid: b"\xF4\x8F\xBF".as_bstr(),
+                    incomplete: true,
+                }),
+                None,
+            )
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/memchr.rs.html b/src/memchr/arch/all/memchr.rs.html new file mode 100644 index 000000000..4830dbd73 --- /dev/null +++ b/src/memchr/arch/all/memchr.rs.html @@ -0,0 +1,1993 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+
/*!
+Provides architecture independent implementations of `memchr` and friends.
+
+The main types in this module are [`One`], [`Two`] and [`Three`]. They are for
+searching for one, two or three distinct bytes, respectively, in a haystack.
+Each type also has corresponding double ended iterators. These searchers
+are typically slower than hand-coded vector routines accomplishing the same
+task, but are also typically faster than naive scalar code. These routines
+effectively work by treating a `usize` as a vector of 8-bit lanes, and thus
+achieves some level of data parallelism even without explicit vector support.
+
+The `One` searcher also provides a [`One::count`] routine for efficiently
+counting the number of times a single byte occurs in a haystack. This is
+useful, for example, for counting the number of lines in a haystack. This
+routine exists because it is usually faster, especially with a high match
+count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its
+`Iterator::count` implementation to use this routine.)
+
+Only one, two and three bytes are supported because three bytes is about
+the point where one sees diminishing returns. Beyond this point and it's
+probably (but not necessarily) better to just use a simple `[bool; 256]` array
+or similar. However, it depends mightily on the specific work-load and the
+expected match frequency.
+*/
+
+use crate::{arch::generic::memchr as generic, ext::Pointer};
+
+/// The number of bytes in a single `usize` value.
+const USIZE_BYTES: usize = (usize::BITS / 8) as usize;
+/// The bits that must be zero for a `*const usize` to be properly aligned.
+const USIZE_ALIGN: usize = USIZE_BYTES - 1;
+
+/// Finds all occurrences of a single byte in a haystack.
+#[derive(Clone, Copy, Debug)]
+pub struct One {
+    s1: u8,
+    v1: usize,
+}
+
+impl One {
+    /// The number of bytes we examine per each iteration of our search loop.
+    const LOOP_BYTES: usize = 2 * USIZE_BYTES;
+
+    /// Create a new searcher that finds occurrences of the byte given.
+    #[inline]
+    pub fn new(needle: u8) -> One {
+        One { s1: needle, v1: splat(needle) }
+    }
+
+    /// A test-only routine so that we can bundle a bunch of quickcheck
+    /// properties into a single macro. Basically, this provides a constructor
+    /// that makes it identical to most other memchr implementations, which
+    /// have fallible constructors.
+    #[cfg(test)]
+    pub(crate) fn try_new(needle: u8) -> Option<One> {
+        Some(One::new(needle))
+    }
+
+    /// Return the first occurrence of the needle in the given haystack. If no
+    /// such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of the needle in the given haystack. If no
+    /// such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Counts all occurrences of this byte in the given haystack.
+    #[inline]
+    pub fn count(&self, haystack: &[u8]) -> usize {
+        // SAFETY: All of our pointers are derived directly from a borrowed
+        // slice, which is guaranteed to be valid.
+        unsafe {
+            let start = haystack.as_ptr();
+            let end = start.add(haystack.len());
+            self.count_raw(start, end)
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // The start of the search may not be aligned to `*const usize`,
+        // so we do an unaligned load here.
+        let chunk = start.cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // And now we start our search at a guaranteed aligned position.
+        // The first iteration of the loop below will overlap with the the
+        // unaligned chunk above in cases where the search starts at an
+        // unaligned offset, but that's okay as we're only here if that
+        // above didn't find a match.
+        let mut cur =
+            start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN));
+        debug_assert!(cur > start);
+        if len <= One::LOOP_BYTES {
+            return generic::fwd_byte_by_byte(cur, end, confirm);
+        }
+        debug_assert!(end.sub(One::LOOP_BYTES) >= start);
+        while cur <= end.sub(One::LOOP_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let a = cur.cast::<usize>().read();
+            let b = cur.add(USIZE_BYTES).cast::<usize>().read();
+            if self.has_needle(a) || self.has_needle(b) {
+                break;
+            }
+            cur = cur.add(One::LOOP_BYTES);
+        }
+        generic::fwd_byte_by_byte(cur, end, confirm)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let chunk = end.sub(USIZE_BYTES).cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let mut cur = end.sub(end.as_usize() & USIZE_ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        if len <= One::LOOP_BYTES {
+            return generic::rev_byte_by_byte(start, cur, confirm);
+        }
+        while cur >= start.add(One::LOOP_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let a = cur.sub(2 * USIZE_BYTES).cast::<usize>().read();
+            let b = cur.sub(1 * USIZE_BYTES).cast::<usize>().read();
+            if self.has_needle(a) || self.has_needle(b) {
+                break;
+            }
+            cur = cur.sub(One::LOOP_BYTES);
+        }
+        generic::rev_byte_by_byte(start, cur, confirm)
+    }
+
+    /// Counts all occurrences of this byte in the given haystack represented
+    /// by raw pointers.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `0` will always be returned.
+    #[inline]
+    pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize {
+        if start >= end {
+            return 0;
+        }
+        // Sadly I couldn't get the SWAR approach to work here, so we just do
+        // one byte at a time for now. PRs to improve this are welcome.
+        let mut ptr = start;
+        let mut count = 0;
+        while ptr < end {
+            count += (ptr.read() == self.s1) as usize;
+            ptr = ptr.offset(1);
+        }
+        count
+    }
+
+    /// Returns an iterator over all occurrences of the needle byte in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> {
+        OneIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+
+    #[inline(always)]
+    fn has_needle(&self, chunk: usize) -> bool {
+        has_zero_byte(self.v1 ^ chunk)
+    }
+
+    #[inline(always)]
+    fn confirm(&self, haystack_byte: u8) -> bool {
+        self.s1 == haystack_byte
+    }
+}
+
+/// An iterator over all occurrences of a single byte in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`One::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`One`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct OneIter<'a, 'h> {
+    /// The underlying memchr searcher.
+    searcher: &'a One,
+    /// Generic iterator implementation.
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for OneIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.it.count(|s, e| {
+            // SAFETY: We rely on our generic iterator to return valid start
+            // and end pointers.
+            unsafe { self.searcher.count_raw(s, e) }
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+/// Finds all occurrences of two bytes in a haystack.
+///
+/// That is, this reports matches of one of two possible bytes. For example,
+/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`,
+/// `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Two {
+    s1: u8,
+    s2: u8,
+    v1: usize,
+    v2: usize,
+}
+
+impl Two {
+    /// Create a new searcher that finds occurrences of the two needle bytes
+    /// given.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8) -> Two {
+        Two {
+            s1: needle1,
+            s2: needle2,
+            v1: splat(needle1),
+            v2: splat(needle2),
+        }
+    }
+
+    /// A test-only routine so that we can bundle a bunch of quickcheck
+    /// properties into a single macro. Basically, this provides a constructor
+    /// that makes it identical to most other memchr implementations, which
+    /// have fallible constructors.
+    #[cfg(test)]
+    pub(crate) fn try_new(needle1: u8, needle2: u8) -> Option<Two> {
+        Some(Two::new(needle1, needle2))
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // The start of the search may not be aligned to `*const usize`,
+        // so we do an unaligned load here.
+        let chunk = start.cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // And now we start our search at a guaranteed aligned position.
+        // The first iteration of the loop below will overlap with the the
+        // unaligned chunk above in cases where the search starts at an
+        // unaligned offset, but that's okay as we're only here if that
+        // above didn't find a match.
+        let mut cur =
+            start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN));
+        debug_assert!(cur > start);
+        debug_assert!(end.sub(USIZE_BYTES) >= start);
+        while cur <= end.sub(USIZE_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let chunk = cur.cast::<usize>().read();
+            if self.has_needle(chunk) {
+                break;
+            }
+            cur = cur.add(USIZE_BYTES);
+        }
+        generic::fwd_byte_by_byte(cur, end, confirm)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let chunk = end.sub(USIZE_BYTES).cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let mut cur = end.sub(end.as_usize() & USIZE_ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        while cur >= start.add(USIZE_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let chunk = cur.sub(USIZE_BYTES).cast::<usize>().read();
+            if self.has_needle(chunk) {
+                break;
+            }
+            cur = cur.sub(USIZE_BYTES);
+        }
+        generic::rev_byte_by_byte(start, cur, confirm)
+    }
+
+    /// Returns an iterator over all occurrences of one of the needle bytes in
+    /// the given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> {
+        TwoIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+
+    #[inline(always)]
+    fn has_needle(&self, chunk: usize) -> bool {
+        has_zero_byte(self.v1 ^ chunk) || has_zero_byte(self.v2 ^ chunk)
+    }
+
+    #[inline(always)]
+    fn confirm(&self, haystack_byte: u8) -> bool {
+        self.s1 == haystack_byte || self.s2 == haystack_byte
+    }
+}
+
+/// An iterator over all occurrences of two possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Two::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Two`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct TwoIter<'a, 'h> {
+    /// The underlying memchr searcher.
+    searcher: &'a Two,
+    /// Generic iterator implementation.
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for TwoIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+/// Finds all occurrences of three bytes in a haystack.
+///
+/// That is, this reports matches of one of three possible bytes. For example,
+/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets
+/// `0`, `2`, `3`, `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Three {
+    s1: u8,
+    s2: u8,
+    s3: u8,
+    v1: usize,
+    v2: usize,
+    v3: usize,
+}
+
+impl Three {
+    /// Create a new searcher that finds occurrences of the three needle bytes
+    /// given.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Three {
+        Three {
+            s1: needle1,
+            s2: needle2,
+            s3: needle3,
+            v1: splat(needle1),
+            v2: splat(needle2),
+            v3: splat(needle3),
+        }
+    }
+
+    /// A test-only routine so that we can bundle a bunch of quickcheck
+    /// properties into a single macro. Basically, this provides a constructor
+    /// that makes it identical to most other memchr implementations, which
+    /// have fallible constructors.
+    #[cfg(test)]
+    pub(crate) fn try_new(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+    ) -> Option<Three> {
+        Some(Three::new(needle1, needle2, needle3))
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value for a non-empty haystack is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // The start of the search may not be aligned to `*const usize`,
+        // so we do an unaligned load here.
+        let chunk = start.cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::fwd_byte_by_byte(start, end, confirm);
+        }
+
+        // And now we start our search at a guaranteed aligned position.
+        // The first iteration of the loop below will overlap with the the
+        // unaligned chunk above in cases where the search starts at an
+        // unaligned offset, but that's okay as we're only here if that
+        // above didn't find a match.
+        let mut cur =
+            start.add(USIZE_BYTES - (start.as_usize() & USIZE_ALIGN));
+        debug_assert!(cur > start);
+        debug_assert!(end.sub(USIZE_BYTES) >= start);
+        while cur <= end.sub(USIZE_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let chunk = cur.cast::<usize>().read();
+            if self.has_needle(chunk) {
+                break;
+            }
+            cur = cur.add(USIZE_BYTES);
+        }
+        generic::fwd_byte_by_byte(cur, end, confirm)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let confirm = |b| self.confirm(b);
+        let len = end.distance(start);
+        if len < USIZE_BYTES {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let chunk = end.sub(USIZE_BYTES).cast::<usize>().read_unaligned();
+        if self.has_needle(chunk) {
+            return generic::rev_byte_by_byte(start, end, confirm);
+        }
+
+        let mut cur = end.sub(end.as_usize() & USIZE_ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        while cur >= start.add(USIZE_BYTES) {
+            debug_assert_eq!(0, cur.as_usize() % USIZE_BYTES);
+
+            let chunk = cur.sub(USIZE_BYTES).cast::<usize>().read();
+            if self.has_needle(chunk) {
+                break;
+            }
+            cur = cur.sub(USIZE_BYTES);
+        }
+        generic::rev_byte_by_byte(start, cur, confirm)
+    }
+
+    /// Returns an iterator over all occurrences of one of the needle bytes in
+    /// the given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> {
+        ThreeIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+
+    #[inline(always)]
+    fn has_needle(&self, chunk: usize) -> bool {
+        has_zero_byte(self.v1 ^ chunk)
+            || has_zero_byte(self.v2 ^ chunk)
+            || has_zero_byte(self.v3 ^ chunk)
+    }
+
+    #[inline(always)]
+    fn confirm(&self, haystack_byte: u8) -> bool {
+        self.s1 == haystack_byte
+            || self.s2 == haystack_byte
+            || self.s3 == haystack_byte
+    }
+}
+
+/// An iterator over all occurrences of three possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Three::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Three`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct ThreeIter<'a, 'h> {
+    /// The underlying memchr searcher.
+    searcher: &'a Three,
+    /// Generic iterator implementation.
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for ThreeIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+/// Return `true` if `x` contains any zero byte.
+///
+/// That is, this routine treats `x` as a register of 8-bit lanes and returns
+/// true when any of those lanes is `0`.
+///
+/// From "Matters Computational" by J. Arndt.
+#[inline(always)]
+fn has_zero_byte(x: usize) -> bool {
+    // "The idea is to subtract one from each of the bytes and then look for
+    // bytes where the borrow propagated all the way to the most significant
+    // bit."
+    const LO: usize = splat(0x01);
+    const HI: usize = splat(0x80);
+
+    (x.wrapping_sub(LO) & !x & HI) != 0
+}
+
+/// Repeat the given byte into a word size number. That is, every 8 bits
+/// is equivalent to the given byte. For example, if `b` is `\x4E` or
+/// `01001110` in binary, then the returned value on a 32-bit system would be:
+/// `01001110_01001110_01001110_01001110`.
+#[inline(always)]
+const fn splat(b: u8) -> usize {
+    // TODO: use `usize::from` once it can be used in const context.
+    (b as usize) * (usize::MAX / 255)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_memchr_quickcheck!(super, try_new);
+
+    #[test]
+    fn forward_one() {
+        crate::tests::memchr::Runner::new(1).forward_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0]).iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_one() {
+        crate::tests::memchr::Runner::new(1).reverse_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0]).iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn count_one() {
+        crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| {
+            Some(One::new(needles[0]).iter(haystack).count())
+        })
+    }
+
+    #[test]
+    fn forward_two() {
+        crate::tests::memchr::Runner::new(2).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2).iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_two() {
+        crate::tests::memchr::Runner::new(2).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2).iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward_three() {
+        crate::tests::memchr::Runner::new(3).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3).iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_three() {
+        crate::tests::memchr::Runner::new(3).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3).iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    // This was found by quickcheck in the course of refactoring this crate
+    // after memchr 2.5.0.
+    #[test]
+    fn regression_double_ended_iterator() {
+        let finder = One::new(b'a');
+        let haystack = "a";
+        let mut it = finder.iter(haystack.as_bytes());
+        assert_eq!(Some(0), it.next());
+        assert_eq!(None, it.next_back());
+    }
+
+    // This regression test was caught by ripgrep's test suite on i686 when
+    // upgrading to memchr 2.6. Namely, something about the \x0B bytes here
+    // screws with the SWAR counting approach I was using. This regression test
+    // prompted me to remove the SWAR counting approach and just replace it
+    // with a byte-at-a-time loop.
+    #[test]
+    fn regression_count_new_lines() {
+        let haystack = "01234567\x0b\n\x0b\n\x0b\n\x0b\nx";
+        let count = One::new(b'\n').count(haystack.as_bytes());
+        assert_eq!(4, count);
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/mod.rs.html b/src/memchr/arch/all/mod.rs.html new file mode 100644 index 000000000..ab6bbe3f6 --- /dev/null +++ b/src/memchr/arch/all/mod.rs.html @@ -0,0 +1,473 @@ +mod.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+
/*!
+Contains architecture independent routines.
+
+These routines are often used as a "fallback" implementation when the more
+specialized architecture dependent routines are unavailable.
+*/
+
+pub mod memchr;
+pub mod packedpair;
+pub mod rabinkarp;
+#[cfg(feature = "alloc")]
+pub mod shiftor;
+pub mod twoway;
+
+/// Returns true if and only if `needle` is a prefix of `haystack`.
+///
+/// This uses a latency optimized variant of `memcmp` internally which *might*
+/// make this faster for very short strings.
+///
+/// # Inlining
+///
+/// This routine is marked `inline(always)`. If you want to call this function
+/// in a way that is not always inlined, you'll need to wrap a call to it in
+/// another function that is marked as `inline(never)` or just `inline`.
+#[inline(always)]
+pub fn is_prefix(haystack: &[u8], needle: &[u8]) -> bool {
+    needle.len() <= haystack.len()
+        && is_equal(&haystack[..needle.len()], needle)
+}
+
+/// Returns true if and only if `needle` is a suffix of `haystack`.
+///
+/// This uses a latency optimized variant of `memcmp` internally which *might*
+/// make this faster for very short strings.
+///
+/// # Inlining
+///
+/// This routine is marked `inline(always)`. If you want to call this function
+/// in a way that is not always inlined, you'll need to wrap a call to it in
+/// another function that is marked as `inline(never)` or just `inline`.
+#[inline(always)]
+pub fn is_suffix(haystack: &[u8], needle: &[u8]) -> bool {
+    needle.len() <= haystack.len()
+        && is_equal(&haystack[haystack.len() - needle.len()..], needle)
+}
+
+/// Compare corresponding bytes in `x` and `y` for equality.
+///
+/// That is, this returns true if and only if `x.len() == y.len()` and
+/// `x[i] == y[i]` for all `0 <= i < x.len()`.
+///
+/// # Inlining
+///
+/// This routine is marked `inline(always)`. If you want to call this function
+/// in a way that is not always inlined, you'll need to wrap a call to it in
+/// another function that is marked as `inline(never)` or just `inline`.
+///
+/// # Motivation
+///
+/// Why not use slice equality instead? Well, slice equality usually results in
+/// a call out to the current platform's `libc` which might not be inlineable
+/// or have other overhead. This routine isn't guaranteed to be a win, but it
+/// might be in some cases.
+#[inline(always)]
+pub fn is_equal(x: &[u8], y: &[u8]) -> bool {
+    if x.len() != y.len() {
+        return false;
+    }
+    // SAFETY: Our pointers are derived directly from borrowed slices which
+    // uphold all of our safety guarantees except for length. We account for
+    // length with the check above.
+    unsafe { is_equal_raw(x.as_ptr(), y.as_ptr(), x.len()) }
+}
+
+/// Compare `n` bytes at the given pointers for equality.
+///
+/// This returns true if and only if `*x.add(i) == *y.add(i)` for all
+/// `0 <= i < n`.
+///
+/// # Inlining
+///
+/// This routine is marked `inline(always)`. If you want to call this function
+/// in a way that is not always inlined, you'll need to wrap a call to it in
+/// another function that is marked as `inline(never)` or just `inline`.
+///
+/// # Motivation
+///
+/// Why not use slice equality instead? Well, slice equality usually results in
+/// a call out to the current platform's `libc` which might not be inlineable
+/// or have other overhead. This routine isn't guaranteed to be a win, but it
+/// might be in some cases.
+///
+/// # Safety
+///
+/// * Both `x` and `y` must be valid for reads of up to `n` bytes.
+/// * Both `x` and `y` must point to an initialized value.
+/// * Both `x` and `y` must each point to an allocated object and
+/// must either be in bounds or at most one byte past the end of the
+/// allocated object. `x` and `y` do not need to point to the same allocated
+/// object, but they may.
+/// * Both `x` and `y` must be _derived from_ a pointer to their respective
+/// allocated objects.
+/// * The distance between `x` and `x+n` must not overflow `isize`. Similarly
+/// for `y` and `y+n`.
+/// * The distance being in bounds must not rely on "wrapping around" the
+/// address space.
+#[inline(always)]
+pub unsafe fn is_equal_raw(
+    mut x: *const u8,
+    mut y: *const u8,
+    n: usize,
+) -> bool {
+    // If we don't have enough bytes to do 4-byte at a time loads, then
+    // handle each possible length specially. Note that I used to have a
+    // byte-at-a-time loop here and that turned out to be quite a bit slower
+    // for the memmem/pathological/defeat-simple-vector-alphabet benchmark.
+    if n < 4 {
+        return match n {
+            0 => true,
+            1 => x.read() == y.read(),
+            2 => {
+                x.cast::<u16>().read_unaligned()
+                    == y.cast::<u16>().read_unaligned()
+            }
+            // I also tried copy_nonoverlapping here and it looks like the
+            // codegen is the same.
+            3 => x.cast::<[u8; 3]>().read() == y.cast::<[u8; 3]>().read(),
+            _ => unreachable!(),
+        };
+    }
+    // When we have 4 or more bytes to compare, then proceed in chunks of 4 at
+    // a time using unaligned loads.
+    //
+    // Also, why do 4 byte loads instead of, say, 8 byte loads? The reason is
+    // that this particular version of memcmp is likely to be called with tiny
+    // needles. That means that if we do 8 byte loads, then a higher proportion
+    // of memcmp calls will use the slower variant above. With that said, this
+    // is a hypothesis and is only loosely supported by benchmarks. There's
+    // likely some improvement that could be made here. The main thing here
+    // though is to optimize for latency, not throughput.
+
+    // SAFETY: The caller is responsible for ensuring the pointers we get are
+    // valid and readable for at least `n` bytes. We also do unaligned loads,
+    // so there's no need to ensure we're aligned. (This is justified by this
+    // routine being specifically for short strings.)
+    let xend = x.add(n.wrapping_sub(4));
+    let yend = y.add(n.wrapping_sub(4));
+    while x < xend {
+        let vx = x.cast::<u32>().read_unaligned();
+        let vy = y.cast::<u32>().read_unaligned();
+        if vx != vy {
+            return false;
+        }
+        x = x.add(4);
+        y = y.add(4);
+    }
+    let vx = xend.cast::<u32>().read_unaligned();
+    let vy = yend.cast::<u32>().read_unaligned();
+    vx == vy
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn equals_different_lengths() {
+        assert!(!is_equal(b"", b"a"));
+        assert!(!is_equal(b"a", b""));
+        assert!(!is_equal(b"ab", b"a"));
+        assert!(!is_equal(b"a", b"ab"));
+    }
+
+    #[test]
+    fn equals_mismatch() {
+        let one_mismatch = [
+            (&b"a"[..], &b"x"[..]),
+            (&b"ab"[..], &b"ax"[..]),
+            (&b"abc"[..], &b"abx"[..]),
+            (&b"abcd"[..], &b"abcx"[..]),
+            (&b"abcde"[..], &b"abcdx"[..]),
+            (&b"abcdef"[..], &b"abcdex"[..]),
+            (&b"abcdefg"[..], &b"abcdefx"[..]),
+            (&b"abcdefgh"[..], &b"abcdefgx"[..]),
+            (&b"abcdefghi"[..], &b"abcdefghx"[..]),
+            (&b"abcdefghij"[..], &b"abcdefghix"[..]),
+            (&b"abcdefghijk"[..], &b"abcdefghijx"[..]),
+            (&b"abcdefghijkl"[..], &b"abcdefghijkx"[..]),
+            (&b"abcdefghijklm"[..], &b"abcdefghijklx"[..]),
+            (&b"abcdefghijklmn"[..], &b"abcdefghijklmx"[..]),
+        ];
+        for (x, y) in one_mismatch {
+            assert_eq!(x.len(), y.len(), "lengths should match");
+            assert!(!is_equal(x, y));
+            assert!(!is_equal(y, x));
+        }
+    }
+
+    #[test]
+    fn equals_yes() {
+        assert!(is_equal(b"", b""));
+        assert!(is_equal(b"a", b"a"));
+        assert!(is_equal(b"ab", b"ab"));
+        assert!(is_equal(b"abc", b"abc"));
+        assert!(is_equal(b"abcd", b"abcd"));
+        assert!(is_equal(b"abcde", b"abcde"));
+        assert!(is_equal(b"abcdef", b"abcdef"));
+        assert!(is_equal(b"abcdefg", b"abcdefg"));
+        assert!(is_equal(b"abcdefgh", b"abcdefgh"));
+        assert!(is_equal(b"abcdefghi", b"abcdefghi"));
+    }
+
+    #[test]
+    fn prefix() {
+        assert!(is_prefix(b"", b""));
+        assert!(is_prefix(b"a", b""));
+        assert!(is_prefix(b"ab", b""));
+        assert!(is_prefix(b"foo", b"foo"));
+        assert!(is_prefix(b"foobar", b"foo"));
+
+        assert!(!is_prefix(b"foo", b"fob"));
+        assert!(!is_prefix(b"foobar", b"fob"));
+    }
+
+    #[test]
+    fn suffix() {
+        assert!(is_suffix(b"", b""));
+        assert!(is_suffix(b"a", b""));
+        assert!(is_suffix(b"ab", b""));
+        assert!(is_suffix(b"foo", b"foo"));
+        assert!(is_suffix(b"foobar", b"bar"));
+
+        assert!(!is_suffix(b"foo", b"goo"));
+        assert!(!is_suffix(b"foobar", b"gar"));
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/packedpair/default_rank.rs.html b/src/memchr/arch/all/packedpair/default_rank.rs.html new file mode 100644 index 000000000..dbbf01ec2 --- /dev/null +++ b/src/memchr/arch/all/packedpair/default_rank.rs.html @@ -0,0 +1,517 @@ +default_rank.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+
pub(crate) const RANK: [u8; 256] = [
+    55,  // '\x00'
+    52,  // '\x01'
+    51,  // '\x02'
+    50,  // '\x03'
+    49,  // '\x04'
+    48,  // '\x05'
+    47,  // '\x06'
+    46,  // '\x07'
+    45,  // '\x08'
+    103, // '\t'
+    242, // '\n'
+    66,  // '\x0b'
+    67,  // '\x0c'
+    229, // '\r'
+    44,  // '\x0e'
+    43,  // '\x0f'
+    42,  // '\x10'
+    41,  // '\x11'
+    40,  // '\x12'
+    39,  // '\x13'
+    38,  // '\x14'
+    37,  // '\x15'
+    36,  // '\x16'
+    35,  // '\x17'
+    34,  // '\x18'
+    33,  // '\x19'
+    56,  // '\x1a'
+    32,  // '\x1b'
+    31,  // '\x1c'
+    30,  // '\x1d'
+    29,  // '\x1e'
+    28,  // '\x1f'
+    255, // ' '
+    148, // '!'
+    164, // '"'
+    149, // '#'
+    136, // '$'
+    160, // '%'
+    155, // '&'
+    173, // "'"
+    221, // '('
+    222, // ')'
+    134, // '*'
+    122, // '+'
+    232, // ','
+    202, // '-'
+    215, // '.'
+    224, // '/'
+    208, // '0'
+    220, // '1'
+    204, // '2'
+    187, // '3'
+    183, // '4'
+    179, // '5'
+    177, // '6'
+    168, // '7'
+    178, // '8'
+    200, // '9'
+    226, // ':'
+    195, // ';'
+    154, // '<'
+    184, // '='
+    174, // '>'
+    126, // '?'
+    120, // '@'
+    191, // 'A'
+    157, // 'B'
+    194, // 'C'
+    170, // 'D'
+    189, // 'E'
+    162, // 'F'
+    161, // 'G'
+    150, // 'H'
+    193, // 'I'
+    142, // 'J'
+    137, // 'K'
+    171, // 'L'
+    176, // 'M'
+    185, // 'N'
+    167, // 'O'
+    186, // 'P'
+    112, // 'Q'
+    175, // 'R'
+    192, // 'S'
+    188, // 'T'
+    156, // 'U'
+    140, // 'V'
+    143, // 'W'
+    123, // 'X'
+    133, // 'Y'
+    128, // 'Z'
+    147, // '['
+    138, // '\\'
+    146, // ']'
+    114, // '^'
+    223, // '_'
+    151, // '`'
+    249, // 'a'
+    216, // 'b'
+    238, // 'c'
+    236, // 'd'
+    253, // 'e'
+    227, // 'f'
+    218, // 'g'
+    230, // 'h'
+    247, // 'i'
+    135, // 'j'
+    180, // 'k'
+    241, // 'l'
+    233, // 'm'
+    246, // 'n'
+    244, // 'o'
+    231, // 'p'
+    139, // 'q'
+    245, // 'r'
+    243, // 's'
+    251, // 't'
+    235, // 'u'
+    201, // 'v'
+    196, // 'w'
+    240, // 'x'
+    214, // 'y'
+    152, // 'z'
+    182, // '{'
+    205, // '|'
+    181, // '}'
+    127, // '~'
+    27,  // '\x7f'
+    212, // '\x80'
+    211, // '\x81'
+    210, // '\x82'
+    213, // '\x83'
+    228, // '\x84'
+    197, // '\x85'
+    169, // '\x86'
+    159, // '\x87'
+    131, // '\x88'
+    172, // '\x89'
+    105, // '\x8a'
+    80,  // '\x8b'
+    98,  // '\x8c'
+    96,  // '\x8d'
+    97,  // '\x8e'
+    81,  // '\x8f'
+    207, // '\x90'
+    145, // '\x91'
+    116, // '\x92'
+    115, // '\x93'
+    144, // '\x94'
+    130, // '\x95'
+    153, // '\x96'
+    121, // '\x97'
+    107, // '\x98'
+    132, // '\x99'
+    109, // '\x9a'
+    110, // '\x9b'
+    124, // '\x9c'
+    111, // '\x9d'
+    82,  // '\x9e'
+    108, // '\x9f'
+    118, // '\xa0'
+    141, // '¡'
+    113, // '¢'
+    129, // '£'
+    119, // '¤'
+    125, // '¥'
+    165, // '¦'
+    117, // '§'
+    92,  // '¨'
+    106, // '©'
+    83,  // 'ª'
+    72,  // '«'
+    99,  // '¬'
+    93,  // '\xad'
+    65,  // '®'
+    79,  // '¯'
+    166, // '°'
+    237, // '±'
+    163, // '²'
+    199, // '³'
+    190, // '´'
+    225, // 'µ'
+    209, // '¶'
+    203, // '·'
+    198, // '¸'
+    217, // '¹'
+    219, // 'º'
+    206, // '»'
+    234, // '¼'
+    248, // '½'
+    158, // '¾'
+    239, // '¿'
+    255, // 'À'
+    255, // 'Á'
+    255, // 'Â'
+    255, // 'Ã'
+    255, // 'Ä'
+    255, // 'Å'
+    255, // 'Æ'
+    255, // 'Ç'
+    255, // 'È'
+    255, // 'É'
+    255, // 'Ê'
+    255, // 'Ë'
+    255, // 'Ì'
+    255, // 'Í'
+    255, // 'Î'
+    255, // 'Ï'
+    255, // 'Ð'
+    255, // 'Ñ'
+    255, // 'Ò'
+    255, // 'Ó'
+    255, // 'Ô'
+    255, // 'Õ'
+    255, // 'Ö'
+    255, // '×'
+    255, // 'Ø'
+    255, // 'Ù'
+    255, // 'Ú'
+    255, // 'Û'
+    255, // 'Ü'
+    255, // 'Ý'
+    255, // 'Þ'
+    255, // 'ß'
+    255, // 'à'
+    255, // 'á'
+    255, // 'â'
+    255, // 'ã'
+    255, // 'ä'
+    255, // 'å'
+    255, // 'æ'
+    255, // 'ç'
+    255, // 'è'
+    255, // 'é'
+    255, // 'ê'
+    255, // 'ë'
+    255, // 'ì'
+    255, // 'í'
+    255, // 'î'
+    255, // 'ï'
+    255, // 'ð'
+    255, // 'ñ'
+    255, // 'ò'
+    255, // 'ó'
+    255, // 'ô'
+    255, // 'õ'
+    255, // 'ö'
+    255, // '÷'
+    255, // 'ø'
+    255, // 'ù'
+    255, // 'ú'
+    255, // 'û'
+    255, // 'ü'
+    255, // 'ý'
+    255, // 'þ'
+    255, // 'ÿ'
+];
+
\ No newline at end of file diff --git a/src/memchr/arch/all/packedpair/mod.rs.html b/src/memchr/arch/all/packedpair/mod.rs.html new file mode 100644 index 000000000..03c4f1530 --- /dev/null +++ b/src/memchr/arch/all/packedpair/mod.rs.html @@ -0,0 +1,719 @@ +mod.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+
/*!
+Provides an architecture independent implementation of the "packed pair"
+algorithm.
+
+The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main
+difference is that it (by default) uses a background distribution of byte
+frequencies to heuristically select the pair of bytes to search for. Note that
+this module provides an architecture independent version that doesn't do as
+good of a job keeping the search for candidates inside a SIMD hot path. It
+however can be good enough in many circumstances.
+
+[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last
+*/
+
+use crate::memchr;
+
+mod default_rank;
+
+/// An architecture independent "packed pair" finder.
+///
+/// This finder picks two bytes that it believes have high predictive power for
+/// indicating an overall match of a needle. At search time, it reports offsets
+/// where the needle could match based on whether the pair of bytes it chose
+/// match.
+///
+/// This is architecture independent because it utilizes `memchr` to find the
+/// occurrence of one of the bytes in the pair, and then checks whether the
+/// second byte matches. If it does, in the case of [`Finder::find_prefilter`],
+/// the location at which the needle could match is returned.
+///
+/// It is generally preferred to use architecture specific routines for a
+/// "packed pair" prefilter, but this can be a useful fallback when the
+/// architecture independent routines are unavailable.
+#[derive(Clone, Copy, Debug)]
+pub struct Finder {
+    pair: Pair,
+    byte1: u8,
+    byte2: u8,
+}
+
+impl Finder {
+    /// Create a new prefilter that reports possible locations where the given
+    /// needle matches.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Option<Finder> {
+        Finder::with_pair(needle, Pair::new(needle)?)
+    }
+
+    /// Create a new prefilter using the pair given.
+    ///
+    /// If the prefilter could not be constructed, then `None` is returned.
+    ///
+    /// This constructor permits callers to control precisely which pair of
+    /// bytes is used as a predicate.
+    #[inline]
+    pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder> {
+        let byte1 = needle[usize::from(pair.index1())];
+        let byte2 = needle[usize::from(pair.index2())];
+        // Currently this can never fail so we could just return a Finder,
+        // but it's conceivable this could change.
+        Some(Finder { pair, byte1, byte2 })
+    }
+
+    /// Run this finder on the given haystack as a prefilter.
+    ///
+    /// If a candidate match is found, then an offset where the needle *could*
+    /// begin in the haystack is returned.
+    #[inline]
+    pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize> {
+        let mut i = 0;
+        let index1 = usize::from(self.pair.index1());
+        let index2 = usize::from(self.pair.index2());
+        loop {
+            // Use a fast vectorized implementation to skip to the next
+            // occurrence of the rarest byte (heuristically chosen) in the
+            // needle.
+            i += memchr(self.byte1, &haystack[i..])?;
+            let found = i;
+            i += 1;
+
+            // If we can't align our first byte match with the haystack, then a
+            // match is impossible.
+            let aligned1 = match found.checked_sub(index1) {
+                None => continue,
+                Some(aligned1) => aligned1,
+            };
+
+            // Now align the second byte match with the haystack. A mismatch
+            // means that a match is impossible.
+            let aligned2 = match aligned1.checked_add(index2) {
+                None => continue,
+                Some(aligned_index2) => aligned_index2,
+            };
+            if haystack.get(aligned2).map_or(true, |&b| b != self.byte2) {
+                continue;
+            }
+
+            // We've done what we can. There might be a match here.
+            return Some(aligned1);
+        }
+    }
+
+    /// Returns the pair of offsets (into the needle) used to check as a
+    /// predicate before confirming whether a needle exists at a particular
+    /// position.
+    #[inline]
+    pub fn pair(&self) -> &Pair {
+        &self.pair
+    }
+}
+
+/// A pair of byte offsets into a needle to use as a predicate.
+///
+/// This pair is used as a predicate to quickly filter out positions in a
+/// haystack in which a needle cannot match. In some cases, this pair can even
+/// be used in vector algorithms such that the vector algorithm only switches
+/// over to scalar code once this pair has been found.
+///
+/// A pair of offsets can be used in both substring search implementations and
+/// in prefilters. The former will report matches of a needle in a haystack
+/// where as the latter will only report possible matches of a needle.
+///
+/// The offsets are limited each to a maximum of 255 to keep memory usage low.
+/// Moreover, it's rarely advantageous to create a predicate using offsets
+/// greater than 255 anyway.
+///
+/// The only guarantee enforced on the pair of offsets is that they are not
+/// equivalent. It is not necessarily the case that `index1 < index2` for
+/// example. By convention, `index1` corresponds to the byte in the needle
+/// that is believed to be most the predictive. Note also that because of the
+/// requirement that the indices be both valid for the needle used to build
+/// the pair and not equal, it follows that a pair can only be constructed for
+/// needles with length at least 2.
+#[derive(Clone, Copy, Debug)]
+pub struct Pair {
+    index1: u8,
+    index2: u8,
+}
+
+impl Pair {
+    /// Create a new pair of offsets from the given needle.
+    ///
+    /// If a pair could not be created (for example, if the needle is too
+    /// short), then `None` is returned.
+    ///
+    /// This chooses the pair in the needle that is believed to be as
+    /// predictive of an overall match of the needle as possible.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Option<Pair> {
+        Pair::with_ranker(needle, DefaultFrequencyRank)
+    }
+
+    /// Create a new pair of offsets from the given needle and ranker.
+    ///
+    /// This permits the caller to choose a background frequency distribution
+    /// with which bytes are selected. The idea is to select a pair of bytes
+    /// that is believed to strongly predict a match in the haystack. This
+    /// usually means selecting bytes that occur rarely in a haystack.
+    ///
+    /// If a pair could not be created (for example, if the needle is too
+    /// short), then `None` is returned.
+    #[inline]
+    pub fn with_ranker<R: HeuristicFrequencyRank>(
+        needle: &[u8],
+        ranker: R,
+    ) -> Option<Pair> {
+        if needle.len() <= 1 {
+            return None;
+        }
+        // Find the rarest two bytes. We make them distinct indices by
+        // construction. (The actual byte value may be the same in degenerate
+        // cases, but that's OK.)
+        let (mut rare1, mut index1) = (needle[0], 0);
+        let (mut rare2, mut index2) = (needle[1], 1);
+        if ranker.rank(rare2) < ranker.rank(rare1) {
+            core::mem::swap(&mut rare1, &mut rare2);
+            core::mem::swap(&mut index1, &mut index2);
+        }
+        let max = usize::from(core::u8::MAX);
+        for (i, &b) in needle.iter().enumerate().take(max).skip(2) {
+            if ranker.rank(b) < ranker.rank(rare1) {
+                rare2 = rare1;
+                index2 = index1;
+                rare1 = b;
+                index1 = u8::try_from(i).unwrap();
+            } else if b != rare1 && ranker.rank(b) < ranker.rank(rare2) {
+                rare2 = b;
+                index2 = u8::try_from(i).unwrap();
+            }
+        }
+        // While not strictly required for how a Pair is normally used, we
+        // really don't want these to be equivalent. If they were, it would
+        // reduce the effectiveness of candidate searching using these rare
+        // bytes by increasing the rate of false positives.
+        assert_ne!(index1, index2);
+        Some(Pair { index1, index2 })
+    }
+
+    /// Create a new pair using the offsets given for the needle given.
+    ///
+    /// This bypasses any sort of heuristic process for choosing the offsets
+    /// and permits the caller to choose the offsets themselves.
+    ///
+    /// Indices are limited to valid `u8` values so that a `Pair` uses less
+    /// memory. It is not possible to create a `Pair` with offsets bigger than
+    /// `u8::MAX`. It's likely that such a thing is not needed, but if it is,
+    /// it's suggested to build your own bespoke algorithm because you're
+    /// likely working on a very niche case. (File an issue if this suggestion
+    /// does not make sense to you.)
+    ///
+    /// If a pair could not be created (for example, if the needle is too
+    /// short), then `None` is returned.
+    #[inline]
+    pub fn with_indices(
+        needle: &[u8],
+        index1: u8,
+        index2: u8,
+    ) -> Option<Pair> {
+        // While not strictly required for how a Pair is normally used, we
+        // really don't want these to be equivalent. If they were, it would
+        // reduce the effectiveness of candidate searching using these rare
+        // bytes by increasing the rate of false positives.
+        if index1 == index2 {
+            return None;
+        }
+        // Similarly, invalid indices means the Pair is invalid too.
+        if usize::from(index1) >= needle.len() {
+            return None;
+        }
+        if usize::from(index2) >= needle.len() {
+            return None;
+        }
+        Some(Pair { index1, index2 })
+    }
+
+    /// Returns the first offset of the pair.
+    #[inline]
+    pub fn index1(&self) -> u8 {
+        self.index1
+    }
+
+    /// Returns the second offset of the pair.
+    #[inline]
+    pub fn index2(&self) -> u8 {
+        self.index2
+    }
+}
+
+/// This trait allows the user to customize the heuristic used to determine the
+/// relative frequency of a given byte in the dataset being searched.
+///
+/// The use of this trait can have a dramatic impact on performance depending
+/// on the type of data being searched. The details of why are explained in the
+/// docs of [`crate::memmem::Prefilter`]. To summarize, the core algorithm uses
+/// a prefilter to quickly identify candidate matches that are later verified
+/// more slowly. This prefilter is implemented in terms of trying to find
+/// `rare` bytes at specific offsets that will occur less frequently in the
+/// dataset. While the concept of a `rare` byte is similar for most datasets,
+/// there are some specific datasets (like binary executables) that have
+/// dramatically different byte distributions. For these datasets customizing
+/// the byte frequency heuristic can have a massive impact on performance, and
+/// might even need to be done at runtime.
+///
+/// The default implementation of `HeuristicFrequencyRank` reads from the
+/// static frequency table defined in `src/memmem/byte_frequencies.rs`. This
+/// is optimal for most inputs, so if you are unsure of the impact of using a
+/// custom `HeuristicFrequencyRank` you should probably just use the default.
+///
+/// # Example
+///
+/// ```
+/// use memchr::{
+///     arch::all::packedpair::HeuristicFrequencyRank,
+///     memmem::FinderBuilder,
+/// };
+///
+/// /// A byte-frequency table that is good for scanning binary executables.
+/// struct Binary;
+///
+/// impl HeuristicFrequencyRank for Binary {
+///     fn rank(&self, byte: u8) -> u8 {
+///         const TABLE: [u8; 256] = [
+///             255, 128, 61, 43, 50, 41, 27, 28, 57, 15, 21, 13, 24, 17, 17,
+///             89, 58, 16, 11, 7, 14, 23, 7, 6, 24, 9, 6, 5, 9, 4, 7, 16,
+///             68, 11, 9, 6, 88, 7, 4, 4, 23, 9, 4, 8, 8, 5, 10, 4, 30, 11,
+///             9, 24, 11, 5, 5, 5, 19, 11, 6, 17, 9, 9, 6, 8,
+///             48, 58, 11, 14, 53, 40, 9, 9, 254, 35, 3, 6, 52, 23, 6, 6, 27,
+///             4, 7, 11, 14, 13, 10, 11, 11, 5, 2, 10, 16, 12, 6, 19,
+///             19, 20, 5, 14, 16, 31, 19, 7, 14, 20, 4, 4, 19, 8, 18, 20, 24,
+///             1, 25, 19, 58, 29, 10, 5, 15, 20, 2, 2, 9, 4, 3, 5,
+///             51, 11, 4, 53, 23, 39, 6, 4, 13, 81, 4, 186, 5, 67, 3, 2, 15,
+///             0, 0, 1, 3, 2, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0,
+///             12, 2, 1, 1, 3, 1, 1, 1, 6, 1, 2, 1, 3, 1, 1, 2, 9, 1, 1, 0,
+///             2, 2, 4, 4, 11, 6, 7, 3, 6, 9, 4, 5,
+///             46, 18, 8, 18, 17, 3, 8, 20, 16, 10, 3, 7, 175, 4, 6, 7, 13,
+///             3, 7, 3, 3, 1, 3, 3, 10, 3, 1, 5, 2, 0, 1, 2,
+///             16, 3, 5, 1, 6, 1, 1, 2, 58, 20, 3, 14, 12, 2, 1, 3, 16, 3, 5,
+///             8, 3, 1, 8, 6, 17, 6, 5, 3, 8, 6, 13, 175,
+///         ];
+///         TABLE[byte as usize]
+///     }
+/// }
+/// // Create a new finder with the custom heuristic.
+/// let finder = FinderBuilder::new()
+///     .build_forward_with_ranker(Binary, b"\x00\x00\xdd\xdd");
+/// // Find needle with custom heuristic.
+/// assert!(finder.find(b"\x00\x00\x00\xdd\xdd").is_some());
+/// ```
+pub trait HeuristicFrequencyRank {
+    /// Return the heuristic frequency rank of the given byte. A lower rank
+    /// means the byte is believed to occur less frequently in the haystack.
+    ///
+    /// Some uses of this heuristic may treat arbitrary absolute rank values as
+    /// significant. For example, an implementation detail in this crate may
+    /// determine that heuristic prefilters are inappropriate if every byte in
+    /// the needle has a "high" rank.
+    fn rank(&self, byte: u8) -> u8;
+}
+
+/// The default byte frequency heuristic that is good for most haystacks.
+pub(crate) struct DefaultFrequencyRank;
+
+impl HeuristicFrequencyRank for DefaultFrequencyRank {
+    fn rank(&self, byte: u8) -> u8 {
+        self::default_rank::RANK[usize::from(byte)]
+    }
+}
+
+/// This permits passing any implementation of `HeuristicFrequencyRank` as a
+/// borrowed version of itself.
+impl<'a, R> HeuristicFrequencyRank for &'a R
+where
+    R: HeuristicFrequencyRank,
+{
+    fn rank(&self, byte: u8) -> u8 {
+        (**self).rank(byte)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn forward_packedpair() {
+        fn find(
+            haystack: &[u8],
+            needle: &[u8],
+            _index1: u8,
+            _index2: u8,
+        ) -> Option<Option<usize>> {
+            // We ignore the index positions requested since it winds up making
+            // this test too slow overall.
+            let f = Finder::new(needle)?;
+            Some(f.find_prefilter(haystack))
+        }
+        crate::tests::packedpair::Runner::new().fwd(find).run()
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/rabinkarp.rs.html b/src/memchr/arch/all/rabinkarp.rs.html new file mode 100644 index 000000000..66543bc1e --- /dev/null +++ b/src/memchr/arch/all/rabinkarp.rs.html @@ -0,0 +1,781 @@ +rabinkarp.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+
/*!
+An implementation of the [Rabin-Karp substring search algorithm][rabinkarp].
+
+Rabin-Karp works by creating a hash of the needle provided and then computing
+a rolling hash for each needle sized window in the haystack. When the rolling
+hash matches the hash of the needle, a byte-wise comparison is done to check
+if a match exists. The worst case time complexity of Rabin-Karp is `O(m *
+n)` where `m ~ len(needle)` and `n ~ len(haystack)`. Its worst case space
+complexity is constant.
+
+The main utility of Rabin-Karp is that the searcher can be constructed very
+quickly with very little memory. This makes it especially useful when searching
+for small needles in small haystacks, as it might finish its search before a
+beefier algorithm (like Two-Way) even starts.
+
+[rabinkarp]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
+*/
+
+/*
+(This was the comment I wrote for this module originally when it was not
+exposed. The comment still looks useful, but it's a bit in the weeds, so it's
+not public itself.)
+
+This module implements the classical Rabin-Karp substring search algorithm,
+with no extra frills. While its use would seem to break our time complexity
+guarantee of O(m+n) (RK's time complexity is O(mn)), we are careful to only
+ever use RK on a constant subset of haystacks. The main point here is that
+RK has good latency properties for small needles/haystacks. It's very quick
+to compute a needle hash and zip through the haystack when compared to
+initializing Two-Way, for example. And this is especially useful for cases
+where the haystack is just too short for vector instructions to do much good.
+
+The hashing function used here is the same one recommended by ESMAJ.
+
+Another choice instead of Rabin-Karp would be Shift-Or. But its latency
+isn't quite as good since its preprocessing time is a bit more expensive
+(both in practice and in theory). However, perhaps Shift-Or has a place
+somewhere else for short patterns. I think the main problem is that it
+requires space proportional to the alphabet and the needle. If we, for
+example, supported needles up to length 16, then the total table size would be
+len(alphabet)*size_of::<u16>()==512 bytes. Which isn't exactly small, and it's
+probably bad to put that on the stack. So ideally, we'd throw it on the heap,
+but we'd really like to write as much code without using alloc/std as possible.
+But maybe it's worth the special casing. It's a TODO to benchmark.
+
+Wikipedia has a decent explanation, if a bit heavy on the theory:
+https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
+
+But ESMAJ provides something a bit more concrete:
+http://www-igm.univ-mlv.fr/~lecroq/string/node5.html
+
+Finally, aho-corasick uses Rabin-Karp for multiple pattern match in some cases:
+https://github.com/BurntSushi/aho-corasick/blob/3852632f10587db0ff72ef29e88d58bf305a0946/src/packed/rabinkarp.rs
+*/
+
+use crate::ext::Pointer;
+
+/// A forward substring searcher using the Rabin-Karp algorithm.
+///
+/// Note that, as a lower level API, a `Finder` does not have access to the
+/// needle it was constructed with. For this reason, executing a search
+/// with a `Finder` requires passing both the needle and the haystack,
+/// where the needle is exactly equivalent to the one given to the `Finder`
+/// at construction time. This design was chosen so that callers can have
+/// more precise control over where and how many times a needle is stored.
+/// For example, in cases where Rabin-Karp is just one of several possible
+/// substring search algorithms.
+#[derive(Clone, Debug)]
+pub struct Finder {
+    /// The actual hash.
+    hash: Hash,
+    /// The factor needed to multiply a byte by in order to subtract it from
+    /// the hash. It is defined to be 2^(n-1) (using wrapping exponentiation),
+    /// where n is the length of the needle. This is how we "remove" a byte
+    /// from the hash once the hash window rolls past it.
+    hash_2pow: u32,
+}
+
+impl Finder {
+    /// Create a new Rabin-Karp forward searcher for the given `needle`.
+    ///
+    /// The needle may be empty. The empty needle matches at every byte offset.
+    ///
+    /// Note that callers must pass the same needle to all search calls using
+    /// this `Finder`.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Finder {
+        let mut s = Finder { hash: Hash::new(), hash_2pow: 1 };
+        let first_byte = match needle.get(0) {
+            None => return s,
+            Some(&first_byte) => first_byte,
+        };
+        s.hash.add(first_byte);
+        for b in needle.iter().copied().skip(1) {
+            s.hash.add(b);
+            s.hash_2pow = s.hash_2pow.wrapping_shl(1);
+        }
+        s
+    }
+
+    /// Return the first occurrence of the `needle` in the `haystack`
+    /// given. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The `needle` provided must match the needle given to this finder at
+    /// construction time.
+    ///
+    /// The maximum value this can return is `haystack.len()`, which can only
+    /// occur when the needle and haystack both have length zero. Otherwise,
+    /// for non-empty haystacks, the maximum value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        unsafe {
+            let hstart = haystack.as_ptr();
+            let hend = hstart.add(haystack.len());
+            let nstart = needle.as_ptr();
+            let nend = nstart.add(needle.len());
+            let found = self.find_raw(hstart, hend, nstart, nend)?;
+            Some(found.distance(hstart))
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `<= end`. The pointer returned is only ever equivalent
+    /// to `end` when both the needle and haystack are empty. (That is, the
+    /// empty string matches the empty string.)
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// Note that `start` and `end` below refer to both pairs of pointers given
+    /// to this routine. That is, the conditions apply to both `hstart`/`hend`
+    /// and `nstart`/`nend`.
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    /// * It must be the case that `start <= end`.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        hstart: *const u8,
+        hend: *const u8,
+        nstart: *const u8,
+        nend: *const u8,
+    ) -> Option<*const u8> {
+        let hlen = hend.distance(hstart);
+        let nlen = nend.distance(nstart);
+        if nlen > hlen {
+            return None;
+        }
+        let mut cur = hstart;
+        let end = hend.sub(nlen);
+        let mut hash = Hash::forward(cur, cur.add(nlen));
+        loop {
+            if self.hash == hash && is_equal_raw(cur, nstart, nlen) {
+                return Some(cur);
+            }
+            if cur >= end {
+                return None;
+            }
+            hash.roll(self, cur.read(), cur.add(nlen).read());
+            cur = cur.add(1);
+        }
+    }
+}
+
+/// A reverse substring searcher using the Rabin-Karp algorithm.
+#[derive(Clone, Debug)]
+pub struct FinderRev(Finder);
+
+impl FinderRev {
+    /// Create a new Rabin-Karp reverse searcher for the given `needle`.
+    #[inline]
+    pub fn new(needle: &[u8]) -> FinderRev {
+        let mut s = FinderRev(Finder { hash: Hash::new(), hash_2pow: 1 });
+        let last_byte = match needle.last() {
+            None => return s,
+            Some(&last_byte) => last_byte,
+        };
+        s.0.hash.add(last_byte);
+        for b in needle.iter().rev().copied().skip(1) {
+            s.0.hash.add(b);
+            s.0.hash_2pow = s.0.hash_2pow.wrapping_shl(1);
+        }
+        s
+    }
+
+    /// Return the last occurrence of the `needle` in the `haystack`
+    /// given. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The `needle` provided must match the needle given to this finder at
+    /// construction time.
+    ///
+    /// The maximum value this can return is `haystack.len()`, which can only
+    /// occur when the needle and haystack both have length zero. Otherwise,
+    /// for non-empty haystacks, the maximum value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        unsafe {
+            let hstart = haystack.as_ptr();
+            let hend = hstart.add(haystack.len());
+            let nstart = needle.as_ptr();
+            let nend = nstart.add(needle.len());
+            let found = self.rfind_raw(hstart, hend, nstart, nend)?;
+            Some(found.distance(hstart))
+        }
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `<= end`. The pointer returned is only ever equivalent
+    /// to `end` when both the needle and haystack are empty. (That is, the
+    /// empty string matches the empty string.)
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// Note that `start` and `end` below refer to both pairs of pointers given
+    /// to this routine. That is, the conditions apply to both `hstart`/`hend`
+    /// and `nstart`/`nend`.
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    /// * It must be the case that `start <= end`.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        hstart: *const u8,
+        hend: *const u8,
+        nstart: *const u8,
+        nend: *const u8,
+    ) -> Option<*const u8> {
+        let hlen = hend.distance(hstart);
+        let nlen = nend.distance(nstart);
+        if nlen > hlen {
+            return None;
+        }
+        let mut cur = hend.sub(nlen);
+        let start = hstart;
+        let mut hash = Hash::reverse(cur, cur.add(nlen));
+        loop {
+            if self.0.hash == hash && is_equal_raw(cur, nstart, nlen) {
+                return Some(cur);
+            }
+            if cur <= start {
+                return None;
+            }
+            cur = cur.sub(1);
+            hash.roll(&self.0, cur.add(nlen).read(), cur.read());
+        }
+    }
+}
+
+/// Whether RK is believed to be very fast for the given needle/haystack.
+#[inline]
+pub(crate) fn is_fast(haystack: &[u8], _needle: &[u8]) -> bool {
+    haystack.len() < 16
+}
+
+/// A Rabin-Karp hash. This might represent the hash of a needle, or the hash
+/// of a rolling window in the haystack.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+struct Hash(u32);
+
+impl Hash {
+    /// Create a new hash that represents the empty string.
+    #[inline(always)]
+    fn new() -> Hash {
+        Hash(0)
+    }
+
+    /// Create a new hash from the bytes given for use in forward searches.
+    ///
+    /// # Safety
+    ///
+    /// The given pointers must be valid to read from within their range.
+    #[inline(always)]
+    unsafe fn forward(mut start: *const u8, end: *const u8) -> Hash {
+        let mut hash = Hash::new();
+        while start < end {
+            hash.add(start.read());
+            start = start.add(1);
+        }
+        hash
+    }
+
+    /// Create a new hash from the bytes given for use in reverse searches.
+    ///
+    /// # Safety
+    ///
+    /// The given pointers must be valid to read from within their range.
+    #[inline(always)]
+    unsafe fn reverse(start: *const u8, mut end: *const u8) -> Hash {
+        let mut hash = Hash::new();
+        while start < end {
+            end = end.sub(1);
+            hash.add(end.read());
+        }
+        hash
+    }
+
+    /// Add 'new' and remove 'old' from this hash. The given needle hash should
+    /// correspond to the hash computed for the needle being searched for.
+    ///
+    /// This is meant to be used when the rolling window of the haystack is
+    /// advanced.
+    #[inline(always)]
+    fn roll(&mut self, finder: &Finder, old: u8, new: u8) {
+        self.del(finder, old);
+        self.add(new);
+    }
+
+    /// Add a byte to this hash.
+    #[inline(always)]
+    fn add(&mut self, byte: u8) {
+        self.0 = self.0.wrapping_shl(1).wrapping_add(u32::from(byte));
+    }
+
+    /// Remove a byte from this hash. The given needle hash should correspond
+    /// to the hash computed for the needle being searched for.
+    #[inline(always)]
+    fn del(&mut self, finder: &Finder, byte: u8) {
+        let factor = finder.hash_2pow;
+        self.0 = self.0.wrapping_sub(u32::from(byte).wrapping_mul(factor));
+    }
+}
+
+/// Returns true when `x[i] == y[i]` for all `0 <= i < n`.
+///
+/// We forcefully don't inline this to hint at the compiler that it is unlikely
+/// to be called. This causes the inner rabinkarp loop above to be a bit
+/// tighter and leads to some performance improvement. See the
+/// memmem/krate/prebuilt/sliceslice-words/words benchmark.
+///
+/// # Safety
+///
+/// Same as `crate::arch::all::is_equal_raw`.
+#[cold]
+#[inline(never)]
+unsafe fn is_equal_raw(x: *const u8, y: *const u8, n: usize) -> bool {
+    crate::arch::all::is_equal_raw(x, y, n)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_substring_forward_quickcheck!(|h, n| Some(
+        Finder::new(n).find(h, n)
+    ));
+    define_substring_reverse_quickcheck!(|h, n| Some(
+        FinderRev::new(n).rfind(h, n)
+    ));
+
+    #[test]
+    fn forward() {
+        crate::tests::substring::Runner::new()
+            .fwd(|h, n| Some(Finder::new(n).find(h, n)))
+            .run();
+    }
+
+    #[test]
+    fn reverse() {
+        crate::tests::substring::Runner::new()
+            .rev(|h, n| Some(FinderRev::new(n).rfind(h, n)))
+            .run();
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/shiftor.rs.html b/src/memchr/arch/all/shiftor.rs.html new file mode 100644 index 000000000..7f3d90b7b --- /dev/null +++ b/src/memchr/arch/all/shiftor.rs.html @@ -0,0 +1,179 @@ +shiftor.rs - source
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
+
/*!
+An implementation of the [Shift-Or substring search algorithm][shiftor].
+
+[shiftor]: https://en.wikipedia.org/wiki/Bitap_algorithm
+*/
+
+use alloc::boxed::Box;
+
+/// The type of our mask.
+///
+/// While we don't expose anyway to configure this in the public API, if one
+/// really needs less memory usage or support for longer needles, then it is
+/// suggested to copy the code from this module and modify it to fit your
+/// needs. The code below is written to be correct regardless of whether Mask
+/// is a u8, u16, u32, u64 or u128.
+type Mask = u16;
+
+/// A forward substring searcher using the Shift-Or algorithm.
+#[derive(Debug)]
+pub struct Finder {
+    masks: Box<[Mask; 256]>,
+    needle_len: usize,
+}
+
+impl Finder {
+    const MAX_NEEDLE_LEN: usize = (Mask::BITS - 1) as usize;
+
+    /// Create a new Shift-Or forward searcher for the given `needle`.
+    ///
+    /// The needle may be empty. The empty needle matches at every byte offset.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Option<Finder> {
+        let needle_len = needle.len();
+        if needle_len > Finder::MAX_NEEDLE_LEN {
+            // A match is found when bit 7 is set in 'result' in the search
+            // routine below. So our needle can't be bigger than 7. We could
+            // permit bigger needles by using u16, u32 or u64 for our mask
+            // entries. But this is all we need for this example.
+            return None;
+        }
+        let mut searcher = Finder { masks: Box::from([!0; 256]), needle_len };
+        for (i, &byte) in needle.iter().enumerate() {
+            searcher.masks[usize::from(byte)] &= !(1 << i);
+        }
+        Some(searcher)
+    }
+
+    /// Return the first occurrence of the needle given to `Finder::new` in
+    /// the `haystack` given. If no such occurrence exists, then `None` is
+    /// returned.
+    ///
+    /// Unlike most other substring search implementations in this crate, this
+    /// finder does not require passing the needle at search time. A match can
+    /// be determined without the needle at all since the required information
+    /// is already encoded into this finder at construction time.
+    ///
+    /// The maximum value this can return is `haystack.len()`, which can only
+    /// occur when the needle and haystack both have length zero. Otherwise,
+    /// for non-empty haystacks, the maximum value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        if self.needle_len == 0 {
+            return Some(0);
+        }
+        let mut result = !1;
+        for (i, &byte) in haystack.iter().enumerate() {
+            result |= self.masks[usize::from(byte)];
+            result <<= 1;
+            if result & (1 << self.needle_len) == 0 {
+                return Some(i + 1 - self.needle_len);
+            }
+        }
+        None
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_substring_forward_quickcheck!(|h, n| Some(Finder::new(n)?.find(h)));
+
+    #[test]
+    fn forward() {
+        crate::tests::substring::Runner::new()
+            .fwd(|h, n| Some(Finder::new(n)?.find(h)))
+            .run();
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/all/twoway.rs.html b/src/memchr/arch/all/twoway.rs.html new file mode 100644 index 000000000..2d54925b7 --- /dev/null +++ b/src/memchr/arch/all/twoway.rs.html @@ -0,0 +1,1755 @@ +twoway.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+
/*!
+An implementation of the [Two-Way substring search algorithm][two-way].
+
+[`Finder`] can be built for forward searches, while [`FinderRev`] can be built
+for reverse searches.
+
+Two-Way makes for a nice general purpose substring search algorithm because of
+its time and space complexity properties. It also performs well in practice.
+Namely, with `m = len(needle)` and `n = len(haystack)`, Two-Way takes `O(m)`
+time to create a finder, `O(1)` space and `O(n)` search time. In other words,
+the preprocessing step is quick, doesn't require any heap memory and the worst
+case search time is guaranteed to be linear in the haystack regardless of the
+size of the needle.
+
+While vector algorithms will usually beat Two-Way handedly, vector algorithms
+also usually have pathological or edge cases that are better handled by Two-Way.
+Moreover, not all targets support vector algorithms or implementations for them
+simply may not exist yet.
+
+Two-Way can be found in the `memmem` implementations in at least [GNU libc] and
+[musl].
+
+[two-way]: https://en.wikipedia.org/wiki/Two-way_string-matching_algorithm
+[GNU libc]: https://www.gnu.org/software/libc/
+[musl]: https://www.musl-libc.org/
+*/
+
+use core::cmp;
+
+use crate::{
+    arch::all::{is_prefix, is_suffix},
+    memmem::Pre,
+};
+
+/// A forward substring searcher that uses the Two-Way algorithm.
+#[derive(Clone, Copy, Debug)]
+pub struct Finder(TwoWay);
+
+/// A reverse substring searcher that uses the Two-Way algorithm.
+#[derive(Clone, Copy, Debug)]
+pub struct FinderRev(TwoWay);
+
+/// An implementation of the TwoWay substring search algorithm.
+///
+/// This searcher supports forward and reverse search, although not
+/// simultaneously. It runs in `O(n + m)` time and `O(1)` space, where
+/// `n ~ len(needle)` and `m ~ len(haystack)`.
+///
+/// The implementation here roughly matches that which was developed by
+/// Crochemore and Perrin in their 1991 paper "Two-way string-matching." The
+/// changes in this implementation are 1) the use of zero-based indices, 2) a
+/// heuristic skip table based on the last byte (borrowed from Rust's standard
+/// library) and 3) the addition of heuristics for a fast skip loop. For (3),
+/// callers can pass any kind of prefilter they want, but usually it's one
+/// based on a heuristic that uses an approximate background frequency of bytes
+/// to choose rare bytes to quickly look for candidate match positions. Note
+/// though that currently, this prefilter functionality is not exposed directly
+/// in the public API. (File an issue if you want it and provide a use case
+/// please.)
+///
+/// The heuristic for fast skipping is automatically shut off if it's
+/// detected to be ineffective at search time. Generally, this only occurs in
+/// pathological cases. But this is generally necessary in order to preserve
+/// a `O(n + m)` time bound.
+///
+/// The code below is fairly complex and not obviously correct at all. It's
+/// likely necessary to read the Two-Way paper cited above in order to fully
+/// grok this code. The essence of it is:
+///
+/// 1. Do something to detect a "critical" position in the needle.
+/// 2. For the current position in the haystack, look if `needle[critical..]`
+/// matches at that position.
+/// 3. If so, look if `needle[..critical]` matches.
+/// 4. If a mismatch occurs, shift the search by some amount based on the
+/// critical position and a pre-computed shift.
+///
+/// This type is wrapped in the forward and reverse finders that expose
+/// consistent forward or reverse APIs.
+#[derive(Clone, Copy, Debug)]
+struct TwoWay {
+    /// A small bitset used as a quick prefilter (in addition to any prefilter
+    /// given by the caller). Namely, a bit `i` is set if and only if `b%64==i`
+    /// for any `b == needle[i]`.
+    ///
+    /// When used as a prefilter, if the last byte at the current candidate
+    /// position is NOT in this set, then we can skip that entire candidate
+    /// position (the length of the needle). This is essentially the shift
+    /// trick found in Boyer-Moore, but only applied to bytes that don't appear
+    /// in the needle.
+    ///
+    /// N.B. This trick was inspired by something similar in std's
+    /// implementation of Two-Way.
+    byteset: ApproximateByteSet,
+    /// A critical position in needle. Specifically, this position corresponds
+    /// to beginning of either the minimal or maximal suffix in needle. (N.B.
+    /// See SuffixType below for why "minimal" isn't quite the correct word
+    /// here.)
+    ///
+    /// This is the position at which every search begins. Namely, search
+    /// starts by scanning text to the right of this position, and only if
+    /// there's a match does the text to the left of this position get scanned.
+    critical_pos: usize,
+    /// The amount we shift by in the Two-Way search algorithm. This
+    /// corresponds to the "small period" and "large period" cases.
+    shift: Shift,
+}
+
+impl Finder {
+    /// Create a searcher that finds occurrences of the given `needle`.
+    ///
+    /// An empty `needle` results in a match at every position in a haystack,
+    /// including at `haystack.len()`.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Finder {
+        let byteset = ApproximateByteSet::new(needle);
+        let min_suffix = Suffix::forward(needle, SuffixKind::Minimal);
+        let max_suffix = Suffix::forward(needle, SuffixKind::Maximal);
+        let (period_lower_bound, critical_pos) =
+            if min_suffix.pos > max_suffix.pos {
+                (min_suffix.period, min_suffix.pos)
+            } else {
+                (max_suffix.period, max_suffix.pos)
+            };
+        let shift = Shift::forward(needle, period_lower_bound, critical_pos);
+        Finder(TwoWay { byteset, critical_pos, shift })
+    }
+
+    /// Returns the first occurrence of `needle` in the given `haystack`, or
+    /// `None` if no such occurrence could be found.
+    ///
+    /// The `needle` given must be the same as the `needle` provided to
+    /// [`Finder::new`].
+    ///
+    /// An empty `needle` results in a match at every position in a haystack,
+    /// including at `haystack.len()`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        self.find_with_prefilter(None, haystack, needle)
+    }
+
+    /// This is like [`Finder::find`], but it accepts a prefilter for
+    /// accelerating searches.
+    ///
+    /// Currently this is not exposed in the public API because, at the time
+    /// of writing, I didn't want to spend time thinking about how to expose
+    /// the prefilter infrastructure (if at all). If you have a compelling use
+    /// case for exposing this routine, please create an issue. Do *not* open
+    /// a PR that just exposes `Pre` and friends. Exporting this routine will
+    /// require API design.
+    #[inline(always)]
+    pub(crate) fn find_with_prefilter(
+        &self,
+        pre: Option<Pre<'_>>,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        match self.0.shift {
+            Shift::Small { period } => {
+                self.find_small_imp(pre, haystack, needle, period)
+            }
+            Shift::Large { shift } => {
+                self.find_large_imp(pre, haystack, needle, shift)
+            }
+        }
+    }
+
+    // Each of the two search implementations below can be accelerated by a
+    // prefilter, but it is not always enabled. To avoid its overhead when
+    // its disabled, we explicitly inline each search implementation based on
+    // whether a prefilter will be used or not. The decision on which to use
+    // is made in the parent meta searcher.
+
+    #[inline(always)]
+    fn find_small_imp(
+        &self,
+        mut pre: Option<Pre<'_>>,
+        haystack: &[u8],
+        needle: &[u8],
+        period: usize,
+    ) -> Option<usize> {
+        let mut pos = 0;
+        let mut shift = 0;
+        let last_byte_pos = match needle.len().checked_sub(1) {
+            None => return Some(pos),
+            Some(last_byte) => last_byte,
+        };
+        while pos + needle.len() <= haystack.len() {
+            let mut i = cmp::max(self.0.critical_pos, shift);
+            if let Some(pre) = pre.as_mut() {
+                if pre.is_effective() {
+                    pos += pre.find(&haystack[pos..])?;
+                    shift = 0;
+                    i = self.0.critical_pos;
+                    if pos + needle.len() > haystack.len() {
+                        return None;
+                    }
+                }
+            }
+            if !self.0.byteset.contains(haystack[pos + last_byte_pos]) {
+                pos += needle.len();
+                shift = 0;
+                continue;
+            }
+            while i < needle.len() && needle[i] == haystack[pos + i] {
+                i += 1;
+            }
+            if i < needle.len() {
+                pos += i - self.0.critical_pos + 1;
+                shift = 0;
+            } else {
+                let mut j = self.0.critical_pos;
+                while j > shift && needle[j] == haystack[pos + j] {
+                    j -= 1;
+                }
+                if j <= shift && needle[shift] == haystack[pos + shift] {
+                    return Some(pos);
+                }
+                pos += period;
+                shift = needle.len() - period;
+            }
+        }
+        None
+    }
+
+    #[inline(always)]
+    fn find_large_imp(
+        &self,
+        mut pre: Option<Pre<'_>>,
+        haystack: &[u8],
+        needle: &[u8],
+        shift: usize,
+    ) -> Option<usize> {
+        let mut pos = 0;
+        let last_byte_pos = match needle.len().checked_sub(1) {
+            None => return Some(pos),
+            Some(last_byte) => last_byte,
+        };
+        'outer: while pos + needle.len() <= haystack.len() {
+            if let Some(pre) = pre.as_mut() {
+                if pre.is_effective() {
+                    pos += pre.find(&haystack[pos..])?;
+                    if pos + needle.len() > haystack.len() {
+                        return None;
+                    }
+                }
+            }
+
+            if !self.0.byteset.contains(haystack[pos + last_byte_pos]) {
+                pos += needle.len();
+                continue;
+            }
+            let mut i = self.0.critical_pos;
+            while i < needle.len() && needle[i] == haystack[pos + i] {
+                i += 1;
+            }
+            if i < needle.len() {
+                pos += i - self.0.critical_pos + 1;
+            } else {
+                for j in (0..self.0.critical_pos).rev() {
+                    if needle[j] != haystack[pos + j] {
+                        pos += shift;
+                        continue 'outer;
+                    }
+                }
+                return Some(pos);
+            }
+        }
+        None
+    }
+}
+
+impl FinderRev {
+    /// Create a searcher that finds occurrences of the given `needle`.
+    ///
+    /// An empty `needle` results in a match at every position in a haystack,
+    /// including at `haystack.len()`.
+    #[inline]
+    pub fn new(needle: &[u8]) -> FinderRev {
+        let byteset = ApproximateByteSet::new(needle);
+        let min_suffix = Suffix::reverse(needle, SuffixKind::Minimal);
+        let max_suffix = Suffix::reverse(needle, SuffixKind::Maximal);
+        let (period_lower_bound, critical_pos) =
+            if min_suffix.pos < max_suffix.pos {
+                (min_suffix.period, min_suffix.pos)
+            } else {
+                (max_suffix.period, max_suffix.pos)
+            };
+        let shift = Shift::reverse(needle, period_lower_bound, critical_pos);
+        FinderRev(TwoWay { byteset, critical_pos, shift })
+    }
+
+    /// Returns the last occurrence of `needle` in the given `haystack`, or
+    /// `None` if no such occurrence could be found.
+    ///
+    /// The `needle` given must be the same as the `needle` provided to
+    /// [`FinderRev::new`].
+    ///
+    /// An empty `needle` results in a match at every position in a haystack,
+    /// including at `haystack.len()`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        // For the reverse case, we don't use a prefilter. It's plausible that
+        // perhaps we should, but it's a lot of additional code to do it, and
+        // it's not clear that it's actually worth it. If you have a really
+        // compelling use case for this, please file an issue.
+        match self.0.shift {
+            Shift::Small { period } => {
+                self.rfind_small_imp(haystack, needle, period)
+            }
+            Shift::Large { shift } => {
+                self.rfind_large_imp(haystack, needle, shift)
+            }
+        }
+    }
+
+    #[inline(always)]
+    fn rfind_small_imp(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+        period: usize,
+    ) -> Option<usize> {
+        let nlen = needle.len();
+        let mut pos = haystack.len();
+        let mut shift = nlen;
+        let first_byte = match needle.get(0) {
+            None => return Some(pos),
+            Some(&first_byte) => first_byte,
+        };
+        while pos >= nlen {
+            if !self.0.byteset.contains(haystack[pos - nlen]) {
+                pos -= nlen;
+                shift = nlen;
+                continue;
+            }
+            let mut i = cmp::min(self.0.critical_pos, shift);
+            while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] {
+                i -= 1;
+            }
+            if i > 0 || first_byte != haystack[pos - nlen] {
+                pos -= self.0.critical_pos - i + 1;
+                shift = nlen;
+            } else {
+                let mut j = self.0.critical_pos;
+                while j < shift && needle[j] == haystack[pos - nlen + j] {
+                    j += 1;
+                }
+                if j >= shift {
+                    return Some(pos - nlen);
+                }
+                pos -= period;
+                shift = period;
+            }
+        }
+        None
+    }
+
+    #[inline(always)]
+    fn rfind_large_imp(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+        shift: usize,
+    ) -> Option<usize> {
+        let nlen = needle.len();
+        let mut pos = haystack.len();
+        let first_byte = match needle.get(0) {
+            None => return Some(pos),
+            Some(&first_byte) => first_byte,
+        };
+        while pos >= nlen {
+            if !self.0.byteset.contains(haystack[pos - nlen]) {
+                pos -= nlen;
+                continue;
+            }
+            let mut i = self.0.critical_pos;
+            while i > 0 && needle[i - 1] == haystack[pos - nlen + i - 1] {
+                i -= 1;
+            }
+            if i > 0 || first_byte != haystack[pos - nlen] {
+                pos -= self.0.critical_pos - i + 1;
+            } else {
+                let mut j = self.0.critical_pos;
+                while j < nlen && needle[j] == haystack[pos - nlen + j] {
+                    j += 1;
+                }
+                if j == nlen {
+                    return Some(pos - nlen);
+                }
+                pos -= shift;
+            }
+        }
+        None
+    }
+}
+
+/// A representation of the amount we're allowed to shift by during Two-Way
+/// search.
+///
+/// When computing a critical factorization of the needle, we find the position
+/// of the critical factorization by finding the needle's maximal (or minimal)
+/// suffix, along with the period of that suffix. It turns out that the period
+/// of that suffix is a lower bound on the period of the needle itself.
+///
+/// This lower bound is equivalent to the actual period of the needle in
+/// some cases. To describe that case, we denote the needle as `x` where
+/// `x = uv` and `v` is the lexicographic maximal suffix of `v`. The lower
+/// bound given here is always the period of `v`, which is `<= period(x)`. The
+/// case where `period(v) == period(x)` occurs when `len(u) < (len(x) / 2)` and
+/// where `u` is a suffix of `v[0..period(v)]`.
+///
+/// This case is important because the search algorithm for when the
+/// periods are equivalent is slightly different than the search algorithm
+/// for when the periods are not equivalent. In particular, when they aren't
+/// equivalent, we know that the period of the needle is no less than half its
+/// length. In this case, we shift by an amount less than or equal to the
+/// period of the needle (determined by the maximum length of the components
+/// of the critical factorization of `x`, i.e., `max(len(u), len(v))`)..
+///
+/// The above two cases are represented by the variants below. Each entails
+/// a different instantiation of the Two-Way search algorithm.
+///
+/// N.B. If we could find a way to compute the exact period in all cases,
+/// then we could collapse this case analysis and simplify the algorithm. The
+/// Two-Way paper suggests this is possible, but more reading is required to
+/// grok why the authors didn't pursue that path.
+#[derive(Clone, Copy, Debug)]
+enum Shift {
+    Small { period: usize },
+    Large { shift: usize },
+}
+
+impl Shift {
+    /// Compute the shift for a given needle in the forward direction.
+    ///
+    /// This requires a lower bound on the period and a critical position.
+    /// These can be computed by extracting both the minimal and maximal
+    /// lexicographic suffixes, and choosing the right-most starting position.
+    /// The lower bound on the period is then the period of the chosen suffix.
+    fn forward(
+        needle: &[u8],
+        period_lower_bound: usize,
+        critical_pos: usize,
+    ) -> Shift {
+        let large = cmp::max(critical_pos, needle.len() - critical_pos);
+        if critical_pos * 2 >= needle.len() {
+            return Shift::Large { shift: large };
+        }
+
+        let (u, v) = needle.split_at(critical_pos);
+        if !is_suffix(&v[..period_lower_bound], u) {
+            return Shift::Large { shift: large };
+        }
+        Shift::Small { period: period_lower_bound }
+    }
+
+    /// Compute the shift for a given needle in the reverse direction.
+    ///
+    /// This requires a lower bound on the period and a critical position.
+    /// These can be computed by extracting both the minimal and maximal
+    /// lexicographic suffixes, and choosing the left-most starting position.
+    /// The lower bound on the period is then the period of the chosen suffix.
+    fn reverse(
+        needle: &[u8],
+        period_lower_bound: usize,
+        critical_pos: usize,
+    ) -> Shift {
+        let large = cmp::max(critical_pos, needle.len() - critical_pos);
+        if (needle.len() - critical_pos) * 2 >= needle.len() {
+            return Shift::Large { shift: large };
+        }
+
+        let (v, u) = needle.split_at(critical_pos);
+        if !is_prefix(&v[v.len() - period_lower_bound..], u) {
+            return Shift::Large { shift: large };
+        }
+        Shift::Small { period: period_lower_bound }
+    }
+}
+
+/// A suffix extracted from a needle along with its period.
+#[derive(Debug)]
+struct Suffix {
+    /// The starting position of this suffix.
+    ///
+    /// If this is a forward suffix, then `&bytes[pos..]` can be used. If this
+    /// is a reverse suffix, then `&bytes[..pos]` can be used. That is, for
+    /// forward suffixes, this is an inclusive starting position, where as for
+    /// reverse suffixes, this is an exclusive ending position.
+    pos: usize,
+    /// The period of this suffix.
+    ///
+    /// Note that this is NOT necessarily the period of the string from which
+    /// this suffix comes from. (It is always less than or equal to the period
+    /// of the original string.)
+    period: usize,
+}
+
+impl Suffix {
+    fn forward(needle: &[u8], kind: SuffixKind) -> Suffix {
+        // suffix represents our maximal (or minimal) suffix, along with
+        // its period.
+        let mut suffix = Suffix { pos: 0, period: 1 };
+        // The start of a suffix in `needle` that we are considering as a
+        // more maximal (or minimal) suffix than what's in `suffix`.
+        let mut candidate_start = 1;
+        // The current offset of our suffixes that we're comparing.
+        //
+        // When the characters at this offset are the same, then we mush on
+        // to the next position since no decision is possible. When the
+        // candidate's character is greater (or lesser) than the corresponding
+        // character than our current maximal (or minimal) suffix, then the
+        // current suffix is changed over to the candidate and we restart our
+        // search. Otherwise, the candidate suffix is no good and we restart
+        // our search on the next candidate.
+        //
+        // The three cases above correspond to the three cases in the loop
+        // below.
+        let mut offset = 0;
+
+        while candidate_start + offset < needle.len() {
+            let current = needle[suffix.pos + offset];
+            let candidate = needle[candidate_start + offset];
+            match kind.cmp(current, candidate) {
+                SuffixOrdering::Accept => {
+                    suffix = Suffix { pos: candidate_start, period: 1 };
+                    candidate_start += 1;
+                    offset = 0;
+                }
+                SuffixOrdering::Skip => {
+                    candidate_start += offset + 1;
+                    offset = 0;
+                    suffix.period = candidate_start - suffix.pos;
+                }
+                SuffixOrdering::Push => {
+                    if offset + 1 == suffix.period {
+                        candidate_start += suffix.period;
+                        offset = 0;
+                    } else {
+                        offset += 1;
+                    }
+                }
+            }
+        }
+        suffix
+    }
+
+    fn reverse(needle: &[u8], kind: SuffixKind) -> Suffix {
+        // See the comments in `forward` for how this works.
+        let mut suffix = Suffix { pos: needle.len(), period: 1 };
+        if needle.len() == 1 {
+            return suffix;
+        }
+        let mut candidate_start = match needle.len().checked_sub(1) {
+            None => return suffix,
+            Some(candidate_start) => candidate_start,
+        };
+        let mut offset = 0;
+
+        while offset < candidate_start {
+            let current = needle[suffix.pos - offset - 1];
+            let candidate = needle[candidate_start - offset - 1];
+            match kind.cmp(current, candidate) {
+                SuffixOrdering::Accept => {
+                    suffix = Suffix { pos: candidate_start, period: 1 };
+                    candidate_start -= 1;
+                    offset = 0;
+                }
+                SuffixOrdering::Skip => {
+                    candidate_start -= offset + 1;
+                    offset = 0;
+                    suffix.period = suffix.pos - candidate_start;
+                }
+                SuffixOrdering::Push => {
+                    if offset + 1 == suffix.period {
+                        candidate_start -= suffix.period;
+                        offset = 0;
+                    } else {
+                        offset += 1;
+                    }
+                }
+            }
+        }
+        suffix
+    }
+}
+
+/// The kind of suffix to extract.
+#[derive(Clone, Copy, Debug)]
+enum SuffixKind {
+    /// Extract the smallest lexicographic suffix from a string.
+    ///
+    /// Technically, this doesn't actually pick the smallest lexicographic
+    /// suffix. e.g., Given the choice between `a` and `aa`, this will choose
+    /// the latter over the former, even though `a < aa`. The reasoning for
+    /// this isn't clear from the paper, but it still smells like a minimal
+    /// suffix.
+    Minimal,
+    /// Extract the largest lexicographic suffix from a string.
+    ///
+    /// Unlike `Minimal`, this really does pick the maximum suffix. e.g., Given
+    /// the choice between `z` and `zz`, this will choose the latter over the
+    /// former.
+    Maximal,
+}
+
+/// The result of comparing corresponding bytes between two suffixes.
+#[derive(Clone, Copy, Debug)]
+enum SuffixOrdering {
+    /// This occurs when the given candidate byte indicates that the candidate
+    /// suffix is better than the current maximal (or minimal) suffix. That is,
+    /// the current candidate suffix should supplant the current maximal (or
+    /// minimal) suffix.
+    Accept,
+    /// This occurs when the given candidate byte excludes the candidate suffix
+    /// from being better than the current maximal (or minimal) suffix. That
+    /// is, the current candidate suffix should be dropped and the next one
+    /// should be considered.
+    Skip,
+    /// This occurs when no decision to accept or skip the candidate suffix
+    /// can be made, e.g., when corresponding bytes are equivalent. In this
+    /// case, the next corresponding bytes should be compared.
+    Push,
+}
+
+impl SuffixKind {
+    /// Returns true if and only if the given candidate byte indicates that
+    /// it should replace the current suffix as the maximal (or minimal)
+    /// suffix.
+    fn cmp(self, current: u8, candidate: u8) -> SuffixOrdering {
+        use self::SuffixOrdering::*;
+
+        match self {
+            SuffixKind::Minimal if candidate < current => Accept,
+            SuffixKind::Minimal if candidate > current => Skip,
+            SuffixKind::Minimal => Push,
+            SuffixKind::Maximal if candidate > current => Accept,
+            SuffixKind::Maximal if candidate < current => Skip,
+            SuffixKind::Maximal => Push,
+        }
+    }
+}
+
+/// A bitset used to track whether a particular byte exists in a needle or not.
+///
+/// Namely, bit 'i' is set if and only if byte%64==i for any byte in the
+/// needle. If a particular byte in the haystack is NOT in this set, then one
+/// can conclude that it is also not in the needle, and thus, one can advance
+/// in the haystack by needle.len() bytes.
+#[derive(Clone, Copy, Debug)]
+struct ApproximateByteSet(u64);
+
+impl ApproximateByteSet {
+    /// Create a new set from the given needle.
+    fn new(needle: &[u8]) -> ApproximateByteSet {
+        let mut bits = 0;
+        for &b in needle {
+            bits |= 1 << (b % 64);
+        }
+        ApproximateByteSet(bits)
+    }
+
+    /// Return true if and only if the given byte might be in this set. This
+    /// may return a false positive, but will never return a false negative.
+    #[inline(always)]
+    fn contains(&self, byte: u8) -> bool {
+        self.0 & (1 << (byte % 64)) != 0
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+
+    use super::*;
+
+    /// Convenience wrapper for computing the suffix as a byte string.
+    fn get_suffix_forward(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) {
+        let s = Suffix::forward(needle, kind);
+        (&needle[s.pos..], s.period)
+    }
+
+    /// Convenience wrapper for computing the reverse suffix as a byte string.
+    fn get_suffix_reverse(needle: &[u8], kind: SuffixKind) -> (&[u8], usize) {
+        let s = Suffix::reverse(needle, kind);
+        (&needle[..s.pos], s.period)
+    }
+
+    /// Return all of the non-empty suffixes in the given byte string.
+    fn suffixes(bytes: &[u8]) -> Vec<&[u8]> {
+        (0..bytes.len()).map(|i| &bytes[i..]).collect()
+    }
+
+    /// Return the lexicographically maximal suffix of the given byte string.
+    fn naive_maximal_suffix_forward(needle: &[u8]) -> &[u8] {
+        let mut sufs = suffixes(needle);
+        sufs.sort();
+        sufs.pop().unwrap()
+    }
+
+    /// Return the lexicographically maximal suffix of the reverse of the given
+    /// byte string.
+    fn naive_maximal_suffix_reverse(needle: &[u8]) -> Vec<u8> {
+        let mut reversed = needle.to_vec();
+        reversed.reverse();
+        let mut got = naive_maximal_suffix_forward(&reversed).to_vec();
+        got.reverse();
+        got
+    }
+
+    define_substring_forward_quickcheck!(|h, n| Some(
+        Finder::new(n).find(h, n)
+    ));
+    define_substring_reverse_quickcheck!(|h, n| Some(
+        FinderRev::new(n).rfind(h, n)
+    ));
+
+    #[test]
+    fn forward() {
+        crate::tests::substring::Runner::new()
+            .fwd(|h, n| Some(Finder::new(n).find(h, n)))
+            .run();
+    }
+
+    #[test]
+    fn reverse() {
+        crate::tests::substring::Runner::new()
+            .rev(|h, n| Some(FinderRev::new(n).rfind(h, n)))
+            .run();
+    }
+
+    #[test]
+    fn suffix_forward() {
+        macro_rules! assert_suffix_min {
+            ($given:expr, $expected:expr, $period:expr) => {
+                let (got_suffix, got_period) =
+                    get_suffix_forward($given.as_bytes(), SuffixKind::Minimal);
+                let got_suffix = core::str::from_utf8(got_suffix).unwrap();
+                assert_eq!(($expected, $period), (got_suffix, got_period));
+            };
+        }
+
+        macro_rules! assert_suffix_max {
+            ($given:expr, $expected:expr, $period:expr) => {
+                let (got_suffix, got_period) =
+                    get_suffix_forward($given.as_bytes(), SuffixKind::Maximal);
+                let got_suffix = core::str::from_utf8(got_suffix).unwrap();
+                assert_eq!(($expected, $period), (got_suffix, got_period));
+            };
+        }
+
+        assert_suffix_min!("a", "a", 1);
+        assert_suffix_max!("a", "a", 1);
+
+        assert_suffix_min!("ab", "ab", 2);
+        assert_suffix_max!("ab", "b", 1);
+
+        assert_suffix_min!("ba", "a", 1);
+        assert_suffix_max!("ba", "ba", 2);
+
+        assert_suffix_min!("abc", "abc", 3);
+        assert_suffix_max!("abc", "c", 1);
+
+        assert_suffix_min!("acb", "acb", 3);
+        assert_suffix_max!("acb", "cb", 2);
+
+        assert_suffix_min!("cba", "a", 1);
+        assert_suffix_max!("cba", "cba", 3);
+
+        assert_suffix_min!("abcabc", "abcabc", 3);
+        assert_suffix_max!("abcabc", "cabc", 3);
+
+        assert_suffix_min!("abcabcabc", "abcabcabc", 3);
+        assert_suffix_max!("abcabcabc", "cabcabc", 3);
+
+        assert_suffix_min!("abczz", "abczz", 5);
+        assert_suffix_max!("abczz", "zz", 1);
+
+        assert_suffix_min!("zzabc", "abc", 3);
+        assert_suffix_max!("zzabc", "zzabc", 5);
+
+        assert_suffix_min!("aaa", "aaa", 1);
+        assert_suffix_max!("aaa", "aaa", 1);
+
+        assert_suffix_min!("foobar", "ar", 2);
+        assert_suffix_max!("foobar", "r", 1);
+    }
+
+    #[test]
+    fn suffix_reverse() {
+        macro_rules! assert_suffix_min {
+            ($given:expr, $expected:expr, $period:expr) => {
+                let (got_suffix, got_period) =
+                    get_suffix_reverse($given.as_bytes(), SuffixKind::Minimal);
+                let got_suffix = core::str::from_utf8(got_suffix).unwrap();
+                assert_eq!(($expected, $period), (got_suffix, got_period));
+            };
+        }
+
+        macro_rules! assert_suffix_max {
+            ($given:expr, $expected:expr, $period:expr) => {
+                let (got_suffix, got_period) =
+                    get_suffix_reverse($given.as_bytes(), SuffixKind::Maximal);
+                let got_suffix = core::str::from_utf8(got_suffix).unwrap();
+                assert_eq!(($expected, $period), (got_suffix, got_period));
+            };
+        }
+
+        assert_suffix_min!("a", "a", 1);
+        assert_suffix_max!("a", "a", 1);
+
+        assert_suffix_min!("ab", "a", 1);
+        assert_suffix_max!("ab", "ab", 2);
+
+        assert_suffix_min!("ba", "ba", 2);
+        assert_suffix_max!("ba", "b", 1);
+
+        assert_suffix_min!("abc", "a", 1);
+        assert_suffix_max!("abc", "abc", 3);
+
+        assert_suffix_min!("acb", "a", 1);
+        assert_suffix_max!("acb", "ac", 2);
+
+        assert_suffix_min!("cba", "cba", 3);
+        assert_suffix_max!("cba", "c", 1);
+
+        assert_suffix_min!("abcabc", "abca", 3);
+        assert_suffix_max!("abcabc", "abcabc", 3);
+
+        assert_suffix_min!("abcabcabc", "abcabca", 3);
+        assert_suffix_max!("abcabcabc", "abcabcabc", 3);
+
+        assert_suffix_min!("abczz", "a", 1);
+        assert_suffix_max!("abczz", "abczz", 5);
+
+        assert_suffix_min!("zzabc", "zza", 3);
+        assert_suffix_max!("zzabc", "zz", 1);
+
+        assert_suffix_min!("aaa", "aaa", 1);
+        assert_suffix_max!("aaa", "aaa", 1);
+    }
+
+    #[cfg(not(miri))]
+    quickcheck::quickcheck! {
+        fn qc_suffix_forward_maximal(bytes: Vec<u8>) -> bool {
+            if bytes.is_empty() {
+                return true;
+            }
+
+            let (got, _) = get_suffix_forward(&bytes, SuffixKind::Maximal);
+            let expected = naive_maximal_suffix_forward(&bytes);
+            got == expected
+        }
+
+        fn qc_suffix_reverse_maximal(bytes: Vec<u8>) -> bool {
+            if bytes.is_empty() {
+                return true;
+            }
+
+            let (got, _) = get_suffix_reverse(&bytes, SuffixKind::Maximal);
+            let expected = naive_maximal_suffix_reverse(&bytes);
+            expected == got
+        }
+    }
+
+    // This is a regression test caught by quickcheck that exercised a bug in
+    // the reverse small period handling. The bug was that we were using 'if j
+    // == shift' to determine if a match occurred, but the correct guard is 'if
+    // j >= shift', which matches the corresponding guard in the forward impl.
+    #[test]
+    fn regression_rev_small_period() {
+        let rfind = |h, n| FinderRev::new(n).rfind(h, n);
+        let haystack = "ababaz";
+        let needle = "abab";
+        assert_eq!(Some(0), rfind(haystack.as_bytes(), needle.as_bytes()));
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/generic/memchr.rs.html b/src/memchr/arch/generic/memchr.rs.html new file mode 100644 index 000000000..5a4e05973 --- /dev/null +++ b/src/memchr/arch/generic/memchr.rs.html @@ -0,0 +1,2429 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+
/*!
+Generic crate-internal routines for the `memchr` family of functions.
+*/
+
+// What follows is a vector algorithm generic over the specific vector
+// type to detect the position of one, two or three needles in a haystack.
+// From what I know, this is a "classic" algorithm, although I don't
+// believe it has been published in any peer reviewed journal. I believe
+// it can be found in places like glibc and Go's standard library. It
+// appears to be well known and is elaborated on in more detail here:
+// https://gms.tf/stdfind-and-memchr-optimizations.html
+//
+// While the routine below is fairly long and perhaps intimidating, the basic
+// idea is actually very simple and can be expressed straight-forwardly in
+// pseudo code. The psuedo code below is written for 128 bit vectors, but the
+// actual code below works for anything that implements the Vector trait.
+//
+//     needle = (n1 << 15) | (n1 << 14) | ... | (n1 << 1) | n1
+//     // Note: shift amount is in bytes
+//
+//     while i <= haystack.len() - 16:
+//       // A 16 byte vector. Each byte in chunk corresponds to a byte in
+//       // the haystack.
+//       chunk = haystack[i:i+16]
+//       // Compare bytes in needle with bytes in chunk. The result is a 16
+//       // byte chunk where each byte is 0xFF if the corresponding bytes
+//       // in needle and chunk were equal, or 0x00 otherwise.
+//       eqs = cmpeq(needle, chunk)
+//       // Return a 32 bit integer where the most significant 16 bits
+//       // are always 0 and the lower 16 bits correspond to whether the
+//       // most significant bit in the correspond byte in `eqs` is set.
+//       // In other words, `mask as u16` has bit i set if and only if
+//       // needle[i] == chunk[i].
+//       mask = movemask(eqs)
+//
+//       // Mask is 0 if there is no match, and non-zero otherwise.
+//       if mask != 0:
+//         // trailing_zeros tells us the position of the least significant
+//         // bit that is set.
+//         return i + trailing_zeros(mask)
+//
+//     // haystack length may not be a multiple of 16, so search the rest.
+//     while i < haystack.len():
+//       if haystack[i] == n1:
+//         return i
+//
+//     // No match found.
+//     return NULL
+//
+// In fact, we could loosely translate the above code to Rust line-for-line
+// and it would be a pretty fast algorithm. But, we pull out all the stops
+// to go as fast as possible:
+//
+// 1. We use aligned loads. That is, we do some finagling to make sure our
+//    primary loop not only proceeds in increments of 16 bytes, but that
+//    the address of haystack's pointer that we dereference is aligned to
+//    16 bytes. 16 is a magic number here because it is the size of SSE2
+//    128-bit vector. (For the AVX2 algorithm, 32 is the magic number.)
+//    Therefore, to get aligned loads, our pointer's address must be evenly
+//    divisible by 16.
+// 2. Our primary loop proceeds 64 bytes at a time instead of 16. It's
+//    kind of like loop unrolling, but we combine the equality comparisons
+//    using a vector OR such that we only need to extract a single mask to
+//    determine whether a match exists or not. If so, then we do some
+//    book-keeping to determine the precise location but otherwise mush on.
+// 3. We use our "chunk" comparison routine in as many places as possible,
+//    even if it means using unaligned loads. In particular, if haystack
+//    starts with an unaligned address, then we do an unaligned load to
+//    search the first 16 bytes. We then start our primary loop at the
+//    smallest subsequent aligned address, which will actually overlap with
+//    previously searched bytes. But we're OK with that. We do a similar
+//    dance at the end of our primary loop. Finally, to avoid a
+//    byte-at-a-time loop at the end, we do a final 16 byte unaligned load
+//    that may overlap with a previous load. This is OK because it converts
+//    a loop into a small number of very fast vector instructions. The overlap
+//    is OK because we know the place where the overlap occurs does not
+//    contain a match.
+//
+// And that's pretty all there is to it. Note that since the below is
+// generic and since it's meant to be inlined into routines with a
+// `#[target_feature(enable = "...")]` annotation, we must mark all routines as
+// both unsafe and `#[inline(always)]`.
+//
+// The fact that the code below is generic does somewhat inhibit us. For
+// example, I've noticed that introducing an unlineable `#[cold]` function to
+// handle the match case in the loop generates tighter assembly, but there is
+// no way to do this in the generic code below because the generic code doesn't
+// know what `target_feature` annotation to apply to the unlineable function.
+// We could make such functions part of the `Vector` trait, but we instead live
+// with the slightly sub-optimal codegen for now since it doesn't seem to have
+// a noticeable perf difference.
+
+use crate::{
+    ext::Pointer,
+    vector::{MoveMask, Vector},
+};
+
+/// Finds all occurrences of a single byte in a haystack.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct One<V> {
+    s1: u8,
+    v1: V,
+}
+
+impl<V: Vector> One<V> {
+    /// The number of bytes we examine per each iteration of our search loop.
+    const LOOP_SIZE: usize = 4 * V::BYTES;
+
+    /// Create a new searcher that finds occurrences of the byte given.
+    #[inline(always)]
+    pub(crate) unsafe fn new(needle: u8) -> One<V> {
+        One { s1: needle, v1: V::splat(needle) }
+    }
+
+    /// Returns the needle given to `One::new`.
+    #[inline(always)]
+    pub(crate) fn needle1(&self) -> u8 {
+        self.s1
+    }
+
+    /// Return a pointer to the first occurrence of the needle in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::first_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        // Search a possibly unaligned chunk at `start`. This covers any part
+        // of the haystack prior to where aligned loads can start.
+        if let Some(cur) = self.search_chunk(start, topos) {
+            return Some(cur);
+        }
+        // Set `cur` to the first V-aligned pointer greater than `start`.
+        let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN));
+        debug_assert!(cur > start && end.sub(V::BYTES) >= start);
+        if len >= Self::LOOP_SIZE {
+            while cur <= end.sub(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(1 * V::BYTES));
+                let c = V::load_aligned(cur.add(2 * V::BYTES));
+                let d = V::load_aligned(cur.add(3 * V::BYTES));
+                let eqa = self.v1.cmpeq(a);
+                let eqb = self.v1.cmpeq(b);
+                let eqc = self.v1.cmpeq(c);
+                let eqd = self.v1.cmpeq(d);
+                let or1 = eqa.or(eqb);
+                let or2 = eqc.or(eqd);
+                let or3 = or1.or(or2);
+                if or3.movemask_will_have_non_zero() {
+                    let mask = eqa.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(topos(mask)));
+                    }
+
+                    let mask = eqb.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(1 * V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqc.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(2 * V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqd.movemask();
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(3 * V::BYTES).add(topos(mask)));
+                }
+                cur = cur.add(Self::LOOP_SIZE);
+            }
+        }
+        // Handle any leftovers after the aligned loop above. We use unaligned
+        // loads here, but I believe we are guaranteed that they are aligned
+        // since `cur` is aligned.
+        while cur <= end.sub(V::BYTES) {
+            debug_assert!(end.distance(cur) >= V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+            cur = cur.add(V::BYTES);
+        }
+        // Finally handle any remaining bytes less than the size of V. In this
+        // case, our pointer may indeed be unaligned and the load may overlap
+        // with the previous one. But that's okay since we know the previous
+        // load didn't lead to a match (otherwise we wouldn't be here).
+        if cur < end {
+            debug_assert!(end.distance(cur) < V::BYTES);
+            cur = cur.sub(V::BYTES - end.distance(cur));
+            debug_assert_eq!(end.distance(cur), V::BYTES);
+            return self.search_chunk(cur, topos);
+        }
+        None
+    }
+
+    /// Return a pointer to the last occurrence of the needle in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::last_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) {
+            return Some(cur);
+        }
+        let mut cur = end.sub(end.as_usize() & V::ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        if len >= Self::LOOP_SIZE {
+            while cur >= start.add(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                cur = cur.sub(Self::LOOP_SIZE);
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(1 * V::BYTES));
+                let c = V::load_aligned(cur.add(2 * V::BYTES));
+                let d = V::load_aligned(cur.add(3 * V::BYTES));
+                let eqa = self.v1.cmpeq(a);
+                let eqb = self.v1.cmpeq(b);
+                let eqc = self.v1.cmpeq(c);
+                let eqd = self.v1.cmpeq(d);
+                let or1 = eqa.or(eqb);
+                let or2 = eqc.or(eqd);
+                let or3 = or1.or(or2);
+                if or3.movemask_will_have_non_zero() {
+                    let mask = eqd.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(3 * V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqc.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(2 * V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqb.movemask();
+                    if mask.has_non_zero() {
+                        return Some(cur.add(1 * V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqa.movemask();
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(topos(mask)));
+                }
+            }
+        }
+        while cur >= start.add(V::BYTES) {
+            debug_assert!(cur.distance(start) >= V::BYTES);
+            cur = cur.sub(V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+        }
+        if cur > start {
+            debug_assert!(cur.distance(start) < V::BYTES);
+            return self.search_chunk(start, topos);
+        }
+        None
+    }
+
+    /// Return a count of all matching bytes in the given haystack.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn count_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> usize {
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let confirm = |b| b == self.needle1();
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        // Set `cur` to the first V-aligned pointer greater than `start`.
+        let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN));
+        // Count any matching bytes before we start our aligned loop.
+        let mut count = count_byte_by_byte(start, cur, confirm);
+        debug_assert!(cur > start && end.sub(V::BYTES) >= start);
+        if len >= Self::LOOP_SIZE {
+            while cur <= end.sub(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(1 * V::BYTES));
+                let c = V::load_aligned(cur.add(2 * V::BYTES));
+                let d = V::load_aligned(cur.add(3 * V::BYTES));
+                let eqa = self.v1.cmpeq(a);
+                let eqb = self.v1.cmpeq(b);
+                let eqc = self.v1.cmpeq(c);
+                let eqd = self.v1.cmpeq(d);
+                count += eqa.movemask().count_ones();
+                count += eqb.movemask().count_ones();
+                count += eqc.movemask().count_ones();
+                count += eqd.movemask().count_ones();
+                cur = cur.add(Self::LOOP_SIZE);
+            }
+        }
+        // Handle any leftovers after the aligned loop above. We use unaligned
+        // loads here, but I believe we are guaranteed that they are aligned
+        // since `cur` is aligned.
+        while cur <= end.sub(V::BYTES) {
+            debug_assert!(end.distance(cur) >= V::BYTES);
+            let chunk = V::load_unaligned(cur);
+            count += self.v1.cmpeq(chunk).movemask().count_ones();
+            cur = cur.add(V::BYTES);
+        }
+        // And finally count any leftovers that weren't caught above.
+        count += count_byte_by_byte(cur, end, confirm);
+        count
+    }
+
+    /// Search `V::BYTES` starting at `cur` via an unaligned load.
+    ///
+    /// `mask_to_offset` should be a function that converts a `movemask` to
+    /// an offset such that `cur.add(offset)` corresponds to a pointer to the
+    /// match location if one is found. Generally it is expected to use either
+    /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether
+    /// one is implementing a forward or reverse search, respectively.
+    ///
+    /// # Safety
+    ///
+    /// `cur` must be a valid pointer and it must be valid to do an unaligned
+    /// load of size `V::BYTES` at `cur`.
+    #[inline(always)]
+    unsafe fn search_chunk(
+        &self,
+        cur: *const u8,
+        mask_to_offset: impl Fn(V::Mask) -> usize,
+    ) -> Option<*const u8> {
+        let chunk = V::load_unaligned(cur);
+        let mask = self.v1.cmpeq(chunk).movemask();
+        if mask.has_non_zero() {
+            Some(cur.add(mask_to_offset(mask)))
+        } else {
+            None
+        }
+    }
+}
+
+/// Finds all occurrences of two bytes in a haystack.
+///
+/// That is, this reports matches of one of two possible bytes. For example,
+/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`,
+/// `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct Two<V> {
+    s1: u8,
+    s2: u8,
+    v1: V,
+    v2: V,
+}
+
+impl<V: Vector> Two<V> {
+    /// The number of bytes we examine per each iteration of our search loop.
+    const LOOP_SIZE: usize = 2 * V::BYTES;
+
+    /// Create a new searcher that finds occurrences of the byte given.
+    #[inline(always)]
+    pub(crate) unsafe fn new(needle1: u8, needle2: u8) -> Two<V> {
+        Two {
+            s1: needle1,
+            s2: needle2,
+            v1: V::splat(needle1),
+            v2: V::splat(needle2),
+        }
+    }
+
+    /// Returns the first needle given to `Two::new`.
+    #[inline(always)]
+    pub(crate) fn needle1(&self) -> u8 {
+        self.s1
+    }
+
+    /// Returns the second needle given to `Two::new`.
+    #[inline(always)]
+    pub(crate) fn needle2(&self) -> u8 {
+        self.s2
+    }
+
+    /// Return a pointer to the first occurrence of one of the needles in the
+    /// given haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::first_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        // Search a possibly unaligned chunk at `start`. This covers any part
+        // of the haystack prior to where aligned loads can start.
+        if let Some(cur) = self.search_chunk(start, topos) {
+            return Some(cur);
+        }
+        // Set `cur` to the first V-aligned pointer greater than `start`.
+        let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN));
+        debug_assert!(cur > start && end.sub(V::BYTES) >= start);
+        if len >= Self::LOOP_SIZE {
+            while cur <= end.sub(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(V::BYTES));
+                let eqa1 = self.v1.cmpeq(a);
+                let eqb1 = self.v1.cmpeq(b);
+                let eqa2 = self.v2.cmpeq(a);
+                let eqb2 = self.v2.cmpeq(b);
+                let or1 = eqa1.or(eqb1);
+                let or2 = eqa2.or(eqb2);
+                let or3 = or1.or(or2);
+                if or3.movemask_will_have_non_zero() {
+                    let mask = eqa1.movemask().or(eqa2.movemask());
+                    if mask.has_non_zero() {
+                        return Some(cur.add(topos(mask)));
+                    }
+
+                    let mask = eqb1.movemask().or(eqb2.movemask());
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(V::BYTES).add(topos(mask)));
+                }
+                cur = cur.add(Self::LOOP_SIZE);
+            }
+        }
+        // Handle any leftovers after the aligned loop above. We use unaligned
+        // loads here, but I believe we are guaranteed that they are aligned
+        // since `cur` is aligned.
+        while cur <= end.sub(V::BYTES) {
+            debug_assert!(end.distance(cur) >= V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+            cur = cur.add(V::BYTES);
+        }
+        // Finally handle any remaining bytes less than the size of V. In this
+        // case, our pointer may indeed be unaligned and the load may overlap
+        // with the previous one. But that's okay since we know the previous
+        // load didn't lead to a match (otherwise we wouldn't be here).
+        if cur < end {
+            debug_assert!(end.distance(cur) < V::BYTES);
+            cur = cur.sub(V::BYTES - end.distance(cur));
+            debug_assert_eq!(end.distance(cur), V::BYTES);
+            return self.search_chunk(cur, topos);
+        }
+        None
+    }
+
+    /// Return a pointer to the last occurrence of the needle in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::last_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) {
+            return Some(cur);
+        }
+        let mut cur = end.sub(end.as_usize() & V::ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        if len >= Self::LOOP_SIZE {
+            while cur >= start.add(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                cur = cur.sub(Self::LOOP_SIZE);
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(V::BYTES));
+                let eqa1 = self.v1.cmpeq(a);
+                let eqb1 = self.v1.cmpeq(b);
+                let eqa2 = self.v2.cmpeq(a);
+                let eqb2 = self.v2.cmpeq(b);
+                let or1 = eqa1.or(eqb1);
+                let or2 = eqa2.or(eqb2);
+                let or3 = or1.or(or2);
+                if or3.movemask_will_have_non_zero() {
+                    let mask = eqb1.movemask().or(eqb2.movemask());
+                    if mask.has_non_zero() {
+                        return Some(cur.add(V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqa1.movemask().or(eqa2.movemask());
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(topos(mask)));
+                }
+            }
+        }
+        while cur >= start.add(V::BYTES) {
+            debug_assert!(cur.distance(start) >= V::BYTES);
+            cur = cur.sub(V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+        }
+        if cur > start {
+            debug_assert!(cur.distance(start) < V::BYTES);
+            return self.search_chunk(start, topos);
+        }
+        None
+    }
+
+    /// Search `V::BYTES` starting at `cur` via an unaligned load.
+    ///
+    /// `mask_to_offset` should be a function that converts a `movemask` to
+    /// an offset such that `cur.add(offset)` corresponds to a pointer to the
+    /// match location if one is found. Generally it is expected to use either
+    /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether
+    /// one is implementing a forward or reverse search, respectively.
+    ///
+    /// # Safety
+    ///
+    /// `cur` must be a valid pointer and it must be valid to do an unaligned
+    /// load of size `V::BYTES` at `cur`.
+    #[inline(always)]
+    unsafe fn search_chunk(
+        &self,
+        cur: *const u8,
+        mask_to_offset: impl Fn(V::Mask) -> usize,
+    ) -> Option<*const u8> {
+        let chunk = V::load_unaligned(cur);
+        let eq1 = self.v1.cmpeq(chunk);
+        let eq2 = self.v2.cmpeq(chunk);
+        let mask = eq1.or(eq2).movemask();
+        if mask.has_non_zero() {
+            let mask1 = eq1.movemask();
+            let mask2 = eq2.movemask();
+            Some(cur.add(mask_to_offset(mask1.or(mask2))))
+        } else {
+            None
+        }
+    }
+}
+
+/// Finds all occurrences of two bytes in a haystack.
+///
+/// That is, this reports matches of one of two possible bytes. For example,
+/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`,
+/// `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct Three<V> {
+    s1: u8,
+    s2: u8,
+    s3: u8,
+    v1: V,
+    v2: V,
+    v3: V,
+}
+
+impl<V: Vector> Three<V> {
+    /// The number of bytes we examine per each iteration of our search loop.
+    const LOOP_SIZE: usize = 2 * V::BYTES;
+
+    /// Create a new searcher that finds occurrences of the byte given.
+    #[inline(always)]
+    pub(crate) unsafe fn new(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+    ) -> Three<V> {
+        Three {
+            s1: needle1,
+            s2: needle2,
+            s3: needle3,
+            v1: V::splat(needle1),
+            v2: V::splat(needle2),
+            v3: V::splat(needle3),
+        }
+    }
+
+    /// Returns the first needle given to `Three::new`.
+    #[inline(always)]
+    pub(crate) fn needle1(&self) -> u8 {
+        self.s1
+    }
+
+    /// Returns the second needle given to `Three::new`.
+    #[inline(always)]
+    pub(crate) fn needle2(&self) -> u8 {
+        self.s2
+    }
+
+    /// Returns the third needle given to `Three::new`.
+    #[inline(always)]
+    pub(crate) fn needle3(&self) -> u8 {
+        self.s3
+    }
+
+    /// Return a pointer to the first occurrence of one of the needles in the
+    /// given haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::first_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        // Search a possibly unaligned chunk at `start`. This covers any part
+        // of the haystack prior to where aligned loads can start.
+        if let Some(cur) = self.search_chunk(start, topos) {
+            return Some(cur);
+        }
+        // Set `cur` to the first V-aligned pointer greater than `start`.
+        let mut cur = start.add(V::BYTES - (start.as_usize() & V::ALIGN));
+        debug_assert!(cur > start && end.sub(V::BYTES) >= start);
+        if len >= Self::LOOP_SIZE {
+            while cur <= end.sub(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(V::BYTES));
+                let eqa1 = self.v1.cmpeq(a);
+                let eqb1 = self.v1.cmpeq(b);
+                let eqa2 = self.v2.cmpeq(a);
+                let eqb2 = self.v2.cmpeq(b);
+                let eqa3 = self.v3.cmpeq(a);
+                let eqb3 = self.v3.cmpeq(b);
+                let or1 = eqa1.or(eqb1);
+                let or2 = eqa2.or(eqb2);
+                let or3 = eqa3.or(eqb3);
+                let or4 = or1.or(or2);
+                let or5 = or3.or(or4);
+                if or5.movemask_will_have_non_zero() {
+                    let mask = eqa1
+                        .movemask()
+                        .or(eqa2.movemask())
+                        .or(eqa3.movemask());
+                    if mask.has_non_zero() {
+                        return Some(cur.add(topos(mask)));
+                    }
+
+                    let mask = eqb1
+                        .movemask()
+                        .or(eqb2.movemask())
+                        .or(eqb3.movemask());
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(V::BYTES).add(topos(mask)));
+                }
+                cur = cur.add(Self::LOOP_SIZE);
+            }
+        }
+        // Handle any leftovers after the aligned loop above. We use unaligned
+        // loads here, but I believe we are guaranteed that they are aligned
+        // since `cur` is aligned.
+        while cur <= end.sub(V::BYTES) {
+            debug_assert!(end.distance(cur) >= V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+            cur = cur.add(V::BYTES);
+        }
+        // Finally handle any remaining bytes less than the size of V. In this
+        // case, our pointer may indeed be unaligned and the load may overlap
+        // with the previous one. But that's okay since we know the previous
+        // load didn't lead to a match (otherwise we wouldn't be here).
+        if cur < end {
+            debug_assert!(end.distance(cur) < V::BYTES);
+            cur = cur.sub(V::BYTES - end.distance(cur));
+            debug_assert_eq!(end.distance(cur), V::BYTES);
+            return self.search_chunk(cur, topos);
+        }
+        None
+    }
+
+    /// Return a pointer to the last occurrence of the needle in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// # Safety
+    ///
+    /// * It must be the case that `start < end` and that the distance between
+    /// them is at least equal to `V::BYTES`. That is, it must always be valid
+    /// to do at least an unaligned load of `V` at `start`.
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    #[inline(always)]
+    pub(crate) unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        // If we want to support vectors bigger than 256 bits, we probably
+        // need to move up to using a u64 for the masks used below. Currently
+        // they are 32 bits, which means we're SOL for vectors that need masks
+        // bigger than 32 bits. Overall unclear until there's a use case.
+        debug_assert!(V::BYTES <= 32, "vector cannot be bigger than 32 bytes");
+
+        let topos = V::Mask::last_offset;
+        let len = end.distance(start);
+        debug_assert!(
+            len >= V::BYTES,
+            "haystack has length {}, but must be at least {}",
+            len,
+            V::BYTES
+        );
+
+        if let Some(cur) = self.search_chunk(end.sub(V::BYTES), topos) {
+            return Some(cur);
+        }
+        let mut cur = end.sub(end.as_usize() & V::ALIGN);
+        debug_assert!(start <= cur && cur <= end);
+        if len >= Self::LOOP_SIZE {
+            while cur >= start.add(Self::LOOP_SIZE) {
+                debug_assert_eq!(0, cur.as_usize() % V::BYTES);
+
+                cur = cur.sub(Self::LOOP_SIZE);
+                let a = V::load_aligned(cur);
+                let b = V::load_aligned(cur.add(V::BYTES));
+                let eqa1 = self.v1.cmpeq(a);
+                let eqb1 = self.v1.cmpeq(b);
+                let eqa2 = self.v2.cmpeq(a);
+                let eqb2 = self.v2.cmpeq(b);
+                let eqa3 = self.v3.cmpeq(a);
+                let eqb3 = self.v3.cmpeq(b);
+                let or1 = eqa1.or(eqb1);
+                let or2 = eqa2.or(eqb2);
+                let or3 = eqa3.or(eqb3);
+                let or4 = or1.or(or2);
+                let or5 = or3.or(or4);
+                if or5.movemask_will_have_non_zero() {
+                    let mask = eqb1
+                        .movemask()
+                        .or(eqb2.movemask())
+                        .or(eqb3.movemask());
+                    if mask.has_non_zero() {
+                        return Some(cur.add(V::BYTES).add(topos(mask)));
+                    }
+
+                    let mask = eqa1
+                        .movemask()
+                        .or(eqa2.movemask())
+                        .or(eqa3.movemask());
+                    debug_assert!(mask.has_non_zero());
+                    return Some(cur.add(topos(mask)));
+                }
+            }
+        }
+        while cur >= start.add(V::BYTES) {
+            debug_assert!(cur.distance(start) >= V::BYTES);
+            cur = cur.sub(V::BYTES);
+            if let Some(cur) = self.search_chunk(cur, topos) {
+                return Some(cur);
+            }
+        }
+        if cur > start {
+            debug_assert!(cur.distance(start) < V::BYTES);
+            return self.search_chunk(start, topos);
+        }
+        None
+    }
+
+    /// Search `V::BYTES` starting at `cur` via an unaligned load.
+    ///
+    /// `mask_to_offset` should be a function that converts a `movemask` to
+    /// an offset such that `cur.add(offset)` corresponds to a pointer to the
+    /// match location if one is found. Generally it is expected to use either
+    /// `mask_to_first_offset` or `mask_to_last_offset`, depending on whether
+    /// one is implementing a forward or reverse search, respectively.
+    ///
+    /// # Safety
+    ///
+    /// `cur` must be a valid pointer and it must be valid to do an unaligned
+    /// load of size `V::BYTES` at `cur`.
+    #[inline(always)]
+    unsafe fn search_chunk(
+        &self,
+        cur: *const u8,
+        mask_to_offset: impl Fn(V::Mask) -> usize,
+    ) -> Option<*const u8> {
+        let chunk = V::load_unaligned(cur);
+        let eq1 = self.v1.cmpeq(chunk);
+        let eq2 = self.v2.cmpeq(chunk);
+        let eq3 = self.v3.cmpeq(chunk);
+        let mask = eq1.or(eq2).or(eq3).movemask();
+        if mask.has_non_zero() {
+            let mask1 = eq1.movemask();
+            let mask2 = eq2.movemask();
+            let mask3 = eq3.movemask();
+            Some(cur.add(mask_to_offset(mask1.or(mask2).or(mask3))))
+        } else {
+            None
+        }
+    }
+}
+
+/// An iterator over all occurrences of a set of bytes in a haystack.
+///
+/// This iterator implements the routines necessary to provide a
+/// `DoubleEndedIterator` impl, which means it can also be used to find
+/// occurrences in reverse order.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'h` refers to the lifetime of the haystack being searched.
+///
+/// This type is intended to be used to implement all iterators for the
+/// `memchr` family of functions. It handles a tiny bit of marginally tricky
+/// raw pointer math, but otherwise expects the caller to provide `find_raw`
+/// and `rfind_raw` routines for each call of `next` and `next_back`,
+/// respectively.
+#[derive(Clone, Debug)]
+pub(crate) struct Iter<'h> {
+    /// The original starting point into the haystack. We use this to convert
+    /// pointers to offsets.
+    original_start: *const u8,
+    /// The current starting point into the haystack. That is, where the next
+    /// search will begin.
+    start: *const u8,
+    /// The current ending point into the haystack. That is, where the next
+    /// reverse search will begin.
+    end: *const u8,
+    /// A marker for tracking the lifetime of the start/cur_start/cur_end
+    /// pointers above, which all point into the haystack.
+    haystack: core::marker::PhantomData<&'h [u8]>,
+}
+
+// SAFETY: Iter contains no shared references to anything that performs any
+// interior mutations. Also, the lifetime guarantees that Iter will not outlive
+// the haystack.
+unsafe impl<'h> Send for Iter<'h> {}
+
+// SAFETY: Iter perform no interior mutations, therefore no explicit
+// synchronization is necessary. Also, the lifetime guarantees that Iter will
+// not outlive the haystack.
+unsafe impl<'h> Sync for Iter<'h> {}
+
+impl<'h> Iter<'h> {
+    /// Create a new generic memchr iterator.
+    #[inline(always)]
+    pub(crate) fn new(haystack: &'h [u8]) -> Iter<'h> {
+        Iter {
+            original_start: haystack.as_ptr(),
+            start: haystack.as_ptr(),
+            end: haystack.as_ptr().wrapping_add(haystack.len()),
+            haystack: core::marker::PhantomData,
+        }
+    }
+
+    /// Returns the next occurrence in the forward direction.
+    ///
+    /// # Safety
+    ///
+    /// Callers must ensure that if a pointer is returned from the closure
+    /// provided, then it must be greater than or equal to the start pointer
+    /// and less than the end pointer.
+    #[inline(always)]
+    pub(crate) unsafe fn next(
+        &mut self,
+        mut find_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>,
+    ) -> Option<usize> {
+        // SAFETY: Pointers are derived directly from the same &[u8] haystack.
+        // We only ever modify start/end corresponding to a matching offset
+        // found between start and end. Thus all changes to start/end maintain
+        // our safety requirements.
+        //
+        // The only other assumption we rely on is that the pointer returned
+        // by `find_raw` satisfies `self.start <= found < self.end`, and that
+        // safety contract is forwarded to the caller.
+        let found = find_raw(self.start, self.end)?;
+        let result = found.distance(self.original_start);
+        self.start = found.add(1);
+        Some(result)
+    }
+
+    /// Returns the number of remaining elements in this iterator.
+    #[inline(always)]
+    pub(crate) fn count(
+        self,
+        mut count_raw: impl FnMut(*const u8, *const u8) -> usize,
+    ) -> usize {
+        // SAFETY: Pointers are derived directly from the same &[u8] haystack.
+        // We only ever modify start/end corresponding to a matching offset
+        // found between start and end. Thus all changes to start/end maintain
+        // our safety requirements.
+        count_raw(self.start, self.end)
+    }
+
+    /// Returns the next occurrence in reverse.
+    ///
+    /// # Safety
+    ///
+    /// Callers must ensure that if a pointer is returned from the closure
+    /// provided, then it must be greater than or equal to the start pointer
+    /// and less than the end pointer.
+    #[inline(always)]
+    pub(crate) unsafe fn next_back(
+        &mut self,
+        mut rfind_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>,
+    ) -> Option<usize> {
+        // SAFETY: Pointers are derived directly from the same &[u8] haystack.
+        // We only ever modify start/end corresponding to a matching offset
+        // found between start and end. Thus all changes to start/end maintain
+        // our safety requirements.
+        //
+        // The only other assumption we rely on is that the pointer returned
+        // by `rfind_raw` satisfies `self.start <= found < self.end`, and that
+        // safety contract is forwarded to the caller.
+        let found = rfind_raw(self.start, self.end)?;
+        let result = found.distance(self.original_start);
+        self.end = found;
+        Some(result)
+    }
+
+    /// Provides an implementation of `Iterator::size_hint`.
+    #[inline(always)]
+    pub(crate) fn size_hint(&self) -> (usize, Option<usize>) {
+        (0, Some(self.end.as_usize().saturating_sub(self.start.as_usize())))
+    }
+}
+
+/// Search a slice using a function that operates on raw pointers.
+///
+/// Given a function to search a contiguous sequence of memory for the location
+/// of a non-empty set of bytes, this will execute that search on a slice of
+/// bytes. The pointer returned by the given function will be converted to an
+/// offset relative to the starting point of the given slice. That is, if a
+/// match is found, the offset returned by this routine is guaranteed to be a
+/// valid index into `haystack`.
+///
+/// Callers may use this for a forward or reverse search.
+///
+/// # Safety
+///
+/// Callers must ensure that if a pointer is returned by `find_raw`, then the
+/// pointer must be greater than or equal to the starting pointer and less than
+/// the end pointer.
+#[inline(always)]
+pub(crate) unsafe fn search_slice_with_raw(
+    haystack: &[u8],
+    mut find_raw: impl FnMut(*const u8, *const u8) -> Option<*const u8>,
+) -> Option<usize> {
+    // SAFETY: We rely on `find_raw` to return a correct and valid pointer, but
+    // otherwise, `start` and `end` are valid due to the guarantees provided by
+    // a &[u8].
+    let start = haystack.as_ptr();
+    let end = start.add(haystack.len());
+    let found = find_raw(start, end)?;
+    Some(found.distance(start))
+}
+
+/// Performs a forward byte-at-a-time loop until either `ptr >= end_ptr` or
+/// until `confirm(*ptr)` returns `true`. If the former occurs, then `None` is
+/// returned. If the latter occurs, then the pointer at which `confirm` returns
+/// `true` is returned.
+///
+/// # Safety
+///
+/// Callers must provide valid pointers and they must satisfy `start_ptr <=
+/// ptr` and `ptr <= end_ptr`.
+#[inline(always)]
+pub(crate) unsafe fn fwd_byte_by_byte<F: Fn(u8) -> bool>(
+    start: *const u8,
+    end: *const u8,
+    confirm: F,
+) -> Option<*const u8> {
+    debug_assert!(start <= end);
+    let mut ptr = start;
+    while ptr < end {
+        if confirm(*ptr) {
+            return Some(ptr);
+        }
+        ptr = ptr.offset(1);
+    }
+    None
+}
+
+/// Performs a reverse byte-at-a-time loop until either `ptr < start_ptr` or
+/// until `confirm(*ptr)` returns `true`. If the former occurs, then `None` is
+/// returned. If the latter occurs, then the pointer at which `confirm` returns
+/// `true` is returned.
+///
+/// # Safety
+///
+/// Callers must provide valid pointers and they must satisfy `start_ptr <=
+/// ptr` and `ptr <= end_ptr`.
+#[inline(always)]
+pub(crate) unsafe fn rev_byte_by_byte<F: Fn(u8) -> bool>(
+    start: *const u8,
+    end: *const u8,
+    confirm: F,
+) -> Option<*const u8> {
+    debug_assert!(start <= end);
+
+    let mut ptr = end;
+    while ptr > start {
+        ptr = ptr.offset(-1);
+        if confirm(*ptr) {
+            return Some(ptr);
+        }
+    }
+    None
+}
+
+/// Performs a forward byte-at-a-time loop until `ptr >= end_ptr` and returns
+/// the number of times `confirm(*ptr)` returns `true`.
+///
+/// # Safety
+///
+/// Callers must provide valid pointers and they must satisfy `start_ptr <=
+/// ptr` and `ptr <= end_ptr`.
+#[inline(always)]
+pub(crate) unsafe fn count_byte_by_byte<F: Fn(u8) -> bool>(
+    start: *const u8,
+    end: *const u8,
+    confirm: F,
+) -> usize {
+    debug_assert!(start <= end);
+    let mut ptr = start;
+    let mut count = 0;
+    while ptr < end {
+        if confirm(*ptr) {
+            count += 1;
+        }
+        ptr = ptr.offset(1);
+    }
+    count
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/generic/mod.rs.html b/src/memchr/arch/generic/mod.rs.html new file mode 100644 index 000000000..1fbd7cdb1 --- /dev/null +++ b/src/memchr/arch/generic/mod.rs.html @@ -0,0 +1,29 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+
/*!
+This module defines "generic" routines that can be specialized to specific
+architectures.
+
+We don't expose this module primarily because it would require exposing all
+of the internal infrastructure required to write these generic routines.
+That infrastructure should be treated as an implementation detail so that
+it is allowed to evolve. Instead, what we expose are architecture specific
+instantiations of these generic implementations. The generic code just lets us
+write the code once (usually).
+*/
+
+pub(crate) mod memchr;
+pub(crate) mod packedpair;
+
\ No newline at end of file diff --git a/src/memchr/arch/generic/packedpair.rs.html b/src/memchr/arch/generic/packedpair.rs.html new file mode 100644 index 000000000..55902936e --- /dev/null +++ b/src/memchr/arch/generic/packedpair.rs.html @@ -0,0 +1,635 @@ +packedpair.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+
/*!
+Generic crate-internal routines for the "packed pair" SIMD algorithm.
+
+The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main
+difference is that it (by default) uses a background distribution of byte
+frequencies to heuristically select the pair of bytes to search for.
+
+[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last
+*/
+
+use crate::{
+    arch::all::{is_equal_raw, packedpair::Pair},
+    ext::Pointer,
+    vector::{MoveMask, Vector},
+};
+
+/// A generic architecture dependent "packed pair" finder.
+///
+/// This finder picks two bytes that it believes have high predictive power
+/// for indicating an overall match of a needle. Depending on whether
+/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets
+/// where the needle matches or could match. In the prefilter case, candidates
+/// are reported whenever the [`Pair`] of bytes given matches.
+///
+/// This is architecture dependent because it uses specific vector operations
+/// to look for occurrences of the pair of bytes.
+///
+/// This type is not meant to be exported and is instead meant to be used as
+/// the implementation for architecture specific facades. Why? Because it's a
+/// bit of a quirky API that requires `inline(always)` annotations. And pretty
+/// much everything has safety obligations due (at least) to the caller needing
+/// to inline calls into routines marked with
+/// `#[target_feature(enable = "...")]`.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct Finder<V> {
+    pair: Pair,
+    v1: V,
+    v2: V,
+    min_haystack_len: usize,
+}
+
+impl<V: Vector> Finder<V> {
+    /// Create a new pair searcher. The searcher returned can either report
+    /// exact matches of `needle` or act as a prefilter and report candidate
+    /// positions of `needle`.
+    ///
+    /// # Safety
+    ///
+    /// Callers must ensure that whatever vector type this routine is called
+    /// with is supported by the current environment.
+    ///
+    /// Callers must also ensure that `needle.len() >= 2`.
+    #[inline(always)]
+    pub(crate) unsafe fn new(needle: &[u8], pair: Pair) -> Finder<V> {
+        let max_index = pair.index1().max(pair.index2());
+        let min_haystack_len =
+            core::cmp::max(needle.len(), usize::from(max_index) + V::BYTES);
+        let v1 = V::splat(needle[usize::from(pair.index1())]);
+        let v2 = V::splat(needle[usize::from(pair.index2())]);
+        Finder { pair, v1, v2, min_haystack_len }
+    }
+
+    /// Searches the given haystack for the given needle. The needle given
+    /// should be the same as the needle that this finder was initialized
+    /// with.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// Since this is meant to be used with vector functions, callers need to
+    /// specialize this inside of a function with a `target_feature` attribute.
+    /// Therefore, callers must ensure that whatever target feature is being
+    /// used supports the vector functions that this function is specialized
+    /// for. (For the specific vector functions used, see the Vector trait
+    /// implementations.)
+    #[inline(always)]
+    pub(crate) unsafe fn find(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        assert!(
+            haystack.len() >= self.min_haystack_len,
+            "haystack too small, should be at least {} but got {}",
+            self.min_haystack_len,
+            haystack.len(),
+        );
+
+        let all = V::Mask::all_zeros_except_least_significant(0);
+        let start = haystack.as_ptr();
+        let end = start.add(haystack.len());
+        let max = end.sub(self.min_haystack_len);
+        let mut cur = start;
+
+        // N.B. I did experiment with unrolling the loop to deal with size(V)
+        // bytes at a time and 2*size(V) bytes at a time. The double unroll
+        // was marginally faster while the quadruple unroll was unambiguously
+        // slower. In the end, I decided the complexity from unrolling wasn't
+        // worth it. I used the memmem/krate/prebuilt/huge-en/ benchmarks to
+        // compare.
+        while cur <= max {
+            if let Some(chunki) = self.find_in_chunk(needle, cur, end, all) {
+                return Some(matched(start, cur, chunki));
+            }
+            cur = cur.add(V::BYTES);
+        }
+        if cur < end {
+            let remaining = end.distance(cur);
+            debug_assert!(
+                remaining < self.min_haystack_len,
+                "remaining bytes should be smaller than the minimum haystack \
+                 length of {}, but there are {} bytes remaining",
+                self.min_haystack_len,
+                remaining,
+            );
+            if remaining < needle.len() {
+                return None;
+            }
+            debug_assert!(
+                max < cur,
+                "after main loop, cur should have exceeded max",
+            );
+            let overlap = cur.distance(max);
+            debug_assert!(
+                overlap > 0,
+                "overlap ({}) must always be non-zero",
+                overlap,
+            );
+            debug_assert!(
+                overlap < V::BYTES,
+                "overlap ({}) cannot possibly be >= than a vector ({})",
+                overlap,
+                V::BYTES,
+            );
+            // The mask has all of its bits set except for the first N least
+            // significant bits, where N=overlap. This way, any matches that
+            // occur in find_in_chunk within the overlap are automatically
+            // ignored.
+            let mask = V::Mask::all_zeros_except_least_significant(overlap);
+            cur = max;
+            let m = self.find_in_chunk(needle, cur, end, mask);
+            if let Some(chunki) = m {
+                return Some(matched(start, cur, chunki));
+            }
+        }
+        None
+    }
+
+    /// Searches the given haystack for offsets that represent candidate
+    /// matches of the `needle` given to this finder's constructor. The offsets
+    /// returned, if they are a match, correspond to the starting offset of
+    /// `needle` in the given `haystack`.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// Since this is meant to be used with vector functions, callers need to
+    /// specialize this inside of a function with a `target_feature` attribute.
+    /// Therefore, callers must ensure that whatever target feature is being
+    /// used supports the vector functions that this function is specialized
+    /// for. (For the specific vector functions used, see the Vector trait
+    /// implementations.)
+    #[inline(always)]
+    pub(crate) unsafe fn find_prefilter(
+        &self,
+        haystack: &[u8],
+    ) -> Option<usize> {
+        assert!(
+            haystack.len() >= self.min_haystack_len,
+            "haystack too small, should be at least {} but got {}",
+            self.min_haystack_len,
+            haystack.len(),
+        );
+
+        let start = haystack.as_ptr();
+        let end = start.add(haystack.len());
+        let max = end.sub(self.min_haystack_len);
+        let mut cur = start;
+
+        // N.B. I did experiment with unrolling the loop to deal with size(V)
+        // bytes at a time and 2*size(V) bytes at a time. The double unroll
+        // was marginally faster while the quadruple unroll was unambiguously
+        // slower. In the end, I decided the complexity from unrolling wasn't
+        // worth it. I used the memmem/krate/prebuilt/huge-en/ benchmarks to
+        // compare.
+        while cur <= max {
+            if let Some(chunki) = self.find_prefilter_in_chunk(cur) {
+                return Some(matched(start, cur, chunki));
+            }
+            cur = cur.add(V::BYTES);
+        }
+        if cur < end {
+            // This routine immediately quits if a candidate match is found.
+            // That means that if we're here, no candidate matches have been
+            // found at or before 'ptr'. Thus, we don't need to mask anything
+            // out even though we might technically search part of the haystack
+            // that we've already searched (because we know it can't match).
+            cur = max;
+            if let Some(chunki) = self.find_prefilter_in_chunk(cur) {
+                return Some(matched(start, cur, chunki));
+            }
+        }
+        None
+    }
+
+    /// Search for an occurrence of our byte pair from the needle in the chunk
+    /// pointed to by cur, with the end of the haystack pointed to by end.
+    /// When an occurrence is found, memcmp is run to check if a match occurs
+    /// at the corresponding position.
+    ///
+    /// `mask` should have bits set corresponding the positions in the chunk
+    /// in which matches are considered. This is only used for the last vector
+    /// load where the beginning of the vector might have overlapped with the
+    /// last load in the main loop. The mask lets us avoid visiting positions
+    /// that have already been discarded as matches.
+    ///
+    /// # Safety
+    ///
+    /// It must be safe to do an unaligned read of size(V) bytes starting at
+    /// both (cur + self.index1) and (cur + self.index2). It must also be safe
+    /// to do unaligned loads on cur up to (end - needle.len()).
+    #[inline(always)]
+    unsafe fn find_in_chunk(
+        &self,
+        needle: &[u8],
+        cur: *const u8,
+        end: *const u8,
+        mask: V::Mask,
+    ) -> Option<usize> {
+        let index1 = usize::from(self.pair.index1());
+        let index2 = usize::from(self.pair.index2());
+        let chunk1 = V::load_unaligned(cur.add(index1));
+        let chunk2 = V::load_unaligned(cur.add(index2));
+        let eq1 = chunk1.cmpeq(self.v1);
+        let eq2 = chunk2.cmpeq(self.v2);
+
+        let mut offsets = eq1.and(eq2).movemask().and(mask);
+        while offsets.has_non_zero() {
+            let offset = offsets.first_offset();
+            let cur = cur.add(offset);
+            if end.sub(needle.len()) < cur {
+                return None;
+            }
+            if is_equal_raw(needle.as_ptr(), cur, needle.len()) {
+                return Some(offset);
+            }
+            offsets = offsets.clear_least_significant_bit();
+        }
+        None
+    }
+
+    /// Search for an occurrence of our byte pair from the needle in the chunk
+    /// pointed to by cur, with the end of the haystack pointed to by end.
+    /// When an occurrence is found, memcmp is run to check if a match occurs
+    /// at the corresponding position.
+    ///
+    /// # Safety
+    ///
+    /// It must be safe to do an unaligned read of size(V) bytes starting at
+    /// both (cur + self.index1) and (cur + self.index2). It must also be safe
+    /// to do unaligned reads on cur up to (end - needle.len()).
+    #[inline(always)]
+    unsafe fn find_prefilter_in_chunk(&self, cur: *const u8) -> Option<usize> {
+        let index1 = usize::from(self.pair.index1());
+        let index2 = usize::from(self.pair.index2());
+        let chunk1 = V::load_unaligned(cur.add(index1));
+        let chunk2 = V::load_unaligned(cur.add(index2));
+        let eq1 = chunk1.cmpeq(self.v1);
+        let eq2 = chunk2.cmpeq(self.v2);
+
+        let offsets = eq1.and(eq2).movemask();
+        if !offsets.has_non_zero() {
+            return None;
+        }
+        Some(offsets.first_offset())
+    }
+
+    /// Returns the pair of offsets (into the needle) used to check as a
+    /// predicate before confirming whether a needle exists at a particular
+    /// position.
+    #[inline]
+    pub(crate) fn pair(&self) -> &Pair {
+        &self.pair
+    }
+
+    /// Returns the minimum haystack length that this `Finder` can search.
+    ///
+    /// Providing a haystack to this `Finder` shorter than this length is
+    /// guaranteed to result in a panic.
+    #[inline(always)]
+    pub(crate) fn min_haystack_len(&self) -> usize {
+        self.min_haystack_len
+    }
+}
+
+/// Accepts a chunk-relative offset and returns a haystack relative offset.
+///
+/// This used to be marked `#[cold]` and `#[inline(never)]`, but I couldn't
+/// observe a consistent measureable difference between that and just inlining
+/// it. So we go with inlining it.
+///
+/// # Safety
+///
+/// Same at `ptr::offset_from` in addition to `cur >= start`.
+#[inline(always)]
+unsafe fn matched(start: *const u8, cur: *const u8, chunki: usize) -> usize {
+    cur.distance(start) + chunki
+}
+
+// If you're looking for tests, those are run for each instantiation of the
+// above code. So for example, see arch::x86_64::sse2::packedpair.
+
\ No newline at end of file diff --git a/src/memchr/arch/mod.rs.html b/src/memchr/arch/mod.rs.html new file mode 100644 index 000000000..0cdc534bd --- /dev/null +++ b/src/memchr/arch/mod.rs.html @@ -0,0 +1,33 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+
/*!
+A module with low-level architecture dependent routines.
+
+These routines are useful as primitives for tasks not covered by the higher
+level crate API.
+*/
+
+pub mod all;
+pub(crate) mod generic;
+
+#[cfg(target_arch = "aarch64")]
+pub mod aarch64;
+#[cfg(target_arch = "wasm32")]
+pub mod wasm32;
+#[cfg(target_arch = "x86_64")]
+pub mod x86_64;
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/avx2/memchr.rs.html b/src/memchr/arch/x86_64/avx2/memchr.rs.html new file mode 100644 index 000000000..f368020d7 --- /dev/null +++ b/src/memchr/arch/x86_64/avx2/memchr.rs.html @@ -0,0 +1,2705 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+
/*!
+This module defines 256-bit vector implementations of `memchr` and friends.
+
+The main types in this module are [`One`], [`Two`] and [`Three`]. They are for
+searching for one, two or three distinct bytes, respectively, in a haystack.
+Each type also has corresponding double ended iterators. These searchers are
+typically much faster than scalar routines accomplishing the same task.
+
+The `One` searcher also provides a [`One::count`] routine for efficiently
+counting the number of times a single byte occurs in a haystack. This is
+useful, for example, for counting the number of lines in a haystack. This
+routine exists because it is usually faster, especially with a high match
+count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its
+`Iterator::count` implementation to use this routine.)
+
+Only one, two and three bytes are supported because three bytes is about
+the point where one sees diminishing returns. Beyond this point and it's
+probably (but not necessarily) better to just use a simple `[bool; 256]` array
+or similar. However, it depends mightily on the specific work-load and the
+expected match frequency.
+*/
+
+use core::arch::x86_64::{__m128i, __m256i};
+
+use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector};
+
+/// Finds all occurrences of a single byte in a haystack.
+#[derive(Clone, Copy, Debug)]
+pub struct One {
+    /// Used for haystacks less than 32 bytes.
+    sse2: generic::One<__m128i>,
+    /// Used for haystacks bigger than 32 bytes.
+    avx2: generic::One<__m256i>,
+}
+
+impl One {
+    /// Create a new searcher that finds occurrences of the needle byte given.
+    ///
+    /// This particular searcher is specialized to use AVX2 vector instructions
+    /// that typically make it quite fast. (SSE2 is used for haystacks that
+    /// are too short to accommodate an AVX2 vector.)
+    ///
+    /// If either SSE2 or AVX2 is unavailable in the current environment, then
+    /// `None` is returned.
+    #[inline]
+    pub fn new(needle: u8) -> Option<One> {
+        if One::is_available() {
+            // SAFETY: we check that sse2 and avx2 are available above.
+            unsafe { Some(One::new_unchecked(needle)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to AVX2 vectors and routines without
+    /// checking that either SSE2 or AVX2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute both `sse2` and
+    /// `avx2` instructions in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    pub unsafe fn new_unchecked(needle: u8) -> One {
+        One {
+            sse2: generic::One::new(needle),
+            avx2: generic::One::new(needle),
+        }
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`One::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `One::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+        #[cfg(target_feature = "sse2")]
+        {
+            #[cfg(target_feature = "avx2")]
+            {
+                true
+            }
+            #[cfg(not(target_feature = "avx2"))]
+            {
+                #[cfg(feature = "std")]
+                {
+                    std::is_x86_feature_detected!("avx2")
+                }
+                #[cfg(not(feature = "std"))]
+                {
+                    false
+                }
+            }
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Counts all occurrences of this byte in the given haystack.
+    #[inline]
+    pub fn count(&self, haystack: &[u8]) -> usize {
+        // SAFETY: All of our pointers are derived directly from a borrowed
+        // slice, which is guaranteed to be valid.
+        unsafe {
+            let start = haystack.as_ptr();
+            let end = start.add(haystack.len());
+            self.count_raw(start, end)
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::fwd_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.find_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `One` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // Note that we could call `self.avx2.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `One`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless
+        // the caller code has the same target feature annotations. Namely,
+        // the common case (at time of writing) is for calling code to not
+        // have the `avx2` target feature enabled *at compile time*. Without
+        // `target_feature` on this routine, it can be inlined which will
+        // handle some of the short-haystack cases above without touching the
+        // architecture specific code.
+        self.find_raw_avx2(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::rev_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.rfind_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `One` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.avx2.rfind_raw` directly here.
+        self.rfind_raw_avx2(start, end)
+    }
+
+    /// Counts all occurrences of this byte in the given haystack represented
+    /// by raw pointers.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `0` will always be returned.
+    #[inline]
+    pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize {
+        if start >= end {
+            return 0;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::count_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.count_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `One` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        self.count_raw_avx2(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.rfind_raw(start, end)
+    }
+
+    /// Execute a count using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::count_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn count_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> usize {
+        self.sse2.count_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn find_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.find_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn rfind_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.rfind_raw(start, end)
+    }
+
+    /// Execute a count using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::count_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn count_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> usize {
+        self.avx2.count_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle byte in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> {
+        OneIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of a single byte in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`One::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`One`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct OneIter<'a, 'h> {
+    searcher: &'a One,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for OneIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.it.count(|s, e| {
+            // SAFETY: We rely on our generic iterator to return valid start
+            // and end pointers.
+            unsafe { self.searcher.count_raw(s, e) }
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {}
+
+/// Finds all occurrences of two bytes in a haystack.
+///
+/// That is, this reports matches of one of two possible bytes. For example,
+/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`,
+/// `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Two {
+    /// Used for haystacks less than 32 bytes.
+    sse2: generic::Two<__m128i>,
+    /// Used for haystacks bigger than 32 bytes.
+    avx2: generic::Two<__m256i>,
+}
+
+impl Two {
+    /// Create a new searcher that finds occurrences of the needle bytes given.
+    ///
+    /// This particular searcher is specialized to use AVX2 vector instructions
+    /// that typically make it quite fast. (SSE2 is used for haystacks that
+    /// are too short to accommodate an AVX2 vector.)
+    ///
+    /// If either SSE2 or AVX2 is unavailable in the current environment, then
+    /// `None` is returned.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8) -> Option<Two> {
+        if Two::is_available() {
+            // SAFETY: we check that sse2 and avx2 are available above.
+            unsafe { Some(Two::new_unchecked(needle1, needle2)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to AVX2 vectors and routines without
+    /// checking that either SSE2 or AVX2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute both `sse2` and
+    /// `avx2` instructions in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two {
+        Two {
+            sse2: generic::Two::new(needle1, needle2),
+            avx2: generic::Two::new(needle1, needle2),
+        }
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Two::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `Two::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+        #[cfg(target_feature = "sse2")]
+        {
+            #[cfg(target_feature = "avx2")]
+            {
+                true
+            }
+            #[cfg(not(target_feature = "avx2"))]
+            {
+                #[cfg(feature = "std")]
+                {
+                    std::is_x86_feature_detected!("avx2")
+                }
+                #[cfg(not(feature = "std"))]
+                {
+                    false
+                }
+            }
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::fwd_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1() || b == self.sse2.needle2()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.find_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `Two` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // Note that we could call `self.avx2.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `Two`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless
+        // the caller code has the same target feature annotations. Namely,
+        // the common case (at time of writing) is for calling code to not
+        // have the `avx2` target feature enabled *at compile time*. Without
+        // `target_feature` on this routine, it can be inlined which will
+        // handle some of the short-haystack cases above without touching the
+        // architecture specific code.
+        self.find_raw_avx2(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::rev_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1() || b == self.sse2.needle2()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.rfind_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `Two` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.avx2.rfind_raw` directly here.
+        self.rfind_raw_avx2(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.rfind_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn find_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.find_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn rfind_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.rfind_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle bytes in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> {
+        TwoIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of two possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Two::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Two`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct TwoIter<'a, 'h> {
+    searcher: &'a Two,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for TwoIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {}
+
+/// Finds all occurrences of three bytes in a haystack.
+///
+/// That is, this reports matches of one of three possible bytes. For example,
+/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets
+/// `0`, `2`, `3`, `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Three {
+    /// Used for haystacks less than 32 bytes.
+    sse2: generic::Three<__m128i>,
+    /// Used for haystacks bigger than 32 bytes.
+    avx2: generic::Three<__m256i>,
+}
+
+impl Three {
+    /// Create a new searcher that finds occurrences of the needle bytes given.
+    ///
+    /// This particular searcher is specialized to use AVX2 vector instructions
+    /// that typically make it quite fast. (SSE2 is used for haystacks that
+    /// are too short to accommodate an AVX2 vector.)
+    ///
+    /// If either SSE2 or AVX2 is unavailable in the current environment, then
+    /// `None` is returned.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option<Three> {
+        if Three::is_available() {
+            // SAFETY: we check that sse2 and avx2 are available above.
+            unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to AVX2 vectors and routines without
+    /// checking that either SSE2 or AVX2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute both `sse2` and
+    /// `avx2` instructions in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    pub unsafe fn new_unchecked(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+    ) -> Three {
+        Three {
+            sse2: generic::Three::new(needle1, needle2, needle3),
+            avx2: generic::Three::new(needle1, needle2, needle3),
+        }
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Three::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `Three::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+        #[cfg(target_feature = "sse2")]
+        {
+            #[cfg(target_feature = "avx2")]
+            {
+                true
+            }
+            #[cfg(not(target_feature = "avx2"))]
+            {
+                #[cfg(feature = "std")]
+                {
+                    std::is_x86_feature_detected!("avx2")
+                }
+                #[cfg(not(feature = "std"))]
+                {
+                    false
+                }
+            }
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::fwd_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1()
+                        || b == self.sse2.needle2()
+                        || b == self.sse2.needle3()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.find_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `Three` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // Note that we could call `self.avx2.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `Three`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless
+        // the caller code has the same target feature annotations. Namely,
+        // the common case (at time of writing) is for calling code to not
+        // have the `avx2` target feature enabled *at compile time*. Without
+        // `target_feature` on this routine, it can be inlined which will
+        // handle some of the short-haystack cases above without touching the
+        // architecture specific code.
+        self.find_raw_avx2(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        let len = end.distance(start);
+        if len < __m256i::BYTES {
+            return if len < __m128i::BYTES {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                generic::rev_byte_by_byte(start, end, |b| {
+                    b == self.sse2.needle1()
+                        || b == self.sse2.needle2()
+                        || b == self.sse2.needle3()
+                })
+            } else {
+                // SAFETY: We require the caller to pass valid start/end
+                // pointers.
+                self.rfind_raw_sse2(start, end)
+            };
+        }
+        // SAFETY: Building a `Three` means it's safe to call both 'sse2' and
+        // 'avx2' routines. Also, we've checked that our haystack is big
+        // enough to run on the vector routine. Pointer validity is caller's
+        // responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.avx2.rfind_raw` directly here.
+        self.rfind_raw_avx2(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_sse2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.sse2.rfind_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn find_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.find_raw(start, end)
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an AVX2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2`/`avx2` routines.)
+    #[target_feature(enable = "avx2")]
+    #[inline]
+    unsafe fn rfind_raw_avx2(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.avx2.rfind_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle bytes in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> {
+        ThreeIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of three possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Three::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Three`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct ThreeIter<'a, 'h> {
+    searcher: &'a Three,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for ThreeIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_memchr_quickcheck!(super);
+
+    #[test]
+    fn forward_one() {
+        crate::tests::memchr::Runner::new(1).forward_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0])?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_one() {
+        crate::tests::memchr::Runner::new(1).reverse_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0])?.iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn count_one() {
+        crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| {
+            Some(One::new(needles[0])?.iter(haystack).count())
+        })
+    }
+
+    #[test]
+    fn forward_two() {
+        crate::tests::memchr::Runner::new(2).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2)?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_two() {
+        crate::tests::memchr::Runner::new(2).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2)?.iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward_three() {
+        crate::tests::memchr::Runner::new(3).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3)?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_three() {
+        crate::tests::memchr::Runner::new(3).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect())
+            },
+        )
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/avx2/mod.rs.html b/src/memchr/arch/x86_64/avx2/mod.rs.html new file mode 100644 index 000000000..de688f78e --- /dev/null +++ b/src/memchr/arch/x86_64/avx2/mod.rs.html @@ -0,0 +1,13 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+
/*!
+Algorithms for the `x86_64` target using 256-bit vectors via AVX2.
+*/
+
+pub mod memchr;
+pub mod packedpair;
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/avx2/packedpair.rs.html b/src/memchr/arch/x86_64/avx2/packedpair.rs.html new file mode 100644 index 000000000..6a4723225 --- /dev/null +++ b/src/memchr/arch/x86_64/avx2/packedpair.rs.html @@ -0,0 +1,545 @@ +packedpair.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+
/*!
+A 256-bit vector implementation of the "packed pair" SIMD algorithm.
+
+The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main
+difference is that it (by default) uses a background distribution of byte
+frequencies to heuristically select the pair of bytes to search for.
+
+[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last
+*/
+
+use core::arch::x86_64::{__m128i, __m256i};
+
+use crate::arch::{all::packedpair::Pair, generic::packedpair};
+
+/// A "packed pair" finder that uses 256-bit vector operations.
+///
+/// This finder picks two bytes that it believes have high predictive power
+/// for indicating an overall match of a needle. Depending on whether
+/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets
+/// where the needle matches or could match. In the prefilter case, candidates
+/// are reported whenever the [`Pair`] of bytes given matches.
+#[derive(Clone, Copy, Debug)]
+pub struct Finder {
+    sse2: packedpair::Finder<__m128i>,
+    avx2: packedpair::Finder<__m256i>,
+}
+
+impl Finder {
+    /// Create a new pair searcher. The searcher returned can either report
+    /// exact matches of `needle` or act as a prefilter and report candidate
+    /// positions of `needle`.
+    ///
+    /// If AVX2 is unavailable in the current environment or if a [`Pair`]
+    /// could not be constructed from the needle given, then `None` is
+    /// returned.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Option<Finder> {
+        Finder::with_pair(needle, Pair::new(needle)?)
+    }
+
+    /// Create a new "packed pair" finder using the pair of bytes given.
+    ///
+    /// This constructor permits callers to control precisely which pair of
+    /// bytes is used as a predicate.
+    ///
+    /// If AVX2 is unavailable in the current environment, then `None` is
+    /// returned.
+    #[inline]
+    pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder> {
+        if Finder::is_available() {
+            // SAFETY: we check that sse2/avx2 is available above. We are also
+            // guaranteed to have needle.len() > 1 because we have a valid
+            // Pair.
+            unsafe { Some(Finder::with_pair_impl(needle, pair)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new `Finder` specific to SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as the safety for `packedpair::Finder::new`, and callers must also
+    /// ensure that both SSE2 and AVX2 are available.
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder {
+        let sse2 = packedpair::Finder::<__m128i>::new(needle, pair);
+        let avx2 = packedpair::Finder::<__m256i>::new(needle, pair);
+        Finder { sse2, avx2 }
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Finder::with_pair`] will
+    /// return a `Some` value. Similarly, when it is false, it is guaranteed
+    /// that `Finder::with_pair` will return a `None` value. Notice that this
+    /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely,
+    /// even when `Finder::is_available` is true, it is not guaranteed that a
+    /// valid [`Pair`] can be found from the needle given.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+        #[cfg(target_feature = "sse2")]
+        {
+            #[cfg(target_feature = "avx2")]
+            {
+                true
+            }
+            #[cfg(not(target_feature = "avx2"))]
+            {
+                #[cfg(feature = "std")]
+                {
+                    std::is_x86_feature_detected!("avx2")
+                }
+                #[cfg(not(feature = "std"))]
+                {
+                    false
+                }
+            }
+        }
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    #[inline]
+    pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines.
+        unsafe { self.find_impl(haystack, needle) }
+    }
+
+    /// Run this finder on the given haystack as a prefilter.
+    ///
+    /// If a candidate match is found, then an offset where the needle *could*
+    /// begin in the haystack is returned.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    #[inline]
+    pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines.
+        unsafe { self.find_prefilter_impl(haystack) }
+    }
+
+    /// Execute a search using AVX2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Finder`, which can only be constructed
+    /// when it is safe to call `sse2` and `avx2` routines.)
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    unsafe fn find_impl(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        if haystack.len() < self.avx2.min_haystack_len() {
+            self.sse2.find(haystack, needle)
+        } else {
+            self.avx2.find(haystack, needle)
+        }
+    }
+
+    /// Execute a prefilter search using AVX2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Finder`, which can only be constructed
+    /// when it is safe to call `sse2` and `avx2` routines.)
+    #[target_feature(enable = "sse2", enable = "avx2")]
+    #[inline]
+    unsafe fn find_prefilter_impl(&self, haystack: &[u8]) -> Option<usize> {
+        if haystack.len() < self.avx2.min_haystack_len() {
+            self.sse2.find_prefilter(haystack)
+        } else {
+            self.avx2.find_prefilter(haystack)
+        }
+    }
+
+    /// Returns the pair of offsets (into the needle) used to check as a
+    /// predicate before confirming whether a needle exists at a particular
+    /// position.
+    #[inline]
+    pub fn pair(&self) -> &Pair {
+        self.avx2.pair()
+    }
+
+    /// Returns the minimum haystack length that this `Finder` can search.
+    ///
+    /// Using a haystack with length smaller than this in a search will result
+    /// in a panic. The reason for this restriction is that this finder is
+    /// meant to be a low-level component that is part of a larger substring
+    /// strategy. In that sense, it avoids trying to handle all cases and
+    /// instead only handles the cases that it can handle very well.
+    #[inline]
+    pub fn min_haystack_len(&self) -> usize {
+        // The caller doesn't need to care about AVX2's min_haystack_len
+        // since this implementation will automatically switch to the SSE2
+        // implementation if the haystack is too short for AVX2. Therefore, the
+        // caller only needs to care about SSE2's min_haystack_len.
+        //
+        // This does assume that SSE2's min_haystack_len is less than or
+        // equal to AVX2's min_haystack_len. In practice, this is true and
+        // there is no way it could be false based on how this Finder is
+        // implemented. Namely, both SSE2 and AVX2 use the same `Pair`. If
+        // they used different pairs, then it's possible (although perhaps
+        // pathological) for SSE2's min_haystack_len to be bigger than AVX2's.
+        self.sse2.min_haystack_len()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn find(haystack: &[u8], needle: &[u8]) -> Option<Option<usize>> {
+        let f = Finder::new(needle)?;
+        if haystack.len() < f.min_haystack_len() {
+            return None;
+        }
+        Some(f.find(haystack, needle))
+    }
+
+    define_substring_forward_quickcheck!(find);
+
+    #[test]
+    fn forward_substring() {
+        crate::tests::substring::Runner::new().fwd(find).run()
+    }
+
+    #[test]
+    fn forward_packedpair() {
+        fn find(
+            haystack: &[u8],
+            needle: &[u8],
+            index1: u8,
+            index2: u8,
+        ) -> Option<Option<usize>> {
+            let pair = Pair::with_indices(needle, index1, index2)?;
+            let f = Finder::with_pair(needle, pair)?;
+            if haystack.len() < f.min_haystack_len() {
+                return None;
+            }
+            Some(f.find(haystack, needle))
+        }
+        crate::tests::packedpair::Runner::new().fwd(find).run()
+    }
+
+    #[test]
+    fn forward_packedpair_prefilter() {
+        fn find(
+            haystack: &[u8],
+            needle: &[u8],
+            index1: u8,
+            index2: u8,
+        ) -> Option<Option<usize>> {
+            if !cfg!(target_feature = "sse2") {
+                return None;
+            }
+            let pair = Pair::with_indices(needle, index1, index2)?;
+            let f = Finder::with_pair(needle, pair)?;
+            if haystack.len() < f.min_haystack_len() {
+                return None;
+            }
+            Some(f.find_prefilter(haystack))
+        }
+        crate::tests::packedpair::Runner::new().fwd(find).run()
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/memchr.rs.html b/src/memchr/arch/x86_64/memchr.rs.html new file mode 100644 index 000000000..5ebcd238c --- /dev/null +++ b/src/memchr/arch/x86_64/memchr.rs.html @@ -0,0 +1,671 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+
/*!
+Wrapper routines for `memchr` and friends.
+
+These routines efficiently dispatch to the best implementation based on what
+the CPU supports.
+*/
+
+/// Provides a way to run a memchr-like function while amortizing the cost of
+/// runtime CPU feature detection.
+///
+/// This works by loading a function pointer from an atomic global. Initially,
+/// this global is set to a function that does CPU feature detection. For
+/// example, if AVX2 is enabled, then the AVX2 implementation is used.
+/// Otherwise, at least on x86_64, the SSE2 implementation is used. (And
+/// in some niche cases, if SSE2 isn't available, then the architecture
+/// independent fallback implementation is used.)
+///
+/// After the first call to this function, the atomic global is replaced with
+/// the specific AVX2, SSE2 or fallback routine chosen. Subsequent calls then
+/// will directly call the chosen routine instead of needing to go through the
+/// CPU feature detection branching again.
+///
+/// This particular macro is specifically written to provide the implementation
+/// of functions with the following signature:
+///
+/// ```ignore
+/// fn memchr(needle1: u8, start: *const u8, end: *const u8) -> Option<usize>;
+/// ```
+///
+/// Where you can also have `memchr2` and `memchr3`, but with `needle2` and
+/// `needle3`, respectively. The `start` and `end` parameters correspond to the
+/// start and end of the haystack, respectively.
+///
+/// We use raw pointers here instead of the more obvious `haystack: &[u8]` so
+/// that the function is compatible with our lower level iterator logic that
+/// operates on raw pointers. We use this macro to implement "raw" memchr
+/// routines with the signature above, and then define memchr routines using
+/// regular slices on top of them.
+///
+/// Note that we use `#[cfg(target_feature = "sse2")]` below even though
+/// it shouldn't be strictly necessary because without it, it seems to
+/// cause the compiler to blow up. I guess it can't handle a function
+/// pointer being created with a sse target feature? Dunno. See the
+/// `build-for-x86-64-but-non-sse-target` CI job if you want to experiment with
+/// this.
+///
+/// # Safety
+///
+/// Primarily callers must that `$fnty` is a correct function pointer type and
+/// not something else.
+///
+/// Callers must also ensure that `$memchrty::$memchrfind` corresponds to a
+/// routine that returns a valid function pointer when a match is found. That
+/// is, a pointer that is `>= start` and `< end`.
+///
+/// Callers must also ensure that the `$hay_start` and `$hay_end` identifiers
+/// correspond to valid pointers.
+macro_rules! unsafe_ifunc {
+    (
+        $memchrty:ident,
+        $memchrfind:ident,
+        $fnty:ty,
+        $retty:ty,
+        $hay_start:ident,
+        $hay_end:ident,
+        $($needle:ident),+
+    ) => {{
+        #![allow(unused_unsafe)]
+
+        use core::sync::atomic::{AtomicPtr, Ordering};
+
+        type Fn = *mut ();
+        type RealFn = $fnty;
+        static FN: AtomicPtr<()> = AtomicPtr::new(detect as Fn);
+
+        #[cfg(target_feature = "sse2")]
+        #[target_feature(enable = "sse2", enable = "avx2")]
+        unsafe fn find_avx2(
+            $($needle: u8),+,
+            $hay_start: *const u8,
+            $hay_end: *const u8,
+        ) -> $retty {
+            use crate::arch::x86_64::avx2::memchr::$memchrty;
+            $memchrty::new_unchecked($($needle),+)
+                .$memchrfind($hay_start, $hay_end)
+        }
+
+        #[cfg(target_feature = "sse2")]
+        #[target_feature(enable = "sse2")]
+        unsafe fn find_sse2(
+            $($needle: u8),+,
+            $hay_start: *const u8,
+            $hay_end: *const u8,
+        ) -> $retty {
+            use crate::arch::x86_64::sse2::memchr::$memchrty;
+            $memchrty::new_unchecked($($needle),+)
+                .$memchrfind($hay_start, $hay_end)
+        }
+
+        unsafe fn find_fallback(
+            $($needle: u8),+,
+            $hay_start: *const u8,
+            $hay_end: *const u8,
+        ) -> $retty {
+            use crate::arch::all::memchr::$memchrty;
+            $memchrty::new($($needle),+).$memchrfind($hay_start, $hay_end)
+        }
+
+        unsafe fn detect(
+            $($needle: u8),+,
+            $hay_start: *const u8,
+            $hay_end: *const u8,
+        ) -> $retty {
+            let fun = {
+                #[cfg(not(target_feature = "sse2"))]
+                {
+                    debug!(
+                        "no sse2 feature available, using fallback for {}",
+                        stringify!($memchrty),
+                    );
+                    find_fallback as RealFn
+                }
+                #[cfg(target_feature = "sse2")]
+                {
+                    use crate::arch::x86_64::{sse2, avx2};
+                    if avx2::memchr::$memchrty::is_available() {
+                        debug!("chose AVX2 for {}", stringify!($memchrty));
+                        find_avx2 as RealFn
+                    } else if sse2::memchr::$memchrty::is_available() {
+                        debug!("chose SSE2 for {}", stringify!($memchrty));
+                        find_sse2 as RealFn
+                    } else {
+                        debug!("chose fallback for {}", stringify!($memchrty));
+                        find_fallback as RealFn
+                    }
+                }
+            };
+            FN.store(fun as Fn, Ordering::Relaxed);
+            // SAFETY: The only thing we need to uphold here is the
+            // `#[target_feature]` requirements. Since we check is_available
+            // above before using the corresponding implementation, we are
+            // guaranteed to only call code that is supported on the current
+            // CPU.
+            fun($($needle),+, $hay_start, $hay_end)
+        }
+
+        // SAFETY: By virtue of the caller contract, RealFn is a function
+        // pointer, which is always safe to transmute with a *mut (). Also,
+        // since we use $memchrty::is_available, it is guaranteed to be safe
+        // to call $memchrty::$memchrfind.
+        unsafe {
+            let fun = FN.load(Ordering::Relaxed);
+            core::mem::transmute::<Fn, RealFn>(fun)(
+                $($needle),+,
+                $hay_start,
+                $hay_end,
+            )
+        }
+    }};
+}
+
+// The routines below dispatch to AVX2, SSE2 or a fallback routine based on
+// what's available in the current environment. The secret sauce here is that
+// we only check for which one to use approximately once, and then "cache" that
+// choice into a global function pointer. Subsequent invocations then just call
+// the appropriate function directly.
+
+/// memchr, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::find_raw`.
+#[inline(always)]
+pub(crate) fn memchr_raw(
+    n1: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        One,
+        find_raw,
+        unsafe fn(u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1
+    )
+}
+
+/// memrchr, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::rfind_raw`.
+#[inline(always)]
+pub(crate) fn memrchr_raw(
+    n1: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        One,
+        rfind_raw,
+        unsafe fn(u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1
+    )
+}
+
+/// memchr2, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Two::find_raw`.
+#[inline(always)]
+pub(crate) fn memchr2_raw(
+    n1: u8,
+    n2: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        Two,
+        find_raw,
+        unsafe fn(u8, u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1,
+        n2
+    )
+}
+
+/// memrchr2, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Two::rfind_raw`.
+#[inline(always)]
+pub(crate) fn memrchr2_raw(
+    n1: u8,
+    n2: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        Two,
+        rfind_raw,
+        unsafe fn(u8, u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1,
+        n2
+    )
+}
+
+/// memchr3, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Three::find_raw`.
+#[inline(always)]
+pub(crate) fn memchr3_raw(
+    n1: u8,
+    n2: u8,
+    n3: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        Three,
+        find_raw,
+        unsafe fn(u8, u8, u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1,
+        n2,
+        n3
+    )
+}
+
+/// memrchr3, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Three::rfind_raw`.
+#[inline(always)]
+pub(crate) fn memrchr3_raw(
+    n1: u8,
+    n2: u8,
+    n3: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        Three,
+        rfind_raw,
+        unsafe fn(u8, u8, u8, *const u8, *const u8) -> Option<*const u8>,
+        Option<*const u8>,
+        start,
+        end,
+        n1,
+        n2,
+        n3
+    )
+}
+
+/// Count all matching bytes, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::count_raw`.
+#[inline(always)]
+pub(crate) fn count_raw(n1: u8, start: *const u8, end: *const u8) -> usize {
+    // SAFETY: We provide a valid function pointer type.
+    unsafe_ifunc!(
+        One,
+        count_raw,
+        unsafe fn(u8, *const u8, *const u8) -> usize,
+        usize,
+        start,
+        end,
+        n1
+    )
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/mod.rs.html b/src/memchr/arch/x86_64/mod.rs.html new file mode 100644 index 000000000..15ae56731 --- /dev/null +++ b/src/memchr/arch/x86_64/mod.rs.html @@ -0,0 +1,17 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+
/*!
+Vector algorithms for the `x86_64` target.
+*/
+
+pub mod avx2;
+pub mod sse2;
+
+pub(crate) mod memchr;
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/sse2/memchr.rs.html b/src/memchr/arch/x86_64/sse2/memchr.rs.html new file mode 100644 index 000000000..f91f9ff1b --- /dev/null +++ b/src/memchr/arch/x86_64/sse2/memchr.rs.html @@ -0,0 +1,2155 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+
/*!
+This module defines 128-bit vector implementations of `memchr` and friends.
+
+The main types in this module are [`One`], [`Two`] and [`Three`]. They are for
+searching for one, two or three distinct bytes, respectively, in a haystack.
+Each type also has corresponding double ended iterators. These searchers are
+typically much faster than scalar routines accomplishing the same task.
+
+The `One` searcher also provides a [`One::count`] routine for efficiently
+counting the number of times a single byte occurs in a haystack. This is
+useful, for example, for counting the number of lines in a haystack. This
+routine exists because it is usually faster, especially with a high match
+count, then using [`One::find`] repeatedly. ([`OneIter`] specializes its
+`Iterator::count` implementation to use this routine.)
+
+Only one, two and three bytes are supported because three bytes is about
+the point where one sees diminishing returns. Beyond this point and it's
+probably (but not necessarily) better to just use a simple `[bool; 256]` array
+or similar. However, it depends mightily on the specific work-load and the
+expected match frequency.
+*/
+
+use core::arch::x86_64::__m128i;
+
+use crate::{arch::generic::memchr as generic, ext::Pointer, vector::Vector};
+
+/// Finds all occurrences of a single byte in a haystack.
+#[derive(Clone, Copy, Debug)]
+pub struct One(generic::One<__m128i>);
+
+impl One {
+    /// Create a new searcher that finds occurrences of the needle byte given.
+    ///
+    /// This particular searcher is specialized to use SSE2 vector instructions
+    /// that typically make it quite fast.
+    ///
+    /// If SSE2 is unavailable in the current environment, then `None` is
+    /// returned.
+    #[inline]
+    pub fn new(needle: u8) -> Option<One> {
+        if One::is_available() {
+            // SAFETY: we check that sse2 is available above.
+            unsafe { Some(One::new_unchecked(needle)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to SSE2 vectors and routines without
+    /// checking that SSE2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute `sse2` instructions
+    /// in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    pub unsafe fn new_unchecked(needle: u8) -> One {
+        One(generic::One::new(needle))
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`One::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `One::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(target_feature = "sse2")]
+        {
+            true
+        }
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Counts all occurrences of this byte in the given haystack.
+    #[inline]
+    pub fn count(&self, haystack: &[u8]) -> usize {
+        // SAFETY: All of our pointers are derived directly from a borrowed
+        // slice, which is guaranteed to be valid.
+        unsafe {
+            let start = haystack.as_ptr();
+            let end = start.add(haystack.len());
+            self.count_raw(start, end)
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::fwd_byte_by_byte(start, end, |b| {
+                b == self.0.needle1()
+            });
+        }
+        // SAFETY: Building a `One` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // Note that we could call `self.0.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `One`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless the
+        // caller code has the same target feature annotations. Which is maybe
+        // okay for SSE2, but we do the same thing for AVX2 where caller code
+        // probably usually doesn't have AVX2 enabled. That means that this
+        // routine can be inlined which will handle some of the short-haystack
+        // cases above without touching the architecture specific code.
+        self.find_raw_impl(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::rev_byte_by_byte(start, end, |b| {
+                b == self.0.needle1()
+            });
+        }
+        // SAFETY: Building a `One` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.0.rfind_raw` directly here.
+        self.rfind_raw_impl(start, end)
+    }
+
+    /// Counts all occurrences of this byte in the given haystack represented
+    /// by raw pointers.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `0` will always be returned.
+    #[inline]
+    pub unsafe fn count_raw(&self, start: *const u8, end: *const u8) -> usize {
+        if start >= end {
+            return 0;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::count_byte_by_byte(start, end, |b| {
+                b == self.0.needle1()
+            });
+        }
+        // SAFETY: Building a `One` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        self.count_raw_impl(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.rfind_raw(start, end)
+    }
+
+    /// Execute a count using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`One::count_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `One`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn count_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> usize {
+        self.0.count_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle byte in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> OneIter<'a, 'h> {
+        OneIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of a single byte in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`One::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`One`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct OneIter<'a, 'h> {
+    searcher: &'a One,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for OneIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.it.count(|s, e| {
+            // SAFETY: We rely on our generic iterator to return valid start
+            // and end pointers.
+            unsafe { self.searcher.count_raw(s, e) }
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for OneIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for OneIter<'a, 'h> {}
+
+/// Finds all occurrences of two bytes in a haystack.
+///
+/// That is, this reports matches of one of two possible bytes. For example,
+/// searching for `a` or `b` in `afoobar` would report matches at offsets `0`,
+/// `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Two(generic::Two<__m128i>);
+
+impl Two {
+    /// Create a new searcher that finds occurrences of the needle bytes given.
+    ///
+    /// This particular searcher is specialized to use SSE2 vector instructions
+    /// that typically make it quite fast.
+    ///
+    /// If SSE2 is unavailable in the current environment, then `None` is
+    /// returned.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8) -> Option<Two> {
+        if Two::is_available() {
+            // SAFETY: we check that sse2 is available above.
+            unsafe { Some(Two::new_unchecked(needle1, needle2)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to SSE2 vectors and routines without
+    /// checking that SSE2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute `sse2` instructions
+    /// in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    pub unsafe fn new_unchecked(needle1: u8, needle2: u8) -> Two {
+        Two(generic::Two::new(needle1, needle2))
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Two::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `Two::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(target_feature = "sse2")]
+        {
+            true
+        }
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::fwd_byte_by_byte(start, end, |b| {
+                b == self.0.needle1() || b == self.0.needle2()
+            });
+        }
+        // SAFETY: Building a `Two` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // Note that we could call `self.0.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `Two`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless the
+        // caller code has the same target feature annotations. Which is maybe
+        // okay for SSE2, but we do the same thing for AVX2 where caller code
+        // probably usually doesn't have AVX2 enabled. That means that this
+        // routine can be inlined which will handle some of the short-haystack
+        // cases above without touching the architecture specific code.
+        self.find_raw_impl(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::rev_byte_by_byte(start, end, |b| {
+                b == self.0.needle1() || b == self.0.needle2()
+            });
+        }
+        // SAFETY: Building a `Two` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.0.rfind_raw` directly here.
+        self.rfind_raw_impl(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Two::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Two`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.rfind_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle bytes in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> TwoIter<'a, 'h> {
+        TwoIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of two possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Two::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Two`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct TwoIter<'a, 'h> {
+    searcher: &'a Two,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for TwoIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for TwoIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for TwoIter<'a, 'h> {}
+
+/// Finds all occurrences of three bytes in a haystack.
+///
+/// That is, this reports matches of one of three possible bytes. For example,
+/// searching for `a`, `b` or `o` in `afoobar` would report matches at offsets
+/// `0`, `2`, `3`, `4` and `5`.
+#[derive(Clone, Copy, Debug)]
+pub struct Three(generic::Three<__m128i>);
+
+impl Three {
+    /// Create a new searcher that finds occurrences of the needle bytes given.
+    ///
+    /// This particular searcher is specialized to use SSE2 vector instructions
+    /// that typically make it quite fast.
+    ///
+    /// If SSE2 is unavailable in the current environment, then `None` is
+    /// returned.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8, needle3: u8) -> Option<Three> {
+        if Three::is_available() {
+            // SAFETY: we check that sse2 is available above.
+            unsafe { Some(Three::new_unchecked(needle1, needle2, needle3)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new finder specific to SSE2 vectors and routines without
+    /// checking that SSE2 is available.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that it is safe to execute `sse2` instructions
+    /// in the current environment.
+    ///
+    /// Note that it is a common misconception that if one compiles for an
+    /// `x86_64` target, then they therefore automatically have access to SSE2
+    /// instructions. While this is almost always the case, it isn't true in
+    /// 100% of cases.
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    pub unsafe fn new_unchecked(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+    ) -> Three {
+        Three(generic::Three::new(needle1, needle2, needle3))
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Three::new`] will return
+    /// a `Some` value. Similarly, when it is false, it is guaranteed that
+    /// `Three::new` will return a `None` value.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(target_feature = "sse2")]
+        {
+            true
+        }
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+    }
+
+    /// Return the first occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `find_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.find_raw(s, e)
+            })
+        }
+    }
+
+    /// Return the last occurrence of one of the needle bytes in the given
+    /// haystack. If no such occurrence exists, then `None` is returned.
+    ///
+    /// The occurrence is reported as an offset into `haystack`. Its maximum
+    /// value is `haystack.len() - 1`.
+    #[inline]
+    pub fn rfind(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: `rfind_raw` guarantees that if a pointer is returned, it
+        // falls within the bounds of the start and end pointers.
+        unsafe {
+            generic::search_slice_with_raw(haystack, |s, e| {
+                self.rfind_raw(s, e)
+            })
+        }
+    }
+
+    /// Like `find`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn find_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::fwd_byte_by_byte(start, end, |b| {
+                b == self.0.needle1()
+                    || b == self.0.needle2()
+                    || b == self.0.needle3()
+            });
+        }
+        // SAFETY: Building a `Three` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // Note that we could call `self.0.find_raw` directly here. But that
+        // means we'd have to annotate this routine with `target_feature`.
+        // Which is fine, because this routine is `unsafe` anyway and the
+        // `target_feature` obligation is met by virtue of building a `Three`.
+        // The real problem is that a routine with a `target_feature`
+        // annotation generally can't be inlined into caller code unless the
+        // caller code has the same target feature annotations. Which is maybe
+        // okay for SSE2, but we do the same thing for AVX2 where caller code
+        // probably usually doesn't have AVX2 enabled. That means that this
+        // routine can be inlined which will handle some of the short-haystack
+        // cases above without touching the architecture specific code.
+        self.find_raw_impl(start, end)
+    }
+
+    /// Like `rfind`, but accepts and returns raw pointers.
+    ///
+    /// When a match is found, the pointer returned is guaranteed to be
+    /// `>= start` and `< end`.
+    ///
+    /// This routine is useful if you're already using raw pointers and would
+    /// like to avoid converting back to a slice before executing a search.
+    ///
+    /// # Safety
+    ///
+    /// * Both `start` and `end` must be valid for reads.
+    /// * Both `start` and `end` must point to an initialized value.
+    /// * Both `start` and `end` must point to the same allocated object and
+    /// must either be in bounds or at most one byte past the end of the
+    /// allocated object.
+    /// * Both `start` and `end` must be _derived from_ a pointer to the same
+    /// object.
+    /// * The distance between `start` and `end` must not overflow `isize`.
+    /// * The distance being in bounds must not rely on "wrapping around" the
+    /// address space.
+    ///
+    /// Note that callers may pass a pair of pointers such that `start >= end`.
+    /// In that case, `None` will always be returned.
+    #[inline]
+    pub unsafe fn rfind_raw(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        if start >= end {
+            return None;
+        }
+        if end.distance(start) < __m128i::BYTES {
+            // SAFETY: We require the caller to pass valid start/end pointers.
+            return generic::rev_byte_by_byte(start, end, |b| {
+                b == self.0.needle1()
+                    || b == self.0.needle2()
+                    || b == self.0.needle3()
+            });
+        }
+        // SAFETY: Building a `Three` means it's safe to call 'sse2' routines.
+        // Also, we've checked that our haystack is big enough to run on the
+        // vector routine. Pointer validity is caller's responsibility.
+        //
+        // See note in forward routine above for why we don't just call
+        // `self.0.rfind_raw` directly here.
+        self.rfind_raw_impl(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::find_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.find_raw(start, end)
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as [`Three::rfind_raw`], except the distance between `start` and
+    /// `end` must be at least the size of an SSE2 vector (in bytes).
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Three`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn rfind_raw_impl(
+        &self,
+        start: *const u8,
+        end: *const u8,
+    ) -> Option<*const u8> {
+        self.0.rfind_raw(start, end)
+    }
+
+    /// Returns an iterator over all occurrences of the needle byte in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn iter<'a, 'h>(&'a self, haystack: &'h [u8]) -> ThreeIter<'a, 'h> {
+        ThreeIter { searcher: self, it: generic::Iter::new(haystack) }
+    }
+}
+
+/// An iterator over all occurrences of three possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`Three::iter`] method.
+///
+/// The lifetime parameters are as follows:
+///
+/// * `'a` refers to the lifetime of the underlying [`Three`] searcher.
+/// * `'h` refers to the lifetime of the haystack being searched.
+#[derive(Clone, Debug)]
+pub struct ThreeIter<'a, 'h> {
+    searcher: &'a Three,
+    it: generic::Iter<'h>,
+}
+
+impl<'a, 'h> Iterator for ThreeIter<'a, 'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'find_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next(|s, e| self.searcher.find_raw(s, e)) }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'a, 'h> DoubleEndedIterator for ThreeIter<'a, 'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: We rely on the generic iterator to provide valid start
+        // and end pointers, but we guarantee that any pointer returned by
+        // 'rfind_raw' falls within the bounds of the start and end pointer.
+        unsafe { self.it.next_back(|s, e| self.searcher.rfind_raw(s, e)) }
+    }
+}
+
+impl<'a, 'h> core::iter::FusedIterator for ThreeIter<'a, 'h> {}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_memchr_quickcheck!(super);
+
+    #[test]
+    fn forward_one() {
+        crate::tests::memchr::Runner::new(1).forward_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0])?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_one() {
+        crate::tests::memchr::Runner::new(1).reverse_iter(
+            |haystack, needles| {
+                Some(One::new(needles[0])?.iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn count_one() {
+        crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| {
+            Some(One::new(needles[0])?.iter(haystack).count())
+        })
+    }
+
+    #[test]
+    fn forward_two() {
+        crate::tests::memchr::Runner::new(2).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2)?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_two() {
+        crate::tests::memchr::Runner::new(2).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(Two::new(n1, n2)?.iter(haystack).rev().collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward_three() {
+        crate::tests::memchr::Runner::new(3).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3)?.iter(haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse_three() {
+        crate::tests::memchr::Runner::new(3).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(Three::new(n1, n2, n3)?.iter(haystack).rev().collect())
+            },
+        )
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/sse2/mod.rs.html b/src/memchr/arch/x86_64/sse2/mod.rs.html new file mode 100644 index 000000000..e4b8073a6 --- /dev/null +++ b/src/memchr/arch/x86_64/sse2/mod.rs.html @@ -0,0 +1,13 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+
/*!
+Algorithms for the `x86_64` target using 128-bit vectors via SSE2.
+*/
+
+pub mod memchr;
+pub mod packedpair;
+
\ No newline at end of file diff --git a/src/memchr/arch/x86_64/sse2/packedpair.rs.html b/src/memchr/arch/x86_64/sse2/packedpair.rs.html new file mode 100644 index 000000000..92fde00e7 --- /dev/null +++ b/src/memchr/arch/x86_64/sse2/packedpair.rs.html @@ -0,0 +1,465 @@ +packedpair.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+
/*!
+A 128-bit vector implementation of the "packed pair" SIMD algorithm.
+
+The "packed pair" algorithm is based on the [generic SIMD] algorithm. The main
+difference is that it (by default) uses a background distribution of byte
+frequencies to heuristically select the pair of bytes to search for.
+
+[generic SIMD]: http://0x80.pl/articles/simd-strfind.html#first-and-last
+*/
+
+use core::arch::x86_64::__m128i;
+
+use crate::arch::{all::packedpair::Pair, generic::packedpair};
+
+/// A "packed pair" finder that uses 128-bit vector operations.
+///
+/// This finder picks two bytes that it believes have high predictive power
+/// for indicating an overall match of a needle. Depending on whether
+/// `Finder::find` or `Finder::find_prefilter` is used, it reports offsets
+/// where the needle matches or could match. In the prefilter case, candidates
+/// are reported whenever the [`Pair`] of bytes given matches.
+#[derive(Clone, Copy, Debug)]
+pub struct Finder(packedpair::Finder<__m128i>);
+
+impl Finder {
+    /// Create a new pair searcher. The searcher returned can either report
+    /// exact matches of `needle` or act as a prefilter and report candidate
+    /// positions of `needle`.
+    ///
+    /// If SSE2 is unavailable in the current environment or if a [`Pair`]
+    /// could not be constructed from the needle given, then `None` is
+    /// returned.
+    #[inline]
+    pub fn new(needle: &[u8]) -> Option<Finder> {
+        Finder::with_pair(needle, Pair::new(needle)?)
+    }
+
+    /// Create a new "packed pair" finder using the pair of bytes given.
+    ///
+    /// This constructor permits callers to control precisely which pair of
+    /// bytes is used as a predicate.
+    ///
+    /// If SSE2 is unavailable in the current environment, then `None` is
+    /// returned.
+    #[inline]
+    pub fn with_pair(needle: &[u8], pair: Pair) -> Option<Finder> {
+        if Finder::is_available() {
+            // SAFETY: we check that sse2 is available above. We are also
+            // guaranteed to have needle.len() > 1 because we have a valid
+            // Pair.
+            unsafe { Some(Finder::with_pair_impl(needle, pair)) }
+        } else {
+            None
+        }
+    }
+
+    /// Create a new `Finder` specific to SSE2 vectors and routines.
+    ///
+    /// # Safety
+    ///
+    /// Same as the safety for `packedpair::Finder::new`, and callers must also
+    /// ensure that SSE2 is available.
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn with_pair_impl(needle: &[u8], pair: Pair) -> Finder {
+        let finder = packedpair::Finder::<__m128i>::new(needle, pair);
+        Finder(finder)
+    }
+
+    /// Returns true when this implementation is available in the current
+    /// environment.
+    ///
+    /// When this is true, it is guaranteed that [`Finder::with_pair`] will
+    /// return a `Some` value. Similarly, when it is false, it is guaranteed
+    /// that `Finder::with_pair` will return a `None` value. Notice that this
+    /// does not guarantee that [`Finder::new`] will return a `Finder`. Namely,
+    /// even when `Finder::is_available` is true, it is not guaranteed that a
+    /// valid [`Pair`] can be found from the needle given.
+    ///
+    /// Note also that for the lifetime of a single program, if this returns
+    /// true then it will always return true.
+    #[inline]
+    pub fn is_available() -> bool {
+        #[cfg(not(target_feature = "sse2"))]
+        {
+            false
+        }
+        #[cfg(target_feature = "sse2")]
+        {
+            true
+        }
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    #[inline]
+    pub fn find(&self, haystack: &[u8], needle: &[u8]) -> Option<usize> {
+        // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines.
+        unsafe { self.find_impl(haystack, needle) }
+    }
+
+    /// Run this finder on the given haystack as a prefilter.
+    ///
+    /// If a candidate match is found, then an offset where the needle *could*
+    /// begin in the haystack is returned.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    #[inline]
+    pub fn find_prefilter(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: Building a `Finder` means it's safe to call 'sse2' routines.
+        unsafe { self.find_prefilter_impl(haystack) }
+    }
+
+    /// Execute a search using SSE2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Finder`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_impl(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        self.0.find(haystack, needle)
+    }
+
+    /// Execute a prefilter search using SSE2 vectors and routines.
+    ///
+    /// # Panics
+    ///
+    /// When `haystack.len()` is less than [`Finder::min_haystack_len`].
+    ///
+    /// # Safety
+    ///
+    /// (The target feature safety obligation is automatically fulfilled by
+    /// virtue of being a method on `Finder`, which can only be constructed
+    /// when it is safe to call `sse2` routines.)
+    #[target_feature(enable = "sse2")]
+    #[inline]
+    unsafe fn find_prefilter_impl(&self, haystack: &[u8]) -> Option<usize> {
+        self.0.find_prefilter(haystack)
+    }
+
+    /// Returns the pair of offsets (into the needle) used to check as a
+    /// predicate before confirming whether a needle exists at a particular
+    /// position.
+    #[inline]
+    pub fn pair(&self) -> &Pair {
+        self.0.pair()
+    }
+
+    /// Returns the minimum haystack length that this `Finder` can search.
+    ///
+    /// Using a haystack with length smaller than this in a search will result
+    /// in a panic. The reason for this restriction is that this finder is
+    /// meant to be a low-level component that is part of a larger substring
+    /// strategy. In that sense, it avoids trying to handle all cases and
+    /// instead only handles the cases that it can handle very well.
+    #[inline]
+    pub fn min_haystack_len(&self) -> usize {
+        self.0.min_haystack_len()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn find(haystack: &[u8], needle: &[u8]) -> Option<Option<usize>> {
+        let f = Finder::new(needle)?;
+        if haystack.len() < f.min_haystack_len() {
+            return None;
+        }
+        Some(f.find(haystack, needle))
+    }
+
+    define_substring_forward_quickcheck!(find);
+
+    #[test]
+    fn forward_substring() {
+        crate::tests::substring::Runner::new().fwd(find).run()
+    }
+
+    #[test]
+    fn forward_packedpair() {
+        fn find(
+            haystack: &[u8],
+            needle: &[u8],
+            index1: u8,
+            index2: u8,
+        ) -> Option<Option<usize>> {
+            let pair = Pair::with_indices(needle, index1, index2)?;
+            let f = Finder::with_pair(needle, pair)?;
+            if haystack.len() < f.min_haystack_len() {
+                return None;
+            }
+            Some(f.find(haystack, needle))
+        }
+        crate::tests::packedpair::Runner::new().fwd(find).run()
+    }
+
+    #[test]
+    fn forward_packedpair_prefilter() {
+        fn find(
+            haystack: &[u8],
+            needle: &[u8],
+            index1: u8,
+            index2: u8,
+        ) -> Option<Option<usize>> {
+            let pair = Pair::with_indices(needle, index1, index2)?;
+            let f = Finder::with_pair(needle, pair)?;
+            if haystack.len() < f.min_haystack_len() {
+                return None;
+            }
+            Some(f.find_prefilter(haystack))
+        }
+        crate::tests::packedpair::Runner::new().fwd(find).run()
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/cow.rs.html b/src/memchr/cow.rs.html new file mode 100644 index 000000000..51ad815f7 --- /dev/null +++ b/src/memchr/cow.rs.html @@ -0,0 +1,215 @@ +cow.rs - source
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
+
use core::ops;
+
+/// A specialized copy-on-write byte string.
+///
+/// The purpose of this type is to permit usage of a "borrowed or owned
+/// byte string" in a way that keeps std/no-std compatibility. That is, in
+/// no-std/alloc mode, this type devolves into a simple &[u8] with no owned
+/// variant available. We can't just use a plain Cow because Cow is not in
+/// core.
+#[derive(Clone, Debug)]
+pub struct CowBytes<'a>(Imp<'a>);
+
+// N.B. We don't use alloc::borrow::Cow here since we can get away with a
+// Box<[u8]> for our use case, which is 1/3 smaller than the Vec<u8> that
+// a Cow<[u8]> would use.
+#[cfg(feature = "alloc")]
+#[derive(Clone, Debug)]
+enum Imp<'a> {
+    Borrowed(&'a [u8]),
+    Owned(alloc::boxed::Box<[u8]>),
+}
+
+#[cfg(not(feature = "alloc"))]
+#[derive(Clone, Debug)]
+struct Imp<'a>(&'a [u8]);
+
+impl<'a> ops::Deref for CowBytes<'a> {
+    type Target = [u8];
+
+    #[inline(always)]
+    fn deref(&self) -> &[u8] {
+        self.as_slice()
+    }
+}
+
+impl<'a> CowBytes<'a> {
+    /// Create a new borrowed CowBytes.
+    #[inline(always)]
+    pub(crate) fn new<B: ?Sized + AsRef<[u8]>>(bytes: &'a B) -> CowBytes<'a> {
+        CowBytes(Imp::new(bytes.as_ref()))
+    }
+
+    /// Create a new owned CowBytes.
+    #[cfg(feature = "alloc")]
+    #[inline(always)]
+    fn new_owned(bytes: alloc::boxed::Box<[u8]>) -> CowBytes<'static> {
+        CowBytes(Imp::Owned(bytes))
+    }
+
+    /// Return a borrowed byte string, regardless of whether this is an owned
+    /// or borrowed byte string internally.
+    #[inline(always)]
+    pub(crate) fn as_slice(&self) -> &[u8] {
+        self.0.as_slice()
+    }
+
+    /// Return an owned version of this copy-on-write byte string.
+    ///
+    /// If this is already an owned byte string internally, then this is a
+    /// no-op. Otherwise, the internal byte string is copied.
+    #[cfg(feature = "alloc")]
+    #[inline(always)]
+    pub(crate) fn into_owned(self) -> CowBytes<'static> {
+        match self.0 {
+            Imp::Borrowed(b) => {
+                CowBytes::new_owned(alloc::boxed::Box::from(b))
+            }
+            Imp::Owned(b) => CowBytes::new_owned(b),
+        }
+    }
+}
+
+impl<'a> Imp<'a> {
+    #[inline(always)]
+    pub fn new(bytes: &'a [u8]) -> Imp<'a> {
+        #[cfg(feature = "alloc")]
+        {
+            Imp::Borrowed(bytes)
+        }
+        #[cfg(not(feature = "alloc"))]
+        {
+            Imp(bytes)
+        }
+    }
+
+    #[cfg(feature = "alloc")]
+    #[inline(always)]
+    pub fn as_slice(&self) -> &[u8] {
+        #[cfg(feature = "alloc")]
+        {
+            match self {
+                Imp::Owned(ref x) => x,
+                Imp::Borrowed(x) => x,
+            }
+        }
+        #[cfg(not(feature = "alloc"))]
+        {
+            self.0
+        }
+    }
+
+    #[cfg(not(feature = "alloc"))]
+    #[inline(always)]
+    pub fn as_slice(&self) -> &[u8] {
+        self.0
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/ext.rs.html b/src/memchr/ext.rs.html new file mode 100644 index 000000000..43e86f998 --- /dev/null +++ b/src/memchr/ext.rs.html @@ -0,0 +1,105 @@ +ext.rs - source
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
+
/// A trait for adding some helper routines to pointers.
+pub(crate) trait Pointer {
+    /// Returns the distance, in units of `T`, between `self` and `origin`.
+    ///
+    /// # Safety
+    ///
+    /// Same as `ptr::offset_from` in addition to `self >= origin`.
+    unsafe fn distance(self, origin: Self) -> usize;
+
+    /// Casts this pointer to `usize`.
+    ///
+    /// Callers should not convert the `usize` back to a pointer if at all
+    /// possible. (And if you believe it's necessary, open an issue to discuss
+    /// why. Otherwise, it has the potential to violate pointer provenance.)
+    /// The purpose of this function is just to be able to do arithmetic, i.e.,
+    /// computing offsets or alignments.
+    fn as_usize(self) -> usize;
+}
+
+impl<T> Pointer for *const T {
+    unsafe fn distance(self, origin: *const T) -> usize {
+        // TODO: Replace with `ptr::sub_ptr` once stabilized.
+        usize::try_from(self.offset_from(origin)).unwrap_unchecked()
+    }
+
+    fn as_usize(self) -> usize {
+        self as usize
+    }
+}
+
+impl<T> Pointer for *mut T {
+    unsafe fn distance(self, origin: *mut T) -> usize {
+        (self as *const T).distance(origin as *const T)
+    }
+
+    fn as_usize(self) -> usize {
+        (self as *const T).as_usize()
+    }
+}
+
+/// A trait for adding some helper routines to raw bytes.
+pub(crate) trait Byte {
+    /// Converts this byte to a `char` if it's ASCII. Otherwise panics.
+    fn to_char(self) -> char;
+}
+
+impl Byte for u8 {
+    fn to_char(self) -> char {
+        assert!(self.is_ascii());
+        char::from(self)
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/lib.rs.html b/src/memchr/lib.rs.html new file mode 100644 index 000000000..ef6f6ac2d --- /dev/null +++ b/src/memchr/lib.rs.html @@ -0,0 +1,443 @@ +lib.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+
/*!
+This library provides heavily optimized routines for string search primitives.
+
+# Overview
+
+This section gives a brief high level overview of what this crate offers.
+
+* The top-level module provides routines for searching for 1, 2 or 3 bytes
+  in the forward or reverse direction. When searching for more than one byte,
+  positions are considered a match if the byte at that position matches any
+  of the bytes.
+* The [`memmem`] sub-module provides forward and reverse substring search
+  routines.
+
+In all such cases, routines operate on `&[u8]` without regard to encoding. This
+is exactly what you want when searching either UTF-8 or arbitrary bytes.
+
+# Example: using `memchr`
+
+This example shows how to use `memchr` to find the first occurrence of `z` in
+a haystack:
+
+```
+use memchr::memchr;
+
+let haystack = b"foo bar baz quuz";
+assert_eq!(Some(10), memchr(b'z', haystack));
+```
+
+# Example: matching one of three possible bytes
+
+This examples shows how to use `memrchr3` to find occurrences of `a`, `b` or
+`c`, starting at the end of the haystack.
+
+```
+use memchr::memchr3_iter;
+
+let haystack = b"xyzaxyzbxyzc";
+
+let mut it = memchr3_iter(b'a', b'b', b'c', haystack).rev();
+assert_eq!(Some(11), it.next());
+assert_eq!(Some(7), it.next());
+assert_eq!(Some(3), it.next());
+assert_eq!(None, it.next());
+```
+
+# Example: iterating over substring matches
+
+This example shows how to use the [`memmem`] sub-module to find occurrences of
+a substring in a haystack.
+
+```
+use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::find_iter(haystack, "foo");
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+```
+
+# Example: repeating a search for the same needle
+
+It may be possible for the overhead of constructing a substring searcher to be
+measurable in some workloads. In cases where the same needle is used to search
+many haystacks, it is possible to do construction once and thus to avoid it for
+subsequent searches. This can be done with a [`memmem::Finder`]:
+
+```
+use memchr::memmem;
+
+let finder = memmem::Finder::new("foo");
+
+assert_eq!(Some(4), finder.find(b"baz foo quux"));
+assert_eq!(None, finder.find(b"quux baz bar"));
+```
+
+# Why use this crate?
+
+At first glance, the APIs provided by this crate might seem weird. Why provide
+a dedicated routine like `memchr` for something that could be implemented
+clearly and trivially in one line:
+
+```
+fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    haystack.iter().position(|&b| b == needle)
+}
+```
+
+Or similarly, why does this crate provide substring search routines when Rust's
+core library already provides them?
+
+```
+fn search(haystack: &str, needle: &str) -> Option<usize> {
+    haystack.find(needle)
+}
+```
+
+The primary reason for both of them to exist is performance. When it comes to
+performance, at a high level at least, there are two primary ways to look at
+it:
+
+* **Throughput**: For this, think about it as, "given some very large haystack
+  and a byte that never occurs in that haystack, how long does it take to
+  search through it and determine that it, in fact, does not occur?"
+* **Latency**: For this, think about it as, "given a tiny haystack---just a
+  few bytes---how long does it take to determine if a byte is in it?"
+
+The `memchr` routine in this crate has _slightly_ worse latency than the
+solution presented above, however, its throughput can easily be over an
+order of magnitude faster. This is a good general purpose trade off to make.
+You rarely lose, but often gain big.
+
+**NOTE:** The name `memchr` comes from the corresponding routine in `libc`. A
+key advantage of using this library is that its performance is not tied to its
+quality of implementation in the `libc` you happen to be using, which can vary
+greatly from platform to platform.
+
+But what about substring search? This one is a bit more complicated. The
+primary reason for its existence is still indeed performance, but it's also
+useful because Rust's core library doesn't actually expose any substring
+search routine on arbitrary bytes. The only substring search routine that
+exists works exclusively on valid UTF-8.
+
+So if you have valid UTF-8, is there a reason to use this over the standard
+library substring search routine? Yes. This routine is faster on almost every
+metric, including latency. The natural question then, is why isn't this
+implementation in the standard library, even if only for searching on UTF-8?
+The reason is that the implementation details for using SIMD in the standard
+library haven't quite been worked out yet.
+
+**NOTE:** Currently, only `x86_64`, `wasm32` and `aarch64` targets have vector
+accelerated implementations of `memchr` (and friends) and `memmem`.
+
+# Crate features
+
+* **std** - When enabled (the default), this will permit features specific to
+the standard library. Currently, the only thing used from the standard library
+is runtime SIMD CPU feature detection. This means that this feature must be
+enabled to get AVX2 accelerated routines on `x86_64` targets without enabling
+the `avx2` feature at compile time, for example. When `std` is not enabled,
+this crate will still attempt to use SSE2 accelerated routines on `x86_64`. It
+will also use AVX2 accelerated routines when the `avx2` feature is enabled at
+compile time. In general, enable this feature if you can.
+* **alloc** - When enabled (the default), APIs in this crate requiring some
+kind of allocation will become available. For example, the
+[`memmem::Finder::into_ownedd`](crate::memmem::Finder::into_owned) API and the
+[`arch::all::shiftor`](crate::arch::all::shiftor) substring search
+implementation. Otherwise, this crate is designed from the ground up to be
+usable in core-only contexts, so the `alloc` feature doesn't add much
+currently. Notably, disabling `std` but enabling `alloc` will **not** result
+in the use of AVX2 on `x86_64` targets unless the `avx2` feature is enabled
+at compile time. (With `std` enabled, AVX2 can be used even without the `avx2`
+feature enabled at compile time by way of runtime CPU feature detection.)
+* **logging** - When enabled (disabled by default), the `log` crate is used
+to emit log messages about what kinds of `memchr` and `memmem` algorithms
+are used. Namely, both `memchr` and `memmem` have a number of different
+implementation choices depending on the target and CPU, and the log messages
+can help show what specific implementations are being used. Generally, this is
+useful for debugging performance issues.
+* **libc** - **DEPRECATED**. Previously, this enabled the use of the target's
+`memchr` function from whatever `libc` was linked into the program. This
+feature is now a no-op because this crate's implementation of `memchr` should
+now be sufficiently fast on a number of platforms that `libc` should no longer
+be needed. (This feature is somewhat of a holdover from this crate's origins.
+Originally, this crate was literally just a safe wrapper function around the
+`memchr` function from `libc`.)
+*/
+
+#![deny(missing_docs)]
+#![no_std]
+// It's just not worth trying to squash all dead code warnings. Pretty
+// unfortunate IMO. Not really sure how to fix this other than to either
+// live with it or sprinkle a whole mess of `cfg` annotations everywhere.
+#![cfg_attr(
+    not(any(
+        all(target_arch = "x86_64", target_feature = "sse2"),
+        target_arch = "wasm32",
+        target_arch = "aarch64",
+    )),
+    allow(dead_code)
+)]
+// Same deal for miri.
+#![cfg_attr(miri, allow(dead_code, unused_macros))]
+
+// Supporting 8-bit (or others) would be fine. If you need it, please submit a
+// bug report at https://github.com/BurntSushi/memchr
+#[cfg(not(any(
+    target_pointer_width = "16",
+    target_pointer_width = "32",
+    target_pointer_width = "64"
+)))]
+compile_error!("memchr currently not supported on non-{16,32,64}");
+
+#[cfg(any(test, feature = "std"))]
+extern crate std;
+
+#[cfg(any(test, feature = "alloc"))]
+extern crate alloc;
+
+pub use crate::memchr::{
+    memchr, memchr2, memchr2_iter, memchr3, memchr3_iter, memchr_iter,
+    memrchr, memrchr2, memrchr2_iter, memrchr3, memrchr3_iter, memrchr_iter,
+    Memchr, Memchr2, Memchr3,
+};
+
+#[macro_use]
+mod macros;
+
+#[cfg(test)]
+#[macro_use]
+mod tests;
+
+pub mod arch;
+mod cow;
+mod ext;
+mod memchr;
+pub mod memmem;
+mod vector;
+
\ No newline at end of file diff --git a/src/memchr/macros.rs.html b/src/memchr/macros.rs.html new file mode 100644 index 000000000..7f333b5ed --- /dev/null +++ b/src/memchr/macros.rs.html @@ -0,0 +1,41 @@ +macros.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+
// Some feature combinations result in some of these macros never being used.
+// Which is fine. Just squash the warnings.
+#![allow(unused_macros)]
+
+macro_rules! log {
+    ($($tt:tt)*) => {
+        #[cfg(feature = "logging")]
+        {
+            $($tt)*
+        }
+    }
+}
+
+macro_rules! debug {
+    ($($tt:tt)*) => { log!(log::debug!($($tt)*)) }
+}
+
+macro_rules! trace {
+    ($($tt:tt)*) => { log!(log::trace!($($tt)*)) }
+}
+
\ No newline at end of file diff --git a/src/memchr/memchr.rs.html b/src/memchr/memchr.rs.html new file mode 100644 index 000000000..4d1f28996 --- /dev/null +++ b/src/memchr/memchr.rs.html @@ -0,0 +1,1807 @@ +memchr.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+
use core::iter::Rev;
+
+use crate::arch::generic::memchr as generic;
+
+/// Search for the first occurrence of a byte in a slice.
+///
+/// This returns the index corresponding to the first occurrence of `needle` in
+/// `haystack`, or `None` if one is not found. If an index is returned, it is
+/// guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().position(|&b| b == needle)`, this routine will attempt to
+/// use highly optimized vector operations that can be an order of magnitude
+/// faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the first position of a byte in a byte string.
+///
+/// ```
+/// use memchr::memchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memchr(b'k', haystack), Some(8));
+/// ```
+#[inline]
+pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    // SAFETY: memchr_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memchr_raw(needle, start, end)
+        })
+    }
+}
+
+/// Search for the last occurrence of a byte in a slice.
+///
+/// This returns the index corresponding to the last occurrence of `needle` in
+/// `haystack`, or `None` if one is not found. If an index is returned, it is
+/// guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().rposition(|&b| b == needle)`, this routine will attempt to
+/// use highly optimized vector operations that can be an order of magnitude
+/// faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the last position of a byte in a byte string.
+///
+/// ```
+/// use memchr::memrchr;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memrchr(b'o', haystack), Some(17));
+/// ```
+#[inline]
+pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    // SAFETY: memrchr_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memrchr_raw(needle, start, end)
+        })
+    }
+}
+
+/// Search for the first occurrence of two possible bytes in a haystack.
+///
+/// This returns the index corresponding to the first occurrence of one of the
+/// needle bytes in `haystack`, or `None` if one is not found. If an index is
+/// returned, it is guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().position(|&b| b == needle1 || b == needle2)`, this routine
+/// will attempt to use highly optimized vector operations that can be an order
+/// of magnitude faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the first position of one of two possible bytes in a
+/// haystack.
+///
+/// ```
+/// use memchr::memchr2;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memchr2(b'k', b'q', haystack), Some(4));
+/// ```
+#[inline]
+pub fn memchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
+    // SAFETY: memchr2_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memchr2_raw(needle1, needle2, start, end)
+        })
+    }
+}
+
+/// Search for the last occurrence of two possible bytes in a haystack.
+///
+/// This returns the index corresponding to the last occurrence of one of the
+/// needle bytes in `haystack`, or `None` if one is not found. If an index is
+/// returned, it is guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2)`, this
+/// routine will attempt to use highly optimized vector operations that can be
+/// an order of magnitude faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the last position of one of two possible bytes in a
+/// haystack.
+///
+/// ```
+/// use memchr::memrchr2;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memrchr2(b'k', b'o', haystack), Some(17));
+/// ```
+#[inline]
+pub fn memrchr2(needle1: u8, needle2: u8, haystack: &[u8]) -> Option<usize> {
+    // SAFETY: memrchr2_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memrchr2_raw(needle1, needle2, start, end)
+        })
+    }
+}
+
+/// Search for the first occurrence of three possible bytes in a haystack.
+///
+/// This returns the index corresponding to the first occurrence of one of the
+/// needle bytes in `haystack`, or `None` if one is not found. If an index is
+/// returned, it is guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().position(|&b| b == needle1 || b == needle2 || b == needle3)`,
+/// this routine will attempt to use highly optimized vector operations that
+/// can be an order of magnitude faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the first position of one of three possible bytes in
+/// a haystack.
+///
+/// ```
+/// use memchr::memchr3;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memchr3(b'k', b'q', b'u', haystack), Some(4));
+/// ```
+#[inline]
+pub fn memchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    // SAFETY: memchr3_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memchr3_raw(needle1, needle2, needle3, start, end)
+        })
+    }
+}
+
+/// Search for the last occurrence of three possible bytes in a haystack.
+///
+/// This returns the index corresponding to the last occurrence of one of the
+/// needle bytes in `haystack`, or `None` if one is not found. If an index is
+/// returned, it is guaranteed to be less than `haystack.len()`.
+///
+/// While this is semantically the same as something like
+/// `haystack.iter().rposition(|&b| b == needle1 || b == needle2 || b == needle3)`,
+/// this routine will attempt to use highly optimized vector operations that
+/// can be an order of magnitude faster (or more).
+///
+/// # Example
+///
+/// This shows how to find the last position of one of three possible bytes in
+/// a haystack.
+///
+/// ```
+/// use memchr::memrchr3;
+///
+/// let haystack = b"the quick brown fox";
+/// assert_eq!(memrchr3(b'k', b'o', b'n', haystack), Some(17));
+/// ```
+#[inline]
+pub fn memrchr3(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Option<usize> {
+    // SAFETY: memrchr3_raw, when a match is found, always returns a valid
+    // pointer between start and end.
+    unsafe {
+        generic::search_slice_with_raw(haystack, |start, end| {
+            memrchr3_raw(needle1, needle2, needle3, start, end)
+        })
+    }
+}
+
+/// Returns an iterator over all occurrences of the needle in a haystack.
+///
+/// The iterator returned implements `DoubleEndedIterator`. This means it
+/// can also be used to find occurrences in reverse order.
+#[inline]
+pub fn memchr_iter<'h>(needle: u8, haystack: &'h [u8]) -> Memchr<'h> {
+    Memchr::new(needle, haystack)
+}
+
+/// Returns an iterator over all occurrences of the needle in a haystack, in
+/// reverse.
+#[inline]
+pub fn memrchr_iter(needle: u8, haystack: &[u8]) -> Rev<Memchr<'_>> {
+    Memchr::new(needle, haystack).rev()
+}
+
+/// Returns an iterator over all occurrences of the needles in a haystack.
+///
+/// The iterator returned implements `DoubleEndedIterator`. This means it
+/// can also be used to find occurrences in reverse order.
+#[inline]
+pub fn memchr2_iter<'h>(
+    needle1: u8,
+    needle2: u8,
+    haystack: &'h [u8],
+) -> Memchr2<'h> {
+    Memchr2::new(needle1, needle2, haystack)
+}
+
+/// Returns an iterator over all occurrences of the needles in a haystack, in
+/// reverse.
+#[inline]
+pub fn memrchr2_iter(
+    needle1: u8,
+    needle2: u8,
+    haystack: &[u8],
+) -> Rev<Memchr2<'_>> {
+    Memchr2::new(needle1, needle2, haystack).rev()
+}
+
+/// Returns an iterator over all occurrences of the needles in a haystack.
+///
+/// The iterator returned implements `DoubleEndedIterator`. This means it
+/// can also be used to find occurrences in reverse order.
+#[inline]
+pub fn memchr3_iter<'h>(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &'h [u8],
+) -> Memchr3<'h> {
+    Memchr3::new(needle1, needle2, needle3, haystack)
+}
+
+/// Returns an iterator over all occurrences of the needles in a haystack, in
+/// reverse.
+#[inline]
+pub fn memrchr3_iter(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    haystack: &[u8],
+) -> Rev<Memchr3<'_>> {
+    Memchr3::new(needle1, needle2, needle3, haystack).rev()
+}
+
+/// An iterator over all occurrences of a single byte in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`memchr_iter`] or `[memrchr_iter`]
+/// functions. It can also be created with the [`Memchr::new`] method.
+///
+/// The lifetime parameter `'h` refers to the lifetime of the haystack being
+/// searched.
+#[derive(Clone, Debug)]
+pub struct Memchr<'h> {
+    needle1: u8,
+    it: crate::arch::generic::memchr::Iter<'h>,
+}
+
+impl<'h> Memchr<'h> {
+    /// Returns an iterator over all occurrences of the needle byte in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn new(needle1: u8, haystack: &'h [u8]) -> Memchr<'h> {
+        Memchr {
+            needle1,
+            it: crate::arch::generic::memchr::Iter::new(haystack),
+        }
+    }
+}
+
+impl<'h> Iterator for Memchr<'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next`.
+        unsafe {
+            // NOTE: I attempted to define an enum of previously created
+            // searchers and then switch on those here instead of just
+            // calling `memchr_raw` (or `One::new(..).find_raw(..)`). But
+            // that turned out to have a fair bit of extra overhead when
+            // searching very small haystacks.
+            self.it.next(|s, e| memchr_raw(self.needle1, s, e))
+        }
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        self.it.count(|s, e| {
+            // SAFETY: We rely on our generic iterator to return valid start
+            // and end pointers.
+            unsafe { count_raw(self.needle1, s, e) }
+        })
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'h> DoubleEndedIterator for Memchr<'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next_back`.
+        unsafe { self.it.next_back(|s, e| memrchr_raw(self.needle1, s, e)) }
+    }
+}
+
+impl<'h> core::iter::FusedIterator for Memchr<'h> {}
+
+/// An iterator over all occurrences of two possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`memchr2_iter`] or `[memrchr2_iter`]
+/// functions. It can also be created with the [`Memchr2::new`] method.
+///
+/// The lifetime parameter `'h` refers to the lifetime of the haystack being
+/// searched.
+#[derive(Clone, Debug)]
+pub struct Memchr2<'h> {
+    needle1: u8,
+    needle2: u8,
+    it: crate::arch::generic::memchr::Iter<'h>,
+}
+
+impl<'h> Memchr2<'h> {
+    /// Returns an iterator over all occurrences of the needle bytes in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn new(needle1: u8, needle2: u8, haystack: &'h [u8]) -> Memchr2<'h> {
+        Memchr2 {
+            needle1,
+            needle2,
+            it: crate::arch::generic::memchr::Iter::new(haystack),
+        }
+    }
+}
+
+impl<'h> Iterator for Memchr2<'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next`.
+        unsafe {
+            self.it.next(|s, e| memchr2_raw(self.needle1, self.needle2, s, e))
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'h> DoubleEndedIterator for Memchr2<'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next_back`.
+        unsafe {
+            self.it.next_back(|s, e| {
+                memrchr2_raw(self.needle1, self.needle2, s, e)
+            })
+        }
+    }
+}
+
+impl<'h> core::iter::FusedIterator for Memchr2<'h> {}
+
+/// An iterator over all occurrences of three possible bytes in a haystack.
+///
+/// This iterator implements `DoubleEndedIterator`, which means it can also be
+/// used to find occurrences in reverse order.
+///
+/// This iterator is created by the [`memchr2_iter`] or `[memrchr2_iter`]
+/// functions. It can also be created with the [`Memchr3::new`] method.
+///
+/// The lifetime parameter `'h` refers to the lifetime of the haystack being
+/// searched.
+#[derive(Clone, Debug)]
+pub struct Memchr3<'h> {
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    it: crate::arch::generic::memchr::Iter<'h>,
+}
+
+impl<'h> Memchr3<'h> {
+    /// Returns an iterator over all occurrences of the needle bytes in the
+    /// given haystack.
+    ///
+    /// The iterator returned implements `DoubleEndedIterator`. This means it
+    /// can also be used to find occurrences in reverse order.
+    #[inline]
+    pub fn new(
+        needle1: u8,
+        needle2: u8,
+        needle3: u8,
+        haystack: &'h [u8],
+    ) -> Memchr3<'h> {
+        Memchr3 {
+            needle1,
+            needle2,
+            needle3,
+            it: crate::arch::generic::memchr::Iter::new(haystack),
+        }
+    }
+}
+
+impl<'h> Iterator for Memchr3<'h> {
+    type Item = usize;
+
+    #[inline]
+    fn next(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next`.
+        unsafe {
+            self.it.next(|s, e| {
+                memchr3_raw(self.needle1, self.needle2, self.needle3, s, e)
+            })
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.it.size_hint()
+    }
+}
+
+impl<'h> DoubleEndedIterator for Memchr3<'h> {
+    #[inline]
+    fn next_back(&mut self) -> Option<usize> {
+        // SAFETY: All of our implementations of memchr ensure that any
+        // pointers returns will fall within the start and end bounds, and this
+        // upholds the safety contract of `self.it.next_back`.
+        unsafe {
+            self.it.next_back(|s, e| {
+                memrchr3_raw(self.needle1, self.needle2, self.needle3, s, e)
+            })
+        }
+    }
+}
+
+impl<'h> core::iter::FusedIterator for Memchr3<'h> {}
+
+/// memchr, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::find_raw`.
+#[inline]
+unsafe fn memchr_raw(
+    needle: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        // x86_64 does CPU feature detection at runtime in order to use AVX2
+        // instructions even when the `avx2` feature isn't enabled at compile
+        // time. This function also handles using a fallback if neither AVX2
+        // nor SSE2 (unusual) are available.
+        crate::arch::x86_64::memchr::memchr_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memchr_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memchr_raw(needle, start, end)
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::One::new(needle).find_raw(start, end)
+    }
+}
+
+/// memrchr, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::rfind_raw`.
+#[inline]
+unsafe fn memrchr_raw(
+    needle: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::memrchr_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memrchr_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memrchr_raw(needle, start, end)
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::One::new(needle).rfind_raw(start, end)
+    }
+}
+
+/// memchr2, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Two::find_raw`.
+#[inline]
+unsafe fn memchr2_raw(
+    needle1: u8,
+    needle2: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::memchr2_raw(needle1, needle2, start, end)
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memchr2_raw(needle1, needle2, start, end)
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memchr2_raw(needle1, needle2, start, end)
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::Two::new(needle1, needle2)
+            .find_raw(start, end)
+    }
+}
+
+/// memrchr2, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Two::rfind_raw`.
+#[inline]
+unsafe fn memrchr2_raw(
+    needle1: u8,
+    needle2: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::memrchr2_raw(needle1, needle2, start, end)
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memrchr2_raw(needle1, needle2, start, end)
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memrchr2_raw(
+            needle1, needle2, start, end,
+        )
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::Two::new(needle1, needle2)
+            .rfind_raw(start, end)
+    }
+}
+
+/// memchr3, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Three::find_raw`.
+#[inline]
+unsafe fn memchr3_raw(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::memchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::Three::new(needle1, needle2, needle3)
+            .find_raw(start, end)
+    }
+}
+
+/// memrchr3, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `Three::rfind_raw`.
+#[inline]
+unsafe fn memrchr3_raw(
+    needle1: u8,
+    needle2: u8,
+    needle3: u8,
+    start: *const u8,
+    end: *const u8,
+) -> Option<*const u8> {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::memrchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::memrchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::memrchr3_raw(
+            needle1, needle2, needle3, start, end,
+        )
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::Three::new(needle1, needle2, needle3)
+            .rfind_raw(start, end)
+    }
+}
+
+/// Count all matching bytes, but using raw pointers to represent the haystack.
+///
+/// # Safety
+///
+/// Pointers must be valid. See `One::count_raw`.
+#[inline]
+unsafe fn count_raw(needle: u8, start: *const u8, end: *const u8) -> usize {
+    #[cfg(target_arch = "x86_64")]
+    {
+        crate::arch::x86_64::memchr::count_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "wasm32")]
+    {
+        crate::arch::wasm32::memchr::count_raw(needle, start, end)
+    }
+    #[cfg(target_arch = "aarch64")]
+    {
+        crate::arch::aarch64::memchr::count_raw(needle, start, end)
+    }
+    #[cfg(not(any(
+        target_arch = "x86_64",
+        target_arch = "wasm32",
+        target_arch = "aarch64"
+    )))]
+    {
+        crate::arch::all::memchr::One::new(needle).count_raw(start, end)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn forward1_iter() {
+        crate::tests::memchr::Runner::new(1).forward_iter(
+            |haystack, needles| {
+                Some(memchr_iter(needles[0], haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward1_oneshot() {
+        crate::tests::memchr::Runner::new(1).forward_oneshot(
+            |haystack, needles| Some(memchr(needles[0], haystack)),
+        )
+    }
+
+    #[test]
+    fn reverse1_iter() {
+        crate::tests::memchr::Runner::new(1).reverse_iter(
+            |haystack, needles| {
+                Some(memrchr_iter(needles[0], haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse1_oneshot() {
+        crate::tests::memchr::Runner::new(1).reverse_oneshot(
+            |haystack, needles| Some(memrchr(needles[0], haystack)),
+        )
+    }
+
+    #[test]
+    fn count1_iter() {
+        crate::tests::memchr::Runner::new(1).count_iter(|haystack, needles| {
+            Some(memchr_iter(needles[0], haystack).count())
+        })
+    }
+
+    #[test]
+    fn forward2_iter() {
+        crate::tests::memchr::Runner::new(2).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(memchr2_iter(n1, n2, haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward2_oneshot() {
+        crate::tests::memchr::Runner::new(2).forward_oneshot(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(memchr2(n1, n2, haystack))
+            },
+        )
+    }
+
+    #[test]
+    fn reverse2_iter() {
+        crate::tests::memchr::Runner::new(2).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(memrchr2_iter(n1, n2, haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse2_oneshot() {
+        crate::tests::memchr::Runner::new(2).reverse_oneshot(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                Some(memrchr2(n1, n2, haystack))
+            },
+        )
+    }
+
+    #[test]
+    fn forward3_iter() {
+        crate::tests::memchr::Runner::new(3).forward_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(memchr3_iter(n1, n2, n3, haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn forward3_oneshot() {
+        crate::tests::memchr::Runner::new(3).forward_oneshot(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(memchr3(n1, n2, n3, haystack))
+            },
+        )
+    }
+
+    #[test]
+    fn reverse3_iter() {
+        crate::tests::memchr::Runner::new(3).reverse_iter(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(memrchr3_iter(n1, n2, n3, haystack).collect())
+            },
+        )
+    }
+
+    #[test]
+    fn reverse3_oneshot() {
+        crate::tests::memchr::Runner::new(3).reverse_oneshot(
+            |haystack, needles| {
+                let n1 = needles.get(0).copied()?;
+                let n2 = needles.get(1).copied()?;
+                let n3 = needles.get(2).copied()?;
+                Some(memrchr3(n1, n2, n3, haystack))
+            },
+        )
+    }
+
+    // Prior to memchr 2.6, the memchr iterators both implemented Send and
+    // Sync. But in memchr 2.6, the iterator changed to use raw pointers
+    // internally and I didn't add explicit Send/Sync impls. This ended up
+    // regressing the API. This test ensures we don't do that again.
+    //
+    // See: https://github.com/BurntSushi/memchr/issues/133
+    #[test]
+    fn sync_regression() {
+        use core::panic::{RefUnwindSafe, UnwindSafe};
+
+        fn assert_send_sync<T: Send + Sync + UnwindSafe + RefUnwindSafe>() {}
+        assert_send_sync::<Memchr>();
+        assert_send_sync::<Memchr2>();
+        assert_send_sync::<Memchr3>()
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/memmem/mod.rs.html b/src/memchr/memmem/mod.rs.html new file mode 100644 index 000000000..497f381d0 --- /dev/null +++ b/src/memchr/memmem/mod.rs.html @@ -0,0 +1,1475 @@ +mod.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+
/*!
+This module provides forward and reverse substring search routines.
+
+Unlike the standard library's substring search routines, these work on
+arbitrary bytes. For all non-empty needles, these routines will report exactly
+the same values as the corresponding routines in the standard library. For
+the empty needle, the standard library reports matches only at valid UTF-8
+boundaries, where as these routines will report matches at every position.
+
+Other than being able to work on arbitrary bytes, the primary reason to prefer
+these routines over the standard library routines is that these will generally
+be faster. In some cases, significantly so.
+
+# Example: iterating over substring matches
+
+This example shows how to use [`find_iter`] to find occurrences of a substring
+in a haystack.
+
+```
+use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::find_iter(haystack, "foo");
+assert_eq!(Some(0), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(16), it.next());
+assert_eq!(None, it.next());
+```
+
+# Example: iterating over substring matches in reverse
+
+This example shows how to use [`rfind_iter`] to find occurrences of a substring
+in a haystack starting from the end of the haystack.
+
+**NOTE:** This module does not implement double ended iterators, so reverse
+searches aren't done by calling `rev` on a forward iterator.
+
+```
+use memchr::memmem;
+
+let haystack = b"foo bar foo baz foo";
+
+let mut it = memmem::rfind_iter(haystack, "foo");
+assert_eq!(Some(16), it.next());
+assert_eq!(Some(8), it.next());
+assert_eq!(Some(0), it.next());
+assert_eq!(None, it.next());
+```
+
+# Example: repeating a search for the same needle
+
+It may be possible for the overhead of constructing a substring searcher to be
+measurable in some workloads. In cases where the same needle is used to search
+many haystacks, it is possible to do construction once and thus to avoid it for
+subsequent searches. This can be done with a [`Finder`] (or a [`FinderRev`] for
+reverse searches).
+
+```
+use memchr::memmem;
+
+let finder = memmem::Finder::new("foo");
+
+assert_eq!(Some(4), finder.find(b"baz foo quux"));
+assert_eq!(None, finder.find(b"quux baz bar"));
+```
+*/
+
+pub use crate::memmem::searcher::PrefilterConfig as Prefilter;
+
+// This is exported here for use in the crate::arch::all::twoway
+// implementation. This is essentially an abstraction breaker. Namely, the
+// public API of twoway doesn't support providing a prefilter, but its crate
+// internal API does. The main reason for this is that I didn't want to do the
+// API design required to support it without a concrete use case.
+pub(crate) use crate::memmem::searcher::Pre;
+
+use crate::{
+    arch::all::{
+        packedpair::{DefaultFrequencyRank, HeuristicFrequencyRank},
+        rabinkarp,
+    },
+    cow::CowBytes,
+    memmem::searcher::{PrefilterState, Searcher, SearcherRev},
+};
+
+mod searcher;
+
+/// Returns an iterator over all non-overlapping occurrences of a substring in
+/// a haystack.
+///
+/// # Complexity
+///
+/// This routine is guaranteed to have worst case linear time complexity
+/// with respect to both the needle and the haystack. That is, this runs
+/// in `O(needle.len() + haystack.len())` time.
+///
+/// This routine is also guaranteed to have worst case constant space
+/// complexity.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use memchr::memmem;
+///
+/// let haystack = b"foo bar foo baz foo";
+/// let mut it = memmem::find_iter(haystack, b"foo");
+/// assert_eq!(Some(0), it.next());
+/// assert_eq!(Some(8), it.next());
+/// assert_eq!(Some(16), it.next());
+/// assert_eq!(None, it.next());
+/// ```
+#[inline]
+pub fn find_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>(
+    haystack: &'h [u8],
+    needle: &'n N,
+) -> FindIter<'h, 'n> {
+    FindIter::new(haystack, Finder::new(needle))
+}
+
+/// Returns a reverse iterator over all non-overlapping occurrences of a
+/// substring in a haystack.
+///
+/// # Complexity
+///
+/// This routine is guaranteed to have worst case linear time complexity
+/// with respect to both the needle and the haystack. That is, this runs
+/// in `O(needle.len() + haystack.len())` time.
+///
+/// This routine is also guaranteed to have worst case constant space
+/// complexity.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use memchr::memmem;
+///
+/// let haystack = b"foo bar foo baz foo";
+/// let mut it = memmem::rfind_iter(haystack, b"foo");
+/// assert_eq!(Some(16), it.next());
+/// assert_eq!(Some(8), it.next());
+/// assert_eq!(Some(0), it.next());
+/// assert_eq!(None, it.next());
+/// ```
+#[inline]
+pub fn rfind_iter<'h, 'n, N: 'n + ?Sized + AsRef<[u8]>>(
+    haystack: &'h [u8],
+    needle: &'n N,
+) -> FindRevIter<'h, 'n> {
+    FindRevIter::new(haystack, FinderRev::new(needle))
+}
+
+/// Returns the index of the first occurrence of the given needle.
+///
+/// Note that if you're are searching for the same needle in many different
+/// small haystacks, it may be faster to initialize a [`Finder`] once,
+/// and reuse it for each search.
+///
+/// # Complexity
+///
+/// This routine is guaranteed to have worst case linear time complexity
+/// with respect to both the needle and the haystack. That is, this runs
+/// in `O(needle.len() + haystack.len())` time.
+///
+/// This routine is also guaranteed to have worst case constant space
+/// complexity.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use memchr::memmem;
+///
+/// let haystack = b"foo bar baz";
+/// assert_eq!(Some(0), memmem::find(haystack, b"foo"));
+/// assert_eq!(Some(4), memmem::find(haystack, b"bar"));
+/// assert_eq!(None, memmem::find(haystack, b"quux"));
+/// ```
+#[inline]
+pub fn find(haystack: &[u8], needle: &[u8]) -> Option<usize> {
+    if haystack.len() < 64 {
+        rabinkarp::Finder::new(needle).find(haystack, needle)
+    } else {
+        Finder::new(needle).find(haystack)
+    }
+}
+
+/// Returns the index of the last occurrence of the given needle.
+///
+/// Note that if you're are searching for the same needle in many different
+/// small haystacks, it may be faster to initialize a [`FinderRev`] once,
+/// and reuse it for each search.
+///
+/// # Complexity
+///
+/// This routine is guaranteed to have worst case linear time complexity
+/// with respect to both the needle and the haystack. That is, this runs
+/// in `O(needle.len() + haystack.len())` time.
+///
+/// This routine is also guaranteed to have worst case constant space
+/// complexity.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use memchr::memmem;
+///
+/// let haystack = b"foo bar baz";
+/// assert_eq!(Some(0), memmem::rfind(haystack, b"foo"));
+/// assert_eq!(Some(4), memmem::rfind(haystack, b"bar"));
+/// assert_eq!(Some(8), memmem::rfind(haystack, b"ba"));
+/// assert_eq!(None, memmem::rfind(haystack, b"quux"));
+/// ```
+#[inline]
+pub fn rfind(haystack: &[u8], needle: &[u8]) -> Option<usize> {
+    if haystack.len() < 64 {
+        rabinkarp::FinderRev::new(needle).rfind(haystack, needle)
+    } else {
+        FinderRev::new(needle).rfind(haystack)
+    }
+}
+
+/// An iterator over non-overlapping substring matches.
+///
+/// Matches are reported by the byte offset at which they begin.
+///
+/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
+/// needle.
+#[derive(Debug)]
+pub struct FindIter<'h, 'n> {
+    haystack: &'h [u8],
+    prestate: PrefilterState,
+    finder: Finder<'n>,
+    pos: usize,
+}
+
+impl<'h, 'n> FindIter<'h, 'n> {
+    #[inline(always)]
+    pub(crate) fn new(
+        haystack: &'h [u8],
+        finder: Finder<'n>,
+    ) -> FindIter<'h, 'n> {
+        let prestate = PrefilterState::new();
+        FindIter { haystack, prestate, finder, pos: 0 }
+    }
+
+    /// Convert this iterator into its owned variant, such that it no longer
+    /// borrows the finder and needle.
+    ///
+    /// If this is already an owned iterator, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `alloc` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> FindIter<'h, 'static> {
+        FindIter {
+            haystack: self.haystack,
+            prestate: self.prestate,
+            finder: self.finder.into_owned(),
+            pos: self.pos,
+        }
+    }
+}
+
+impl<'h, 'n> Iterator for FindIter<'h, 'n> {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        let needle = self.finder.needle();
+        let haystack = self.haystack.get(self.pos..)?;
+        let idx =
+            self.finder.searcher.find(&mut self.prestate, haystack, needle)?;
+
+        let pos = self.pos + idx;
+        self.pos = pos + needle.len().max(1);
+
+        Some(pos)
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // The largest possible number of non-overlapping matches is the
+        // quotient of the haystack and the needle (or the length of the
+        // haystack, if the needle is empty)
+        match self.haystack.len().checked_sub(self.pos) {
+            None => (0, Some(0)),
+            Some(haystack_len) => match self.finder.needle().len() {
+                // Empty needles always succeed and match at every point
+                // (including the very end)
+                0 => (
+                    haystack_len.saturating_add(1),
+                    haystack_len.checked_add(1),
+                ),
+                needle_len => (0, Some(haystack_len / needle_len)),
+            },
+        }
+    }
+}
+
+/// An iterator over non-overlapping substring matches in reverse.
+///
+/// Matches are reported by the byte offset at which they begin.
+///
+/// `'h` is the lifetime of the haystack while `'n` is the lifetime of the
+/// needle.
+#[derive(Debug)]
+pub struct FindRevIter<'h, 'n> {
+    haystack: &'h [u8],
+    finder: FinderRev<'n>,
+    /// When searching with an empty needle, this gets set to `None` after
+    /// we've yielded the last element at `0`.
+    pos: Option<usize>,
+}
+
+impl<'h, 'n> FindRevIter<'h, 'n> {
+    #[inline(always)]
+    pub(crate) fn new(
+        haystack: &'h [u8],
+        finder: FinderRev<'n>,
+    ) -> FindRevIter<'h, 'n> {
+        let pos = Some(haystack.len());
+        FindRevIter { haystack, finder, pos }
+    }
+
+    /// Convert this iterator into its owned variant, such that it no longer
+    /// borrows the finder and needle.
+    ///
+    /// If this is already an owned iterator, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `std` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> FindRevIter<'h, 'static> {
+        FindRevIter {
+            haystack: self.haystack,
+            finder: self.finder.into_owned(),
+            pos: self.pos,
+        }
+    }
+}
+
+impl<'h, 'n> Iterator for FindRevIter<'h, 'n> {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<usize> {
+        let pos = match self.pos {
+            None => return None,
+            Some(pos) => pos,
+        };
+        let result = self.finder.rfind(&self.haystack[..pos]);
+        match result {
+            None => None,
+            Some(i) => {
+                if pos == i {
+                    self.pos = pos.checked_sub(1);
+                } else {
+                    self.pos = Some(i);
+                }
+                Some(i)
+            }
+        }
+    }
+}
+
+/// A single substring searcher fixed to a particular needle.
+///
+/// The purpose of this type is to permit callers to construct a substring
+/// searcher that can be used to search haystacks without the overhead of
+/// constructing the searcher in the first place. This is a somewhat niche
+/// concern when it's necessary to re-use the same needle to search multiple
+/// different haystacks with as little overhead as possible. In general, using
+/// [`find`] is good enough, but `Finder` is useful when you can meaningfully
+/// observe searcher construction time in a profile.
+///
+/// When the `std` feature is enabled, then this type has an `into_owned`
+/// version which permits building a `Finder` that is not connected to
+/// the lifetime of its needle.
+#[derive(Clone, Debug)]
+pub struct Finder<'n> {
+    needle: CowBytes<'n>,
+    searcher: Searcher,
+}
+
+impl<'n> Finder<'n> {
+    /// Create a new finder for the given needle.
+    #[inline]
+    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'n B) -> Finder<'n> {
+        FinderBuilder::new().build_forward(needle)
+    }
+
+    /// Returns the index of the first occurrence of this needle in the given
+    /// haystack.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use memchr::memmem::Finder;
+    ///
+    /// let haystack = b"foo bar baz";
+    /// assert_eq!(Some(0), Finder::new("foo").find(haystack));
+    /// assert_eq!(Some(4), Finder::new("bar").find(haystack));
+    /// assert_eq!(None, Finder::new("quux").find(haystack));
+    /// ```
+    #[inline]
+    pub fn find(&self, haystack: &[u8]) -> Option<usize> {
+        let mut prestate = PrefilterState::new();
+        let needle = self.needle.as_slice();
+        self.searcher.find(&mut prestate, haystack, needle)
+    }
+
+    /// Returns an iterator over all occurrences of a substring in a haystack.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use memchr::memmem::Finder;
+    ///
+    /// let haystack = b"foo bar foo baz foo";
+    /// let finder = Finder::new(b"foo");
+    /// let mut it = finder.find_iter(haystack);
+    /// assert_eq!(Some(0), it.next());
+    /// assert_eq!(Some(8), it.next());
+    /// assert_eq!(Some(16), it.next());
+    /// assert_eq!(None, it.next());
+    /// ```
+    #[inline]
+    pub fn find_iter<'a, 'h>(
+        &'a self,
+        haystack: &'h [u8],
+    ) -> FindIter<'h, 'a> {
+        FindIter::new(haystack, self.as_ref())
+    }
+
+    /// Convert this finder into its owned variant, such that it no longer
+    /// borrows the needle.
+    ///
+    /// If this is already an owned finder, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `alloc` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> Finder<'static> {
+        Finder {
+            needle: self.needle.into_owned(),
+            searcher: self.searcher.clone(),
+        }
+    }
+
+    /// Convert this finder into its borrowed variant.
+    ///
+    /// This is primarily useful if your finder is owned and you'd like to
+    /// store its borrowed variant in some intermediate data structure.
+    ///
+    /// Note that the lifetime parameter of the returned finder is tied to the
+    /// lifetime of `self`, and may be shorter than the `'n` lifetime of the
+    /// needle itself. Namely, a finder's needle can be either borrowed or
+    /// owned, so the lifetime of the needle returned must necessarily be the
+    /// shorter of the two.
+    #[inline]
+    pub fn as_ref(&self) -> Finder<'_> {
+        Finder {
+            needle: CowBytes::new(self.needle()),
+            searcher: self.searcher.clone(),
+        }
+    }
+
+    /// Returns the needle that this finder searches for.
+    ///
+    /// Note that the lifetime of the needle returned is tied to the lifetime
+    /// of the finder, and may be shorter than the `'n` lifetime. Namely, a
+    /// finder's needle can be either borrowed or owned, so the lifetime of the
+    /// needle returned must necessarily be the shorter of the two.
+    #[inline]
+    pub fn needle(&self) -> &[u8] {
+        self.needle.as_slice()
+    }
+}
+
+/// A single substring reverse searcher fixed to a particular needle.
+///
+/// The purpose of this type is to permit callers to construct a substring
+/// searcher that can be used to search haystacks without the overhead of
+/// constructing the searcher in the first place. This is a somewhat niche
+/// concern when it's necessary to re-use the same needle to search multiple
+/// different haystacks with as little overhead as possible. In general,
+/// using [`rfind`] is good enough, but `FinderRev` is useful when you can
+/// meaningfully observe searcher construction time in a profile.
+///
+/// When the `std` feature is enabled, then this type has an `into_owned`
+/// version which permits building a `FinderRev` that is not connected to
+/// the lifetime of its needle.
+#[derive(Clone, Debug)]
+pub struct FinderRev<'n> {
+    needle: CowBytes<'n>,
+    searcher: SearcherRev,
+}
+
+impl<'n> FinderRev<'n> {
+    /// Create a new reverse finder for the given needle.
+    #[inline]
+    pub fn new<B: ?Sized + AsRef<[u8]>>(needle: &'n B) -> FinderRev<'n> {
+        FinderBuilder::new().build_reverse(needle)
+    }
+
+    /// Returns the index of the last occurrence of this needle in the given
+    /// haystack.
+    ///
+    /// The haystack may be any type that can be cheaply converted into a
+    /// `&[u8]`. This includes, but is not limited to, `&str` and `&[u8]`.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use memchr::memmem::FinderRev;
+    ///
+    /// let haystack = b"foo bar baz";
+    /// assert_eq!(Some(0), FinderRev::new("foo").rfind(haystack));
+    /// assert_eq!(Some(4), FinderRev::new("bar").rfind(haystack));
+    /// assert_eq!(None, FinderRev::new("quux").rfind(haystack));
+    /// ```
+    pub fn rfind<B: AsRef<[u8]>>(&self, haystack: B) -> Option<usize> {
+        self.searcher.rfind(haystack.as_ref(), self.needle.as_slice())
+    }
+
+    /// Returns a reverse iterator over all occurrences of a substring in a
+    /// haystack.
+    ///
+    /// # Complexity
+    ///
+    /// This routine is guaranteed to have worst case linear time complexity
+    /// with respect to both the needle and the haystack. That is, this runs
+    /// in `O(needle.len() + haystack.len())` time.
+    ///
+    /// This routine is also guaranteed to have worst case constant space
+    /// complexity.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use memchr::memmem::FinderRev;
+    ///
+    /// let haystack = b"foo bar foo baz foo";
+    /// let finder = FinderRev::new(b"foo");
+    /// let mut it = finder.rfind_iter(haystack);
+    /// assert_eq!(Some(16), it.next());
+    /// assert_eq!(Some(8), it.next());
+    /// assert_eq!(Some(0), it.next());
+    /// assert_eq!(None, it.next());
+    /// ```
+    #[inline]
+    pub fn rfind_iter<'a, 'h>(
+        &'a self,
+        haystack: &'h [u8],
+    ) -> FindRevIter<'h, 'a> {
+        FindRevIter::new(haystack, self.as_ref())
+    }
+
+    /// Convert this finder into its owned variant, such that it no longer
+    /// borrows the needle.
+    ///
+    /// If this is already an owned finder, then this is a no-op. Otherwise,
+    /// this copies the needle.
+    ///
+    /// This is only available when the `std` feature is enabled.
+    #[cfg(feature = "alloc")]
+    #[inline]
+    pub fn into_owned(self) -> FinderRev<'static> {
+        FinderRev {
+            needle: self.needle.into_owned(),
+            searcher: self.searcher.clone(),
+        }
+    }
+
+    /// Convert this finder into its borrowed variant.
+    ///
+    /// This is primarily useful if your finder is owned and you'd like to
+    /// store its borrowed variant in some intermediate data structure.
+    ///
+    /// Note that the lifetime parameter of the returned finder is tied to the
+    /// lifetime of `self`, and may be shorter than the `'n` lifetime of the
+    /// needle itself. Namely, a finder's needle can be either borrowed or
+    /// owned, so the lifetime of the needle returned must necessarily be the
+    /// shorter of the two.
+    #[inline]
+    pub fn as_ref(&self) -> FinderRev<'_> {
+        FinderRev {
+            needle: CowBytes::new(self.needle()),
+            searcher: self.searcher.clone(),
+        }
+    }
+
+    /// Returns the needle that this finder searches for.
+    ///
+    /// Note that the lifetime of the needle returned is tied to the lifetime
+    /// of the finder, and may be shorter than the `'n` lifetime. Namely, a
+    /// finder's needle can be either borrowed or owned, so the lifetime of the
+    /// needle returned must necessarily be the shorter of the two.
+    #[inline]
+    pub fn needle(&self) -> &[u8] {
+        self.needle.as_slice()
+    }
+}
+
+/// A builder for constructing non-default forward or reverse memmem finders.
+///
+/// A builder is primarily useful for configuring a substring searcher.
+/// Currently, the only configuration exposed is the ability to disable
+/// heuristic prefilters used to speed up certain searches.
+#[derive(Clone, Debug, Default)]
+pub struct FinderBuilder {
+    prefilter: Prefilter,
+}
+
+impl FinderBuilder {
+    /// Create a new finder builder with default settings.
+    pub fn new() -> FinderBuilder {
+        FinderBuilder::default()
+    }
+
+    /// Build a forward finder using the given needle from the current
+    /// settings.
+    pub fn build_forward<'n, B: ?Sized + AsRef<[u8]>>(
+        &self,
+        needle: &'n B,
+    ) -> Finder<'n> {
+        self.build_forward_with_ranker(DefaultFrequencyRank, needle)
+    }
+
+    /// Build a forward finder using the given needle and a custom heuristic for
+    /// determining the frequency of a given byte in the dataset.
+    /// See [`HeuristicFrequencyRank`] for more details.
+    pub fn build_forward_with_ranker<
+        'n,
+        R: HeuristicFrequencyRank,
+        B: ?Sized + AsRef<[u8]>,
+    >(
+        &self,
+        ranker: R,
+        needle: &'n B,
+    ) -> Finder<'n> {
+        let needle = needle.as_ref();
+        Finder {
+            needle: CowBytes::new(needle),
+            searcher: Searcher::new(self.prefilter, ranker, needle),
+        }
+    }
+
+    /// Build a reverse finder using the given needle from the current
+    /// settings.
+    pub fn build_reverse<'n, B: ?Sized + AsRef<[u8]>>(
+        &self,
+        needle: &'n B,
+    ) -> FinderRev<'n> {
+        let needle = needle.as_ref();
+        FinderRev {
+            needle: CowBytes::new(needle),
+            searcher: SearcherRev::new(needle),
+        }
+    }
+
+    /// Configure the prefilter setting for the finder.
+    ///
+    /// See the documentation for [`Prefilter`] for more discussion on why
+    /// you might want to configure this.
+    pub fn prefilter(&mut self, prefilter: Prefilter) -> &mut FinderBuilder {
+        self.prefilter = prefilter;
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    define_substring_forward_quickcheck!(|h, n| Some(Finder::new(n).find(h)));
+    define_substring_reverse_quickcheck!(|h, n| Some(
+        FinderRev::new(n).rfind(h)
+    ));
+
+    #[test]
+    fn forward() {
+        crate::tests::substring::Runner::new()
+            .fwd(|h, n| Some(Finder::new(n).find(h)))
+            .run();
+    }
+
+    #[test]
+    fn reverse() {
+        crate::tests::substring::Runner::new()
+            .rev(|h, n| Some(FinderRev::new(n).rfind(h)))
+            .run();
+    }
+}
+
\ No newline at end of file diff --git a/src/memchr/memmem/searcher.rs.html b/src/memchr/memmem/searcher.rs.html new file mode 100644 index 000000000..df1528778 --- /dev/null +++ b/src/memchr/memmem/searcher.rs.html @@ -0,0 +1,2061 @@ +searcher.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+
use crate::arch::all::{
+    packedpair::{HeuristicFrequencyRank, Pair},
+    rabinkarp, twoway,
+};
+
+#[cfg(target_arch = "aarch64")]
+use crate::arch::aarch64::neon::packedpair as neon;
+#[cfg(target_arch = "wasm32")]
+use crate::arch::wasm32::simd128::packedpair as simd128;
+#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+use crate::arch::x86_64::{
+    avx2::packedpair as avx2, sse2::packedpair as sse2,
+};
+
+/// A "meta" substring searcher.
+///
+/// To a first approximation, this chooses what it believes to be the "best"
+/// substring search implemnetation based on the needle at construction time.
+/// Then, every call to `find` will execute that particular implementation. To
+/// a second approximation, multiple substring search algorithms may be used,
+/// depending on the haystack. For example, for supremely short haystacks,
+/// Rabin-Karp is typically used.
+///
+/// See the documentation on `Prefilter` for an explanation of the dispatching
+/// mechanism. The quick summary is that an enum has too much overhead and
+/// we can't use dynamic dispatch via traits because we need to work in a
+/// core-only environment. (Dynamic dispatch works in core-only, but you
+/// need `&dyn Trait` and we really need a `Box<dyn Trait>` here. The latter
+/// requires `alloc`.) So instead, we use a union and an appropriately paired
+/// free function to read from the correct field on the union and execute the
+/// chosen substring search implementation.
+#[derive(Clone)]
+pub(crate) struct Searcher {
+    call: SearcherKindFn,
+    kind: SearcherKind,
+    rabinkarp: rabinkarp::Finder,
+}
+
+impl Searcher {
+    /// Creates a new "meta" substring searcher that attempts to choose the
+    /// best algorithm based on the needle, heuristics and what the current
+    /// target supports.
+    #[inline]
+    pub(crate) fn new<R: HeuristicFrequencyRank>(
+        prefilter: PrefilterConfig,
+        ranker: R,
+        needle: &[u8],
+    ) -> Searcher {
+        let rabinkarp = rabinkarp::Finder::new(needle);
+        if needle.len() <= 1 {
+            return if needle.is_empty() {
+                trace!("building empty substring searcher");
+                Searcher {
+                    call: searcher_kind_empty,
+                    kind: SearcherKind { empty: () },
+                    rabinkarp,
+                }
+            } else {
+                trace!("building one-byte substring searcher");
+                debug_assert_eq!(1, needle.len());
+                Searcher {
+                    call: searcher_kind_one_byte,
+                    kind: SearcherKind { one_byte: needle[0] },
+                    rabinkarp,
+                }
+            };
+        }
+        let pair = match Pair::with_ranker(needle, &ranker) {
+            Some(pair) => pair,
+            None => return Searcher::twoway(needle, rabinkarp, None),
+        };
+        debug_assert_ne!(
+            pair.index1(),
+            pair.index2(),
+            "pair offsets should not be equivalent"
+        );
+        #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+        {
+            if let Some(pp) = avx2::Finder::with_pair(needle, pair) {
+                if do_packed_search(needle) {
+                    trace!("building x86_64 AVX2 substring searcher");
+                    let kind = SearcherKind { avx2: pp };
+                    Searcher { call: searcher_kind_avx2, kind, rabinkarp }
+                } else if prefilter.is_none() {
+                    Searcher::twoway(needle, rabinkarp, None)
+                } else {
+                    let prestrat = Prefilter::avx2(pp, needle);
+                    Searcher::twoway(needle, rabinkarp, Some(prestrat))
+                }
+            } else if let Some(pp) = sse2::Finder::with_pair(needle, pair) {
+                if do_packed_search(needle) {
+                    trace!("building x86_64 SSE2 substring searcher");
+                    let kind = SearcherKind { sse2: pp };
+                    Searcher { call: searcher_kind_sse2, kind, rabinkarp }
+                } else if prefilter.is_none() {
+                    Searcher::twoway(needle, rabinkarp, None)
+                } else {
+                    let prestrat = Prefilter::sse2(pp, needle);
+                    Searcher::twoway(needle, rabinkarp, Some(prestrat))
+                }
+            } else if prefilter.is_none() {
+                Searcher::twoway(needle, rabinkarp, None)
+            } else {
+                // We're pretty unlikely to get to this point, but it is
+                // possible to be running on x86_64 without SSE2. Namely, it's
+                // really up to the OS whether it wants to support vector
+                // registers or not.
+                let prestrat = Prefilter::fallback(ranker, pair, needle);
+                Searcher::twoway(needle, rabinkarp, prestrat)
+            }
+        }
+        #[cfg(target_arch = "wasm32")]
+        {
+            if let Some(pp) = simd128::Finder::with_pair(needle, pair) {
+                if do_packed_search(needle) {
+                    trace!("building wasm32 simd128 substring searcher");
+                    let kind = SearcherKind { simd128: pp };
+                    Searcher { call: searcher_kind_simd128, kind, rabinkarp }
+                } else if prefilter.is_none() {
+                    Searcher::twoway(needle, rabinkarp, None)
+                } else {
+                    let prestrat = Prefilter::simd128(pp, needle);
+                    Searcher::twoway(needle, rabinkarp, Some(prestrat))
+                }
+            } else if prefilter.is_none() {
+                Searcher::twoway(needle, rabinkarp, None)
+            } else {
+                let prestrat = Prefilter::fallback(ranker, pair, needle);
+                Searcher::twoway(needle, rabinkarp, prestrat)
+            }
+        }
+        #[cfg(target_arch = "aarch64")]
+        {
+            if let Some(pp) = neon::Finder::with_pair(needle, pair) {
+                if do_packed_search(needle) {
+                    trace!("building aarch64 neon substring searcher");
+                    let kind = SearcherKind { neon: pp };
+                    Searcher { call: searcher_kind_neon, kind, rabinkarp }
+                } else if prefilter.is_none() {
+                    Searcher::twoway(needle, rabinkarp, None)
+                } else {
+                    let prestrat = Prefilter::neon(pp, needle);
+                    Searcher::twoway(needle, rabinkarp, Some(prestrat))
+                }
+            } else if prefilter.is_none() {
+                Searcher::twoway(needle, rabinkarp, None)
+            } else {
+                let prestrat = Prefilter::fallback(ranker, pair, needle);
+                Searcher::twoway(needle, rabinkarp, prestrat)
+            }
+        }
+        #[cfg(not(any(
+            all(target_arch = "x86_64", target_feature = "sse2"),
+            target_arch = "wasm32",
+            target_arch = "aarch64"
+        )))]
+        {
+            if prefilter.is_none() {
+                Searcher::twoway(needle, rabinkarp, None)
+            } else {
+                let prestrat = Prefilter::fallback(ranker, pair, needle);
+                Searcher::twoway(needle, rabinkarp, prestrat)
+            }
+        }
+    }
+
+    /// Creates a new searcher that always uses the Two-Way algorithm. This is
+    /// typically used when vector algorithms are unavailable or inappropriate.
+    /// (For example, when the needle is "too long.")
+    ///
+    /// If a prefilter is given, then the searcher returned will be accelerated
+    /// by the prefilter.
+    #[inline]
+    fn twoway(
+        needle: &[u8],
+        rabinkarp: rabinkarp::Finder,
+        prestrat: Option<Prefilter>,
+    ) -> Searcher {
+        let finder = twoway::Finder::new(needle);
+        match prestrat {
+            None => {
+                trace!("building scalar two-way substring searcher");
+                let kind = SearcherKind { two_way: finder };
+                Searcher { call: searcher_kind_two_way, kind, rabinkarp }
+            }
+            Some(prestrat) => {
+                trace!(
+                    "building scalar two-way \
+                     substring searcher with a prefilter"
+                );
+                let two_way_with_prefilter =
+                    TwoWayWithPrefilter { finder, prestrat };
+                let kind = SearcherKind { two_way_with_prefilter };
+                Searcher {
+                    call: searcher_kind_two_way_with_prefilter,
+                    kind,
+                    rabinkarp,
+                }
+            }
+        }
+    }
+
+    /// Searches the given haystack for the given needle. The needle given
+    /// should be the same as the needle that this finder was initialized
+    /// with.
+    ///
+    /// Inlining this can lead to big wins for latency, and #[inline] doesn't
+    /// seem to be enough in some cases.
+    #[inline(always)]
+    pub(crate) fn find(
+        &self,
+        prestate: &mut PrefilterState,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        if haystack.len() < needle.len() {
+            None
+        } else {
+            // SAFETY: By construction, we've ensured that the function
+            // in `self.call` is properly paired with the union used in
+            // `self.kind`.
+            unsafe { (self.call)(self, prestate, haystack, needle) }
+        }
+    }
+}
+
+impl core::fmt::Debug for Searcher {
+    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+        f.debug_struct("Searcher")
+            .field("call", &"<searcher function>")
+            .field("kind", &"<searcher kind union>")
+            .field("rabinkarp", &self.rabinkarp)
+            .finish()
+    }
+}
+
+/// A union indicating one of several possible substring search implementations
+/// that are in active use.
+///
+/// This union should only be read by one of the functions prefixed with
+/// `searcher_kind_`. Namely, the correct function is meant to be paired with
+/// the union by the caller, such that the function always reads from the
+/// designated union field.
+#[derive(Clone, Copy)]
+union SearcherKind {
+    empty: (),
+    one_byte: u8,
+    two_way: twoway::Finder,
+    two_way_with_prefilter: TwoWayWithPrefilter,
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    sse2: crate::arch::x86_64::sse2::packedpair::Finder,
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    avx2: crate::arch::x86_64::avx2::packedpair::Finder,
+    #[cfg(target_arch = "wasm32")]
+    simd128: crate::arch::wasm32::simd128::packedpair::Finder,
+    #[cfg(target_arch = "aarch64")]
+    neon: crate::arch::aarch64::neon::packedpair::Finder,
+}
+
+/// A two-way substring searcher with a prefilter.
+#[derive(Copy, Clone, Debug)]
+struct TwoWayWithPrefilter {
+    finder: twoway::Finder,
+    prestrat: Prefilter,
+}
+
+/// The type of a substring search function.
+///
+/// # Safety
+///
+/// When using a function of this type, callers must ensure that the correct
+/// function is paired with the value populated in `SearcherKind` union.
+type SearcherKindFn = unsafe fn(
+    searcher: &Searcher,
+    prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize>;
+
+/// Reads from the `empty` field of `SearcherKind` to handle the case of
+/// searching for the empty needle. Works on all platforms.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.empty` union field is set.
+unsafe fn searcher_kind_empty(
+    _searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    _haystack: &[u8],
+    _needle: &[u8],
+) -> Option<usize> {
+    Some(0)
+}
+
+/// Reads from the `one_byte` field of `SearcherKind` to handle the case of
+/// searching for a single byte needle. Works on all platforms.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.one_byte` union field is set.
+unsafe fn searcher_kind_one_byte(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    _needle: &[u8],
+) -> Option<usize> {
+    let needle = searcher.kind.one_byte;
+    crate::memchr(needle, haystack)
+}
+
+/// Reads from the `two_way` field of `SearcherKind` to handle the case of
+/// searching for an arbitrary needle without prefilter acceleration. Works on
+/// all platforms.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.two_way` union field is set.
+unsafe fn searcher_kind_two_way(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    if rabinkarp::is_fast(haystack, needle) {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        searcher.kind.two_way.find(haystack, needle)
+    }
+}
+
+/// Reads from the `two_way_with_prefilter` field of `SearcherKind` to handle
+/// the case of searching for an arbitrary needle with prefilter acceleration.
+/// Works on all platforms.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.two_way_with_prefilter` union
+/// field is set.
+unsafe fn searcher_kind_two_way_with_prefilter(
+    searcher: &Searcher,
+    prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    if rabinkarp::is_fast(haystack, needle) {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        let TwoWayWithPrefilter { ref finder, ref prestrat } =
+            searcher.kind.two_way_with_prefilter;
+        let pre = Pre { prestate, prestrat };
+        finder.find_with_prefilter(Some(pre), haystack, needle)
+    }
+}
+
+/// Reads from the `sse2` field of `SearcherKind` to execute the x86_64 SSE2
+/// vectorized substring search implementation.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.sse2` union field is set.
+#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+unsafe fn searcher_kind_sse2(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    let finder = &searcher.kind.sse2;
+    if haystack.len() < finder.min_haystack_len() {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        finder.find(haystack, needle)
+    }
+}
+
+/// Reads from the `avx2` field of `SearcherKind` to execute the x86_64 AVX2
+/// vectorized substring search implementation.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.avx2` union field is set.
+#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+unsafe fn searcher_kind_avx2(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    let finder = &searcher.kind.avx2;
+    if haystack.len() < finder.min_haystack_len() {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        finder.find(haystack, needle)
+    }
+}
+
+/// Reads from the `simd128` field of `SearcherKind` to execute the wasm32
+/// simd128 vectorized substring search implementation.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.simd128` union field is set.
+#[cfg(target_arch = "wasm32")]
+unsafe fn searcher_kind_simd128(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    let finder = &searcher.kind.simd128;
+    if haystack.len() < finder.min_haystack_len() {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        finder.find(haystack, needle)
+    }
+}
+
+/// Reads from the `neon` field of `SearcherKind` to execute the aarch64 neon
+/// vectorized substring search implementation.
+///
+/// # Safety
+///
+/// Callers must ensure that the `searcher.kind.neon` union field is set.
+#[cfg(target_arch = "aarch64")]
+unsafe fn searcher_kind_neon(
+    searcher: &Searcher,
+    _prestate: &mut PrefilterState,
+    haystack: &[u8],
+    needle: &[u8],
+) -> Option<usize> {
+    let finder = &searcher.kind.neon;
+    if haystack.len() < finder.min_haystack_len() {
+        searcher.rabinkarp.find(haystack, needle)
+    } else {
+        finder.find(haystack, needle)
+    }
+}
+
+/// A reverse substring searcher.
+#[derive(Clone, Debug)]
+pub(crate) struct SearcherRev {
+    kind: SearcherRevKind,
+    rabinkarp: rabinkarp::FinderRev,
+}
+
+/// The kind of the reverse searcher.
+///
+/// For the reverse case, we don't do any SIMD acceleration or prefilters.
+/// There is no specific technical reason why we don't, but rather don't do it
+/// because it's not clear it's worth the extra code to do so. If you have a
+/// use case for it, please file an issue.
+///
+/// We also don't do the union trick as we do with the forward case and
+/// prefilters. Basically for the same reason we don't have prefilters or
+/// vector algorithms for reverse searching: it's not clear it's worth doing.
+/// Please file an issue if you have a compelling use case for fast reverse
+/// substring search.
+#[derive(Clone, Debug)]
+enum SearcherRevKind {
+    Empty,
+    OneByte { needle: u8 },
+    TwoWay { finder: twoway::FinderRev },
+}
+
+impl SearcherRev {
+    /// Creates a new searcher for finding occurrences of the given needle in
+    /// reverse. That is, it reports the last (instead of the first) occurrence
+    /// of a needle in a haystack.
+    #[inline]
+    pub(crate) fn new(needle: &[u8]) -> SearcherRev {
+        let kind = if needle.len() <= 1 {
+            if needle.is_empty() {
+                trace!("building empty reverse substring searcher");
+                SearcherRevKind::Empty
+            } else {
+                trace!("building one-byte reverse substring searcher");
+                debug_assert_eq!(1, needle.len());
+                SearcherRevKind::OneByte { needle: needle[0] }
+            }
+        } else {
+            trace!("building scalar two-way reverse substring searcher");
+            let finder = twoway::FinderRev::new(needle);
+            SearcherRevKind::TwoWay { finder }
+        };
+        let rabinkarp = rabinkarp::FinderRev::new(needle);
+        SearcherRev { kind, rabinkarp }
+    }
+
+    /// Searches the given haystack for the last occurrence of the given
+    /// needle. The needle given should be the same as the needle that this
+    /// finder was initialized with.
+    #[inline]
+    pub(crate) fn rfind(
+        &self,
+        haystack: &[u8],
+        needle: &[u8],
+    ) -> Option<usize> {
+        if haystack.len() < needle.len() {
+            return None;
+        }
+        match self.kind {
+            SearcherRevKind::Empty => Some(haystack.len()),
+            SearcherRevKind::OneByte { needle } => {
+                crate::memrchr(needle, haystack)
+            }
+            SearcherRevKind::TwoWay { ref finder } => {
+                if rabinkarp::is_fast(haystack, needle) {
+                    self.rabinkarp.rfind(haystack, needle)
+                } else {
+                    finder.rfind(haystack, needle)
+                }
+            }
+        }
+    }
+}
+
+/// Prefilter controls whether heuristics are used to accelerate searching.
+///
+/// A prefilter refers to the idea of detecting candidate matches very quickly,
+/// and then confirming whether those candidates are full matches. This
+/// idea can be quite effective since it's often the case that looking for
+/// candidates can be a lot faster than running a complete substring search
+/// over the entire input. Namely, looking for candidates can be done with
+/// extremely fast vectorized code.
+///
+/// The downside of a prefilter is that it assumes false positives (which are
+/// candidates generated by a prefilter that aren't matches) are somewhat rare
+/// relative to the frequency of full matches. That is, if a lot of false
+/// positives are generated, then it's possible for search time to be worse
+/// than if the prefilter wasn't enabled in the first place.
+///
+/// Another downside of a prefilter is that it can result in highly variable
+/// performance, where some cases are extraordinarily fast and others aren't.
+/// Typically, variable performance isn't a problem, but it may be for your use
+/// case.
+///
+/// The use of prefilters in this implementation does use a heuristic to detect
+/// when a prefilter might not be carrying its weight, and will dynamically
+/// disable its use. Nevertheless, this configuration option gives callers
+/// the ability to disable prefilters if you have knowledge that they won't be
+/// useful.
+#[derive(Clone, Copy, Debug)]
+#[non_exhaustive]
+pub enum PrefilterConfig {
+    /// Never used a prefilter in substring search.
+    None,
+    /// Automatically detect whether a heuristic prefilter should be used. If
+    /// it is used, then heuristics will be used to dynamically disable the
+    /// prefilter if it is believed to not be carrying its weight.
+    Auto,
+}
+
+impl Default for PrefilterConfig {
+    fn default() -> PrefilterConfig {
+        PrefilterConfig::Auto
+    }
+}
+
+impl PrefilterConfig {
+    /// Returns true when this prefilter is set to the `None` variant.
+    fn is_none(&self) -> bool {
+        matches!(*self, PrefilterConfig::None)
+    }
+}
+
+/// The implementation of a prefilter.
+///
+/// This type encapsulates dispatch to one of several possible choices for a
+/// prefilter. Generally speaking, all prefilters have the same approximate
+/// algorithm: they choose a couple of bytes from the needle that are believed
+/// to be rare, use a fast vector algorithm to look for those bytes and return
+/// positions as candidates for some substring search algorithm (currently only
+/// Two-Way) to confirm as a match or not.
+///
+/// The differences between the algorithms are actually at the vector
+/// implementation level. Namely, we need different routines based on both
+/// which target architecture we're on and what CPU features are supported.
+///
+/// The straight-forwardly obvious approach here is to use an enum, and make
+/// `Prefilter::find` do case analysis to determine which algorithm was
+/// selected and invoke it. However, I've observed that this leads to poor
+/// codegen in some cases, especially in latency sensitive benchmarks. That is,
+/// this approach comes with overhead that I wasn't able to eliminate.
+///
+/// The second obvious approach is to use dynamic dispatch with traits. Doing
+/// that in this context where `Prefilter` owns the selection generally
+/// requires heap allocation, and this code is designed to run in core-only
+/// environments.
+///
+/// So we settle on using a union (that's `PrefilterKind`) and a function
+/// pointer (that's `PrefilterKindFn`). We select the right function pointer
+/// based on which field in the union we set, and that function in turn
+/// knows which field of the union to access. The downside of this approach
+/// is that it forces us to think about safety, but the upside is that
+/// there are some nice latency improvements to benchmarks. (Especially the
+/// `memmem/sliceslice/short` benchmark.)
+///
+/// In cases where we've selected a vector algorithm and the haystack given
+/// is too short, we fallback to the scalar version of `memchr` on the
+/// `rarest_byte`. (The scalar version of `memchr` is still better than a naive
+/// byte-at-a-time loop because it will read in `usize`-sized chunks at a
+/// time.)
+#[derive(Clone, Copy)]
+struct Prefilter {
+    call: PrefilterKindFn,
+    kind: PrefilterKind,
+    rarest_byte: u8,
+    rarest_offset: u8,
+}
+
+impl Prefilter {
+    /// Return a "fallback" prefilter, but only if it is believed to be
+    /// effective.
+    #[inline]
+    fn fallback<R: HeuristicFrequencyRank>(
+        ranker: R,
+        pair: Pair,
+        needle: &[u8],
+    ) -> Option<Prefilter> {
+        /// The maximum frequency rank permitted for the fallback prefilter.
+        /// If the rarest byte in the needle has a frequency rank above this
+        /// value, then no prefilter is used if the fallback prefilter would
+        /// otherwise be selected.
+        const MAX_FALLBACK_RANK: u8 = 250;
+
+        trace!("building fallback prefilter");
+        let rarest_offset = pair.index1();
+        let rarest_byte = needle[usize::from(rarest_offset)];
+        let rarest_rank = ranker.rank(rarest_byte);
+        if rarest_rank > MAX_FALLBACK_RANK {
+            None
+        } else {
+            let finder = crate::arch::all::packedpair::Finder::with_pair(
+                needle,
+                pair.clone(),
+            )?;
+            let call = prefilter_kind_fallback;
+            let kind = PrefilterKind { fallback: finder };
+            Some(Prefilter { call, kind, rarest_byte, rarest_offset })
+        }
+    }
+
+    /// Return a prefilter using a x86_64 SSE2 vector algorithm.
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    #[inline]
+    fn sse2(finder: sse2::Finder, needle: &[u8]) -> Prefilter {
+        trace!("building x86_64 SSE2 prefilter");
+        let rarest_offset = finder.pair().index1();
+        let rarest_byte = needle[usize::from(rarest_offset)];
+        Prefilter {
+            call: prefilter_kind_sse2,
+            kind: PrefilterKind { sse2: finder },
+            rarest_byte,
+            rarest_offset,
+        }
+    }
+
+    /// Return a prefilter using a x86_64 AVX2 vector algorithm.
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    #[inline]
+    fn avx2(finder: avx2::Finder, needle: &[u8]) -> Prefilter {
+        trace!("building x86_64 AVX2 prefilter");
+        let rarest_offset = finder.pair().index1();
+        let rarest_byte = needle[usize::from(rarest_offset)];
+        Prefilter {
+            call: prefilter_kind_avx2,
+            kind: PrefilterKind { avx2: finder },
+            rarest_byte,
+            rarest_offset,
+        }
+    }
+
+    /// Return a prefilter using a wasm32 simd128 vector algorithm.
+    #[cfg(target_arch = "wasm32")]
+    #[inline]
+    fn simd128(finder: simd128::Finder, needle: &[u8]) -> Prefilter {
+        trace!("building wasm32 simd128 prefilter");
+        let rarest_offset = finder.pair().index1();
+        let rarest_byte = needle[usize::from(rarest_offset)];
+        Prefilter {
+            call: prefilter_kind_simd128,
+            kind: PrefilterKind { simd128: finder },
+            rarest_byte,
+            rarest_offset,
+        }
+    }
+
+    /// Return a prefilter using a aarch64 neon vector algorithm.
+    #[cfg(target_arch = "aarch64")]
+    #[inline]
+    fn neon(finder: neon::Finder, needle: &[u8]) -> Prefilter {
+        trace!("building aarch64 neon prefilter");
+        let rarest_offset = finder.pair().index1();
+        let rarest_byte = needle[usize::from(rarest_offset)];
+        Prefilter {
+            call: prefilter_kind_neon,
+            kind: PrefilterKind { neon: finder },
+            rarest_byte,
+            rarest_offset,
+        }
+    }
+
+    /// Return a *candidate* position for a match.
+    ///
+    /// When this returns an offset, it implies that a match could begin at
+    /// that offset, but it may not. That is, it is possible for a false
+    /// positive to be returned.
+    ///
+    /// When `None` is returned, then it is guaranteed that there are no
+    /// matches for the needle in the given haystack. That is, it is impossible
+    /// for a false negative to be returned.
+    ///
+    /// The purpose of this routine is to look for candidate matching positions
+    /// as quickly as possible before running a (likely) slower confirmation
+    /// step.
+    #[inline]
+    fn find(&self, haystack: &[u8]) -> Option<usize> {
+        // SAFETY: By construction, we've ensured that the function in
+        // `self.call` is properly paired with the union used in `self.kind`.
+        unsafe { (self.call)(self, haystack) }
+    }
+
+    /// A "simple" prefilter that just looks for the occurrence of the rarest
+    /// byte from the needle. This is generally only used for very small
+    /// haystacks.
+    #[inline]
+    fn find_simple(&self, haystack: &[u8]) -> Option<usize> {
+        // We don't use crate::memchr here because the haystack should be small
+        // enough that memchr won't be able to use vector routines anyway. So
+        // we just skip straight to the fallback implementation which is likely
+        // faster. (A byte-at-a-time loop is only used when the haystack is
+        // smaller than `size_of::<usize>()`.)
+        crate::arch::all::memchr::One::new(self.rarest_byte)
+            .find(haystack)
+            .map(|i| i.saturating_sub(usize::from(self.rarest_offset)))
+    }
+}
+
+impl core::fmt::Debug for Prefilter {
+    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+        f.debug_struct("Prefilter")
+            .field("call", &"<prefilter function>")
+            .field("kind", &"<prefilter kind union>")
+            .field("rarest_byte", &self.rarest_byte)
+            .field("rarest_offset", &self.rarest_offset)
+            .finish()
+    }
+}
+
+/// A union indicating one of several possible prefilters that are in active
+/// use.
+///
+/// This union should only be read by one of the functions prefixed with
+/// `prefilter_kind_`. Namely, the correct function is meant to be paired with
+/// the union by the caller, such that the function always reads from the
+/// designated union field.
+#[derive(Clone, Copy)]
+union PrefilterKind {
+    fallback: crate::arch::all::packedpair::Finder,
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    sse2: crate::arch::x86_64::sse2::packedpair::Finder,
+    #[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+    avx2: crate::arch::x86_64::avx2::packedpair::Finder,
+    #[cfg(target_arch = "wasm32")]
+    simd128: crate::arch::wasm32::simd128::packedpair::Finder,
+    #[cfg(target_arch = "aarch64")]
+    neon: crate::arch::aarch64::neon::packedpair::Finder,
+}
+
+/// The type of a prefilter function.
+///
+/// # Safety
+///
+/// When using a function of this type, callers must ensure that the correct
+/// function is paired with the value populated in `PrefilterKind` union.
+type PrefilterKindFn =
+    unsafe fn(strat: &Prefilter, haystack: &[u8]) -> Option<usize>;
+
+/// Reads from the `fallback` field of `PrefilterKind` to execute the fallback
+/// prefilter. Works on all platforms.
+///
+/// # Safety
+///
+/// Callers must ensure that the `strat.kind.fallback` union field is set.
+unsafe fn prefilter_kind_fallback(
+    strat: &Prefilter,
+    haystack: &[u8],
+) -> Option<usize> {
+    strat.kind.fallback.find_prefilter(haystack)
+}
+
+/// Reads from the `sse2` field of `PrefilterKind` to execute the x86_64 SSE2
+/// prefilter.
+///
+/// # Safety
+///
+/// Callers must ensure that the `strat.kind.sse2` union field is set.
+#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+unsafe fn prefilter_kind_sse2(
+    strat: &Prefilter,
+    haystack: &[u8],
+) -> Option<usize> {
+    let finder = &strat.kind.sse2;
+    if haystack.len() < finder.min_haystack_len() {
+        strat.find_simple(haystack)
+    } else {
+        finder.find_prefilter(haystack)
+    }
+}
+
+/// Reads from the `avx2` field of `PrefilterKind` to execute the x86_64 AVX2
+/// prefilter.
+///
+/// # Safety
+///
+/// Callers must ensure that the `strat.kind.avx2` union field is set.
+#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
+unsafe fn prefilter_kind_avx2(
+    strat: &Prefilter,
+    haystack: &[u8],
+) -> Option<usize> {
+    let finder = &strat.kind.avx2;
+    if haystack.len() < finder.min_haystack_len() {
+        strat.find_simple(haystack)
+    } else {
+        finder.find_prefilter(haystack)
+    }
+}
+
+/// Reads from the `simd128` field of `PrefilterKind` to execute the wasm32
+/// simd128 prefilter.
+///
+/// # Safety
+///
+/// Callers must ensure that the `strat.kind.simd128` union field is set.
+#[cfg(target_arch = "wasm32")]
+unsafe fn prefilter_kind_simd128(
+    strat: &Prefilter,
+    haystack: &[u8],
+) -> Option<usize> {
+    let finder = &strat.kind.simd128;
+    if haystack.len() < finder.min_haystack_len() {
+        strat.find_simple(haystack)
+    } else {
+        finder.find_prefilter(haystack)
+    }
+}
+
+/// Reads from the `neon` field of `PrefilterKind` to execute the aarch64 neon
+/// prefilter.
+///
+/// # Safety
+///
+/// Callers must ensure that the `strat.kind.neon` union field is set.
+#[cfg(target_arch = "aarch64")]
+unsafe fn prefilter_kind_neon(
+    strat: &Prefilter,
+    haystack: &[u8],
+) -> Option<usize> {
+    let finder = &strat.kind.neon;
+    if haystack.len() < finder.min_haystack_len() {
+        strat.find_simple(haystack)
+    } else {
+        finder.find_prefilter(haystack)
+    }
+}
+
+/// PrefilterState tracks state associated with the effectiveness of a
+/// prefilter. It is used to track how many bytes, on average, are skipped by
+/// the prefilter. If this average dips below a certain threshold over time,
+/// then the state renders the prefilter inert and stops using it.
+///
+/// A prefilter state should be created for each search. (Where creating an
+/// iterator is treated as a single search.) A prefilter state should only be
+/// created from a `Freqy`. e.g., An inert `Freqy` will produce an inert
+/// `PrefilterState`.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct PrefilterState {
+    /// The number of skips that has been executed. This is always 1 greater
+    /// than the actual number of skips. The special sentinel value of 0
+    /// indicates that the prefilter is inert. This is useful to avoid
+    /// additional checks to determine whether the prefilter is still
+    /// "effective." Once a prefilter becomes inert, it should no longer be
+    /// used (according to our heuristics).
+    skips: u32,
+    /// The total number of bytes that have been skipped.
+    skipped: u32,
+}
+
+impl PrefilterState {
+    /// The minimum number of skip attempts to try before considering whether
+    /// a prefilter is effective or not.
+    const MIN_SKIPS: u32 = 50;
+
+    /// The minimum amount of bytes that skipping must average.
+    ///
+    /// This value was chosen based on varying it and checking
+    /// the microbenchmarks. In particular, this can impact the
+    /// pathological/repeated-{huge,small} benchmarks quite a bit if it's set
+    /// too low.
+    const MIN_SKIP_BYTES: u32 = 8;
+
+    /// Create a fresh prefilter state.
+    #[inline]
+    pub(crate) fn new() -> PrefilterState {
+        PrefilterState { skips: 1, skipped: 0 }
+    }
+
+    /// Update this state with the number of bytes skipped on the last
+    /// invocation of the prefilter.
+    #[inline]
+    fn update(&mut self, skipped: usize) {
+        self.skips = self.skips.saturating_add(1);
+        // We need to do this dance since it's technically possible for
+        // `skipped` to overflow a `u32`. (And we use a `u32` to reduce the
+        // size of a prefilter state.)
+        self.skipped = match u32::try_from(skipped) {
+            Err(_) => core::u32::MAX,
+            Ok(skipped) => self.skipped.saturating_add(skipped),
+        };
+    }
+
+    /// Return true if and only if this state indicates that a prefilter is
+    /// still effective.
+    #[inline]
+    fn is_effective(&mut self) -> bool {
+        if self.is_inert() {
+            return false;
+        }
+        if self.skips() < PrefilterState::MIN_SKIPS {
+            return true;
+        }
+        if self.skipped >= PrefilterState::MIN_SKIP_BYTES * self.skips() {
+            return true;
+        }
+
+        // We're inert.
+        self.skips = 0;
+        false
+    }
+
+    /// Returns true if the prefilter this state represents should no longer
+    /// be used.
+    #[inline]
+    fn is_inert(&self) -> bool {
+        self.skips == 0
+    }
+
+    /// Returns the total number of times the prefilter has been used.
+    #[inline]
+    fn skips(&self) -> u32 {
+        // Remember, `0` is a sentinel value indicating inertness, so we
+        // always need to subtract `1` to get our actual number of skips.
+        self.skips.saturating_sub(1)
+    }
+}
+
+/// A combination of prefilter effectiveness state and the prefilter itself.
+#[derive(Debug)]
+pub(crate) struct Pre<'a> {
+    /// State that tracks the effectiveness of a prefilter.
+    prestate: &'a mut PrefilterState,
+    /// The actual prefilter.
+    prestrat: &'a Prefilter,
+}
+
+impl<'a> Pre<'a> {
+    /// Call this prefilter on the given haystack with the given needle.
+    #[inline]
+    pub(crate) fn find(&mut self, haystack: &[u8]) -> Option<usize> {
+        let result = self.prestrat.find(haystack);
+        self.prestate.update(result.unwrap_or(haystack.len()));
+        result
+    }
+
+    /// Return true if and only if this prefilter should be used.
+    #[inline]
+    pub(crate) fn is_effective(&mut self) -> bool {
+        self.prestate.is_effective()
+    }
+}
+
+/// Returns true if the needle has the right characteristics for a vector
+/// algorithm to handle the entirety of substring search.
+///
+/// Vector algorithms can be used for prefilters for other substring search
+/// algorithms (like Two-Way), but they can also be used for substring search
+/// on their own. When used for substring search, vector algorithms will
+/// quickly identify candidate match positions (just like in the prefilter
+/// case), but instead of returning the candidate position they will try to
+/// confirm the match themselves. Confirmation happens via `memcmp`. This
+/// works well for short needles, but can break down when many false candidate
+/// positions are generated for large needles. Thus, we only permit vector
+/// algorithms to own substring search when the needle is of a certain length.
+#[inline]
+fn do_packed_search(needle: &[u8]) -> bool {
+    /// The minimum length of a needle required for this algorithm. The minimum
+    /// is 2 since a length of 1 should just use memchr and a length of 0 isn't
+    /// a case handled by this searcher.
+    const MIN_LEN: usize = 2;
+
+    /// The maximum length of a needle required for this algorithm.
+    ///
+    /// In reality, there is no hard max here. The code below can handle any
+    /// length needle. (Perhaps that suggests there are missing optimizations.)
+    /// Instead, this is a heuristic and a bound guaranteeing our linear time
+    /// complexity.
+    ///
+    /// It is a heuristic because when a candidate match is found, memcmp is
+    /// run. For very large needles with lots of false positives, memcmp can
+    /// make the code run quite slow.
+    ///
+    /// It is a bound because the worst case behavior with memcmp is
+    /// multiplicative in the size of the needle and haystack, and we want
+    /// to keep that additive. This bound ensures we still meet that bound
+    /// theoretically, since it's just a constant. We aren't acting in bad
+    /// faith here, memcmp on tiny needles is so fast that even in pathological
+    /// cases (see pathological vector benchmarks), this is still just as fast
+    /// or faster in practice.
+    ///
+    /// This specific number was chosen by tweaking a bit and running
+    /// benchmarks. The rare-medium-needle, for example, gets about 5% faster
+    /// by using this algorithm instead of a prefilter-accelerated Two-Way.
+    /// There's also a theoretical desire to keep this number reasonably
+    /// low, to mitigate the impact of pathological cases. I did try 64, and
+    /// some benchmarks got a little better, and others (particularly the
+    /// pathological ones), got a lot worse. So... 32 it is?
+    const MAX_LEN: usize = 32;
+    MIN_LEN <= needle.len() && needle.len() <= MAX_LEN
+}
+
\ No newline at end of file diff --git a/src/memchr/vector.rs.html b/src/memchr/vector.rs.html new file mode 100644 index 000000000..49fb3c742 --- /dev/null +++ b/src/memchr/vector.rs.html @@ -0,0 +1,1031 @@ +vector.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+
/// A trait for describing vector operations used by vectorized searchers.
+///
+/// The trait is highly constrained to low level vector operations needed.
+/// In general, it was invented mostly to be generic over x86's __m128i and
+/// __m256i types. At time of writing, it also supports wasm and aarch64
+/// 128-bit vector types as well.
+///
+/// # Safety
+///
+/// All methods are not safe since they are intended to be implemented using
+/// vendor intrinsics, which are also not safe. Callers must ensure that the
+/// appropriate target features are enabled in the calling function, and that
+/// the current CPU supports them. All implementations should avoid marking the
+/// routines with #[target_feature] and instead mark them as #[inline(always)]
+/// to ensure they get appropriately inlined. (inline(always) cannot be used
+/// with target_feature.)
+pub(crate) trait Vector: Copy + core::fmt::Debug {
+    /// The number of bits in the vector.
+    const BITS: usize;
+    /// The number of bytes in the vector. That is, this is the size of the
+    /// vector in memory.
+    const BYTES: usize;
+    /// The bits that must be zero in order for a `*const u8` pointer to be
+    /// correctly aligned to read vector values.
+    const ALIGN: usize;
+
+    /// The type of the value returned by `Vector::movemask`.
+    ///
+    /// This supports abstracting over the specific representation used in
+    /// order to accommodate different representations in different ISAs.
+    type Mask: MoveMask;
+
+    /// Create a vector with 8-bit lanes with the given byte repeated into each
+    /// lane.
+    unsafe fn splat(byte: u8) -> Self;
+
+    /// Read a vector-size number of bytes from the given pointer. The pointer
+    /// must be aligned to the size of the vector.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that at least `BYTES` bytes are readable from
+    /// `data` and that `data` is aligned to a `BYTES` boundary.
+    unsafe fn load_aligned(data: *const u8) -> Self;
+
+    /// Read a vector-size number of bytes from the given pointer. The pointer
+    /// does not need to be aligned.
+    ///
+    /// # Safety
+    ///
+    /// Callers must guarantee that at least `BYTES` bytes are readable from
+    /// `data`.
+    unsafe fn load_unaligned(data: *const u8) -> Self;
+
+    /// _mm_movemask_epi8 or _mm256_movemask_epi8
+    unsafe fn movemask(self) -> Self::Mask;
+    /// _mm_cmpeq_epi8 or _mm256_cmpeq_epi8
+    unsafe fn cmpeq(self, vector2: Self) -> Self;
+    /// _mm_and_si128 or _mm256_and_si256
+    unsafe fn and(self, vector2: Self) -> Self;
+    /// _mm_or or _mm256_or_si256
+    unsafe fn or(self, vector2: Self) -> Self;
+    /// Returns true if and only if `Self::movemask` would return a mask that
+    /// contains at least one non-zero bit.
+    unsafe fn movemask_will_have_non_zero(self) -> bool {
+        self.movemask().has_non_zero()
+    }
+}
+
+/// A trait that abstracts over a vector-to-scalar operation called
+/// "move mask."
+///
+/// On x86-64, this is `_mm_movemask_epi8` for SSE2 and `_mm256_movemask_epi8`
+/// for AVX2. It takes a vector of `u8` lanes and returns a scalar where the
+/// `i`th bit is set if and only if the most significant bit in the `i`th lane
+/// of the vector is set. The simd128 ISA for wasm32 also supports this
+/// exact same operation natively.
+///
+/// ... But aarch64 doesn't. So we have to fake it with more instructions and
+/// a slightly different representation. We could do extra work to unify the
+/// representations, but then would require additional costs in the hot path
+/// for `memchr` and `packedpair`. So instead, we abstraction over the specific
+/// representation with this trait an ddefine the operations we actually need.
+pub(crate) trait MoveMask: Copy + core::fmt::Debug {
+    /// Return a mask that is all zeros except for the least significant `n`
+    /// lanes in a corresponding vector.
+    fn all_zeros_except_least_significant(n: usize) -> Self;
+
+    /// Returns true if and only if this mask has a a non-zero bit anywhere.
+    fn has_non_zero(self) -> bool;
+
+    /// Returns the number of bits set to 1 in this mask.
+    fn count_ones(self) -> usize;
+
+    /// Does a bitwise `and` operation between `self` and `other`.
+    fn and(self, other: Self) -> Self;
+
+    /// Does a bitwise `or` operation between `self` and `other`.
+    fn or(self, other: Self) -> Self;
+
+    /// Returns a mask that is equivalent to `self` but with the least
+    /// significant 1-bit set to 0.
+    fn clear_least_significant_bit(self) -> Self;
+
+    /// Returns the offset of the first non-zero lane this mask represents.
+    fn first_offset(self) -> usize;
+
+    /// Returns the offset of the last non-zero lane this mask represents.
+    fn last_offset(self) -> usize;
+}
+
+/// This is a "sensible" movemask implementation where each bit represents
+/// whether the most significant bit is set in each corresponding lane of a
+/// vector. This is used on x86-64 and wasm, but such a mask is more expensive
+/// to get on aarch64 so we use something a little different.
+///
+/// We call this "sensible" because this is what we get using native sse/avx
+/// movemask instructions. But neon has no such native equivalent.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct SensibleMoveMask(u32);
+
+impl SensibleMoveMask {
+    /// Get the mask in a form suitable for computing offsets.
+    ///
+    /// Basically, this normalizes to little endian. On big endian, this swaps
+    /// the bytes.
+    #[inline(always)]
+    fn get_for_offset(self) -> u32 {
+        #[cfg(target_endian = "big")]
+        {
+            self.0.swap_bytes()
+        }
+        #[cfg(target_endian = "little")]
+        {
+            self.0
+        }
+    }
+}
+
+impl MoveMask for SensibleMoveMask {
+    #[inline(always)]
+    fn all_zeros_except_least_significant(n: usize) -> SensibleMoveMask {
+        debug_assert!(n < 32);
+        SensibleMoveMask(!((1 << n) - 1))
+    }
+
+    #[inline(always)]
+    fn has_non_zero(self) -> bool {
+        self.0 != 0
+    }
+
+    #[inline(always)]
+    fn count_ones(self) -> usize {
+        self.0.count_ones() as usize
+    }
+
+    #[inline(always)]
+    fn and(self, other: SensibleMoveMask) -> SensibleMoveMask {
+        SensibleMoveMask(self.0 & other.0)
+    }
+
+    #[inline(always)]
+    fn or(self, other: SensibleMoveMask) -> SensibleMoveMask {
+        SensibleMoveMask(self.0 | other.0)
+    }
+
+    #[inline(always)]
+    fn clear_least_significant_bit(self) -> SensibleMoveMask {
+        SensibleMoveMask(self.0 & (self.0 - 1))
+    }
+
+    #[inline(always)]
+    fn first_offset(self) -> usize {
+        // We are dealing with little endian here (and if we aren't, we swap
+        // the bytes so we are in practice), where the most significant byte
+        // is at a higher address. That means the least significant bit that
+        // is set corresponds to the position of our first matching byte.
+        // That position corresponds to the number of zeros after the least
+        // significant bit.
+        self.get_for_offset().trailing_zeros() as usize
+    }
+
+    #[inline(always)]
+    fn last_offset(self) -> usize {
+        // We are dealing with little endian here (and if we aren't, we swap
+        // the bytes so we are in practice), where the most significant byte is
+        // at a higher address. That means the most significant bit that is set
+        // corresponds to the position of our last matching byte. The position
+        // from the end of the mask is therefore the number of leading zeros
+        // in a 32 bit integer, and the position from the start of the mask is
+        // therefore 32 - (leading zeros) - 1.
+        32 - self.get_for_offset().leading_zeros() as usize - 1
+    }
+}
+
+#[cfg(target_arch = "x86_64")]
+mod x86sse2 {
+    use core::arch::x86_64::*;
+
+    use super::{SensibleMoveMask, Vector};
+
+    impl Vector for __m128i {
+        const BITS: usize = 128;
+        const BYTES: usize = 16;
+        const ALIGN: usize = Self::BYTES - 1;
+
+        type Mask = SensibleMoveMask;
+
+        #[inline(always)]
+        unsafe fn splat(byte: u8) -> __m128i {
+            _mm_set1_epi8(byte as i8)
+        }
+
+        #[inline(always)]
+        unsafe fn load_aligned(data: *const u8) -> __m128i {
+            _mm_load_si128(data as *const __m128i)
+        }
+
+        #[inline(always)]
+        unsafe fn load_unaligned(data: *const u8) -> __m128i {
+            _mm_loadu_si128(data as *const __m128i)
+        }
+
+        #[inline(always)]
+        unsafe fn movemask(self) -> SensibleMoveMask {
+            SensibleMoveMask(_mm_movemask_epi8(self) as u32)
+        }
+
+        #[inline(always)]
+        unsafe fn cmpeq(self, vector2: Self) -> __m128i {
+            _mm_cmpeq_epi8(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn and(self, vector2: Self) -> __m128i {
+            _mm_and_si128(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn or(self, vector2: Self) -> __m128i {
+            _mm_or_si128(self, vector2)
+        }
+    }
+}
+
+#[cfg(target_arch = "x86_64")]
+mod x86avx2 {
+    use core::arch::x86_64::*;
+
+    use super::{SensibleMoveMask, Vector};
+
+    impl Vector for __m256i {
+        const BITS: usize = 256;
+        const BYTES: usize = 32;
+        const ALIGN: usize = Self::BYTES - 1;
+
+        type Mask = SensibleMoveMask;
+
+        #[inline(always)]
+        unsafe fn splat(byte: u8) -> __m256i {
+            _mm256_set1_epi8(byte as i8)
+        }
+
+        #[inline(always)]
+        unsafe fn load_aligned(data: *const u8) -> __m256i {
+            _mm256_load_si256(data as *const __m256i)
+        }
+
+        #[inline(always)]
+        unsafe fn load_unaligned(data: *const u8) -> __m256i {
+            _mm256_loadu_si256(data as *const __m256i)
+        }
+
+        #[inline(always)]
+        unsafe fn movemask(self) -> SensibleMoveMask {
+            SensibleMoveMask(_mm256_movemask_epi8(self) as u32)
+        }
+
+        #[inline(always)]
+        unsafe fn cmpeq(self, vector2: Self) -> __m256i {
+            _mm256_cmpeq_epi8(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn and(self, vector2: Self) -> __m256i {
+            _mm256_and_si256(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn or(self, vector2: Self) -> __m256i {
+            _mm256_or_si256(self, vector2)
+        }
+    }
+}
+
+#[cfg(target_arch = "aarch64")]
+mod aarch64neon {
+    use core::arch::aarch64::*;
+
+    use super::{MoveMask, Vector};
+
+    impl Vector for uint8x16_t {
+        const BITS: usize = 128;
+        const BYTES: usize = 16;
+        const ALIGN: usize = Self::BYTES - 1;
+
+        type Mask = NeonMoveMask;
+
+        #[inline(always)]
+        unsafe fn splat(byte: u8) -> uint8x16_t {
+            vdupq_n_u8(byte)
+        }
+
+        #[inline(always)]
+        unsafe fn load_aligned(data: *const u8) -> uint8x16_t {
+            // I've tried `data.cast::<uint8x16_t>().read()` instead, but
+            // couldn't observe any benchmark differences.
+            Self::load_unaligned(data)
+        }
+
+        #[inline(always)]
+        unsafe fn load_unaligned(data: *const u8) -> uint8x16_t {
+            vld1q_u8(data)
+        }
+
+        #[inline(always)]
+        unsafe fn movemask(self) -> NeonMoveMask {
+            let asu16s = vreinterpretq_u16_u8(self);
+            let mask = vshrn_n_u16(asu16s, 4);
+            let asu64 = vreinterpret_u64_u8(mask);
+            let scalar64 = vget_lane_u64(asu64, 0);
+            NeonMoveMask(scalar64 & 0x8888888888888888)
+        }
+
+        #[inline(always)]
+        unsafe fn cmpeq(self, vector2: Self) -> uint8x16_t {
+            vceqq_u8(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn and(self, vector2: Self) -> uint8x16_t {
+            vandq_u8(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn or(self, vector2: Self) -> uint8x16_t {
+            vorrq_u8(self, vector2)
+        }
+
+        /// This is the only interesting implementation of this routine.
+        /// Basically, instead of doing the "shift right narrow" dance, we use
+        /// adajacent folding max to determine whether there are any non-zero
+        /// bytes in our mask. If there are, *then* we'll do the "shift right
+        /// narrow" dance. In benchmarks, this does lead to slightly better
+        /// throughput, but the win doesn't appear huge.
+        #[inline(always)]
+        unsafe fn movemask_will_have_non_zero(self) -> bool {
+            let low = vreinterpretq_u64_u8(vpmaxq_u8(self, self));
+            vgetq_lane_u64(low, 0) != 0
+        }
+    }
+
+    /// Neon doesn't have a `movemask` that works like the one in x86-64, so we
+    /// wind up using a different method[1]. The different method also produces
+    /// a mask, but 4 bits are set in the neon case instead of a single bit set
+    /// in the x86-64 case. We do an extra step to zero out 3 of the 4 bits,
+    /// but we still wind up with at least 3 zeroes between each set bit. This
+    /// generally means that we need to do some division by 4 before extracting
+    /// offsets.
+    ///
+    /// In fact, the existence of this type is the entire reason that we have
+    /// the `MoveMask` trait in the first place. This basically lets us keep
+    /// the different representations of masks without being forced to unify
+    /// them into a single representation, which could result in extra and
+    /// unnecessary work.
+    ///
+    /// [1]: https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
+    #[derive(Clone, Copy, Debug)]
+    pub(crate) struct NeonMoveMask(u64);
+
+    impl NeonMoveMask {
+        /// Get the mask in a form suitable for computing offsets.
+        ///
+        /// Basically, this normalizes to little endian. On big endian, this
+        /// swaps the bytes.
+        #[inline(always)]
+        fn get_for_offset(self) -> u64 {
+            #[cfg(target_endian = "big")]
+            {
+                self.0.swap_bytes()
+            }
+            #[cfg(target_endian = "little")]
+            {
+                self.0
+            }
+        }
+    }
+
+    impl MoveMask for NeonMoveMask {
+        #[inline(always)]
+        fn all_zeros_except_least_significant(n: usize) -> NeonMoveMask {
+            debug_assert!(n < 16);
+            NeonMoveMask(!(((1 << n) << 2) - 1))
+        }
+
+        #[inline(always)]
+        fn has_non_zero(self) -> bool {
+            self.0 != 0
+        }
+
+        #[inline(always)]
+        fn count_ones(self) -> usize {
+            self.0.count_ones() as usize
+        }
+
+        #[inline(always)]
+        fn and(self, other: NeonMoveMask) -> NeonMoveMask {
+            NeonMoveMask(self.0 & other.0)
+        }
+
+        #[inline(always)]
+        fn or(self, other: NeonMoveMask) -> NeonMoveMask {
+            NeonMoveMask(self.0 | other.0)
+        }
+
+        #[inline(always)]
+        fn clear_least_significant_bit(self) -> NeonMoveMask {
+            NeonMoveMask(self.0 & (self.0 - 1))
+        }
+
+        #[inline(always)]
+        fn first_offset(self) -> usize {
+            // We are dealing with little endian here (and if we aren't,
+            // we swap the bytes so we are in practice), where the most
+            // significant byte is at a higher address. That means the least
+            // significant bit that is set corresponds to the position of our
+            // first matching byte. That position corresponds to the number of
+            // zeros after the least significant bit.
+            //
+            // Note that unlike `SensibleMoveMask`, this mask has its bits
+            // spread out over 64 bits instead of 16 bits (for a 128 bit
+            // vector). Namely, where as x86-64 will turn
+            //
+            //   0x00 0xFF 0x00 0x00 0xFF
+            //
+            // into 10010, our neon approach will turn it into
+            //
+            //   10000000000010000000
+            //
+            // And this happens because neon doesn't have a native `movemask`
+            // instruction, so we kind of fake it[1]. Thus, we divide the
+            // number of trailing zeros by 4 to get the "real" offset.
+            //
+            // [1]: https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon
+            (self.get_for_offset().trailing_zeros() >> 2) as usize
+        }
+
+        #[inline(always)]
+        fn last_offset(self) -> usize {
+            // See comment in `first_offset` above. This is basically the same,
+            // but coming from the other direction.
+            16 - (self.get_for_offset().leading_zeros() >> 2) as usize - 1
+        }
+    }
+}
+
+#[cfg(target_arch = "wasm32")]
+mod wasm_simd128 {
+    use core::arch::wasm32::*;
+
+    use super::{SensibleMoveMask, Vector};
+
+    impl Vector for v128 {
+        const BITS: usize = 128;
+        const BYTES: usize = 16;
+        const ALIGN: usize = Self::BYTES - 1;
+
+        type Mask = SensibleMoveMask;
+
+        #[inline(always)]
+        unsafe fn splat(byte: u8) -> v128 {
+            u8x16_splat(byte)
+        }
+
+        #[inline(always)]
+        unsafe fn load_aligned(data: *const u8) -> v128 {
+            *data.cast()
+        }
+
+        #[inline(always)]
+        unsafe fn load_unaligned(data: *const u8) -> v128 {
+            v128_load(data.cast())
+        }
+
+        #[inline(always)]
+        unsafe fn movemask(self) -> SensibleMoveMask {
+            SensibleMoveMask(u8x16_bitmask(self).into())
+        }
+
+        #[inline(always)]
+        unsafe fn cmpeq(self, vector2: Self) -> v128 {
+            u8x16_eq(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn and(self, vector2: Self) -> v128 {
+            v128_and(self, vector2)
+        }
+
+        #[inline(always)]
+        unsafe fn or(self, vector2: Self) -> v128 {
+            v128_or(self, vector2)
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/ascii.rs.html b/src/roe/ascii.rs.html new file mode 100644 index 000000000..cb78aee7c --- /dev/null +++ b/src/roe/ascii.rs.html @@ -0,0 +1,29 @@ +ascii.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+
mod lowercase;
+mod titlecase;
+mod uppercase;
+
+pub use lowercase::make_ascii_lowercase;
+pub use titlecase::make_ascii_titlecase;
+pub use uppercase::make_ascii_uppercase;
+
+#[cfg(feature = "alloc")]
+pub use lowercase::to_ascii_lowercase;
+#[cfg(feature = "alloc")]
+pub use titlecase::to_ascii_titlecase;
+#[cfg(feature = "alloc")]
+pub use uppercase::to_ascii_uppercase;
+
\ No newline at end of file diff --git a/src/roe/ascii/lowercase.rs.html b/src/roe/ascii/lowercase.rs.html new file mode 100644 index 000000000..8f114b5cd --- /dev/null +++ b/src/roe/ascii/lowercase.rs.html @@ -0,0 +1,173 @@ +lowercase.rs - source
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
+
#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+/// Converts the given slice to its ASCII lower case equivalent in-place.
+///
+/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', but non-ASCII letters are
+/// unchanged.
+///
+/// This function can be used to implement [`String#downcase!`] for ASCII
+/// strings in Ruby.
+///
+#[cfg_attr(
+    feature = "alloc",
+    doc = "To return a new lowercased value without modifying the existing one, use [`to_ascii_lowercase`]."
+)]
+/// This function is analogous [`<[u8]>::make_ascii_lowercase`][slice-primitive].
+///
+/// # Examples
+///
+/// ```
+/// # use roe::make_ascii_lowercase;
+/// let mut buf = *b"ABCxyz";
+/// make_ascii_lowercase(&mut buf);
+/// assert_eq!(buf, *b"abcxyz");
+///
+/// let mut buf = *b"1234%&*";
+/// make_ascii_lowercase(&mut buf);
+/// assert_eq!(buf, *b"1234%&*");
+/// ```
+///
+/// [`String#downcase!`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-downcase-21
+/// [slice-primitive]: https://doc.rust-lang.org/std/primitive.slice.html#method.make_ascii_lowercase
+#[inline]
+#[allow(clippy::module_name_repetitions)]
+pub fn make_ascii_lowercase<T: AsMut<[u8]>>(slice: &mut T) {
+    let slice = slice.as_mut();
+    slice.make_ascii_lowercase();
+}
+
+/// Returns a vector containing a copy of the given slice where each byte is
+/// mapped to its ASCII lower case equivalent.
+///
+/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', but non-ASCII letters are
+/// unchanged.
+///
+/// This function can be used to implement [`String#downcase`] and
+/// [`Symbol#downcase`] for ASCII strings in Ruby.
+///
+/// To lowercase the value in-place, use [`make_ascii_lowercase`]. This function
+/// is analogous to [`<[u8]>::to_ascii_lowercase`][slice-primitive].
+///
+/// # Examples
+///
+/// ```
+/// # use roe::to_ascii_lowercase;
+/// assert_eq!(to_ascii_lowercase("ABCxyz"), &b"abcxyz"[..]);
+/// assert_eq!(to_ascii_lowercase("1234%&*"), &b"1234%&*"[..]);
+/// ```
+///
+/// [`String#downcase`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-downcase
+/// [`Symbol#downcase`]: https://ruby-doc.org/core-3.1.2/Symbol.html#method-i-downcase
+/// [slice-primitive]: https://doc.rust-lang.org/std/primitive.slice.html#method.to_ascii_lowercase
+#[inline]
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+#[allow(clippy::module_name_repetitions)]
+pub fn to_ascii_lowercase<T: AsRef<[u8]>>(slice: T) -> Vec<u8> {
+    let slice = slice.as_ref();
+    slice.to_ascii_lowercase()
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn make_ascii_lowercase_empty() {
+        let mut buf = *b"";
+        super::make_ascii_lowercase(&mut buf);
+        assert_eq!(buf, *b"");
+    }
+
+    #[test]
+    #[cfg(feature = "alloc")]
+    fn to_ascii_lowercase_empty() {
+        assert_eq!(super::to_ascii_lowercase(""), b"");
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/ascii/titlecase.rs.html b/src/roe/ascii/titlecase.rs.html new file mode 100644 index 000000000..17e19faad --- /dev/null +++ b/src/roe/ascii/titlecase.rs.html @@ -0,0 +1,213 @@ +titlecase.rs - source
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
+
#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+/// Converts the given slice to its ASCII title case equivalent in-place.
+///
+/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z' in the first byte;
+/// subsequent bytes with ASCII letters 'A' to 'Z' are mapped to 'a' to 'z';
+/// non-ASCII letters are unchanged.
+///
+/// This function can be used to implement [`String#capitalize!`] for ASCII
+/// strings in Ruby.
+///
+#[cfg_attr(
+    feature = "alloc",
+    doc = "To return a new titlecased value without modifying the existing one, use [`to_ascii_titlecase`]."
+)]
+///
+/// # Examples
+///
+/// ```
+/// # use roe::make_ascii_titlecase;
+/// let mut buf = *b"ABCxyz";
+/// make_ascii_titlecase(&mut buf);
+/// assert_eq!(buf, *b"Abcxyz");
+///
+/// let mut buf = *b"1234%&*";
+/// make_ascii_titlecase(&mut buf);
+/// assert_eq!(buf, *b"1234%&*");
+///
+/// let mut buf = *b"ABC1234%&*";
+/// make_ascii_titlecase(&mut buf);
+/// assert_eq!(buf, *b"Abc1234%&*");
+///
+/// let mut buf = *b"1234%&*abcXYZ";
+/// make_ascii_titlecase(&mut buf);
+/// assert_eq!(buf, *b"1234%&*abcxyz");
+///
+/// let mut buf = *b"ABC, XYZ";
+/// make_ascii_titlecase(&mut buf);
+/// assert_eq!(buf, *b"Abc, xyz");
+/// ```
+///
+/// [`String#capitalize!`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-capitalize-21
+#[inline]
+#[allow(clippy::module_name_repetitions)]
+pub fn make_ascii_titlecase<T: AsMut<[u8]>>(slice: &mut T) {
+    let slice = slice.as_mut();
+    if let Some((head, tail)) = slice.split_first_mut() {
+        head.make_ascii_uppercase();
+        tail.make_ascii_lowercase();
+    }
+}
+
+/// Returns a vector containing a copy of the given slice where each byte is
+/// mapped to its ASCII title case equivalent.
+///
+/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z' in the first byte;
+/// subsequent bytes with ASCII letters 'A' to 'Z' are mapped to 'a' to 'z';
+/// non-ASCII letters are unchanged.
+///
+/// This function can be used to implement [`String#capitalize`] and
+/// [`Symbol#capitalize`] for ASCII strings in Ruby.
+///
+/// To titlecase the value in-place, use [`make_ascii_titlecase`].
+///
+/// # Examples
+///
+/// ```
+/// # use roe::to_ascii_titlecase;
+/// assert_eq!(to_ascii_titlecase("ABCxyz"), &b"Abcxyz"[..]);
+/// assert_eq!(to_ascii_titlecase("1234%&*"), &b"1234%&*"[..]);
+/// assert_eq!(to_ascii_titlecase("ABC1234%&*"), &b"Abc1234%&*"[..]);
+/// assert_eq!(to_ascii_titlecase("1234%&*abcXYZ"), &b"1234%&*abcxyz"[..]);
+/// assert_eq!(to_ascii_titlecase("ABC, XYZ"), &b"Abc, xyz"[..]);
+/// ```
+///
+/// [`String#capitalize`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-capitalize
+/// [`Symbol#capitalize`]: https://ruby-doc.org/core-3.1.2/Symbol.html#method-i-capitalize
+#[inline]
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+#[allow(clippy::module_name_repetitions)]
+pub fn to_ascii_titlecase<T: AsRef<[u8]>>(slice: T) -> Vec<u8> {
+    let slice = slice.as_ref();
+    let mut titlecase = slice.to_ascii_lowercase();
+    if let Some(head) = titlecase.first_mut() {
+        head.make_ascii_uppercase();
+    }
+    titlecase
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn make_ascii_titlecase_empty() {
+        let mut buf = *b"";
+        super::make_ascii_titlecase(&mut buf);
+        assert_eq!(buf, *b"");
+    }
+
+    #[test]
+    #[cfg(feature = "alloc")]
+    fn to_ascii_titlecase_empty() {
+        assert_eq!(super::to_ascii_titlecase(""), b"");
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/ascii/uppercase.rs.html b/src/roe/ascii/uppercase.rs.html new file mode 100644 index 000000000..05ee6d339 --- /dev/null +++ b/src/roe/ascii/uppercase.rs.html @@ -0,0 +1,173 @@ +uppercase.rs - source
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
+
#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+/// Converts the given slice to its ASCII upper case equivalent in-place.
+///
+/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', but non-ASCII letters are
+/// unchanged.
+///
+/// This function can be used to implement [`String#upcase!`] for ASCII strings
+/// in Ruby.
+///
+#[cfg_attr(
+    feature = "alloc",
+    doc = "To return a new uppercased value without modifying the existing one, use [`to_ascii_uppercase`]."
+)]
+/// This function is analogous to [`<[u8]>::make_ascii_uppercase`][slice-primitive].
+///
+/// # Examples
+///
+/// ```
+/// # use roe::make_ascii_uppercase;
+/// let mut buf = *b"ABCxyz";
+/// make_ascii_uppercase(&mut buf);
+/// assert_eq!(buf, *b"ABCXYZ");
+///
+/// let mut buf = *b"1234%&*";
+/// make_ascii_uppercase(&mut buf);
+/// assert_eq!(buf, *b"1234%&*");
+/// ```
+///
+/// [`String#upcase!`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-upcase-21
+/// [slice-primitive]: https://doc.rust-lang.org/std/primitive.u8.html#method.make_ascii_uppercase
+#[inline]
+#[allow(clippy::module_name_repetitions)]
+pub fn make_ascii_uppercase<T: AsMut<[u8]>>(slice: &mut T) {
+    let slice = slice.as_mut();
+    slice.make_ascii_uppercase();
+}
+
+/// Returns a vector containing a copy of the given slice where each byte is
+/// mapped to its ASCII upper case equivalent.
+///
+/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', but non-ASCII letters are
+/// unchanged.
+///
+/// This function can be used to implement [`String#upcase`] and
+/// [`Symbol#upcase`] for ASCII strings in Ruby.
+///
+/// To uppercase the value in-place, use [`make_ascii_uppercase`]. This function
+/// is analogous to [`<[u8]>::to_ascii_uppercase`][slice-primitive].
+///
+/// # Examples
+///
+/// ```
+/// # use roe::to_ascii_uppercase;
+/// assert_eq!(to_ascii_uppercase("ABCxyz"), &b"ABCXYZ"[..]);
+/// assert_eq!(to_ascii_uppercase("1234%&*"), &b"1234%&*"[..]);
+/// ```
+///
+/// [`String#upcase`]: https://ruby-doc.org/core-3.1.2/String.html#method-i-upcase
+/// [`Symbol#upcase`]: https://ruby-doc.org/core-3.1.2/Symbol.html#method-i-upcase
+/// [slice-primitive]: https://doc.rust-lang.org/std/primitive.slice.html#method.to_ascii_uppercase
+#[inline]
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+#[allow(clippy::module_name_repetitions)]
+pub fn to_ascii_uppercase<T: AsRef<[u8]>>(slice: T) -> Vec<u8> {
+    let slice = slice.as_ref();
+    slice.to_ascii_uppercase()
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn make_ascii_uppercase_empty() {
+        let mut buf = *b"";
+        super::make_ascii_uppercase(&mut buf);
+        assert_eq!(buf, *b"");
+    }
+
+    #[test]
+    #[cfg(feature = "alloc")]
+    fn to_ascii_uppercase_empty() {
+        assert_eq!(super::to_ascii_uppercase(""), b"");
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/lib.rs.html b/src/roe/lib.rs.html new file mode 100644 index 000000000..21c9aa44e --- /dev/null +++ b/src/roe/lib.rs.html @@ -0,0 +1,949 @@ +lib.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+
#![warn(clippy::all)]
+#![warn(clippy::pedantic)]
+#![cfg_attr(test, allow(clippy::non_ascii_literal))]
+#![cfg_attr(test, allow(clippy::shadow_unrelated))]
+#![warn(clippy::cargo)]
+#![allow(unknown_lints)]
+#![warn(missing_copy_implementations)]
+#![warn(missing_debug_implementations)]
+#![warn(missing_docs)]
+#![warn(rust_2018_idioms)]
+#![warn(trivial_casts, trivial_numeric_casts)]
+#![warn(unused_qualifications)]
+#![warn(variant_size_differences)]
+#![forbid(unsafe_code)]
+// Enable feature callouts in generated documentation:
+// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
+//
+// This approach is borrowed from tokio.
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![cfg_attr(docsrs, feature(doc_alias))]
+
+//! This crate provides [Unicode case mapping] routines and iterators for
+//! [conventionally UTF-8 binary strings].
+//!
+//! Unicode case mapping or case conversion can be used to transform the
+//! characters in a string. To quote the Unicode FAQ:
+//!
+//! > Case mapping or case conversion is a process whereby strings are converted
+//! > to a particular form—uppercase, lowercase, or titlecase—possibly for
+//! > display to the user.
+//!
+//! This crate is currently a *work in progress*. When the API is complete, Roe
+//! will support lowercase, uppercase, titlecase, and case folding iterators for
+//! conventionally UTF-8 byte slices.
+//!
+//! Roe will implement support for full, Turkic, ASCII, and case folding
+//! transforms.
+//!
+//! # Usage
+//!
+//! You can convert case like:
+//!
+//! ```
+//! # use roe::{LowercaseMode, UppercaseMode};
+//! assert_eq!(
+//!     roe::lowercase(b"Artichoke Ruby", LowercaseMode::Ascii).collect::<Vec<_>>(),
+//!     b"artichoke ruby"
+//! );
+//! assert_eq!(
+//!     roe::uppercase("Αύριο".as_bytes(), UppercaseMode::Full).collect::<Vec<_>>(),
+//!     "ΑΎΡΙΟ".as_bytes()
+//! );
+//! ```
+//!
+//!
+//! Roe provides fast path routines that assume the byte slice is ASCII-only.
+//!
+//! # Crate Features
+//!
+//! Roe is `no_std` compatible with an optional dependency on the [`alloc`]
+//! crate.
+//!
+//! Roe has several Cargo features, all of which are enabled by default:
+//!
+//! - **std** - Adds a dependency on [`std`], the Rust Standard Library. This
+//!   feature enables [`std::error::Error`] implementations on error types in
+//!   this crate. Enabling the **std** feature also enables the **alloc**
+//!   feature.
+//! - **alloc** - Adds a dependency on [`alloc`], the Rust allocation and
+//!   collections library. This feature enables APIs that allocate [`String`] or
+//!   [`Vec`].
+//!
+#![cfg_attr(
+    not(feature = "std"),
+    doc = "[`std`]: https://doc.rust-lang.org/std/index.html"
+)]
+#![cfg_attr(
+    not(feature = "std"),
+    doc = "[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html"
+)]
+#![cfg_attr(
+    not(feature = "alloc"),
+    doc = "[`alloc`]: https://doc.rust-lang.org/alloc/index.html"
+)]
+#![cfg_attr(feature = "alloc", doc = "[`String`]: alloc::string::String")]
+#![cfg_attr(
+    not(feature = "alloc"),
+    doc = "[`String`]: https://doc.rust-lang.org/alloc/string/struct.String.html"
+)]
+#![cfg_attr(feature = "alloc", doc = "[`Vec`]: alloc::vec::Vec")]
+#![cfg_attr(
+    not(feature = "alloc"),
+    doc = "[`Vec`]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html"
+)]
+//! [Unicode case mapping]: https://unicode.org/faq/casemap_charprop.html#casemap
+//! [conventionally UTF-8 binary strings]: https://docs.rs/bstr/1.*/bstr/#when-should-i-use-byte-strings
+
+#![no_std]
+#![doc(html_root_url = "https://docs.rs/roe/0.0.5")]
+
+#[cfg(any(feature = "alloc", test))]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+use core::convert::{TryFrom, TryInto};
+use core::fmt;
+use core::str::FromStr;
+
+mod ascii;
+mod lowercase;
+mod uppercase;
+
+pub use ascii::{make_ascii_lowercase, make_ascii_titlecase, make_ascii_uppercase};
+#[cfg(feature = "alloc")]
+pub use ascii::{to_ascii_lowercase, to_ascii_titlecase, to_ascii_uppercase};
+pub use lowercase::Lowercase;
+pub use uppercase::Uppercase;
+
+/// Error that indicates a failure to parse a [`LowercaseMode`] or
+/// [`UppercaseMode`].
+///
+/// This error corresponds to the [Ruby `ArgumentError` Exception class].
+///
+/// # Examples
+///
+/// ```
+/// # use core::convert::TryInto;
+/// # use roe::{InvalidCaseMappingMode, LowercaseMode};
+/// let err = InvalidCaseMappingMode::new();
+/// assert_eq!(err.message(), "invalid option");
+///
+/// let mode: Result<LowercaseMode, InvalidCaseMappingMode> = "full".try_into();
+/// ```
+///
+/// [Ruby `ArgumentError` Exception class]: https://ruby-doc.org/core-3.1.2/ArgumentError.html
+#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub struct InvalidCaseMappingMode {
+    _private: (),
+}
+
+impl InvalidCaseMappingMode {
+    /// Construct a new `InvalidCaseMappingMode` error.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::InvalidCaseMappingMode;
+    /// const ERR: InvalidCaseMappingMode = InvalidCaseMappingMode::new();
+    /// assert_eq!(ERR.message(), "invalid option");
+    /// ```
+    #[must_use]
+    pub const fn new() -> Self {
+        Self { _private: () }
+    }
+
+    /// Retrieve the error message associated with this `InvalidCaseMappingMode`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::InvalidCaseMappingMode;
+    /// const MESSAGE: &str = InvalidCaseMappingMode::new().message();
+    /// assert_eq!(MESSAGE, "invalid option");
+    /// ```
+    #[must_use]
+    #[allow(clippy::unused_self)]
+    pub const fn message(self) -> &'static str {
+        "invalid option"
+    }
+}
+
+impl fmt::Display for InvalidCaseMappingMode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        const MESSAGE: &str = InvalidCaseMappingMode::new().message();
+        f.write_str(MESSAGE)
+    }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for InvalidCaseMappingMode {}
+
+/// Options to configure the behavior of [`lowercase`].
+///
+/// Which letters exactly are replaced, and by which other letters, depends on
+/// the given options.
+///
+/// See individual variants for a description of the available behaviors.
+///
+/// If you're not sure which mode to choose, [`LowercaseMode::Full`] is a a good
+/// default.
+///
+/// [`lowercase`]: crate::lowercase()
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub enum LowercaseMode {
+    /// Full Unicode case mapping, suitable for most languages.
+    ///
+    /// See the [Turkic] and [Lithuanian] variants for exceptions.
+    ///
+    /// Context-dependent case mapping as described in Table 3-14 of the Unicode
+    /// standard is currently not supported.
+    ///
+    /// [Turkic]: Self::Turkic
+    /// [Lithuanian]: Self::Lithuanian
+    Full,
+    /// Only the ASCII region, i.e. the characters `'A'..='Z'` and `'a'..='z'`,
+    /// are affected.
+    ///
+    /// This option cannot be combined with any other option.
+    Ascii,
+    /// Full Unicode case mapping, adapted for Turkic languages (Turkish,
+    /// Azerbaijani, …).
+    ///
+    /// This means that upper case I is mapped to lower case dotless i, and so
+    /// on.
+    Turkic,
+    /// Currently, just [full Unicode case mapping].
+    ///
+    /// In the future, full Unicode case mapping adapted for Lithuanian (keeping
+    /// the dot on the lower case i even if there is an accent on top).
+    ///
+    /// [full Unicode case mapping]: Self::Full
+    Lithuanian,
+    /// Unicode case **folding**, which is more far-reaching than Unicode case
+    /// mapping.
+    ///
+    /// This option currently cannot be combined with any other option (i.e.
+    /// there is currently no variant for turkic languages).
+    Fold,
+}
+
+impl Default for LowercaseMode {
+    fn default() -> Self {
+        Self::Full
+    }
+}
+
+impl TryFrom<&str> for LowercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: &str) -> Result<Self, Self::Error> {
+        value.as_bytes().try_into()
+    }
+}
+
+impl TryFrom<Option<&str>> for LowercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: Option<&str>) -> Result<Self, Self::Error> {
+        value.map(str::as_bytes).try_into()
+    }
+}
+
+impl TryFrom<&[u8]> for LowercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
+        match value {
+            b"ascii" => Ok(Self::Ascii),
+            b"turkic" => Ok(Self::Turkic),
+            b"lithuanian" => Ok(Self::Lithuanian),
+            b"fold" => Ok(Self::Fold),
+            _ => Err(InvalidCaseMappingMode::new()),
+        }
+    }
+}
+
+impl TryFrom<Option<&[u8]>> for LowercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: Option<&[u8]>) -> Result<Self, Self::Error> {
+        match value {
+            None => Ok(Self::Full),
+            Some(b"ascii") => Ok(Self::Ascii),
+            Some(b"turkic") => Ok(Self::Turkic),
+            Some(b"lithuanian") => Ok(Self::Lithuanian),
+            Some(b"fold") => Ok(Self::Fold),
+            Some(_) => Err(InvalidCaseMappingMode::new()),
+        }
+    }
+}
+
+impl FromStr for LowercaseMode {
+    type Err = InvalidCaseMappingMode;
+
+    #[inline]
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        s.try_into()
+    }
+}
+
+/// Returns an iterator that yields a copy of the bytes in the given slice with
+/// all uppercase letters replaced with their lowercase counterparts.
+///
+/// This function treats the given slice as a [conventionally UTF-8 string].
+/// UTF-8 byte sequences are converted to their Unicode lowercase equivalents.
+/// Invalid UTF-8 byte sequences are yielded as is.
+///
+/// The case mapping mode is determined by the given [`LowercaseMode`]. See its
+/// documentation for details on the available case mapping modes.
+///
+/// # Panics
+///
+/// Not all [`LowercaseMode`]s are currently implemented. This function will
+/// panic if the caller supplies [Turkic] or [case folding] lowercasing mode.
+///
+/// [conventionally UTF-8 string]: https://docs.rs/bstr/0.2.*/bstr/#when-should-i-use-byte-strings
+/// [Turkic]: LowercaseMode::Turkic
+/// [case folding]: LowercaseMode::Fold
+// TODO: make this const once we're no longer panicking.
+pub fn lowercase(slice: &[u8], options: LowercaseMode) -> Lowercase<'_> {
+    match options {
+        LowercaseMode::Full | LowercaseMode::Lithuanian => Lowercase::with_slice(slice),
+        LowercaseMode::Ascii => Lowercase::with_ascii_slice(slice),
+        // TODO: implement `turkic` and `fold` modes.
+        LowercaseMode::Turkic => panic!("lowercase Turkic mode is not yet implemented"),
+        LowercaseMode::Fold => panic!("lowercase case folding mode is not yet implemented"),
+    }
+}
+
+/// Options to configure the behavior of [`uppercase`].
+///
+/// Which letters exactly are replaced, and by which other letters, depends on
+/// the given options.
+///
+/// See individual variants for a description of the available behaviors.
+///
+/// If you're not sure which mode to choose, [`UppercaseMode::Full`] is a a good
+/// default.
+///
+/// [`uppercase`]: crate::uppercase()
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+pub enum UppercaseMode {
+    /// Full Unicode case mapping, suitable for most languages.
+    ///
+    /// See the [Turkic] and [Lithuanian] variants for exceptions.
+    ///
+    /// Context-dependent case mapping as described in Table 3-14 of the Unicode
+    /// standard is currently not supported.
+    ///
+    /// [Turkic]: Self::Turkic
+    /// [Lithuanian]: Self::Lithuanian
+    Full,
+    /// Only the ASCII region, i.e. the characters `'A'..='Z'` and `'a'..='z'`,
+    /// are affected.
+    ///
+    /// This option cannot be combined with any other option.
+    Ascii,
+    /// Full Unicode case mapping, adapted for Turkic languages (Turkish,
+    /// Azerbaijani, …).
+    ///
+    /// This means that upper case I is mapped to lower case dotless i, and so
+    /// on.
+    Turkic,
+    /// Currently, just [full Unicode case mapping].
+    ///
+    /// In the future, full Unicode case mapping adapted for Lithuanian (keeping
+    /// the dot on the lower case i even if there is an accent on top).
+    ///
+    /// [full Unicode case mapping]: Self::Full
+    Lithuanian,
+}
+
+impl Default for UppercaseMode {
+    fn default() -> Self {
+        Self::Full
+    }
+}
+
+impl TryFrom<&str> for UppercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: &str) -> Result<Self, Self::Error> {
+        value.as_bytes().try_into()
+    }
+}
+
+impl TryFrom<Option<&str>> for UppercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: Option<&str>) -> Result<Self, Self::Error> {
+        value.map(str::as_bytes).try_into()
+    }
+}
+
+impl TryFrom<&[u8]> for UppercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
+        match value {
+            b"ascii" => Ok(Self::Ascii),
+            b"turkic" => Ok(Self::Turkic),
+            b"lithuanian" => Ok(Self::Lithuanian),
+            _ => Err(InvalidCaseMappingMode::new()),
+        }
+    }
+}
+
+impl TryFrom<Option<&[u8]>> for UppercaseMode {
+    type Error = InvalidCaseMappingMode;
+
+    #[inline]
+    fn try_from(value: Option<&[u8]>) -> Result<Self, Self::Error> {
+        match value {
+            None => Ok(Self::Full),
+            Some(b"ascii") => Ok(Self::Ascii),
+            Some(b"turkic") => Ok(Self::Turkic),
+            Some(b"lithuanian") => Ok(Self::Lithuanian),
+            Some(_) => Err(InvalidCaseMappingMode::new()),
+        }
+    }
+}
+
+impl FromStr for UppercaseMode {
+    type Err = InvalidCaseMappingMode;
+
+    #[inline]
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        s.try_into()
+    }
+}
+
+/// Returns an iterator that yields a copy of the bytes in the given slice with
+/// all lowercase letters replaced with their uppercase counterparts.
+///
+/// This function treats the given slice as a [conventionally UTF-8 string].
+/// UTF-8 byte sequences are converted to their Unicode uppercase equivalents.
+/// Invalid UTF-8 byte sequences are yielded as is.
+///
+/// The case mapping mode is determined by the given [`UppercaseMode`]. See its
+/// documentation for details on the available case mapping modes.
+///
+/// # Panics
+///
+/// Not all [`UppercaseMode`]s are currently implemented. This function will
+/// panic if the caller supplies [Turkic] uppercasing mode.
+///
+/// [conventionally UTF-8 string]: https://docs.rs/bstr/0.2.*/bstr/#when-should-i-use-byte-strings
+/// [Turkic]: LowercaseMode::Turkic
+/// [case folding]: LowercaseMode::Fold
+// TODO: make this const once we're no longer panicking.
+pub fn uppercase(slice: &[u8], options: UppercaseMode) -> Uppercase<'_> {
+    match options {
+        UppercaseMode::Full | UppercaseMode::Lithuanian => Uppercase::with_slice(slice),
+        UppercaseMode::Ascii => Uppercase::with_ascii_slice(slice),
+        // TODO: implement `turkic` mode.
+        UppercaseMode::Turkic => panic!("uppercase Turkic mode is not yet implemented"),
+    }
+}
+
+// Ensure code blocks in README.md compile
+//
+// This module and macro declaration should be kept at the end of the file, in
+// order to not interfere with code coverage.
+#[cfg(doctest)]
+macro_rules! readme {
+    ($x:expr) => {
+        #[doc = $x]
+        mod readme {}
+    };
+    () => {
+        readme!(include_str!("../README.md"));
+    };
+}
+#[cfg(doctest)]
+readme!();
+
\ No newline at end of file diff --git a/src/roe/lowercase.rs.html b/src/roe/lowercase.rs.html new file mode 100644 index 000000000..b8f599286 --- /dev/null +++ b/src/roe/lowercase.rs.html @@ -0,0 +1,547 @@ +lowercase.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+
use core::iter::FusedIterator;
+
+mod ascii;
+mod full;
+
+#[derive(Debug, Clone)]
+#[allow(variant_size_differences)]
+enum Inner<'a> {
+    Empty,
+    Full(full::Lowercase<'a>),
+    Ascii(ascii::Lowercase<'a>),
+}
+
+/// An iterator that yields the lowercase equivalent of a conventionally UTF-8
+/// byte string.
+///
+/// This iterator yields [bytes].
+///
+/// This struct is created by the [`lowercase`] function. See its documentation
+/// for more.
+///
+/// [bytes]: u8
+/// [`lowercase`]: crate::lowercase()
+#[derive(Debug, Clone)]
+#[must_use = "Lowercase is a Iterator and must be used"]
+pub struct Lowercase<'a> {
+    iter: Inner<'a>,
+}
+
+impl<'a> Lowercase<'a> {
+    /// Create a new, empty lowercase iterator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let mut lowercase = Lowercase::new();
+    /// assert_eq!(lowercase.next(), None);
+    /// ```
+    pub const fn new() -> Self {
+        Self { iter: Inner::Empty }
+    }
+
+    /// Create a new lowercase iterator with the given byte slice using full
+    /// Unicode case mapping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let mut lowercase = Lowercase::with_slice(b"abcXYZ");
+    /// assert_eq!(lowercase.next(), Some(b'a'));
+    /// assert_eq!(lowercase.next(), Some(b'b'));
+    /// assert_eq!(lowercase.next(), Some(b'c'));
+    /// assert_eq!(lowercase.next(), Some(b'x'));
+    /// assert_eq!(lowercase.next(), Some(b'y'));
+    /// assert_eq!(lowercase.next(), Some(b'z'));
+    /// assert_eq!(lowercase.next(), None);
+    /// ```
+    ///
+    /// Non-ASCII characters are case mapped:
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let lowercase = Lowercase::with_slice("Αύριο".as_bytes());
+    /// assert_eq!(lowercase.collect::<Vec<_>>(), "αύριο".as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 bytes are yielded as is without impacting Unicode
+    /// characters:
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let mut s = "Αύριο".to_string().into_bytes();
+    /// s.extend(b"\xFF\xFE");
+    /// let lowercase = Lowercase::with_slice(s.as_slice());
+    ///
+    /// let mut expected = "αύριο".to_string().into_bytes();
+    /// expected.extend(b"\xFF\xFE");
+    /// assert_eq!(lowercase.collect::<Vec<_>>(), expected);
+    /// ```
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self {
+            iter: Inner::Full(full::Lowercase::with_slice(slice)),
+        }
+    }
+
+    /// Create a new lowercase iterator with the given byte slice using ASCII
+    /// case mapping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let mut lowercase = Lowercase::with_ascii_slice(b"abcXYZ");
+    /// assert_eq!(lowercase.next(), Some(b'a'));
+    /// assert_eq!(lowercase.next(), Some(b'b'));
+    /// assert_eq!(lowercase.next(), Some(b'c'));
+    /// assert_eq!(lowercase.next(), Some(b'x'));
+    /// assert_eq!(lowercase.next(), Some(b'y'));
+    /// assert_eq!(lowercase.next(), Some(b'z'));
+    /// assert_eq!(lowercase.next(), None);
+    /// ```
+    ///
+    /// Non-ASCII characters are ignored:
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let lowercase = Lowercase::with_ascii_slice("Αύριο".as_bytes());
+    /// assert_eq!(lowercase.collect::<Vec<_>>(), "Αύριο".as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 bytes are yielded as is without impacting ASCII bytes:
+    ///
+    /// ```
+    /// # use roe::Lowercase;
+    /// let lowercase = Lowercase::with_ascii_slice(b"abc\xFF\xFEXYZ");
+    /// assert_eq!(lowercase.collect::<Vec<_>>(), b"abc\xFF\xFExyz");
+    /// ```
+    pub const fn with_ascii_slice(slice: &'a [u8]) -> Self {
+        Self {
+            iter: Inner::Ascii(ascii::Lowercase::with_slice(slice)),
+        }
+    }
+}
+
+impl<'a> Iterator for Lowercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.iter {
+            Inner::Empty => None,
+            Inner::Full(ref mut iter) => iter.next(),
+            Inner::Ascii(ref mut iter) => iter.next(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self.iter {
+            Inner::Empty => (0, Some(0)),
+            Inner::Full(ref iter) => iter.size_hint(),
+            Inner::Ascii(ref iter) => iter.size_hint(),
+        }
+    }
+
+    fn count(self) -> usize {
+        match self.iter {
+            Inner::Empty => 0,
+            Inner::Full(iter) => iter.count(),
+            Inner::Ascii(iter) => iter.count(),
+        }
+    }
+}
+
+impl<'a> FusedIterator for Lowercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+
+    use super::Lowercase;
+
+    #[test]
+    fn empty() {
+        let iter = Lowercase::new();
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+
+        let iter = Lowercase::with_slice(b"");
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+
+        let iter = Lowercase::with_ascii_slice(b"");
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Lowercase::new().size_hint(), (0, Some(0)));
+
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Lowercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(144))
+        );
+        assert_eq!(
+            Lowercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(36))
+        );
+        assert_eq!(
+            Lowercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(96))
+        );
+        assert_eq!(
+            Lowercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(60))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Lowercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(120))
+        );
+
+        assert_eq!(
+            Lowercase::with_ascii_slice(b"abc, xyz").size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Lowercase::with_ascii_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(12))
+        );
+        assert_eq!(
+            Lowercase::with_ascii_slice("�".as_bytes()).size_hint(),
+            (3, Some(3))
+        );
+        assert_eq!(
+            Lowercase::with_ascii_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Lowercase::with_ascii_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(5))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Lowercase::with_ascii_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(10))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Lowercase::new().count(), 0);
+
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Lowercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Lowercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Lowercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Lowercase::with_slice("ZȺȾ".as_bytes()).count(), 7);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Lowercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+
+        assert_eq!(Lowercase::with_ascii_slice(b"abc, xyz").count(), 8);
+        assert_eq!(
+            Lowercase::with_ascii_slice(b"abc, \xFF\xFE, xyz").count(),
+            12
+        );
+        assert_eq!(Lowercase::with_ascii_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Lowercase::with_ascii_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Lowercase::with_ascii_slice("ZȺȾ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Lowercase::with_ascii_slice(&utf8_with_invalid_bytes).count(),
+            10
+        );
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Lowercase::new();
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/lowercase/ascii.rs.html b/src/roe/lowercase/ascii.rs.html new file mode 100644 index 000000000..d6db90067 --- /dev/null +++ b/src/roe/lowercase/ascii.rs.html @@ -0,0 +1,575 @@ +ascii.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+
use core::fmt;
+use core::iter::FusedIterator;
+
+use bstr::ByteSlice;
+
+#[derive(Clone)]
+#[must_use = "Lowercase is a Iterator and must be used"]
+pub struct Lowercase<'a> {
+    slice: &'a [u8],
+}
+
+impl<'a> fmt::Debug for Lowercase<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Lowercase")
+            .field("slice", &self.slice.as_bstr())
+            .finish()
+    }
+}
+
+impl<'a> From<&'a [u8]> for Lowercase<'a> {
+    fn from(slice: &'a [u8]) -> Self {
+        Self::with_slice(slice)
+    }
+}
+
+impl<'a> Lowercase<'a> {
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self { slice }
+    }
+}
+
+impl<'a> Iterator for Lowercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let (&byte, remainder) = self.slice.split_first()?;
+        self.slice = remainder;
+        Some(byte.to_ascii_lowercase())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.slice.len();
+        (len, Some(len))
+    }
+
+    fn count(self) -> usize {
+        self.slice.len()
+    }
+}
+
+impl<'a> DoubleEndedIterator for Lowercase<'a> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        let (&byte, remainder) = self.slice.split_last()?;
+        self.slice = remainder;
+        Some(byte.to_ascii_lowercase())
+    }
+}
+
+impl<'a> ExactSizeIterator for Lowercase<'a> {}
+
+impl<'a> FusedIterator for Lowercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+
+    use super::Lowercase;
+
+    #[test]
+    fn empty() {
+        let iter = Lowercase::from(&b""[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn ascii() {
+        let iter = Lowercase::from(&b"abc"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"aBC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"ABC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"aBC, 123, ABC, baby you and me girl"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"abc, 123, abc, baby you and me girl".as_bstr()
+        );
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn utf8() {
+        let s = "ß".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "ß".as_bytes().as_bstr());
+
+        let s = "Αύριο".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Αύριο".as_bytes().as_bstr()
+        );
+
+        let s = "Έτος".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Έτος".as_bytes().as_bstr()
+        );
+
+        // two-byte characters
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L198-L200
+        let s = "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆"
+                .as_bytes()
+                .as_bstr()
+        );
+
+        // Change length when lowercased
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L226-L232
+        let s = "ZȺȾ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "zȺȾ".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn invalid_utf8() {
+        let iter = Lowercase::from(&b"\xFF\xFE"[..]);
+        assert_eq!(iter.collect::<Vec<u8>>().as_bstr(), b"\xFF\xFE".as_bstr());
+
+        let iter = Lowercase::from(&b"ABC\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"abc\xFF\xFExyz".as_bstr()
+        );
+
+        let iter = Lowercase::from(&b"abc\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"abc\xFF\xFExyz".as_bstr()
+        );
+
+        // The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of
+        // them on their own are invalid. Only one replacement codepoint is
+        // substituted, which demonstrates the "substitution of maximal
+        // subparts" strategy.
+        //
+        // See: https://docs.rs/bstr/1.*/bstr/#handling-of-invalid-utf-8
+        let iter = Lowercase::from(&b"aB\xF0\x9F\x87Yz"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"ab\xF0\x9F\x87yz".as_bstr()
+        );
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn unicode_replacement_character() {
+        let s = "�".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "�".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn dz_titlecase() {
+        let s = "Dž".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "Dž".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn latin_capital_i_with_dot_above() {
+        let s = "İ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "İ".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn case_map_to_two_chars() {
+        let s = "İ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "İ".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Lowercase::with_slice(b"").size_hint(), (0, Some(0)));
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Lowercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(12))
+        );
+        assert_eq!(
+            Lowercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(3))
+        );
+        assert_eq!(
+            Lowercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Lowercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(5))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Lowercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(10))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Lowercase::with_slice(b"").count(), 0);
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Lowercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Lowercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Lowercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Lowercase::with_slice("ZȺȾ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Lowercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Lowercase::with_slice(b"");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice(b"abc, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice(b"abc, \xFF\xFE, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("�".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("Έτος".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("ZȺȾ".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        let iter = Lowercase::with_slice(&utf8_with_invalid_bytes);
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/lowercase/full.rs.html b/src/roe/lowercase/full.rs.html new file mode 100644 index 000000000..b210a9013 --- /dev/null +++ b/src/roe/lowercase/full.rs.html @@ -0,0 +1,725 @@ +full.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+
use core::char::ToLowercase;
+use core::fmt;
+use core::iter::FusedIterator;
+use core::ops::Range;
+
+use bstr::ByteSlice;
+
+#[derive(Clone)]
+#[must_use = "Lowercase is a Iterator and must be used"]
+pub struct Lowercase<'a> {
+    slice: &'a [u8],
+    next_bytes: [u8; 4],
+    next_range: Range<usize>,
+    lowercase: Option<ToLowercase>,
+}
+
+impl<'a> fmt::Debug for Lowercase<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Lowercase")
+            .field("slice", &self.slice.as_bstr())
+            .field("next_bytes", &self.next_bytes)
+            .field("next_range", &self.next_range)
+            .field("lowercase", &self.lowercase)
+            .finish()
+    }
+}
+
+impl<'a> From<&'a [u8]> for Lowercase<'a> {
+    fn from(slice: &'a [u8]) -> Self {
+        Self::with_slice(slice)
+    }
+}
+
+impl<'a> Lowercase<'a> {
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self {
+            slice,
+            next_bytes: [0; 4],
+            next_range: 0..0,
+            lowercase: None,
+        }
+    }
+}
+
+impl<'a> Iterator for Lowercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(idx) = self.next_range.next() {
+            debug_assert!(self.next_bytes.get(idx).is_some());
+
+            return Some(self.next_bytes[idx]);
+        }
+
+        if let Some(ch) = self.lowercase.as_mut().and_then(Iterator::next) {
+            let enc = ch.encode_utf8(&mut self.next_bytes);
+
+            self.next_range = 1..enc.len();
+            debug_assert!(self.next_bytes.get(self.next_range.clone()).is_some());
+
+            return Some(self.next_bytes[0]);
+        }
+
+        self.lowercase = None;
+
+        match bstr::decode_utf8(self.slice) {
+            (_, 0) => None,
+            (Some(ch), size) => {
+                self.slice = &self.slice[size..];
+                let mut lowercase = ch.to_lowercase();
+                let ch = lowercase
+                    .next()
+                    .expect("ToLowercase yields at least one char");
+                let enc = ch.encode_utf8(&mut self.next_bytes);
+
+                self.next_range = 1..enc.len();
+                debug_assert!(self.next_bytes.get(self.next_range.clone()).is_some());
+
+                self.lowercase = Some(lowercase);
+                Some(self.next_bytes[0])
+            }
+            (None, size) => {
+                let (bytes, remainder) = self.slice.split_at(size);
+                self.slice = remainder;
+
+                // Invalid byte sequences are at most three bytes.
+                debug_assert!(self.next_bytes.get(..bytes.len()).is_some());
+
+                self.next_bytes[..bytes.len()].copy_from_slice(bytes);
+                self.next_range = 1..bytes.len();
+                Some(self.next_bytes[0])
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        const TO_LOWER_EXPAND: usize = 3;
+        const UTF_8_CHAR_MAX_BYTES: usize = 4;
+        if self.slice.is_empty() {
+            (0, Some(0))
+        } else if self.slice.is_ascii() {
+            let len = self.slice.len();
+            (len, Some(len))
+        } else {
+            let len = self.slice.len();
+            (len, Some(len * TO_LOWER_EXPAND * UTF_8_CHAR_MAX_BYTES))
+        }
+    }
+
+    fn count(self) -> usize {
+        if self.slice.is_empty() {
+            0
+        } else if self.slice.is_ascii() {
+            self.slice.len()
+        } else {
+            self.fold(0, |acc, _| acc + 1)
+        }
+    }
+}
+
+impl<'a> FusedIterator for Lowercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+    use core::char;
+
+    use super::Lowercase;
+
+    #[test]
+    fn empty() {
+        let iter = Lowercase::from(&b""[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn ascii() {
+        let iter = Lowercase::from(&b"abc"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"aBC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"ABC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"abc".as_bstr());
+
+        let iter = Lowercase::from(&b"aBC, 123, ABC, baby you and me girl"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"abc, 123, abc, baby you and me girl".as_bstr()
+        );
+    }
+
+    #[test]
+    fn utf8() {
+        let s = "ß".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "ß".as_bytes().as_bstr());
+
+        let s = "Αύριο".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "αύριο".as_bytes().as_bstr()
+        );
+
+        let s = "Έτος".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "έτος".as_bytes().as_bstr()
+        );
+
+        // two-byte characters
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L198-L200
+        let s = "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "𐑄 𐐼𐐯𐑅𐐨𐑉𐐯𐐻 𐑁𐐲𐑉𐑅𐐻/𐑅𐐯𐐿𐐲𐑌𐐼 𐐺𐐳𐐿 𐐺𐐴 𐑄 𐑉𐐨𐐾𐐯𐑌𐐻𐑅 𐐱𐑂 𐑄 𐐼𐐯𐑅𐐨𐑉𐐯𐐻 𐐷𐐮𐐭𐑌𐐮𐑂𐐲𐑉𐑅𐐮𐐻𐐮"
+                .as_bytes()
+                .as_bstr()
+        );
+
+        // Change length when lowercased
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L226-L232
+        let s = "ZȺȾ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "zⱥⱦ".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn invalid_utf8() {
+        let iter = Lowercase::from(&b"\xFF\xFE"[..]);
+        assert_eq!(iter.collect::<Vec<u8>>().as_bstr(), b"\xFF\xFE".as_bstr());
+
+        let iter = Lowercase::from(&b"ABC\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"abc\xFF\xFExyz".as_bstr()
+        );
+
+        let iter = Lowercase::from(&b"abc\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"abc\xFF\xFExyz".as_bstr()
+        );
+
+        // The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of
+        // them on their own are invalid. Only one replacement codepoint is
+        // substituted, which demonstrates the "substitution of maximal
+        // subparts" strategy.
+        //
+        // See: https://docs.rs/bstr/1.*/bstr/#handling-of-invalid-utf-8
+        let iter = Lowercase::from(&b"aB\xF0\x9F\x87Yz"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"ab\xF0\x9F\x87yz".as_bstr()
+        );
+    }
+
+    #[test]
+    fn unicode_replacement_character() {
+        let s = "�".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "�".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn dz_titlecase() {
+        let s = "Dž".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "dž".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn latin_capital_i_with_dot_above() {
+        let s = "İ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            [105_u8, 204, 135].as_bstr()
+        );
+    }
+
+    #[test]
+    fn case_map_to_two_chars() {
+        let s = "İ".as_bytes();
+        let iter = Lowercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "i\u{307}".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn case_map_to_three_chars() {
+        // there are no such characters
+        for ch in '\0'..char::MAX {
+            assert!(
+                ch.to_lowercase().count() < 3,
+                "Expected no characters that downcase to three or more characters, found: '{}', which expands to: {:?}",
+                ch,
+                ch.to_lowercase().collect::<Vec<_>>()
+            );
+        }
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Lowercase::with_slice(b"").size_hint(), (0, Some(0)));
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Lowercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(144))
+        );
+        assert_eq!(
+            Lowercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(36))
+        );
+        assert_eq!(
+            Lowercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(96))
+        );
+        assert_eq!(
+            Lowercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(60))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Lowercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(120))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Lowercase::with_slice(b"").count(), 0);
+        assert_eq!(Lowercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Lowercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Lowercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Lowercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Lowercase::with_slice("ZȺȾ".as_bytes()).count(), 7);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Lowercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Lowercase::with_slice(b"");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice(b"abc, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice(b"abc, \xFF\xFE, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("�".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("Έτος".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Lowercase::with_slice("ZȺȾ".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        let iter = Lowercase::with_slice(&utf8_with_invalid_bytes);
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/uppercase.rs.html b/src/roe/uppercase.rs.html new file mode 100644 index 000000000..c9048f415 --- /dev/null +++ b/src/roe/uppercase.rs.html @@ -0,0 +1,547 @@ +uppercase.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+
use core::iter::FusedIterator;
+
+mod ascii;
+mod full;
+
+#[derive(Debug, Clone)]
+#[allow(variant_size_differences)]
+enum Inner<'a> {
+    Empty,
+    Full(full::Uppercase<'a>),
+    Ascii(ascii::Uppercase<'a>),
+}
+
+/// An iterator that yields the uppercase equivalent of a conventionally UTF-8
+/// byte string.
+///
+/// This iterator yields [bytes].
+///
+/// This struct is created by the [`uppercase`] function. See its documentation
+/// for more.
+///
+/// [bytes]: u8
+/// [`uppercase`]: crate::uppercase()
+#[derive(Debug, Clone)]
+#[must_use = "Uppercase is a Iterator and must be used"]
+pub struct Uppercase<'a> {
+    iter: Inner<'a>,
+}
+
+impl<'a> Uppercase<'a> {
+    /// Create a new, empty uppercase iterator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let mut uppercase = Uppercase::new();
+    /// assert_eq!(uppercase.next(), None);
+    /// ```
+    pub const fn new() -> Self {
+        Self { iter: Inner::Empty }
+    }
+
+    /// Create a new uppercase iterator with the given byte slice using full
+    /// Unicode case mapping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let mut uppercase = Uppercase::with_slice(b"abcXYZ");
+    /// assert_eq!(uppercase.next(), Some(b'A'));
+    /// assert_eq!(uppercase.next(), Some(b'B'));
+    /// assert_eq!(uppercase.next(), Some(b'C'));
+    /// assert_eq!(uppercase.next(), Some(b'X'));
+    /// assert_eq!(uppercase.next(), Some(b'Y'));
+    /// assert_eq!(uppercase.next(), Some(b'Z'));
+    /// assert_eq!(uppercase.next(), None);
+    /// ```
+    ///
+    /// Non-ASCII characters are case mapped:
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let uppercase = Uppercase::with_slice("Αύριο".as_bytes());
+    /// assert_eq!(uppercase.collect::<Vec<_>>(), "ΑΎΡΙΟ".as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 bytes are yielded as is without impacting Unicode
+    /// characters:
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let mut s = "Αύριο".to_string().into_bytes();
+    /// s.extend(b"\xFF\xFE");
+    /// let uppercase = Uppercase::with_slice(s.as_slice());
+    ///
+    /// let mut expected = "ΑΎΡΙΟ".to_string().into_bytes();
+    /// expected.extend(b"\xFF\xFE");
+    /// assert_eq!(uppercase.collect::<Vec<_>>(), expected);
+    /// ```
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self {
+            iter: Inner::Full(full::Uppercase::with_slice(slice)),
+        }
+    }
+
+    /// Create a new uppercase iterator with the given byte slice using ASCII
+    /// case mapping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let mut uppercase = Uppercase::with_ascii_slice(b"abcXYZ");
+    /// assert_eq!(uppercase.next(), Some(b'A'));
+    /// assert_eq!(uppercase.next(), Some(b'B'));
+    /// assert_eq!(uppercase.next(), Some(b'C'));
+    /// assert_eq!(uppercase.next(), Some(b'X'));
+    /// assert_eq!(uppercase.next(), Some(b'Y'));
+    /// assert_eq!(uppercase.next(), Some(b'Z'));
+    /// assert_eq!(uppercase.next(), None);
+    /// ```
+    ///
+    /// Non-ASCII characters are ignored:
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let uppercase = Uppercase::with_ascii_slice("Αύριο".as_bytes());
+    /// assert_eq!(uppercase.collect::<Vec<_>>(), "Αύριο".as_bytes());
+    /// ```
+    ///
+    /// Invalid UTF-8 bytes are yielded as is without impacting ASCII bytes:
+    ///
+    /// ```
+    /// # use roe::Uppercase;
+    /// let uppercase = Uppercase::with_ascii_slice(b"abc\xFF\xFEXYZ");
+    /// assert_eq!(uppercase.collect::<Vec<_>>(), b"ABC\xFF\xFEXYZ");
+    /// ```
+    pub const fn with_ascii_slice(slice: &'a [u8]) -> Self {
+        Self {
+            iter: Inner::Ascii(ascii::Uppercase::with_slice(slice)),
+        }
+    }
+}
+
+impl<'a> Iterator for Uppercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.iter {
+            Inner::Empty => None,
+            Inner::Full(ref mut iter) => iter.next(),
+            Inner::Ascii(ref mut iter) => iter.next(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self.iter {
+            Inner::Empty => (0, Some(0)),
+            Inner::Full(ref iter) => iter.size_hint(),
+            Inner::Ascii(ref iter) => iter.size_hint(),
+        }
+    }
+
+    fn count(self) -> usize {
+        match self.iter {
+            Inner::Empty => 0,
+            Inner::Full(iter) => iter.count(),
+            Inner::Ascii(iter) => iter.count(),
+        }
+    }
+}
+
+impl<'a> FusedIterator for Uppercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+
+    use super::Uppercase;
+
+    #[test]
+    fn empty() {
+        let iter = Uppercase::new();
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+
+        let iter = Uppercase::with_slice(b"");
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+
+        let iter = Uppercase::with_ascii_slice(b"");
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Uppercase::new().size_hint(), (0, Some(0)));
+
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Uppercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(144))
+        );
+        assert_eq!(
+            Uppercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(36))
+        );
+        assert_eq!(
+            Uppercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(96))
+        );
+        assert_eq!(
+            Uppercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(60))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Uppercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(120))
+        );
+
+        assert_eq!(
+            Uppercase::with_ascii_slice(b"abc, xyz").size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Uppercase::with_ascii_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(12))
+        );
+        assert_eq!(
+            Uppercase::with_ascii_slice("�".as_bytes()).size_hint(),
+            (3, Some(3))
+        );
+        assert_eq!(
+            Uppercase::with_ascii_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Uppercase::with_ascii_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(5))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Uppercase::with_ascii_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(10))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Uppercase::new().count(), 0);
+
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Uppercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Uppercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Uppercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Uppercase::with_slice("zⱥⱦ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Uppercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+
+        assert_eq!(Uppercase::with_ascii_slice(b"abc, xyz").count(), 8);
+        assert_eq!(
+            Uppercase::with_ascii_slice(b"abc, \xFF\xFE, xyz").count(),
+            12
+        );
+        assert_eq!(Uppercase::with_ascii_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Uppercase::with_ascii_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Uppercase::with_ascii_slice("ZȺȾ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Uppercase::with_ascii_slice(&utf8_with_invalid_bytes).count(),
+            10
+        );
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Uppercase::new();
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/uppercase/ascii.rs.html b/src/roe/uppercase/ascii.rs.html new file mode 100644 index 000000000..04457de9c --- /dev/null +++ b/src/roe/uppercase/ascii.rs.html @@ -0,0 +1,575 @@ +ascii.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+
use core::fmt;
+use core::iter::FusedIterator;
+
+use bstr::ByteSlice;
+
+#[derive(Clone)]
+#[must_use = "Uppercase is a Iterator and must be used"]
+pub struct Uppercase<'a> {
+    slice: &'a [u8],
+}
+
+impl<'a> fmt::Debug for Uppercase<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Uppercase")
+            .field("slice", &self.slice.as_bstr())
+            .finish()
+    }
+}
+
+impl<'a> From<&'a [u8]> for Uppercase<'a> {
+    fn from(slice: &'a [u8]) -> Self {
+        Self::with_slice(slice)
+    }
+}
+
+impl<'a> Uppercase<'a> {
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self { slice }
+    }
+}
+
+impl<'a> Iterator for Uppercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let (&byte, remainder) = self.slice.split_first()?;
+        self.slice = remainder;
+        Some(byte.to_ascii_uppercase())
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let len = self.slice.len();
+        (len, Some(len))
+    }
+
+    fn count(self) -> usize {
+        self.slice.len()
+    }
+}
+
+impl<'a> DoubleEndedIterator for Uppercase<'a> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        let (&byte, remainder) = self.slice.split_last()?;
+        self.slice = remainder;
+        Some(byte.to_ascii_uppercase())
+    }
+}
+
+impl<'a> ExactSizeIterator for Uppercase<'a> {}
+
+impl<'a> FusedIterator for Uppercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+
+    use super::Uppercase;
+
+    #[test]
+    fn empty() {
+        let iter = Uppercase::from(&b""[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn ascii() {
+        let iter = Uppercase::from(&b"abc"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"aBC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"ABC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"aBC, 123, ABC, baby you and me girl"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"ABC, 123, ABC, BABY YOU AND ME GIRL".as_bstr()
+        );
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn utf8() {
+        let s = "ß".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "ß".as_bytes().as_bstr());
+
+        let s = "Αύριο".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Αύριο".as_bytes().as_bstr()
+        );
+
+        let s = "Έτος".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Έτος".as_bytes().as_bstr()
+        );
+
+        // two-byte characters
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L198-L200
+        let s = "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆"
+                .as_bytes()
+                .as_bstr()
+        );
+
+        // Change length when lowercased
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L226-L232
+        let s = "zȺȾ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ZȺȾ".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn invalid_utf8() {
+        let iter = Uppercase::from(&b"\xFF\xFE"[..]);
+        assert_eq!(iter.collect::<Vec<u8>>().as_bstr(), b"\xFF\xFE".as_bstr());
+
+        let iter = Uppercase::from(&b"ABC\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"ABC\xFF\xFEXYZ".as_bstr()
+        );
+
+        let iter = Uppercase::from(&b"abc\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"ABC\xFF\xFEXYZ".as_bstr()
+        );
+
+        // The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of
+        // them on their own are invalid. Only one replacement codepoint is
+        // substituted, which demonstrates the "substitution of maximal
+        // subparts" strategy.
+        //
+        // See: https://docs.rs/bstr/1.*/bstr/#handling-of-invalid-utf-8
+        let iter = Uppercase::from(&b"aB\xF0\x9F\x87Yz"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"AB\xF0\x9F\x87YZ".as_bstr()
+        );
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn unicode_replacement_character() {
+        let s = "�".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "�".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn dz_titlecase() {
+        let s = "Dž".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "Dž".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn latin_capital_i_with_dot_above() {
+        let s = "İ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "İ".as_bytes().as_bstr());
+    }
+
+    // ignore unicode for ASCII iterator
+    #[test]
+    fn case_map_to_two_chars() {
+        let s = "İ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "İ".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Uppercase::with_slice(b"").size_hint(), (0, Some(0)));
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Uppercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(12))
+        );
+        assert_eq!(
+            Uppercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(3))
+        );
+        assert_eq!(
+            Uppercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(8))
+        );
+        assert_eq!(
+            Uppercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(5))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Uppercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(10))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Uppercase::with_slice(b"").count(), 0);
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Uppercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Uppercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Uppercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Uppercase::with_slice("ZȺȾ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Uppercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Uppercase::with_slice(b"");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice(b"abc, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice(b"abc, \xFF\xFE, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("�".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("Έτος".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("ZȺȾ".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        let iter = Uppercase::with_slice(&utf8_with_invalid_bytes);
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/roe/uppercase/full.rs.html b/src/roe/uppercase/full.rs.html new file mode 100644 index 000000000..91ea22592 --- /dev/null +++ b/src/roe/uppercase/full.rs.html @@ -0,0 +1,787 @@ +full.rs - source
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
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+
use core::char::ToUppercase;
+use core::fmt;
+use core::iter::FusedIterator;
+use core::ops::Range;
+
+use bstr::ByteSlice;
+
+#[derive(Clone)]
+#[must_use = "Uppercase is a Iterator and must be used"]
+pub struct Uppercase<'a> {
+    slice: &'a [u8],
+    next_bytes: [u8; 4],
+    next_range: Range<usize>,
+    uppercase: Option<ToUppercase>,
+}
+
+impl<'a> fmt::Debug for Uppercase<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Uppercase")
+            .field("slice", &self.slice.as_bstr())
+            .field("next_bytes", &self.next_bytes)
+            .field("next_range", &self.next_range)
+            .field("uppercase", &self.uppercase)
+            .finish()
+    }
+}
+
+impl<'a> From<&'a [u8]> for Uppercase<'a> {
+    fn from(slice: &'a [u8]) -> Self {
+        Self::with_slice(slice)
+    }
+}
+
+impl<'a> Uppercase<'a> {
+    pub const fn with_slice(slice: &'a [u8]) -> Self {
+        Self {
+            slice,
+            next_bytes: [0; 4],
+            next_range: 0..0,
+            uppercase: None,
+        }
+    }
+}
+
+impl<'a> Iterator for Uppercase<'a> {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(idx) = self.next_range.next() {
+            debug_assert!(self.next_bytes.get(idx).is_some());
+
+            return Some(self.next_bytes[idx]);
+        }
+
+        if let Some(ch) = self.uppercase.as_mut().and_then(Iterator::next) {
+            let enc = ch.encode_utf8(&mut self.next_bytes);
+
+            self.next_range = 1..enc.len();
+            debug_assert!(self.next_bytes.get(self.next_range.clone()).is_some());
+
+            return Some(self.next_bytes[0]);
+        }
+
+        self.uppercase = None;
+
+        match bstr::decode_utf8(self.slice) {
+            (_, 0) => None,
+            (Some(ch), size) => {
+                self.slice = &self.slice[size..];
+                let mut uppercase = ch.to_uppercase();
+                let ch = uppercase
+                    .next()
+                    .expect("ToUppercase yields at least one char");
+                let enc = ch.encode_utf8(&mut self.next_bytes);
+
+                self.next_range = 1..enc.len();
+                debug_assert!(self.next_bytes.get(self.next_range.clone()).is_some());
+
+                self.uppercase = Some(uppercase);
+                Some(self.next_bytes[0])
+            }
+            (None, size) => {
+                let (bytes, remainder) = self.slice.split_at(size);
+                self.slice = remainder;
+
+                // Invalid byte sequences are at most three bytes.
+                debug_assert!(self.next_bytes.get(..bytes.len()).is_some());
+
+                self.next_bytes[..bytes.len()].copy_from_slice(bytes);
+                self.next_range = 1..bytes.len();
+                Some(self.next_bytes[0])
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        const TO_UPPER_EXPAND: usize = 3;
+        const UTF_8_CHAR_MAX_BYTES: usize = 4;
+        if self.slice.is_empty() {
+            (0, Some(0))
+        } else if self.slice.is_ascii() {
+            let len = self.slice.len();
+            (len, Some(len))
+        } else {
+            let len = self.slice.len();
+            (len, Some(len * TO_UPPER_EXPAND * UTF_8_CHAR_MAX_BYTES))
+        }
+    }
+
+    fn count(self) -> usize {
+        if self.slice.is_empty() {
+            0
+        } else if self.slice.is_ascii() {
+            self.slice.len()
+        } else {
+            self.fold(0, |acc, _| acc + 1)
+        }
+    }
+}
+
+impl<'a> FusedIterator for Uppercase<'a> {}
+
+#[cfg(test)]
+mod tests {
+    use alloc::vec::Vec;
+    use bstr::ByteSlice;
+
+    use super::Uppercase;
+
+    #[test]
+    fn empty() {
+        let iter = Uppercase::from(&b""[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"".as_bstr());
+    }
+
+    #[test]
+    fn ascii() {
+        let iter = Uppercase::from(&b"abc"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"aBC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"ABC"[..]);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"ABC".as_bstr());
+
+        let iter = Uppercase::from(&b"aBC, 123, ABC, baby you and me girl"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"ABC, 123, ABC, BABY YOU AND ME GIRL".as_bstr()
+        );
+    }
+
+    #[test]
+    fn utf8() {
+        let s = "ß".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "SS".as_bytes().as_bstr()
+        );
+
+        let s = "Αύριο".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ΑΎΡΙΟ".as_bytes().as_bstr()
+        );
+
+        let s = "Έτος".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ΈΤΟΣ".as_bytes().as_bstr()
+        );
+
+        // two-byte characters
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L198-L200
+        let s = "𐑄 𐐼𐐯𐑅𐐨𐑉𐐯𐐻 𐑁𐐲𐑉𐑅𐐻/𐑅𐐯𐐿𐐲𐑌𐐼 𐐺𐐳𐐿 𐐺𐐴 𐑄 𐑉𐐨𐐾𐐯𐑌𐐻𐑅 𐐱𐑂 𐑄 𐐼𐐯𐑅𐐨𐑉𐐯𐐻 𐐷𐐮𐐭𐑌𐐮𐑂𐐲𐑉𐑅𐐮𐐻𐐮".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐉𐐚 𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆"
+                .as_bytes()
+                .as_bstr()
+        );
+
+        // Change length when uppercased
+        // https://github.com/minimaxir/big-list-of-naughty-strings/blob/894882e7/blns.txt#L226-L232
+        let s = "zⱥⱦ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ZȺȾ".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn invalid_utf8() {
+        let iter = Uppercase::from(&b"\xFF\xFE"[..]);
+        assert_eq!(iter.collect::<Vec<u8>>().as_bstr(), b"\xFF\xFE".as_bstr());
+
+        let iter = Uppercase::from(&b"abc\xFF\xFExyz"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"ABC\xFF\xFEXYZ".as_bstr()
+        );
+
+        let iter = Uppercase::from(&b"abc\xFF\xFEXYZ"[..]);
+        assert_eq!(
+            iter.collect::<Vec<u8>>().as_bstr(),
+            b"ABC\xFF\xFEXYZ".as_bstr()
+        );
+
+        // The bytes \xF0\x9F\x87 could lead to a valid UTF-8 sequence, but 3 of
+        // them on their own are invalid. Only one replacement codepoint is
+        // substituted, which demonstrates the "substitution of maximal
+        // subparts" strategy.
+        //
+        // See: https://docs.rs/bstr/1.*/bstr/#handling-of-invalid-utf-8
+        let iter = Uppercase::from(&b"aB\xF0\x9F\x87Yz"[..]);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            b"AB\xF0\x9F\x87YZ".as_bstr()
+        );
+    }
+
+    #[test]
+    fn unicode_replacement_character() {
+        let s = "�".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "�".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn dz_titlecase() {
+        let s = "Dž".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), "DŽ".as_bytes().as_bstr());
+    }
+
+    #[test]
+    fn latin_small_i_with_dot_above() {
+        let s = "i̇".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            [73_u8, 204, 135].as_bstr()
+        );
+    }
+
+    #[test]
+    fn case_map_to_two_chars() {
+        let s = "և".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ԵՒ".as_bytes().as_bstr()
+        );
+
+        let s = "ẙ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Y\u{30a}".as_bytes().as_bstr()
+        );
+
+        let s = "ᾂ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ἊΙ".as_bytes().as_bstr()
+        );
+
+        let s = "ﬗ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "ՄԽ".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn case_map_to_three_chars() {
+        let s = "ffi".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(iter.collect::<Vec<_>>().as_bstr(), b"FFI".as_bstr());
+
+        let s = "ὖ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Υ\u{313}\u{342}".as_bytes().as_bstr()
+        );
+
+        let s = "ῷ".as_bytes();
+        let iter = Uppercase::from(s);
+        assert_eq!(
+            iter.collect::<Vec<_>>().as_bstr(),
+            "Ω\u{342}Ι".as_bytes().as_bstr()
+        );
+    }
+
+    #[test]
+    fn size_hint() {
+        assert_eq!(Uppercase::with_slice(b"").size_hint(), (0, Some(0)));
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").size_hint(), (8, Some(8)));
+        assert_eq!(
+            Uppercase::with_slice(b"abc, \xFF\xFE, xyz").size_hint(),
+            (12, Some(144))
+        );
+        assert_eq!(
+            Uppercase::with_slice("�".as_bytes()).size_hint(),
+            (3, Some(36))
+        );
+        assert_eq!(
+            Uppercase::with_slice("Έτος".as_bytes()).size_hint(),
+            (8, Some(96))
+        );
+        assert_eq!(
+            Uppercase::with_slice("ZȺȾ".as_bytes()).size_hint(),
+            (5, Some(60))
+        );
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(
+            Uppercase::with_slice(&utf8_with_invalid_bytes).size_hint(),
+            (10, Some(120))
+        );
+    }
+
+    #[test]
+    fn count() {
+        assert_eq!(Uppercase::with_slice(b"").count(), 0);
+        assert_eq!(Uppercase::with_slice(b"abc, xyz").count(), 8);
+        assert_eq!(Uppercase::with_slice(b"abc, \xFF\xFE, xyz").count(), 12);
+        assert_eq!(Uppercase::with_slice("�".as_bytes()).count(), 3);
+        assert_eq!(Uppercase::with_slice("Έτος".as_bytes()).count(), 8);
+        assert_eq!(Uppercase::with_slice("zⱥⱦ".as_bytes()).count(), 5);
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        assert_eq!(Uppercase::with_slice(&utf8_with_invalid_bytes).count(), 10);
+    }
+
+    #[test]
+    fn size_hint_covers_count() {
+        let iter = Uppercase::with_slice(b"");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice(b"abc, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice(b"abc, \xFF\xFE, xyz");
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("�".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("Έτος".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let iter = Uppercase::with_slice("ZȺȾ".as_bytes());
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+
+        let mut utf8_with_invalid_bytes = b"\xFF\xFE".to_vec();
+        utf8_with_invalid_bytes.extend_from_slice("Έτος".as_bytes());
+        let iter = Uppercase::with_slice(&utf8_with_invalid_bytes);
+        let (min, max) = iter.size_hint();
+        let count = iter.count();
+        assert!(min <= count);
+        assert!(count <= max.unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 000000000..1447df792 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 000000000..d7e9c149b --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 000000000..7a1e5fc54 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 000000000..e766e06cc Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 000000000..1866ad4bc Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 000000000..4b3edc29e --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 000000000..462c34efc Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 000000000..0d2941e14 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 000000000..10b558e0b Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 000000000..5ec64eef0 Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 000000000..181a07f63 Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 000000000..2ae08a7be Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 000000000..175fa4f47 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 000000000..0263fc304 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 000000000..8adbd9963 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 000000000..ea4b45cae Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 000000000..8b34b5119 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 000000000..69b8613ce Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/main-5f34af1a0ee6bacd.js b/static.files/main-5f34af1a0ee6bacd.js new file mode 100644 index 000000000..f8ae3ca7a --- /dev/null +++ b/static.files/main-5f34af1a0ee6bacd.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.body,"crate")){mobileTitle.innerText=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}})}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.body,"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(link.href===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 000000000..469959f13 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-5d8b3c7633ad77ba.css b/static.files/noscript-5d8b3c7633ad77ba.css new file mode 100644 index 000000000..8c63ef065 --- /dev/null +++ b/static.files/noscript-5d8b3c7633ad77ba.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 000000000..62424d8ff --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-deb46770fd761b69.css b/static.files/rustdoc-deb46770fd761b69.css new file mode 100644 index 000000000..2922e34a6 --- /dev/null +++ b/static.files/rustdoc-deb46770fd761b69.css @@ -0,0 +1,10 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.5rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.5rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;margin-top:calc((-16px + 0.57rem ) / 2 );}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a,:root[data-theme="ayu"] #source-sidebar>.title{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 000000000..ba830e374 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-8fbf244ebcf71464.js b/static.files/search-8fbf244ebcf71464.js new file mode 100644 index 000000000..168023b4b --- /dev/null +++ b/static.files/search-8fbf244ebcf71464.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias","generic",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem,whereClause,mgensInout){return unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgensInout,mgens=>{if(mgensInout){for(const[fid,qid]of mgens.entries()){mgensInout.set(fid,qid)}}return true})}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){let mgens=new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;let fl=fnTypesIn.length;let fnTypes=fnTypesIn.slice();const backtracking=[];let i=0;let j=0;const backtrack=()=>{while(backtracking.length!==0){const{fnTypesScratch,mgensScratch,queryElemsOffset,fnTypesOffset,unbox,}=backtracking.pop();mgens=new Map(mgensScratch);const fnType=fnTypesScratch[fnTypesOffset];const queryElem=queryElems[queryElemsOffset];if(unbox){if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}mgens.set(fnType.id,0)}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;fnTypes=fnTypesScratch.toSpliced(fnTypesOffset,1,...generics);fl=fnTypes.length;i=queryElemsOffset-1}else{if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}mgens.set(fnType.id,queryElem.id)}fnTypes=fnTypesScratch.slice();fl=fnTypes.length;const tmp=fnTypes[queryElemsOffset];fnTypes[queryElemsOffset]=fnTypes[fnTypesOffset];fnTypes[fnTypesOffset]=tmp;i=queryElemsOffset}return true}return false};for(i=0;i!==ql;++i){const queryElem=queryElems[i];const matchCandidates=[];let fnTypesScratch=null;let mgensScratch=null;for(j=i;j!==fl;++j){const fnType=fnTypes[j];if(unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgens,mgensScratch=>{matchCandidates.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:false,});return false})}if(unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}if(!mgensScratch){mgensScratch=new Map(mgens)}backtracking.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:true,})}}if(matchCandidates.length===0){if(backtrack()){continue}else{return false}}const{fnTypesOffset:candidate,mgensScratch:mgensNew}=matchCandidates.pop();if(fnTypes[candidate].id<0&&queryElems[i].id<0){mgens.set(fnTypes[candidate].id,queryElems[i].id)}for(const[fid,qid]of mgensNew){mgens.set(fid,qid)}const tmp=fnTypes[candidate];fnTypes[candidate]=fnTypes[i];fnTypes[i]=tmp;for(const otherCandidate of matchCandidates){backtracking.push(otherCandidate)}while(i===(ql-1)&&solutionCb&&!solutionCb(mgens)){if(!backtrack()){return false}}}return true}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgens.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(fnType.id!==queryElem.id){return false}if(fnType.generics.length===0&&queryElem.generics.length!==0){return false}const queryElemPathLength=queryElem.pathWithoutLast.length;if(queryElemPathLength>0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i=0){if(!whereClause){return false}if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause)}else if(fnType.generics&&fnType.generics.length>0){return checkIfInList(fnType.generics,queryElem,whereClause)}return false}function checkIfInList(list,elem,whereClause){for(const entry of list){if(checkType(entry,elem,whereClause)){return true}}return false}function checkType(row,elem,whereClause){if(row.id===null){return row.generics.length>0?checkIfInList(row.generics,elem,whereClause):false}if(row.id<0&&elem.id>=0){const gid=(-row.id)-1;return checkIfInList(whereClause[gid],elem,whereClause)}if(row.id<0&&elem.id<0){return true}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem,whereClause,new Map())}return true}return checkIfInList(row.generics,elem,whereClause)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem){if(typeNameIdMap.has(elem.pathLast)){elem.id=typeNameIdMap.get(elem.pathLast)}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.pathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor=type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}if(item.implDisambiguator!==null){anchor=item.implDisambiguator+"/"+anchor}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html#"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.map(type=>buildItemSearchType(type,lowercasePaths))}function buildItemSearchType(type,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}if(pathIndex<0){return{id:pathIndex,ty:TY_GENERIC,path:null,generics,}}if(pathIndex===0){return{id:null,ty:null,path:null,generics,}}const item=lowercasePaths[pathIndex-1];return{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics,}}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/static.files/settings-74424d7eec62a23e.js b/static.files/settings-74424d7eec62a23e.js new file mode 100644 index 000000000..3014f75c5 --- /dev/null +++ b/static.files/settings-74424d7eec62a23e.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-3280b574d94e47b4.js b/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 000000000..9ea88921e --- /dev/null +++ b/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-fec3eaa3851e447d.js b/static.files/storage-fec3eaa3851e447d.js new file mode 100644 index 000000000..a687118f3 --- /dev/null +++ b/static.files/storage-fec3eaa3851e447d.js @@ -0,0 +1 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/static.files/wheel-7b819b6101059cd0.svg b/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 000000000..83c07f63d --- /dev/null +++ b/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file