array_trait/
as_array.rs

1use slice_trait::AsSlice;
2
3pub const trait AsArray: ~const AsSlice
4{
5    /// Length of array as compile-time constant
6    /// 
7    /// ## Example 1: Length
8    /// [Array::LENGTH](Array::LENGTH) will always equal the actual length of the array.
9    /// 
10    /// ```rust
11    /// use array_trait::*;
12    /// 
13    /// const L: usize = 4;
14    /// 
15    /// let array: [f32; L] = [1.0, 2.0, 3.0, 4.0];
16    /// 
17    /// assert_eq!(<[f32; L]>::LENGTH, L);
18    /// assert_eq!(<[f32; L]>::LENGTH, array.len());
19    /// ```
20    /// 
21    /// ## Example 2: Generic const-expression usage
22    /// This can be used in const-expressions as shown below.
23    /// 
24    /// ```rust
25    /// #![feature(generic_const_exprs)]
26    /// #![feature(iter_array_chunks)]
27    /// 
28    /// use array_trait::*;
29    /// 
30    /// fn first_half<T: Array>(array: T) -> [<T as AsSlice>::Elem; T::LENGTH/2]
31    /// {
32    ///     array.into_iter().array_chunks().next().unwrap()
33    /// }
34    /// 
35    /// assert_eq!(first_half([1.0, 2.0, 3.0, 4.0]), [1.0, 2.0]);
36    /// ```
37    const LENGTH: usize;
38
39    /// Returns self as an array-slice
40    /// 
41    /// Similar to [Array::into_array](Array::into_array), but is passed by reference.
42    /// 
43    /// Useful in the case where a trait is implemented using a generic bound to the [Array](Array) trait.
44    /// In this case, the compiler does not automatically know that the type with the [Array](Array)-trait is an actual array.
45    /// This method lets you tell the compiler that you are now working with an actual array, and not just something
46    /// which implements the trait [Array](Array).
47    fn as_array(&self) -> &[Self::Elem; Self::LENGTH];
48    
49    /// Returns self as a mutable array-slice
50    /// 
51    /// Similar to [Array::into_array](Array::into_array), but is passed by mutable reference.
52    /// 
53    /// Useful in the case where a trait is implemented using a generic bound to the [Array](Array) trait.
54    /// In this case, the compiler does not automatically know that the type with the [Array](Array)-trait is an actual array.
55    /// This method lets you tell the compiler that you are now working with an actual array, and not just something
56    /// which implements the trait [Array](Array).
57    fn as_array_mut(&mut self) -> &mut [Self::Elem; Self::LENGTH];
58}
59
60impl<T, const LENGTH: usize> const AsArray for [T; LENGTH]
61{
62    const LENGTH: usize = LENGTH;
63
64    fn as_array(&self) -> &[Self::Elem; Self::LENGTH]
65    {
66        unsafe {core::mem::transmute(self)}
67    }
68    fn as_array_mut(&mut self) -> &mut [Self::Elem; Self::LENGTH]
69    {
70        unsafe {core::mem::transmute(self)}
71    }
72}
73
74/*#[cfg(feature = "alloc")]
75impl<T> const AsArray for alloc::boxed::Box<T>
76where
77    T: ~const AsArray,
78    [(); T::LENGTH]:
79{
80    const LENGTH: usize = T::LENGTH;
81
82    fn as_array(&self) -> &[Self::Elem; Self::LENGTH]
83    {
84        let arr = (**self).as_array();
85        arr
86    }
87    fn as_array_mut(&self) -> &[Self::Elem; Self::LENGTH]
88    {
89        let arr = (**self).as_array_mut();
90        arr
91    }
92}*/
93
94#[cfg(feature = "alloc")]
95impl<T, const N: usize> const AsArray for alloc::boxed::Box<[T; N]>
96{
97    const LENGTH: usize = N;
98
99    fn as_array(&self) -> &[Self::Elem; Self::LENGTH]
100    {
101        let a: &[T; N] = self;
102        unsafe {core::mem::transmute(a)}
103    }
104    fn as_array_mut(&mut self) -> &mut [Self::Elem; Self::LENGTH]
105    {
106        let a: &mut [T; N] = self;
107        unsafe {core::mem::transmute(a)}
108    }
109}