@@ -9,13 +9,18 @@ pub struct Arrays<I: Iterator, const N: usize>
9
9
}
10
10
11
11
impl < I : Iterator , const N : usize > Arrays < I , N > {
12
+ /// Creates a new Arrays iterator.
13
+ /// See [`.arrays()`](crate::Itertools::arrays) for more information.
12
14
pub fn new ( iter : I ) -> Self {
13
15
Self { iter, buf : ArrayVec :: new ( ) }
14
16
}
15
17
}
16
18
impl < I : Iterator , const N : usize > Arrays < I , N > where I :: Item : Clone {
17
- pub fn remaining ( self ) -> Vec < I :: Item > {
18
- self . buf . into_vec ( )
19
+ /// Returns any remaining data left in the iterator.
20
+ /// This is useful if the iterator has left over values
21
+ /// that didn't fit into the array size.
22
+ pub fn remaining ( & self ) -> & [ I :: Item ] {
23
+ self . buf . into_slice ( )
19
24
}
20
25
}
21
26
@@ -36,19 +41,23 @@ impl<I: Iterator, const N: usize> Iterator for Arrays<I, N> {
36
41
}
37
42
}
38
43
44
+ /// Reads N elements from the iter, returning them in an array. If there's not enough
45
+ /// elements, returns None.
39
46
pub fn next_array < I : Iterator , const N : usize > ( iter : & mut I ) -> Option < [ I :: Item ; N ] > {
40
47
let mut array_vec = ArrayVec :: new ( ) ;
41
48
42
- // SAFETY:
43
- // ArrayVec::push_unchecked is safe as long as len < N.
44
- // This is guaranteed by the for loop
45
49
unsafe {
50
+ // SAFETY:
51
+ // ArrayVec::push_unchecked is safe as long as len < N.
52
+ // This is guaranteed by the for loop
46
53
for _ in 0 ..N {
47
54
array_vec. push_unchecked ( iter. next ( ) ?)
48
55
}
49
- }
50
56
51
- array_vec. into_array ( )
57
+ // SAFETY:
58
+ // We have guaranteed to have filled all N elements
59
+ Some ( array_vec. into_array_unchecked ( ) )
60
+ }
52
61
}
53
62
54
63
// ArrayVec is a safe wrapper around a [T; N].
@@ -70,23 +79,44 @@ impl<T, const N: usize> Drop for ArrayVec<T, N> {
70
79
}
71
80
72
81
impl < T , const N : usize > ArrayVec < T , N > {
82
+ /// Creates a new empty ArrayVec
73
83
pub const fn new ( ) -> Self {
74
84
Self {
75
85
data : std:: mem:: MaybeUninit :: uninit ( ) ,
76
86
len : 0 ,
77
87
}
78
88
}
79
89
90
+ /// Returns the number of initialised elements in the ArrayVec
91
+ pub fn len ( & self ) -> usize {
92
+ self . len
93
+ }
94
+
95
+ /// Returns whether the ArrayVec is empty
96
+ pub fn is_empty ( & self ) -> bool {
97
+ self . len == 0
98
+ }
99
+
100
+ /// Returns whether the ArrayVec is full
101
+ pub fn is_full ( & self ) -> bool {
102
+ self . len == N
103
+ }
104
+
105
+ /// Push a value into the ArrayVec
106
+ ///
107
+ /// Panics:
108
+ /// If the ArrayVec is full, this function will panic
80
109
pub fn push ( & mut self , v : T ) {
81
- assert ! ( self . len < N ) ;
82
- // SAFETY: asserts that len < N.
110
+ assert ! ( ! self . is_full ( ) ) ;
111
+ // SAFETY: asserted that self is not full
83
112
unsafe { self . push_unchecked ( v) }
84
113
}
85
114
86
- // Unsafety:
87
- // len must be less than N. If `len < N` is guaranteed, this operation is safe
88
- // This is because the contract of ArrayVec guarantees that if len < N, then the value
89
- // at len is valid and uninitialised.
115
+ /// Push a value into the ArrayVec
116
+ ///
117
+ /// Unsafety:
118
+ /// The ArrayVec must not be full. If the ArrayVec is full, this function will try write data
119
+ /// out-of-bounds.
90
120
pub unsafe fn push_unchecked ( & mut self , v : T ) {
91
121
// The contract of ArrayVec guarantees that the value at self.len, if < N,
92
122
// is uninitialised, and therefore does not need dropping. So use write to
@@ -96,12 +126,9 @@ impl<T, const N: usize> ArrayVec<T, N> {
96
126
self . len += 1 ;
97
127
}
98
128
99
- pub fn len ( & self ) -> usize {
100
- self . len
101
- }
102
-
129
+ /// If the ArrayVec is full, returns the data owned. Otherwise, returns None
103
130
pub fn into_array ( self ) -> Option < [ T ; N ] > {
104
- if self . len == N {
131
+ if self . is_full ( ) {
105
132
// SAFETY:
106
133
// If len == N, then all the data is initialised and this is safe
107
134
unsafe { Some ( self . into_array_unchecked ( ) ) }
@@ -110,35 +137,37 @@ impl<T, const N: usize> ArrayVec<T, N> {
110
137
}
111
138
}
112
139
113
- // Unsafety:
114
- // len must be equal to N. If `len == N` is guaranteed, this operation is safe.
115
- // This is because the contract of ArrayVec guarantees that if len == N, all the values
116
- // have been initialised correctly.
140
+ /// Returns the data owned by the ArrayVec
141
+ ///
142
+ /// Unsafety:
143
+ /// The ArrayVec must be full. If it is not full, some of the values in the array will be
144
+ /// unintialised. This will cause undefined behaviour
117
145
unsafe fn into_array_unchecked ( mut self ) -> [ T ; N ] {
118
146
// move out without dropping
119
147
let data = std:: mem:: replace ( & mut self . data , std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) ) ;
120
148
std:: mem:: forget ( self ) ;
121
149
data. assume_init ( )
122
150
}
123
151
124
- // Unsafety:
125
- // len must be equal to N. If `len == N` is guaranteed, this operation is safe.
126
- // This is because the contract of ArrayVec guarantees that if len == N, all the values
127
- // have been initialised correctly.
152
+ /// Returns the data owned by the ArrayVec, resetting the ArrayVec to an empty state
153
+ ///
154
+ /// Unsafety:
155
+ /// len must be equal to N. If `len == N` is guaranteed, this operation is safe.
156
+ /// This is because the contract of ArrayVec guarantees that if len == N, all the values
157
+ /// have been initialised correctly.
128
158
unsafe fn take_unchecked ( & mut self ) -> [ T ; N ] {
129
159
let data = std:: mem:: replace ( & mut self . data , std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) ) ;
130
160
self . len = 0 ;
131
161
data. assume_init ( )
132
162
}
133
- }
134
163
135
- impl < T : Clone , const N : usize > ArrayVec < T , N > {
136
- pub fn into_vec ( mut self ) -> Vec < T > {
164
+ /// Borrows the initialised data in the ArrayVec
165
+ pub fn into_slice ( & self ) -> & [ T ] {
137
166
unsafe {
138
- let data = std:: mem:: replace ( & mut self . data , std:: mem:: MaybeUninit :: uninit ( ) . assume_init ( ) ) ;
139
- let len = self . len ;
140
- std:: mem:: forget ( self ) ;
141
- std:: slice:: from_raw_parts ( data. as_ptr ( ) as * const T , len ) . to_vec ( )
167
+ // let data = std::mem::replace(&mut self.data, std::mem::MaybeUninit::uninit().assume_init());
168
+ // let len = self.len;
169
+ // std::mem::forget(self);
170
+ std:: slice:: from_raw_parts ( self . data . as_ptr ( ) as * const T , self . len )
142
171
}
143
172
}
144
173
}
0 commit comments