1 //! This crate implements a structure that can be used as a generic array type.use
2 //! Core Rust array types `[T; N]` can't be used generically with
3 //! respect to `N`, so for example this:
13 //! **generic-array** exports a `GenericArray<T,N>` type, which lets
14 //! the above be implemented as:
17 //! # use generic_array::{ArrayLength, GenericArray};
18 //! struct Foo<T, N: ArrayLength<T>> {
19 //! data: GenericArray<T,N>
23 //! The `ArrayLength<T>` trait is implemented by default for
24 //! [unsigned integer types](../typenum/uint/index.html) from
25 //! [typenum](../typenum/index.html).
27 //! For ease of use, an `arr!` macro is provided - example below:
31 //! # extern crate generic_array;
32 //! # extern crate typenum;
34 //! let array = arr![u32; 1, 2, 3];
35 //! assert_eq!(array[2], 3);
39 #![deny(missing_docs)]
42 #[cfg(feature = "serde")]
48 pub extern crate typenum
;
53 #[cfg(feature = "serde")]
56 use core
::iter
::FromIterator
;
57 use core
::marker
::PhantomData
;
58 use core
::mem
::ManuallyDrop
;
59 use core
::ops
::{Deref, DerefMut}
;
60 use core
::{mem, ptr, slice}
;
61 use typenum
::bit
::{B0, B1}
;
62 use typenum
::uint
::{UInt, UTerm, Unsigned}
;
64 #[cfg_attr(test, macro_use)]
71 pub use iter
::GenericArrayIter
;
74 /// Trait making `GenericArray` work, marking types to be used as length of an array
75 pub unsafe trait ArrayLength
<T
>: Unsigned
{
76 /// Associated type representing the array type for the number
80 unsafe impl<T
> ArrayLength
<T
> for UTerm
{
85 /// Internal type used to generate a struct of appropriate size
89 pub struct GenericArrayImplEven
<T
, U
> {
92 _marker
: PhantomData
<T
>,
95 impl<T
: Clone
, U
: Clone
> Clone
for GenericArrayImplEven
<T
, U
> {
96 fn clone(&self) -> GenericArrayImplEven
<T
, U
> {
97 GenericArrayImplEven
{
98 parent1
: self.parent1
.clone(),
99 parent2
: self.parent2
.clone(),
100 _marker
: PhantomData
,
105 impl<T
: Copy
, U
: Copy
> Copy
for GenericArrayImplEven
<T
, U
> {}
107 /// Internal type used to generate a struct of appropriate size
111 pub struct GenericArrayImplOdd
<T
, U
> {
117 impl<T
: Clone
, U
: Clone
> Clone
for GenericArrayImplOdd
<T
, U
> {
118 fn clone(&self) -> GenericArrayImplOdd
<T
, U
> {
119 GenericArrayImplOdd
{
120 parent1
: self.parent1
.clone(),
121 parent2
: self.parent2
.clone(),
122 data
: self.data
.clone(),
127 impl<T
: Copy
, U
: Copy
> Copy
for GenericArrayImplOdd
<T
, U
> {}
129 unsafe impl<T
, N
: ArrayLength
<T
>> ArrayLength
<T
> for UInt
<N
, B0
> {
131 type ArrayType
= GenericArrayImplEven
<T
, N
::ArrayType
>;
134 unsafe impl<T
, N
: ArrayLength
<T
>> ArrayLength
<T
> for UInt
<N
, B1
> {
136 type ArrayType
= GenericArrayImplOdd
<T
, N
::ArrayType
>;
139 /// Struct representing a generic array - `GenericArray<T, N>` works like [T; N]
141 pub struct GenericArray
<T
, U
: ArrayLength
<T
>> {
145 unsafe impl<T
: Send
, N
: ArrayLength
<T
>> Send
for GenericArray
<T
, N
> {}
146 unsafe impl<T
: Sync
, N
: ArrayLength
<T
>> Sync
for GenericArray
<T
, N
> {}
148 impl<T
, N
> Deref
for GenericArray
<T
, N
>
155 fn deref(&self) -> &[T
] {
156 unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) }
160 impl<T
, N
> DerefMut
for GenericArray
<T
, N
>
165 fn deref_mut(&mut self) -> &mut [T
] {
166 unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) }
170 /// Creates an array one element at a time using a mutable iterator
171 /// you can write to with `ptr::write`.
173 /// Incremenent the position while iterating to mark off created elements,
174 /// which will be dropped if `into_inner` is not called.
176 pub struct ArrayBuilder
<T
, N
: ArrayLength
<T
>> {
177 array
: ManuallyDrop
<GenericArray
<T
, N
>>,
181 impl<T
, N
: ArrayLength
<T
>> ArrayBuilder
<T
, N
> {
184 pub unsafe fn new() -> ArrayBuilder
<T
, N
> {
186 array
: ManuallyDrop
::new(mem
::uninitialized()),
191 /// Creates a mutable iterator for writing to the array using `ptr::write`.
193 /// Increment the position value given as a mutable reference as you iterate
194 /// to mark how many elements have been created.
197 pub unsafe fn iter_position(&mut self) -> (slice
::IterMut
<T
>, &mut usize) {
198 (self.array
.iter_mut(), &mut self.position
)
201 /// When done writing (assuming all elements have been written to),
202 /// get the inner array.
205 pub unsafe fn into_inner(self) -> GenericArray
<T
, N
> {
206 let array
= ptr
::read(&self.array
);
210 ManuallyDrop
::into_inner(array
)
214 impl<T
, N
: ArrayLength
<T
>> Drop
for ArrayBuilder
<T
, N
> {
216 for value
in &mut self.array
[..self.position
] {
218 ptr
::drop_in_place(value
);
224 /// Consumes an array.
226 /// Increment the position while iterating and any leftover elements
227 /// will be dropped if position does not go to N
229 pub struct ArrayConsumer
<T
, N
: ArrayLength
<T
>> {
230 array
: ManuallyDrop
<GenericArray
<T
, N
>>,
234 impl<T
, N
: ArrayLength
<T
>> ArrayConsumer
<T
, N
> {
237 pub unsafe fn new(array
: GenericArray
<T
, N
>) -> ArrayConsumer
<T
, N
> {
239 array
: ManuallyDrop
::new(array
),
244 /// Creates an iterator and mutable reference to the internal position
245 /// to keep track of consumed elements.
247 /// Increment the position as you iterate to mark off consumed elements
250 pub unsafe fn iter_position(&mut self) -> (slice
::Iter
<T
>, &mut usize) {
251 (self.array
.iter(), &mut self.position
)
255 impl<T
, N
: ArrayLength
<T
>> Drop
for ArrayConsumer
<T
, N
> {
257 for value
in &mut self.array
[self.position
..N
::to_usize()] {
259 ptr
::drop_in_place(value
);
265 impl<'a
, T
: 'a
, N
> IntoIterator
for &'a GenericArray
<T
, N
>
269 type IntoIter
= slice
::Iter
<'a
, T
>;
272 fn into_iter(self: &'a GenericArray
<T
, N
>) -> Self::IntoIter
{
273 self.as_slice().iter()
277 impl<'a
, T
: 'a
, N
> IntoIterator
for &'a
mut GenericArray
<T
, N
>
281 type IntoIter
= slice
::IterMut
<'a
, T
>;
282 type Item
= &'a
mut T
;
284 fn into_iter(self: &'a
mut GenericArray
<T
, N
>) -> Self::IntoIter
{
285 self.as_mut_slice().iter_mut()
289 impl<T
, N
> FromIterator
<T
> for GenericArray
<T
, N
>
293 fn from_iter
<I
>(iter
: I
) -> GenericArray
<T
, N
>
295 I
: IntoIterator
<Item
= T
>,
298 let mut destination
= ArrayBuilder
::new();
301 let (destination_iter
, position
) = destination
.iter_position();
303 for (src
, dst
) in iter
.into_iter().zip(destination_iter
) {
304 ptr
::write(dst
, src
);
310 if destination
.position
< N
::to_usize() {
311 from_iter_length_fail(destination
.position
, N
::to_usize());
314 destination
.into_inner()
321 fn from_iter_length_fail(length
: usize, expected
: usize) -> ! {
323 "GenericArray::from_iter received {} elements but expected {}",
328 unsafe impl<T
, N
> GenericSequence
<T
> for GenericArray
<T
, N
>
331 Self: IntoIterator
<Item
= T
>,
334 type Sequence
= Self;
336 fn generate
<F
>(mut f
: F
) -> GenericArray
<T
, N
>
338 F
: FnMut(usize) -> T
,
341 let mut destination
= ArrayBuilder
::new();
344 let (destination_iter
, position
) = destination
.iter_position();
346 for (i
, dst
) in destination_iter
.enumerate() {
347 ptr
::write(dst
, f(i
));
353 destination
.into_inner()
358 fn inverted_zip
<B
, U
, F
>(
360 lhs
: GenericArray
<B
, Self::Length
>,
362 ) -> MappedSequence
<GenericArray
<B
, Self::Length
>, B
, U
>
364 GenericArray
<B
, Self::Length
>:
365 GenericSequence
<B
, Length
= Self::Length
> + MappedGenericSequence
<B
, U
>,
366 Self: MappedGenericSequence
<T
, U
>,
367 Self::Length
: ArrayLength
<B
> + ArrayLength
<U
>,
368 F
: FnMut(B
, Self::Item
) -> U
,
371 let mut left
= ArrayConsumer
::new(lhs
);
372 let mut right
= ArrayConsumer
::new(self);
374 let (left_array_iter
, left_position
) = left
.iter_position();
375 let (right_array_iter
, right_position
) = right
.iter_position();
377 FromIterator
::from_iter(left_array_iter
.zip(right_array_iter
).map(|(l
, r
)| {
378 let left_value
= ptr
::read(l
);
379 let right_value
= ptr
::read(r
);
382 *right_position
+= 1;
384 f(left_value
, right_value
)
390 fn inverted_zip2
<B
, Lhs
, U
, F
>(self, lhs
: Lhs
, mut f
: F
) -> MappedSequence
<Lhs
, B
, U
>
392 Lhs
: GenericSequence
<B
, Length
= Self::Length
> + MappedGenericSequence
<B
, U
>,
393 Self: MappedGenericSequence
<T
, U
>,
394 Self::Length
: ArrayLength
<B
> + ArrayLength
<U
>,
395 F
: FnMut(Lhs
::Item
, Self::Item
) -> U
,
398 let mut right
= ArrayConsumer
::new(self);
400 let (right_array_iter
, right_position
) = right
.iter_position();
402 FromIterator
::from_iter(
404 .zip(right_array_iter
)
405 .map(|(left_value
, r
)| {
406 let right_value
= ptr
::read(r
);
408 *right_position
+= 1;
410 f(left_value
, right_value
)
417 unsafe impl<T
, U
, N
> MappedGenericSequence
<T
, U
> for GenericArray
<T
, N
>
419 N
: ArrayLength
<T
> + ArrayLength
<U
>,
420 GenericArray
<U
, N
>: GenericSequence
<U
, Length
= N
>,
422 type Mapped
= GenericArray
<U
, N
>;
425 unsafe impl<T
, N
> FunctionalSequence
<T
> for GenericArray
<T
, N
>
428 Self: GenericSequence
<T
, Item
= T
, Length
= N
>,
430 fn map
<U
, F
>(self, mut f
: F
) -> MappedSequence
<Self, T
, U
>
432 Self::Length
: ArrayLength
<U
>,
433 Self: MappedGenericSequence
<T
, U
>,
437 let mut source
= ArrayConsumer
::new(self);
439 let (array_iter
, position
) = source
.iter_position();
441 FromIterator
::from_iter(array_iter
.map(|src
| {
442 let value
= ptr
::read(src
);
452 fn zip
<B
, Rhs
, U
, F
>(self, rhs
: Rhs
, f
: F
) -> MappedSequence
<Self, T
, U
>
454 Self: MappedGenericSequence
<T
, U
>,
455 Rhs
: MappedGenericSequence
<B
, U
, Mapped
= MappedSequence
<Self, T
, U
>>,
456 Self::Length
: ArrayLength
<B
> + ArrayLength
<U
>,
457 Rhs
: GenericSequence
<B
, Length
= Self::Length
>,
458 F
: FnMut(T
, Rhs
::Item
) -> U
,
460 rhs
.inverted_zip(self, f
)
463 fn fold
<U
, F
>(self, init
: U
, mut f
: F
) -> U
468 let mut source
= ArrayConsumer
::new(self);
470 let (array_iter
, position
) = source
.iter_position();
472 array_iter
.fold(init
, |acc
, src
| {
473 let value
= ptr
::read(src
);
483 impl<T
, N
> GenericArray
<T
, N
>
487 /// Extracts a slice containing the entire array.
489 pub fn as_slice(&self) -> &[T
] {
493 /// Extracts a mutable slice containing the entire array.
495 pub fn as_mut_slice(&mut self) -> &mut [T
] {
499 /// Converts slice to a generic array reference with inferred length;
501 /// Length of the slice must be equal to the length of the array.
503 pub fn from_slice(slice
: &[T
]) -> &GenericArray
<T
, N
> {
507 /// Converts mutable slice to a mutable generic array reference
509 /// Length of the slice must be equal to the length of the array.
511 pub fn from_mut_slice(slice
: &mut [T
]) -> &mut GenericArray
<T
, N
> {
516 impl<'a
, T
, N
: ArrayLength
<T
>> From
<&'a
[T
]> for &'a GenericArray
<T
, N
> {
517 /// Converts slice to a generic array reference with inferred length;
519 /// Length of the slice must be equal to the length of the array.
521 fn from(slice
: &[T
]) -> &GenericArray
<T
, N
> {
522 assert_eq
!(slice
.len(), N
::to_usize());
524 unsafe { &*(slice.as_ptr() as *const GenericArray<T, N>) }
528 impl<'a
, T
, N
: ArrayLength
<T
>> From
<&'a
mut [T
]> for &'a
mut GenericArray
<T
, N
> {
529 /// Converts mutable slice to a mutable generic array reference
531 /// Length of the slice must be equal to the length of the array.
533 fn from(slice
: &mut [T
]) -> &mut GenericArray
<T
, N
> {
534 assert_eq
!(slice
.len(), N
::to_usize());
536 unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray<T, N>) }
540 impl<T
: Clone
, N
> GenericArray
<T
, N
>
544 /// Construct a `GenericArray` from a slice by cloning its content
546 /// Length of the slice must be equal to the length of the array
548 pub fn clone_from_slice(list
: &[T
]) -> GenericArray
<T
, N
> {
549 Self::from_exact_iter(list
.iter().cloned())
550 .expect("Slice must be the same length as the array")
554 impl<T
, N
> GenericArray
<T
, N
>
558 /// Creates a new `GenericArray` instance from an iterator with a known exact size.
560 /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`.
561 pub fn from_exact_iter
<I
>(iter
: I
) -> Option
<Self>
563 I
: IntoIterator
<Item
= T
>,
564 <I
as IntoIterator
>::IntoIter
: ExactSizeIterator
,
566 let iter
= iter
.into_iter();
568 if iter
.len() == N
::to_usize() {
570 let mut destination
= ArrayBuilder
::new();
573 let (destination_iter
, position
) = destination
.iter_position();
575 for (dst
, src
) in destination_iter
.zip(iter
.into_iter()) {
576 ptr
::write(dst
, src
);
582 Some(destination
.into_inner())
590 /// A reimplementation of the `transmute` function, avoiding problems
591 /// when the compiler can't prove equal sizes.
594 pub unsafe fn transmute
<A
, B
>(a
: A
) -> B
{
595 let b
= ::core
::ptr
::read(&a
as *const A
as *const B
);
596 ::core
::mem
::forget(a
);
603 // cargo rustc --lib --profile test --release --
604 // -C target-cpu=native -C opt-level=3 --emit asm
605 // and view the assembly to make sure test_assembly generates
606 // SIMD instructions instead of a niave loop.
609 pub fn black_box
<T
>(val
: T
) -> T
{
610 use core
::{mem, ptr}
;
612 let ret
= unsafe { ptr::read_volatile(&val) }
;
621 let a
= black_box(arr
![i32; 1, 3, 5, 7]);
622 let b
= black_box(arr
![i32; 2, 4, 6, 8]);
624 let c
= (&a
).zip(b
, |l
, r
| l
+ r
);
626 let d
= a
.fold(0, |a
, x
| a
+ x
);
628 assert_eq
!(c
, arr
![i32; 3, 7, 11, 15]);