1 
2 /// Trait for fixed size arrays.
3 ///
4 /// This trait is implemented for some specific array sizes, see
5 /// the implementor list below. At the current state of Rust we can't
6 /// make this fully general for every array size.
7 ///
8 /// The following crate features add more array sizes (and they are not
9 /// enabled by default due to their impact on compliation speed).
10 ///
11 /// - `array-sizes-33-128`: All sizes 33 to 128 are implemented
12 ///   (a few in this range are included by default).
13 /// - `array-sizes-129-255`: All sizes 129 to 255 are implemented
14 ///   (a few in this range are included by default).
15 ///
16 /// ## Safety
17 ///
18 /// This trait can *only* be implemented by fixed-size arrays or types with
19 /// *exactly* the representation of a fixed size array (of the right element
20 /// type and capacity).
21 ///
22 /// Normally this trait is an implementation detail of arrayvec and doesn’t
23 /// need implementing.
24 pub unsafe trait Array {
25     /// The array’s element type
26     type Item;
27     /// The smallest type that can index and tell the length of the array.
28     #[doc(hidden)]
29     type Index: Index;
30     /// The array's element capacity
31     const CAPACITY: usize;
as_slice(&self) -> &[Self::Item]32     fn as_slice(&self) -> &[Self::Item];
as_mut_slice(&mut self) -> &mut [Self::Item]33     fn as_mut_slice(&mut self) -> &mut [Self::Item];
34 }
35 
36 pub trait Index : PartialEq + Copy {
to_usize(self) -> usize37     fn to_usize(self) -> usize;
from(_: usize) -> Self38     fn from(_: usize) -> Self;
39 }
40 
41 impl Index for () {
42     #[inline(always)]
to_usize(self) -> usize43     fn to_usize(self) -> usize { 0 }
44     #[inline(always)]
from(_ix: usize) -> Self45     fn from(_ix: usize) ->  Self { () }
46 }
47 
48 impl Index for bool {
49     #[inline(always)]
to_usize(self) -> usize50     fn to_usize(self) -> usize { self as usize }
51     #[inline(always)]
from(ix: usize) -> Self52     fn from(ix: usize) ->  Self { ix != 0 }
53 }
54 
55 impl Index for u8 {
56     #[inline(always)]
to_usize(self) -> usize57     fn to_usize(self) -> usize { self as usize }
58     #[inline(always)]
from(ix: usize) -> Self59     fn from(ix: usize) ->  Self { ix as u8 }
60 }
61 
62 impl Index for u16 {
63     #[inline(always)]
to_usize(self) -> usize64     fn to_usize(self) -> usize { self as usize }
65     #[inline(always)]
from(ix: usize) -> Self66     fn from(ix: usize) ->  Self { ix as u16 }
67 }
68 
69 impl Index for u32 {
70     #[inline(always)]
to_usize(self) -> usize71     fn to_usize(self) -> usize { self as usize }
72     #[inline(always)]
from(ix: usize) -> Self73     fn from(ix: usize) ->  Self { ix as u32 }
74 }
75 
76 impl Index for usize {
77     #[inline(always)]
to_usize(self) -> usize78     fn to_usize(self) -> usize { self }
79     #[inline(always)]
from(ix: usize) -> Self80     fn from(ix: usize) ->  Self { ix }
81 }
82 
83 macro_rules! fix_array_impl {
84     ($index_type:ty, $len:expr ) => (
85         unsafe impl<T> Array for [T; $len] {
86             type Item = T;
87             type Index = $index_type;
88             const CAPACITY: usize = $len;
89             #[doc(hidden)]
90             fn as_slice(&self) -> &[Self::Item] { self }
91             #[doc(hidden)]
92             fn as_mut_slice(&mut self) -> &mut [Self::Item] { self }
93         }
94     )
95 }
96 
97 macro_rules! fix_array_impl_recursive {
98     ($index_type:ty, ) => ();
99     ($index_type:ty, $($len:expr,)*) => (
100         $(fix_array_impl!($index_type, $len);)*
101     );
102 }
103 
104 
105 fix_array_impl_recursive!((), 0,);
106 fix_array_impl_recursive!(bool, 1,);
107 fix_array_impl_recursive!(u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
108                           15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
109                           28, 29, 30, 31, );
110 
111 #[cfg(not(feature="array-sizes-33-128"))]
112 fix_array_impl_recursive!(u8, 32, 40, 48, 50, 56, 64, 72, 96, 100, 128, );
113 
114 #[cfg(feature="array-sizes-33-128")]
115 fix_array_impl_recursive!(u8,
116 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
117 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
118 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
119 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
120 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
121 125, 126, 127, 128,
122 );
123 
124 #[cfg(not(feature="array-sizes-129-255"))]
125 fix_array_impl_recursive!(u8, 160, 192, 200, 224,);
126 
127 #[cfg(feature="array-sizes-129-255")]
128 fix_array_impl_recursive!(u8,
129 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
130 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
131 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
132 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
133 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
134 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
135 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
136 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
137 253, 254, 255,
138 );
139 
140 fix_array_impl_recursive!(u16, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,);
141 // This array size doesn't exist on 16-bit
142 #[cfg(any(target_pointer_width="32", target_pointer_width="64"))]
143 fix_array_impl_recursive!(u32, 1 << 16,);
144 
145