Reputation: 608
For example,
struct Foo<T, N: ArrayLength<T>> {
data: GenericArray<T, N>
}
I want the length of the data array to be limited within a range like 100
to 1024
bytes. Then, if the Foo
is used like let f: Foo<u8, generic_array::typenum::U8> = Foo {data: GenericArray::default()};
, it will cause a compilation error.
Upvotes: 1
Views: 252
Reputation: 8764
I played around a little with typenum
, this works:
use generic_array::{ArrayLength, GenericArray};
use typenum::{IsGreaterOrEqual, IsLessOrEqual, Same, B1, U100, U1024, U99};
struct Foo<T, N>
where
N: ArrayLength<T>,
N: IsGreaterOrEqual<U100, Output = True>,
N: IsLessOrEqual<U1024, Output = True>,
{
data: GenericArray<T, N>,
}
fn main() {
let f: Foo<u8, U100> = Foo {
data: GenericArray::default(),
};
// Does not compile
let f: Foo<u8, U99> = Foo {
data: GenericArray::default(),
};
}
The IsGreaterOrEqual<M>
etc. traits, confusingly, are implemented even when N < M
. You have to get their result by looking at the associated Output
type. If it is B1
or its synonym True
, then N
is indeed greater than or equal to M
.
You might try to write a trait bound like <N as IsGreaterOrEqual<U100>>::Output == B1
, but that's not possible. You can constrain an associated type either like in the code example, or by using a helper trait in typenum
, Same
: <N as IsGreaterOrEqual<U100>>::Output: Same<B1>
.
Upvotes: 1
Reputation: 103
I think that what you want is Const Generics.
This feature exists in Rust, but it's still a work-in-progress. You can use it in nightly, and as far as I understand, there are some use cases that do work as intended.
Basically this allows you to have a generic type like this:
struct Foo<T, const N: usize> {
// Here you can use `N` as a `const`. For example, to define the size of a `std::array`
}
Here are links to have or follow for this feature:
All in all, I think it's a shame that you can't use it in stable just yet. But great things take time to be built.
Check if you can use it. There are some std
types that do use it today (and in stable because they have been audited to be sound and stable already). For example, std::array
uses it extensively since at least 1 year ago.
I hope this helps <3
Upvotes: 1