1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::type_equals::TypeEquals;
use core::marker::Sized;
use core::mem::{MaybeUninit, transmute_copy, forget};
pub trait Init<T, I, V = ()>: Sized {
#[cfg_attr(feature = "std", doc = r##"
Constructing a Vec containing the values 0 to 4:
```rust
use higher_order_functions::Init;
let vec = Vec::<usize>::init_with(5, |i| i);
assert_eq!(vec, vec![0, 1, 2, 3, 4]);
```
"##)]
fn init_with<F: FnMut(I) -> T>(value: V, elem: F) -> Self;
fn init<F: FnMut(I) -> T>(elem: F) -> Self where V: TypeEquals<()> {
Self::init_with(().into(), elem)
}
}
impl<T, const N: usize> Init<T, usize> for [T; N] {
fn init_with<F: FnMut(usize) -> T>(_: (), mut elem: F) -> Self {
let mut contents: [MaybeUninit<T>; N] = MaybeUninit::uninit_array();
for i in 0..N {
contents[i] = MaybeUninit::new(elem(i));
}
let res = unsafe { transmute_copy(&contents) };
forget(contents);
res
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> Init<T, usize, usize> for lib::vec::Vec<T> {
fn init_with<F: FnMut(usize) -> T>(length: usize, mut elem: F) -> Self {
let mut value = lib::vec::Vec::with_capacity(length);
for i in 0..length {
value.push(elem(i));
}
value
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> Init<T, usize, usize> for lib::collections::LinkedList<T> {
fn init_with<F: FnMut(usize) -> T>(length: usize, mut elem: F) -> Self {
let mut value = lib::collections::LinkedList::new();
for i in 0..length {
value.push_back(elem(i));
}
value
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> Init<Option<T>, usize> for lib::collections::LinkedList<T> {
fn init_with<F: FnMut(usize) -> Option<T>>(_: (), mut elem: F) -> Self {
let mut value = lib::collections::LinkedList::new();
while let Some(x) = elem(value.len()) {
value.push_back(x);
}
value
}
}