I'm trying to migrate some C++ code to Rust. I have tried lots of different approaches but none of them compile.
I want a generic template that can handle different types and has a adjustable total size with a static field (const expression) Capacity:
template<class KeyType, class ValueType, int PageSize>
struct BplusTreeLeaf {
static const uint16_t Capacity = (PageSize-16)/(sizeof(KeyType)+sizeof(ValueType));
KeyType keys[Capacity];
ValueType values[Capacity];
};
I want to access the capacity from outside:
for(int i = 0; i < BplusTreeLeaf<x, y, 4096>::Capacity; i ++) { ... }
It seems that there is no way to do something like this in Rust, or at least in my understanding of Rust:
staticis not allowed in a struct and the documentation tells me to use macros- only types can be "templated" in Rust but not values or expressions. I can't even pass the total size as an argument to the struct definition
This is as far as I got:
macro_rules! BplusTreeLeaf {
($KeyType:ident, $ValueType:ident, $PageSize:expr) => {
static Capacity_: u16 = ($PageSize - 16) / (std::mem::size_of::<$KeyType>() + std::mem::size_of::<$ValueType>());
struct BplusTreeLeaf_ {
keys: [$KeyType, ..Capacity_],
values: [$ValueType, ..Capacity_],
}
}
}
BplusTreeLeaf!(u64, u64, 4096)
The compiler yields "expected constant expr for vector length" which is incorrect because I did not use "mut" for Capacity_, so it has to be a const expression. Even if it would work, Capacity_ and BplusTreeLeaf_ would still be in the global scope/namespace.
Have I misunderstood something elementary in Rust's design or is it just impossible? If it isn't possible now, is there something planned as a future feature or should I stay with C++ 11?