I ran into this problem while reading the struct definitions for page tables (used in an operating system source code targeting x86_64 platform). The definitions are shown below:
pub trait TableLevel {}
pub enum Level4 {}
pub enum Level3 {}
pub enum Level2 {}
pub enum Level1 {}
impl TableLevel for Level4 {}
impl TableLevel for Level3 {}
impl TableLevel for Level2 {}
impl TableLevel for Level1 {}
pub trait HierarchicalLevel: TableLevel {
type NextLevel: TableLevel;
}
impl HierarchicalLevel for Level4 {
type NextLevel = Level3;
}
impl HierarchicalLevel for Level3 {
type NextLevel = Level2;
}
impl HierarchicalLevel for Level2 {
type NextLevel = Level1;
}
This piece of Rust code seems not very clever. I'm wondering if I can parameterize the level number, e.g. 1,2,3,4. With C++, I can achieve this easily:
#include <type_traits>
#include <iostream>
template <unsigned L>
struct Level {
typedef Level<L-1> NextLevel;
};
template <>
struct Level<1> {};
int main() {
// The output below will give "1".
// It checks the type `Level<3>::NextLevel::NextLevel`
// and the type `Level<2>::NextLevel` are indeed the same type.
std::cout
<< std::is_same<Level<3>::NextLevel::NextLevel,
Level<2>::NextLevel>::value
<< std::endl;
return 0;
}
I tried to do the same thing in Rust, but I couldn't because Rust wouldn't allow me do to arithmetic operations with constant parameters.
#![feature(min_const_generics)]
struct Level<const LEVEL: usize> {}
impl <const LEVEL: usize> TableLevel for Level<LEVEL> {}
impl <const LEVEL: usize> HierarchicalLevel for Level<LEVEL> {
// Error message from the compiler:
// generic parameters may not be used in const operations
// cannot perform const operation using `LEVEL`
// help: const parameters may only be used as standalone arguments, i.e. `LEVEL`
type NextLevel = Level<{LEVEL - 1}>;
}
Is it possible to parameterize the level number in the current version (possibly nightly) of Rust?