• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // check-pass
2 
3 #![feature(adt_const_params, generic_const_exprs)]
4 #![allow(incomplete_features)]
5 
6 mod lib {
7     const N_ISLANDS: usize = 4;
8     const N_BRIDGES: usize = 7;
9     const BRIDGES: [(usize, usize); 7] = [(0, 1), (0, 1), (0, 2), (0, 3), (0, 3), (1, 2), (2, 3)];
10 
11     pub type Matrix = [[usize; N_ISLANDS]; N_ISLANDS];
12 
13     const EMPTY_MATRIX: Matrix = [[0; N_ISLANDS]; N_ISLANDS];
14 
build(mut matrix: Matrix, (to, from): (usize, usize)) -> Matrix15     const fn build(mut matrix: Matrix, (to, from): (usize, usize)) -> Matrix {
16         matrix[to][from] += 1;
17         matrix[from][to] += 1;
18         matrix
19     }
20 
walk(mut matrix: Matrix, from: usize, to: usize) -> Matrix21     pub const fn walk(mut matrix: Matrix, from: usize, to: usize) -> Matrix {
22         matrix[from][to] -= 1;
23         matrix[to][from] -= 1;
24         matrix
25     }
26 
to_matrix(bridges: [(usize, usize); N_BRIDGES]) -> Matrix27     const fn to_matrix(bridges: [(usize, usize); N_BRIDGES]) -> Matrix {
28         let matrix = EMPTY_MATRIX;
29 
30         let matrix = build(matrix, bridges[0]);
31         let matrix = build(matrix, bridges[1]);
32         let matrix = build(matrix, bridges[2]);
33         let matrix = build(matrix, bridges[3]);
34         let matrix = build(matrix, bridges[4]);
35         let matrix = build(matrix, bridges[5]);
36         let matrix = build(matrix, bridges[6]);
37 
38         matrix
39     }
40 
41     const BRIDGE_MATRIX: [[usize; N_ISLANDS]; N_ISLANDS] = to_matrix(BRIDGES);
42 
43     pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> {
44         _p: (),
45     }
46 
47     impl Walk<0, BRIDGE_MATRIX> {
new() -> Self48         pub const fn new() -> Self {
49             Self { _p: () }
50         }
51     }
52 
53     impl<const CURRENT: usize, const REMAINING: Matrix> Walk<CURRENT, REMAINING> {
proceed_to<const NEXT: usize>( self, ) -> Walk<NEXT,54         pub fn proceed_to<const NEXT: usize>(
55             self,
56         ) -> Walk<NEXT, { walk(REMAINING, CURRENT, NEXT) }> {
57             Walk { _p: () }
58         }
59     }
60 
61     pub struct Trophy {
62         _p: (),
63     }
64 
65     impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {
collect_prize(self) -> Trophy66         pub fn collect_prize(self) -> Trophy {
67             Trophy { _p: () }
68         }
69     }
70 }
71 
72 pub use lib::{Trophy, Walk};
73 
main()74 fn main() {
75     // Example, taking the first step
76     let _ = Walk::new().proceed_to::<1>();
77 
78     // Don't be so eager to collect the trophy
79     // let trophy = Walk::new()
80     //     .proceed_to::<1>()
81     //     .proceed_to::<0>()
82     //     .collect_prize();
83 
84     // Can't just make a Trophy out of thin air, you must earn it
85     // let trophy: Trophy = Trophy { _p: () };
86 
87     // Can you collect the Trophy?
88 }
89