crunchy/home/lusia/Projects/p2p-chat/target/debug/build/crunchy-4ba36b5cc3d75909/out/
lib.rs

1
2/// Unroll the given for loop
3///
4/// Example:
5///
6/// ```ignore
7/// unroll! {
8///   for i in 0..5 {
9///     println!("Iteration {}", i);
10///   }
11/// }
12/// ```
13///
14/// will expand into:
15///
16/// ```ignore
17/// { println!("Iteration {}", 0); }
18/// { println!("Iteration {}", 1); }
19/// { println!("Iteration {}", 2); }
20/// { println!("Iteration {}", 3); }
21/// { println!("Iteration {}", 4); }
22/// ```
23#[macro_export]
24macro_rules! unroll {
25    (for $v:ident in 0..0 $c:block) => {};
26
27    (for $v:ident < $max:tt in ($start:tt..$end:tt).step_by($val:expr) {$($c:tt)*}) => {
28        {
29            let step = $val;
30            let start = $start;
31            let end = start + ($end - start) / step;
32            unroll! {
33                for val < $max in start..end {
34                    let $v: usize = ((val - start) * step) + start;
35
36                    $($c)*
37                }
38            }
39        }
40    };
41
42    (for $v:ident in ($start:tt..$end:tt).step_by($val:expr) {$($c:tt)*}) => {
43        unroll! {
44            for $v < $end in ($start..$end).step_by($val) {$($c)*}
45        }
46    };
47
48    (for $v:ident in ($start:tt..$end:tt) {$($c:tt)*}) => {
49        unroll!{
50            for $v in $start..$end {$($c)*}
51        }
52    };
53
54    (for $v:ident in $start:tt..$end:tt {$($c:tt)*}) => {
55        #[allow(non_upper_case_globals)]
56        #[allow(unused_comparisons)]
57        {
58            unroll!(@$v, 0, $end, {
59                    if $v >= $start {$($c)*}
60                }
61            );
62        }
63    };
64
65    (for $v:ident < $max:tt in $start:tt..$end:tt $c:block) => {
66        #[allow(non_upper_case_globals)]
67        {
68            let range = $start..$end;
69            assert!(
70                $max >= range.end,
71                "`{}` out of range `{:?}`",
72                stringify!($max),
73                range,
74            );
75            unroll!(
76                @$v,
77                0,
78                $max,
79                {
80                    if $v >= range.start && $v < range.end {
81                        $c
82                    }
83                }
84            );
85        }
86    };
87
88    (for $v:ident in 0..$end:tt {$($statement:tt)*}) => {
89        #[allow(non_upper_case_globals)]
90        { unroll!(@$v, 0, $end, {$($statement)*}); }
91    };
92
93    (@$v:ident, $a:expr, 0, $c:block) => {
94        { const $v: usize = $a; $c }
95    };
96
97    (@$v:ident, $a:expr, 1, $c:block) => {
98        { const $v: usize = $a; $c }
99    };
100
101    (@$v:ident, $a:expr, 2, $c:block) => {
102        { const $v: usize = $a; $c }
103        { const $v: usize = $a + 1; $c }
104    };
105
106    (@$v:ident, $a:expr, 3, $c:block) => {
107        { const $v: usize = $a; $c }
108        { const $v: usize = $a + 1; $c }
109        { const $v: usize = $a + 2; $c }
110    };
111
112    (@$v:ident, $a:expr, 4, $c:block) => {
113        { const $v: usize = $a; $c }
114        { const $v: usize = $a + 1; $c }
115        { const $v: usize = $a + 2; $c }
116        { const $v: usize = $a + 3; $c }
117    };
118
119    (@$v:ident, $a:expr, 5, $c:block) => {
120        { const $v: usize = $a; $c }
121        { const $v: usize = $a + 1; $c }
122        { const $v: usize = $a + 2; $c }
123        { const $v: usize = $a + 3; $c }
124        { const $v: usize = $a + 4; $c }
125    };
126
127    (@$v:ident, $a:expr, 6, $c:block) => {
128        { const $v: usize = $a; $c }
129        { const $v: usize = $a + 1; $c }
130        { const $v: usize = $a + 2; $c }
131        { const $v: usize = $a + 3; $c }
132        { const $v: usize = $a + 4; $c }
133        { const $v: usize = $a + 5; $c }
134    };
135
136    (@$v:ident, $a:expr, 7, $c:block) => {
137        { const $v: usize = $a; $c }
138        { const $v: usize = $a + 1; $c }
139        { const $v: usize = $a + 2; $c }
140        { const $v: usize = $a + 3; $c }
141        { const $v: usize = $a + 4; $c }
142        { const $v: usize = $a + 5; $c }
143        { const $v: usize = $a + 6; $c }
144    };
145
146    (@$v:ident, $a:expr, 8, $c:block) => {
147        { const $v: usize = $a; $c }
148        { const $v: usize = $a + 1; $c }
149        { const $v: usize = $a + 2; $c }
150        { const $v: usize = $a + 3; $c }
151        { const $v: usize = $a + 4; $c }
152        { const $v: usize = $a + 5; $c }
153        { const $v: usize = $a + 6; $c }
154        { const $v: usize = $a + 7; $c }
155    };
156
157    (@$v:ident, $a:expr, 9, $c:block) => {
158        { const $v: usize = $a; $c }
159        { const $v: usize = $a + 1; $c }
160        { const $v: usize = $a + 2; $c }
161        { const $v: usize = $a + 3; $c }
162        { const $v: usize = $a + 4; $c }
163        { const $v: usize = $a + 5; $c }
164        { const $v: usize = $a + 6; $c }
165        { const $v: usize = $a + 7; $c }
166        { const $v: usize = $a + 8; $c }
167    };
168
169    (@$v:ident, $a:expr, 10, $c:block) => {
170        { const $v: usize = $a; $c }
171        { const $v: usize = $a + 1; $c }
172        { const $v: usize = $a + 2; $c }
173        { const $v: usize = $a + 3; $c }
174        { const $v: usize = $a + 4; $c }
175        { const $v: usize = $a + 5; $c }
176        { const $v: usize = $a + 6; $c }
177        { const $v: usize = $a + 7; $c }
178        { const $v: usize = $a + 8; $c }
179        { const $v: usize = $a + 9; $c }
180    };
181
182    (@$v:ident, $a:expr, 11, $c:block) => {
183        { const $v: usize = $a; $c }
184        { const $v: usize = $a + 1; $c }
185        { const $v: usize = $a + 2; $c }
186        { const $v: usize = $a + 3; $c }
187        { const $v: usize = $a + 4; $c }
188        { const $v: usize = $a + 5; $c }
189        { const $v: usize = $a + 6; $c }
190        { const $v: usize = $a + 7; $c }
191        { const $v: usize = $a + 8; $c }
192        { const $v: usize = $a + 9; $c }
193        { const $v: usize = $a + 10; $c }
194    };
195
196    (@$v:ident, $a:expr, 12, $c:block) => {
197        { const $v: usize = $a; $c }
198        { const $v: usize = $a + 1; $c }
199        { const $v: usize = $a + 2; $c }
200        { const $v: usize = $a + 3; $c }
201        { const $v: usize = $a + 4; $c }
202        { const $v: usize = $a + 5; $c }
203        { const $v: usize = $a + 6; $c }
204        { const $v: usize = $a + 7; $c }
205        { const $v: usize = $a + 8; $c }
206        { const $v: usize = $a + 9; $c }
207        { const $v: usize = $a + 10; $c }
208        { const $v: usize = $a + 11; $c }
209    };
210
211    (@$v:ident, $a:expr, 13, $c:block) => {
212        { const $v: usize = $a; $c }
213        { const $v: usize = $a + 1; $c }
214        { const $v: usize = $a + 2; $c }
215        { const $v: usize = $a + 3; $c }
216        { const $v: usize = $a + 4; $c }
217        { const $v: usize = $a + 5; $c }
218        { const $v: usize = $a + 6; $c }
219        { const $v: usize = $a + 7; $c }
220        { const $v: usize = $a + 8; $c }
221        { const $v: usize = $a + 9; $c }
222        { const $v: usize = $a + 10; $c }
223        { const $v: usize = $a + 11; $c }
224        { const $v: usize = $a + 12; $c }
225    };
226
227    (@$v:ident, $a:expr, 14, $c:block) => {
228        { const $v: usize = $a; $c }
229        { const $v: usize = $a + 1; $c }
230        { const $v: usize = $a + 2; $c }
231        { const $v: usize = $a + 3; $c }
232        { const $v: usize = $a + 4; $c }
233        { const $v: usize = $a + 5; $c }
234        { const $v: usize = $a + 6; $c }
235        { const $v: usize = $a + 7; $c }
236        { const $v: usize = $a + 8; $c }
237        { const $v: usize = $a + 9; $c }
238        { const $v: usize = $a + 10; $c }
239        { const $v: usize = $a + 11; $c }
240        { const $v: usize = $a + 12; $c }
241        { const $v: usize = $a + 13; $c }
242    };
243
244    (@$v:ident, $a:expr, 15, $c:block) => {
245        { const $v: usize = $a; $c }
246        { const $v: usize = $a + 1; $c }
247        { const $v: usize = $a + 2; $c }
248        { const $v: usize = $a + 3; $c }
249        { const $v: usize = $a + 4; $c }
250        { const $v: usize = $a + 5; $c }
251        { const $v: usize = $a + 6; $c }
252        { const $v: usize = $a + 7; $c }
253        { const $v: usize = $a + 8; $c }
254        { const $v: usize = $a + 9; $c }
255        { const $v: usize = $a + 10; $c }
256        { const $v: usize = $a + 11; $c }
257        { const $v: usize = $a + 12; $c }
258        { const $v: usize = $a + 13; $c }
259        { const $v: usize = $a + 14; $c }
260    };
261
262    (@$v:ident, $a:expr, 16, $c:block) => {
263        { const $v: usize = $a; $c }
264        { const $v: usize = $a + 1; $c }
265        { const $v: usize = $a + 2; $c }
266        { const $v: usize = $a + 3; $c }
267        { const $v: usize = $a + 4; $c }
268        { const $v: usize = $a + 5; $c }
269        { const $v: usize = $a + 6; $c }
270        { const $v: usize = $a + 7; $c }
271        { const $v: usize = $a + 8; $c }
272        { const $v: usize = $a + 9; $c }
273        { const $v: usize = $a + 10; $c }
274        { const $v: usize = $a + 11; $c }
275        { const $v: usize = $a + 12; $c }
276        { const $v: usize = $a + 13; $c }
277        { const $v: usize = $a + 14; $c }
278        { const $v: usize = $a + 15; $c }
279    };
280
281    (@$v:ident, $a:expr, 17, $c:block) => {
282        unroll!(@$v, $a, 16, $c);
283        { const $v: usize = $a + 16; $c }
284    };
285
286    (@$v:ident, $a:expr, 18, $c:block) => {
287        unroll!(@$v, $a, 9, $c);
288        unroll!(@$v, $a + 9, 9, $c);
289    };
290
291    (@$v:ident, $a:expr, 19, $c:block) => {
292        unroll!(@$v, $a, 18, $c);
293        { const $v: usize = $a + 18; $c }
294    };
295
296    (@$v:ident, $a:expr, 20, $c:block) => {
297        unroll!(@$v, $a, 10, $c);
298        unroll!(@$v, $a + 10, 10, $c);
299    };
300
301    (@$v:ident, $a:expr, 21, $c:block) => {
302        unroll!(@$v, $a, 20, $c);
303        { const $v: usize = $a + 20; $c }
304    };
305
306    (@$v:ident, $a:expr, 22, $c:block) => {
307        unroll!(@$v, $a, 11, $c);
308        unroll!(@$v, $a + 11, 11, $c);
309    };
310
311    (@$v:ident, $a:expr, 23, $c:block) => {
312        unroll!(@$v, $a, 22, $c);
313        { const $v: usize = $a + 22; $c }
314    };
315
316    (@$v:ident, $a:expr, 24, $c:block) => {
317        unroll!(@$v, $a, 12, $c);
318        unroll!(@$v, $a + 12, 12, $c);
319    };
320
321    (@$v:ident, $a:expr, 25, $c:block) => {
322        unroll!(@$v, $a, 24, $c);
323        { const $v: usize = $a + 24; $c }
324    };
325
326    (@$v:ident, $a:expr, 26, $c:block) => {
327        unroll!(@$v, $a, 13, $c);
328        unroll!(@$v, $a + 13, 13, $c);
329    };
330
331    (@$v:ident, $a:expr, 27, $c:block) => {
332        unroll!(@$v, $a, 26, $c);
333        { const $v: usize = $a + 26; $c }
334    };
335
336    (@$v:ident, $a:expr, 28, $c:block) => {
337        unroll!(@$v, $a, 14, $c);
338        unroll!(@$v, $a + 14, 14, $c);
339    };
340
341    (@$v:ident, $a:expr, 29, $c:block) => {
342        unroll!(@$v, $a, 28, $c);
343        { const $v: usize = $a + 28; $c }
344    };
345
346    (@$v:ident, $a:expr, 30, $c:block) => {
347        unroll!(@$v, $a, 15, $c);
348        unroll!(@$v, $a + 15, 15, $c);
349    };
350
351    (@$v:ident, $a:expr, 31, $c:block) => {
352        unroll!(@$v, $a, 30, $c);
353        { const $v: usize = $a + 30; $c }
354    };
355
356    (@$v:ident, $a:expr, 32, $c:block) => {
357        unroll!(@$v, $a, 16, $c);
358        unroll!(@$v, $a + 16, 16, $c);
359    };
360
361    (@$v:ident, $a:expr, 33, $c:block) => {
362        unroll!(@$v, $a, 32, $c);
363        { const $v: usize = $a + 32; $c }
364    };
365
366    (@$v:ident, $a:expr, 34, $c:block) => {
367        unroll!(@$v, $a, 17, $c);
368        unroll!(@$v, $a + 17, 17, $c);
369    };
370
371    (@$v:ident, $a:expr, 35, $c:block) => {
372        unroll!(@$v, $a, 34, $c);
373        { const $v: usize = $a + 34; $c }
374    };
375
376    (@$v:ident, $a:expr, 36, $c:block) => {
377        unroll!(@$v, $a, 18, $c);
378        unroll!(@$v, $a + 18, 18, $c);
379    };
380
381    (@$v:ident, $a:expr, 37, $c:block) => {
382        unroll!(@$v, $a, 36, $c);
383        { const $v: usize = $a + 36; $c }
384    };
385
386    (@$v:ident, $a:expr, 38, $c:block) => {
387        unroll!(@$v, $a, 19, $c);
388        unroll!(@$v, $a + 19, 19, $c);
389    };
390
391    (@$v:ident, $a:expr, 39, $c:block) => {
392        unroll!(@$v, $a, 38, $c);
393        { const $v: usize = $a + 38; $c }
394    };
395
396    (@$v:ident, $a:expr, 40, $c:block) => {
397        unroll!(@$v, $a, 20, $c);
398        unroll!(@$v, $a + 20, 20, $c);
399    };
400
401    (@$v:ident, $a:expr, 41, $c:block) => {
402        unroll!(@$v, $a, 40, $c);
403        { const $v: usize = $a + 40; $c }
404    };
405
406    (@$v:ident, $a:expr, 42, $c:block) => {
407        unroll!(@$v, $a, 21, $c);
408        unroll!(@$v, $a + 21, 21, $c);
409    };
410
411    (@$v:ident, $a:expr, 43, $c:block) => {
412        unroll!(@$v, $a, 42, $c);
413        { const $v: usize = $a + 42; $c }
414    };
415
416    (@$v:ident, $a:expr, 44, $c:block) => {
417        unroll!(@$v, $a, 22, $c);
418        unroll!(@$v, $a + 22, 22, $c);
419    };
420
421    (@$v:ident, $a:expr, 45, $c:block) => {
422        unroll!(@$v, $a, 44, $c);
423        { const $v: usize = $a + 44; $c }
424    };
425
426    (@$v:ident, $a:expr, 46, $c:block) => {
427        unroll!(@$v, $a, 23, $c);
428        unroll!(@$v, $a + 23, 23, $c);
429    };
430
431    (@$v:ident, $a:expr, 47, $c:block) => {
432        unroll!(@$v, $a, 46, $c);
433        { const $v: usize = $a + 46; $c }
434    };
435
436    (@$v:ident, $a:expr, 48, $c:block) => {
437        unroll!(@$v, $a, 24, $c);
438        unroll!(@$v, $a + 24, 24, $c);
439    };
440
441    (@$v:ident, $a:expr, 49, $c:block) => {
442        unroll!(@$v, $a, 48, $c);
443        { const $v: usize = $a + 48; $c }
444    };
445
446    (@$v:ident, $a:expr, 50, $c:block) => {
447        unroll!(@$v, $a, 25, $c);
448        unroll!(@$v, $a + 25, 25, $c);
449    };
450
451    (@$v:ident, $a:expr, 51, $c:block) => {
452        unroll!(@$v, $a, 50, $c);
453        { const $v: usize = $a + 50; $c }
454    };
455
456    (@$v:ident, $a:expr, 52, $c:block) => {
457        unroll!(@$v, $a, 26, $c);
458        unroll!(@$v, $a + 26, 26, $c);
459    };
460
461    (@$v:ident, $a:expr, 53, $c:block) => {
462        unroll!(@$v, $a, 52, $c);
463        { const $v: usize = $a + 52; $c }
464    };
465
466    (@$v:ident, $a:expr, 54, $c:block) => {
467        unroll!(@$v, $a, 27, $c);
468        unroll!(@$v, $a + 27, 27, $c);
469    };
470
471    (@$v:ident, $a:expr, 55, $c:block) => {
472        unroll!(@$v, $a, 54, $c);
473        { const $v: usize = $a + 54; $c }
474    };
475
476    (@$v:ident, $a:expr, 56, $c:block) => {
477        unroll!(@$v, $a, 28, $c);
478        unroll!(@$v, $a + 28, 28, $c);
479    };
480
481    (@$v:ident, $a:expr, 57, $c:block) => {
482        unroll!(@$v, $a, 56, $c);
483        { const $v: usize = $a + 56; $c }
484    };
485
486    (@$v:ident, $a:expr, 58, $c:block) => {
487        unroll!(@$v, $a, 29, $c);
488        unroll!(@$v, $a + 29, 29, $c);
489    };
490
491    (@$v:ident, $a:expr, 59, $c:block) => {
492        unroll!(@$v, $a, 58, $c);
493        { const $v: usize = $a + 58; $c }
494    };
495
496    (@$v:ident, $a:expr, 60, $c:block) => {
497        unroll!(@$v, $a, 30, $c);
498        unroll!(@$v, $a + 30, 30, $c);
499    };
500
501    (@$v:ident, $a:expr, 61, $c:block) => {
502        unroll!(@$v, $a, 60, $c);
503        { const $v: usize = $a + 60; $c }
504    };
505
506    (@$v:ident, $a:expr, 62, $c:block) => {
507        unroll!(@$v, $a, 31, $c);
508        unroll!(@$v, $a + 31, 31, $c);
509    };
510
511    (@$v:ident, $a:expr, 63, $c:block) => {
512        unroll!(@$v, $a, 62, $c);
513        { const $v: usize = $a + 62; $c }
514    };
515
516    (@$v:ident, $a:expr, 64, $c:block) => {
517        unroll!(@$v, $a, 32, $c);
518        unroll!(@$v, $a + 32, 32, $c);
519    };
520
521}
522
523
524#[cfg(all(test, feature = "std"))]
525mod tests {
526    #[test]
527    fn invalid_range() {
528        let mut a: Vec<usize> = vec![];
529        unroll! {
530                for i in (5..4) {
531                    a.push(i);
532                }
533            }
534        assert_eq!(a, vec![]);
535    }
536
537    #[test]
538    fn start_at_one_with_step() {
539        let mut a: Vec<usize> = vec![];
540        unroll! {
541                for i in (2..4).step_by(1) {
542                    a.push(i);
543                }
544            }
545        assert_eq!(a, vec![2, 3]);
546    }
547
548    #[test]
549    fn start_at_one() {
550        let mut a: Vec<usize> = vec![];
551        unroll! {
552                for i in 1..4 {
553                    a.push(i);
554                }
555            }
556        assert_eq!(a, vec![1, 2, 3]);
557    }
558
559    #[test]
560    fn test_all() {
561        {
562            let a: Vec<usize> = vec![];
563            unroll! {
564                for i in 0..0 {
565                    a.push(i);
566                }
567            }
568            assert_eq!(a, (0..0).collect::<Vec<usize>>());
569        }
570        {
571            let mut a: Vec<usize> = vec![];
572            unroll! {
573                for i in 0..1 {
574                    a.push(i);
575                }
576            }
577            assert_eq!(a, (0..1).collect::<Vec<usize>>());
578        }
579        {
580            let mut a: Vec<usize> = vec![];
581            unroll! {
582                for i in 0..64 {
583                    a.push(i);
584                }
585            }
586            assert_eq!(a, (0..64).collect::<Vec<usize>>());
587        }
588        {
589            let mut a: Vec<usize> = vec![];
590            let start = 64 / 4;
591            let end = start * 3;
592            unroll! {
593                for i < 64 in start..end {
594                    a.push(i);
595                }
596            }
597            assert_eq!(a, (start..end).collect::<Vec<usize>>());
598        }
599        {
600            let mut a: Vec<usize> = vec![];
601            unroll! {
602                for i in (0..64).step_by(2) {
603                    a.push(i);
604                }
605            }
606            assert_eq!(a, (0..64 / 2).map(|x| x * 2).collect::<Vec<usize>>());
607        }
608        {
609            let mut a: Vec<usize> = vec![];
610            let start = 64 / 4;
611            let end = start * 3;
612            unroll! {
613                for i < 64 in (start..end).step_by(2) {
614                    a.push(i);
615                }
616            }
617            assert_eq!(a, (start..end).filter(|x| x % 2 == 0).collect::<Vec<usize>>());
618        }
619    }
620}