pub type StackCapture = [u64; 4];
Expand description
mozilla::Variant
A variant / tagged union / heterogenous disjoint union / sum-type template
class. Similar in concept to (but not derived from) boost::variant
.
Sometimes, you may wish to use a C union with non-POD types. However, this is
forbidden in C++ because it is not clear which type in the union should have
its constructor and destructor run on creation and deletion
respectively. This is the problem that mozilla::Variant
solves.
Usage
A mozilla::Variant
instance is constructed (via move or copy) from one of
its variant types (ignoring const and references). It does not support
construction from subclasses of variant types or types that coerce to one of
the variant types.
Variant<char, uint32_t> v1('a');
Variant<UniquePtr<A>, B, C> v2(MakeUnique<A>());
Variant<bool, char> v3(VariantType<char>, 0); // disambiguation needed
Variant<int, int> v4(VariantIndex<1>, 0); // 2nd int
Because specifying the full type of a Variant value is often verbose, there are two easier ways to construct values:
A. AsVariant() can be used to construct a Variant value using type inference in contexts such as expressions or when returning values from functions. Because AsVariant() must copy or move the value into a temporary and this cannot necessarily be elided by the compiler, it’s mostly appropriate only for use with primitive or very small types.
Variant<char, uint32_t> Foo() { return AsVariant('x'); }
// ...
Variant<char, uint32_t> v1 = Foo(); // v1 holds char('x').
B. Brace-construction with VariantType or VariantIndex; this also allows in-place construction with any number of arguments.
struct AB { AB(int, int){...} };
static Variant<AB, bool> foo()
{
return {VariantIndex<0>{}, 1, 2};
}
// ...
Variant<AB, bool> v0 = Foo(); // v0 holds AB(1,2).
All access to the contained value goes through type-safe accessors. Either the stored type, or the type index may be provided.
void
Foo(Variant<A, B, C> v)
{
if (v.is<A>()) {
A& ref = v.as<A>();
...
} else (v.is<1>()) { // Instead of v.is<B>.
...
} else {
...
}
}
In some situation, a Variant may be constructed from templated types, in which case it is possible that the same type could be given multiple times by an external developer. Or seemingly-different types could be aliases. In this case, repeated types can only be accessed through their index, to prevent ambiguous access by type.
// Bad!
template
// Good!
template
Attempting to use the contained value as type T1
when the Variant
instance contains a value of type T2
causes an assertion failure.
A a;
Variant<A, B, C> v(a);
v.as<B>(); // <--- Assertion failure!
Trying to use a Variant<Ts...>
instance as some type U
that is not a
member of the set of Ts...
is a compiler error.
A a;
Variant<A, B, C> v(a);
v.as<SomeRandomType>(); // <--- Compiler error!
Additionally, you can turn a Variant
that is<T>
into a T
by moving it
out of the containing Variant
instance with the extract<T>
method:
Variant<UniquePtr<A>, B, C> v(MakeUnique<A>());
auto ptr = v.extract<UniquePtr<A>>();
Finally, you can exhaustively match on the contained variant and branch into
different code paths depending on which type is contained. This is preferred
to manually checking every variant type T with is
// Bad!
char* foo(Variant<A, B, C, D>& v) {
if (v.is<A>()) {
return ...;
} else if (v.is<B>()) {
return ...;
} else {
return doSomething(v.as<C>()); // Forgot about case D!
}
}
// Instead, a single function object (that can deal with all possible
// options) may be provided:
struct FooMatcher
{
// The return type of all matchers must be identical.
char* operator()(A& a) { ... }
char* operator()(B& b) { ... }
char* operator()(C& c) { ... }
char* operator()(D& d) { ... } // Compile-time error to forget D!
}
char* foo(Variant<A, B, C, D>& v) {
return v.match(FooMatcher());
}
// In some situations, a single generic lambda may also be appropriate:
char* foo(Variant<A, B, C, D>& v) {
return v.match([](auto&) {...});
}
// Alternatively, multiple function objects may be provided, each one
// corresponding to an option, in the same order:
char* foo(Variant<A, B, C, D>& v) {
return v.match([](A&) { ... },
[](B&) { ... },
[](C&) { ... },
[](D&) { ... });
}
// In rare cases, the index of the currently-active alternative is
// needed, it may be obtained by adding a first parameter in the matcner
// callback, which will receive the index in its most compact type (just
// use `size_t` if the exact type is not important), e.g.:
char* foo(Variant<A, B, C, D>& v) {
return v.match([](auto aIndex, auto& aAlternative) {...});
// --OR--
return v.match([](size_t aIndex, auto& aAlternative) {...});
}
Examples
A tree is either an empty leaf, or a node with a value and two children:
struct Leaf { };
template<typename T>
struct Node
{
T value;
Tree<T>* left;
Tree<T>* right;
};
template<typename T>
using Tree = Variant<Leaf, Node<T>>;
A copy-on-write string is either a non-owning reference to some existing string, or an owning reference to our copy:
class CopyOnWriteString
{
Variant<const char*, UniquePtr<char[]>> string;
...
};
Because Variant must be aligned suitable to hold any value stored within it, and because |alignas| requirements don’t affect platform ABI with respect to how parameters are laid out in memory, Variant can’t be used as the type of a function parameter. Pass Variant to functions by pointer or reference instead.
Implementations§
source§impl<T, const N: usize> [T; N]
impl<T, const N: usize> [T; N]
1.55.0 · sourcepub fn map<F, U>(self, f: F) -> [U; N]where
F: FnMut(T) -> U,
pub fn map<F, U>(self, f: F) -> [U; N]where F: FnMut(T) -> U,
Returns an array of the same size as self
, with function f
applied to each element
in order.
If you don’t necessarily need a new fixed-size array, consider using
Iterator::map
instead.
Note on performance and stack usage
Unfortunately, usages of this method are currently not always optimized as well as they could be. This mainly concerns large arrays, as mapping over small arrays seem to be optimized just fine. Also note that in debug mode (i.e. without any optimizations), this method can use a lot of stack space (a few times the size of the array or more).
Therefore, in performance-critical code, try to avoid using this method
on large arrays or check the emitted code. Also try to avoid chained
maps (e.g. arr.map(...).map(...)
).
In many cases, you can instead use Iterator::map
by calling .iter()
or .into_iter()
on your array. [T; N]::map
is only necessary if you
really need a new array of the same size as the result. Rust’s lazy
iterators tend to get optimized very well.
Examples
let x = [1, 2, 3];
let y = x.map(|v| v + 1);
assert_eq!(y, [2, 3, 4]);
let x = [1, 2, 3];
let mut temp = 0;
let y = x.map(|v| { temp += 1; v * temp });
assert_eq!(y, [1, 4, 9]);
let x = ["Ferris", "Bueller's", "Day", "Off"];
let y = x.map(|v| v.len());
assert_eq!(y, [6, 9, 3, 3]);
sourcepub fn try_map<F, R>(
self,
f: F
) -> <<R as Try>::Residual as Residual<[<R as Try>::Output; N]>>::TryTypewhere
F: FnMut(T) -> R,
R: Try,
<R as Try>::Residual: Residual<[<R as Try>::Output; N]>,
🔬This is a nightly-only experimental API. (array_try_map
)
pub fn try_map<F, R>( self, f: F ) -> <<R as Try>::Residual as Residual<[<R as Try>::Output; N]>>::TryTypewhere F: FnMut(T) -> R, R: Try, <R as Try>::Residual: Residual<[<R as Try>::Output; N]>,
array_try_map
)A fallible function f
applied to each element on array self
in order to
return an array the same size as self
or the first error encountered.
The return type of this function depends on the return type of the closure.
If you return Result<T, E>
from the closure, you’ll get a Result<[T; N], E>
.
If you return Option<T>
from the closure, you’ll get an Option<[T; N]>
.
Examples
#![feature(array_try_map)]
let a = ["1", "2", "3"];
let b = a.try_map(|v| v.parse::<u32>()).unwrap().map(|v| v + 1);
assert_eq!(b, [2, 3, 4]);
let a = ["1", "2a", "3"];
let b = a.try_map(|v| v.parse::<u32>());
assert!(b.is_err());
use std::num::NonZeroU32;
let z = [1, 2, 0, 3, 4];
assert_eq!(z.try_map(NonZeroU32::new), None);
let a = [1, 2, 3];
let b = a.try_map(NonZeroU32::new);
let c = b.map(|x| x.map(NonZeroU32::get));
assert_eq!(c, Some(a));
1.57.0 (const: 1.57.0) · sourcepub const fn as_slice(&self) -> &[T]
pub const fn as_slice(&self) -> &[T]
Returns a slice containing the entire array. Equivalent to &s[..]
.
1.57.0 · sourcepub fn as_mut_slice(&mut self) -> &mut [T]
pub fn as_mut_slice(&mut self) -> &mut [T]
Returns a mutable slice containing the entire array. Equivalent to
&mut s[..]
.
sourcepub fn each_ref(&self) -> [&T; N]
🔬This is a nightly-only experimental API. (array_methods
)
pub fn each_ref(&self) -> [&T; N]
array_methods
)Borrows each element and returns an array of references with the same
size as self
.
Example
#![feature(array_methods)]
let floats = [3.1, 2.7, -1.0];
let float_refs: [&f64; 3] = floats.each_ref();
assert_eq!(float_refs, [&3.1, &2.7, &-1.0]);
This method is particularly useful if combined with other methods, like
map
. This way, you can avoid moving the original
array if its elements are not Copy
.
#![feature(array_methods)]
let strings = ["Ferris".to_string(), "♥".to_string(), "Rust".to_string()];
let is_ascii = strings.each_ref().map(|s| s.is_ascii());
assert_eq!(is_ascii, [true, false, true]);
// We can still access the original array: it has not been moved.
assert_eq!(strings.len(), 3);
sourcepub fn each_mut(&mut self) -> [&mut T; N]
🔬This is a nightly-only experimental API. (array_methods
)
pub fn each_mut(&mut self) -> [&mut T; N]
array_methods
)Borrows each element mutably and returns an array of mutable references
with the same size as self
.
Example
#![feature(array_methods)]
let mut floats = [3.1, 2.7, -1.0];
let float_refs: [&mut f64; 3] = floats.each_mut();
*float_refs[0] = 0.0;
assert_eq!(float_refs, [&mut 0.0, &mut 2.7, &mut -1.0]);
assert_eq!(floats, [0.0, 2.7, -1.0]);
sourcepub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T])
🔬This is a nightly-only experimental API. (split_array
)
pub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T])
split_array
)Divides one array reference into two at an index.
The first will contain all indices from [0, M)
(excluding
the index M
itself) and the second will contain all
indices from [M, N)
(excluding the index N
itself).
Panics
Panics if M > N
.
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, &[]);
}
sourcepub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T])
🔬This is a nightly-only experimental API. (split_array
)
pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T])
split_array
)Divides one mutable array reference into two at an index.
The first will contain all indices from [0, M)
(excluding
the index M
itself) and the second will contain all
indices from [M, N)
(excluding the index N
itself).
Panics
Panics if M > N
.
Examples
#![feature(split_array)]
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.split_array_mut::<2>();
assert_eq!(left, &mut [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]);
sourcepub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M])
🔬This is a nightly-only experimental API. (split_array
)
pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M])
split_array
)Divides one array reference into two at an index from the end.
The first will contain all indices from [0, N - M)
(excluding
the index N - M
itself) and the second will contain all
indices from [N - M, N)
(excluding the index N
itself).
Panics
Panics if M > N
.
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]);
}
sourcepub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M])
🔬This is a nightly-only experimental API. (split_array
)
pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M])
split_array
)Divides one mutable array reference into two at an index from the end.
The first will contain all indices from [0, N - M)
(excluding
the index N - M
itself) and the second will contain all
indices from [N - M, N)
(excluding the index N
itself).
Panics
Panics if M > N
.
Examples
#![feature(split_array)]
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.rsplit_array_mut::<4>();
assert_eq!(left, &mut [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]);
Trait Implementations§
source§impl<T> Array for [T; 4]where
T: Default,
impl<T> Array for [T; 4]where T: Default,
source§fn as_slice_mut(&mut self) -> &mut [T]
fn as_slice_mut(&mut self) -> &mut [T]
source§impl<const N: usize, T> AsBytes for [T; N]where
T: AsBytes,
impl<const N: usize, T> AsBytes for [T; N]where T: AsBytes,
1.4.0 · source§impl<T, const N: usize> BorrowMut<[T]> for [T; N]
impl<T, const N: usize> BorrowMut<[T]> for [T; N]
source§fn borrow_mut(&mut self) -> &mut [T]
fn borrow_mut(&mut self) -> &mut [T]
source§impl<'de, T> Deserialize<'de> for [T; 4]where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for [T; 4]where T: Deserialize<'de>,
source§fn deserialize<D>(
deserializer: D
) -> Result<[T; 4], <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>( deserializer: D ) -> Result<[T; 4], <D as Deserializer<'de>>::Error>where D: Deserializer<'de>,
1.71.0 · source§impl<T> From<(T, T, T, T)> for [T; 4]
impl<T> From<(T, T, T, T)> for [T; 4]
source§fn from(tuple: (T, T, T, T)) -> [T; 4]
fn from(tuple: (T, T, T, T)) -> [T; 4]
source§impl<T, const N: usize> From<Simd<T, N>> for [T; N]where
LaneCount<N>: SupportedLaneCount,
T: SimdElement,
impl<T, const N: usize> From<Simd<T, N>> for [T; N]where LaneCount<N>: SupportedLaneCount, T: SimdElement,
source§impl<const N: usize, T> FromBytes for [T; N]where
T: FromBytes,
impl<const N: usize, T> FromBytes for [T; N]where T: FromBytes,
source§fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>where
Self: Sized,
fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>where Self: Sized,
bytes
as a &[Self]
with length
equal to count
without copying. Read moresource§fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])>where
Self: Sized,
fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])>where Self: Sized,
bytes
as a &[Self]
with length
equal to count
without copying. Read moresource§impl<const N: usize, T> FromZeroes for [T; N]where
T: FromZeroes,
impl<const N: usize, T> FromZeroes for [T; N]where T: FromZeroes,
1.0.0 · source§impl<T, const N: usize> Hash for [T; N]where
T: Hash,
impl<T, const N: usize> Hash for [T; N]where T: Hash,
The hash of an array is the same as that of the corresponding slice,
as required by the Borrow
implementation.
use std::hash::BuildHasher;
let b = std::collections::hash_map::RandomState::new();
let a: [u8; 3] = [0xa8, 0x3c, 0x09];
let s: &[u8] = &[0xa8, 0x3c, 0x09];
assert_eq!(b.hash_one(a), b.hash_one(s));
1.53.0 · source§impl<T, const N: usize> IntoIterator for [T; N]
impl<T, const N: usize> IntoIterator for [T; N]
source§fn into_iter(self) -> <[T; N] as IntoIterator>::IntoIter
fn into_iter(self) -> <[T; N] as IntoIterator>::IntoIter
Creates a consuming iterator, that is, one that moves each value out of
the array (from start to end). The array cannot be used after calling
this unless T
implements Copy
, so the whole array is copied.
Arrays have special behavior when calling .into_iter()
prior to the
2021 edition – see the array Editions section for more information.
1.0.0 · source§impl<T, const N: usize> Ord for [T; N]where
T: Ord,
impl<T, const N: usize> Ord for [T; N]where T: Ord,
Implements comparison of arrays lexicographically.
1.0.0 · source§impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N]where
A: PartialEq<B>,
impl<A, B, const N: usize> PartialEq<&mut [B]> for [A; N]where A: PartialEq<B>,
1.0.0 · source§impl<T, const N: usize> PartialOrd<[T; N]> for [T; N]where
T: PartialOrd<T>,
impl<T, const N: usize> PartialOrd<[T; N]> for [T; N]where T: PartialOrd<T>,
source§fn le(&self, other: &[T; N]) -> bool
fn le(&self, other: &[T; N]) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<T> Serialize for [T; 4]where
T: Serialize,
impl<T> Serialize for [T; 4]where T: Serialize,
source§fn serialize<S>(
&self,
serializer: S
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
fn serialize<S>( &self, serializer: S ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where S: Serializer,
1.51.0 · source§impl<T, const N: usize> SlicePattern for [T; N]
impl<T, const N: usize> SlicePattern for [T; N]
1.34.0 · source§impl<T, const N: usize> TryFrom<&[T]> for [T; N]where
T: Copy,
impl<T, const N: usize> TryFrom<&[T]> for [T; N]where T: Copy,
Tries to create an array [T; N]
by copying from a slice &[T]
. Succeeds if
slice.len() == N
.
let bytes: [u8; 3] = [1, 0, 2];
let bytes_head: [u8; 2] = <[u8; 2]>::try_from(&bytes[0..2]).unwrap();
assert_eq!(1, u16::from_le_bytes(bytes_head));
let bytes_tail: [u8; 2] = bytes[1..3].try_into().unwrap();
assert_eq!(512, u16::from_le_bytes(bytes_tail));
§type Error = TryFromSliceError
type Error = TryFromSliceError
1.59.0 · source§impl<T, const N: usize> TryFrom<&mut [T]> for [T; N]where
T: Copy,
impl<T, const N: usize> TryFrom<&mut [T]> for [T; N]where T: Copy,
Tries to create an array [T; N]
by copying from a mutable slice &mut [T]
.
Succeeds if slice.len() == N
.
let mut bytes: [u8; 3] = [1, 0, 2];
let bytes_head: [u8; 2] = <[u8; 2]>::try_from(&mut bytes[0..2]).unwrap();
assert_eq!(1, u16::from_le_bytes(bytes_head));
let bytes_tail: [u8; 2] = (&mut bytes[1..3]).try_into().unwrap();
assert_eq!(512, u16::from_le_bytes(bytes_tail));
§type Error = TryFromSliceError
type Error = TryFromSliceError
source§impl<T, const N: usize> TryFrom<ThinVec<T>> for [T; N]
impl<T, const N: usize> TryFrom<ThinVec<T>> for [T; N]
source§fn try_from(vec: ThinVec<T>) -> Result<[T; N], ThinVec<T>>
fn try_from(vec: ThinVec<T>) -> Result<[T; N], ThinVec<T>>
Gets the entire contents of the ThinVec<T>
as an array,
if its size exactly matches that of the requested array.
Examples
use thin_vec::{ThinVec, thin_vec};
use std::convert::TryInto;
assert_eq!(thin_vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
assert_eq!(<ThinVec<i32>>::new().try_into(), Ok([]));
If the length doesn’t match, the input comes back in Err
:
use thin_vec::{ThinVec, thin_vec};
use std::convert::TryInto;
let r: Result<[i32; 4], _> = (0..10).collect::<ThinVec<_>>().try_into();
assert_eq!(r, Err(thin_vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
If you’re fine with just getting a prefix of the ThinVec<T>
,
you can call .truncate(N)
first.
use thin_vec::{ThinVec, thin_vec};
use std::convert::TryInto;
let mut v = ThinVec::from("hello world");
v.sort();
v.truncate(2);
let [a, b]: [_; 2] = v.try_into().unwrap();
assert_eq!(a, b' ');
assert_eq!(b, b'd');
1.48.0 · source§impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]where
A: Allocator,
impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]where A: Allocator,
source§fn try_from(vec: Vec<T, A>) -> Result<[T; N], Vec<T, A>>
fn try_from(vec: Vec<T, A>) -> Result<[T; N], Vec<T, A>>
Gets the entire contents of the Vec<T>
as an array,
if its size exactly matches that of the requested array.
Examples
assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
If the length doesn’t match, the input comes back in Err
:
let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
If you’re fine with just getting a prefix of the Vec<T>
,
you can call .truncate(N)
first.
let mut v = String::from("hello world").into_bytes();
v.sort();
v.truncate(2);
let [a, b]: [_; 2] = v.try_into().unwrap();
assert_eq!(a, b' ');
assert_eq!(b, b'd');
source§impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]where
A: Allocator,
impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]where A: Allocator,
source§fn try_from(vec: Vec<T, A>) -> Result<[T; N], Vec<T, A>>
fn try_from(vec: Vec<T, A>) -> Result<[T; N], Vec<T, A>>
Gets the entire contents of the Vec<T>
as an array,
if its size exactly matches that of the requested array.
Examples
assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3]));
assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));
If the length doesn’t match, the input comes back in Err
:
let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into();
assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
If you’re fine with just getting a prefix of the Vec<T>
,
you can call .truncate(N)
first.
let mut v = String::from("hello world").into_bytes();
v.sort();
v.truncate(2);
let [a, b]: [_; 2] = v.try_into().unwrap();
assert_eq!(a, b' ');
assert_eq!(b, b'd');
source§impl<T, const N: usize> ULE for [T; N]where
T: ULE,
impl<T, const N: usize> ULE for [T; N]where T: ULE,
source§fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError>
fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError>
&[u8]
. Read moresource§fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ZeroVecError>
fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ZeroVecError>
source§unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &[Self]
unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &[Self]
&[u8]
, and return it as &[Self]
with the same lifetime, assuming
that this byte slice has previously been run through Self::parse_byte_slice()
with
success. Read moresource§impl<'a, T, const N: usize> Yokeable<'a> for [T; N]where
T: Yokeable<'a>,
impl<'a, T, const N: usize> Yokeable<'a> for [T; N]where T: Yokeable<'a>,
§type Output = [<T as Yokeable<'a>>::Output; N]
type Output = [<T as Yokeable<'a>>::Output; N]
Self
with the 'static
replaced with 'a
, i.e. Self<'a>