1
2#![cfg_attr(not(feature = "std"), no_std)]
3
4#[cfg(feature = "std")]
5extern crate heapsize;
6
7#[cfg(not(feature = "std"))]
8extern crate alloc;
9
10#[doc(hidden)]
13pub extern crate core as core_;
14
15use core_::{
16 cmp::Ordering,
17 hash::{Hash, Hasher},
18 fmt,
19 ops::Deref,
20};
21
22#[cfg(not(feature = "std"))]
23use alloc::vec::Vec;
24
25#[cfg(feature = "std")]
26use heapsize::HeapSizeOf;
27
28#[macro_export]
29macro_rules! impl_elastic_array {
30 ($name: ident, $dummy: ident, $size: expr) => (
31 #[doc(hidden)]
32 enum $dummy<T> {
33 Arr([T; $size]),
34 Vec(Vec<T>)
35 }
36
37 impl<T> $dummy<T> {
38 #[doc(hidden)]
39 pub fn slice(&self) -> &[T] {
40 match *self {
41 $dummy::Arr(ref v) => v,
42 $dummy::Vec(ref v) => v
43 }
44 }
45 }
46
47 impl<T> Clone for $dummy<T> where T: Copy {
48 fn clone(&self) -> $dummy<T> {
49 match *self {
50 $dummy::Arr(ref a) => $dummy::Arr(*a),
51 $dummy::Vec(ref v) => $dummy::Vec(v.clone()),
52 }
53 }
54 }
55
56 pub struct $name<T> {
57 raw: $dummy<T>,
58 len: usize
59 }
60
61 impl<T> Eq for $name<T> where T: Eq { }
62
63 impl<T> fmt::Debug for $name<T> where T: fmt::Debug {
64 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
65 match self.raw {
66 $dummy::Arr(ref a) => (&a[..self.len]).fmt(f),
67 $dummy::Vec(ref v) => v.fmt(f),
68 }
69 }
70 }
71
72 impl<T, U> PartialEq<U> for $name<T> where T: PartialEq, U: Deref<Target=[T]> {
73 fn eq(&self, other: &U) -> bool {
74 self.slice() == &**other
75 }
76 }
77
78 impl<T, U> PartialOrd<U> for $name<T> where T: PartialOrd, U: Deref<Target=[T]> {
79 fn partial_cmp(&self, other: &U) -> Option<Ordering> {
80 (&**self).partial_cmp(&*other)
81 }
82 }
83
84 impl<T> Ord for $name<T> where T: Ord {
85 fn cmp(&self, other: &Self) -> Ordering {
86 (&**self).cmp(&*other)
87 }
88 }
89
90 impl<T> Hash for $name<T> where T: Hash {
91 fn hash<H>(&self, state: &mut H) where H: Hasher {
92 self.slice().hash(state)
93 }
94 }
95
96 #[cfg(feature = "std")]
97 impl<T> HeapSizeOf for $name<T> where T: HeapSizeOf {
98 fn heap_size_of_children(&self) -> usize {
99 match self.raw {
100 $dummy::Arr(_) => 0,
101 $dummy::Vec(ref v) => v.heap_size_of_children()
102 }
103 }
104 }
105
106 impl<T> Clone for $name<T> where T: Copy {
107 fn clone(&self) -> $name<T> {
108 $name {
109 raw: self.raw.clone(),
110 len: self.len,
111 }
112 }
113 }
114
115 impl<T> Default for $name<T> where T: Copy + Default {
116 fn default() -> $name<T> {
117 Self::new()
118 }
119 }
120
121 impl<T> $name<T> where T: Copy + Default {
122 pub fn new() -> $name<T> {
123 $name {
124 raw: $dummy::Arr([T::default(); $size]),
125 len: 0
126 }
127 }
128
129 pub fn from_slice(slice: &[T]) -> $name<T> {
130 let mut v = $name::new();
131 v.append_slice(slice);
132 v
133 }
134
135 pub fn from_vec(vec: Vec<T>) -> $name<T> {
136 $name {
137 len: vec.len(),
138 raw: $dummy::Vec(vec),
139 }
140 }
141
142 pub fn push(&mut self, e: T) {
143 match self.raw {
144 $dummy::Arr(ref mut a) if self.len < a.len() => {
145 unsafe {
146 *a.get_unchecked_mut(self.len) = e;
147 }
148 },
149 $dummy::Arr(_) => {
150 let mut vec = Vec::new();
151 vec.reserve(self.len + 1);
152
153 unsafe {
154 $crate::core_::ptr::copy(self.raw.slice().as_ptr(), vec.as_mut_ptr(), self.len);
155 vec.set_len(self.len);
156 }
157
158 vec.push(e);
159 self.raw = $dummy::Vec(vec);
160 },
161 $dummy::Vec(ref mut v) => v.push(e)
162 }
163 self.len += 1;
164 }
165
166 pub fn pop(&mut self) -> Option<T> {
167 if self.len == 0 {
168 return None;
169 }
170
171 self.len -= 1;
172 match self.raw {
173 $dummy::Arr(ref a) => Some(a[self.len]),
174 $dummy::Vec(ref mut v) => v.pop()
175 }
176 }
177
178 pub fn clear(&mut self) {
179 self.raw = $dummy::Arr([T::default(); $size]);
180 self.len = 0;
181 }
182
183 pub fn append_slice(&mut self, elements: &[T]) {
184 let len = self.len;
185 self.insert_slice(len, elements)
186 }
187
188 pub fn into_vec(self) -> Vec<T> {
189 match self.raw {
190 $dummy::Arr(a) => {
191 let mut vec = Vec::new();
192 vec.reserve(self.len);
193 unsafe {
194 $crate::core_::ptr::copy(a.as_ptr(), vec.as_mut_ptr(), self.len);
195 vec.set_len(self.len);
196 }
197 vec
198 }
199 $dummy::Vec(v) => v
200 }
201 }
202
203 pub fn insert_slice(&mut self, index: usize, elements: &[T]) {
204 use $crate::core_::ptr;
205
206 let elen = elements.len();
207
208 if elen == 0 {
209 return;
210 }
211
212 let len = self.len;
213 assert!(index <= len);
214
215 match self.raw {
216 $dummy::Arr(ref mut a) if len + elen <= a.len() => unsafe {
218 let p = a.as_mut_ptr().offset(index as isize);
219 let ep = elements.as_ptr();
220
221 ptr::copy(p, p.offset(elen as isize), len - index);
223 ptr::copy(ep, p, elen);
225 },
226 $dummy::Arr(_) => unsafe {
228 let mut vec = Vec::new();
229 vec.reserve(self.len + elen);
230 {
231 let p = vec.as_mut_ptr();
232 let ob = self.raw.slice().as_ptr();
233 let ep = elements.as_ptr();
234 let oe = ob.offset(index as isize);
235
236 ptr::copy(ob, p, index);
238
239 ptr::copy(ep, p.offset(index as isize), elen);
241
242 ptr::copy(oe, p.offset((index + elen) as isize), len - index);
244 }
245 vec.set_len(self.len + elen);
246 self.raw = $dummy::Vec(vec);
247 },
248 $dummy::Vec(ref mut v) => unsafe {
250 v.reserve(elen);
251
252 let p = v.as_mut_ptr().offset(index as isize);
253 let ep = elements.as_ptr();
254
255 ptr::copy(p, p.offset(elen as isize), len - index);
257 ptr::copy(ep, p, elen);
259
260 v.set_len(self.len + elen);
261 }
262 }
263 self.len += elen;
264 }
265 }
266
267 impl<T> $name<T> {
268 fn slice(&self) -> &[T] {
269 match self.raw {
270 $dummy::Arr(ref a) => &a[..self.len],
271 $dummy::Vec(ref v) => v
272 }
273 }
274 }
275
276 impl<T> Deref for $name<T> {
277 type Target = [T];
278
279 #[inline]
280 fn deref(&self) -> &[T] {
281 self.slice()
282 }
283 }
284
285 impl<T> $crate::core_::convert::AsRef<[T]> for $name<T> {
286 #[inline]
287 fn as_ref(&self) -> &[T] {
288 self.slice()
289 }
290 }
291
292 impl<T> $crate::core_::borrow::Borrow<[T]> for $name<T> {
293 #[inline]
294 fn borrow(&self) -> &[T] {
295 self.slice()
296 }
297 }
298
299 impl<T> $crate::core_::ops::DerefMut for $name<T> {
300 #[inline]
301 fn deref_mut(&mut self) -> &mut [T] {
302 match self.raw {
303 $dummy::Arr(ref mut a) => &mut a[..self.len],
304 $dummy::Vec(ref mut v) => v
305 }
306 }
307 }
308
309 impl<'a, T> From<&'a [T]> for $name<T> where T: 'a + Copy + Default {
310 fn from(s: &'a [T]) -> Self { Self::from_slice(s) }
311 }
312 )
313}
314
315impl_elastic_array!(ElasticArray2, ElasticArray2Dummy, 2);
316impl_elastic_array!(ElasticArray4, ElasticArray4Dummy, 4);
317impl_elastic_array!(ElasticArray8, ElasticArray8Dummy, 8);
318impl_elastic_array!(ElasticArray16, ElasticArray16Dummy, 16);
319impl_elastic_array!(ElasticArray32, ElasticArray32Dummy, 32);
320impl_elastic_array!(ElasticArray36, ElasticArray36Dummy, 36);
321impl_elastic_array!(ElasticArray64, ElasticArray64Dummy, 64);
322impl_elastic_array!(ElasticArray128, ElasticArray128Dummy, 128);
323impl_elastic_array!(ElasticArray256, ElasticArray256Dummy, 256);
324impl_elastic_array!(ElasticArray512, ElasticArray512Dummy, 512);
325impl_elastic_array!(ElasticArray1024, ElasticArray1024Dummy, 1024);
326impl_elastic_array!(ElasticArray2048, ElasticArray2048Dummy, 2048);
327
328#[cfg(test)]
329mod tests {
330
331 type BytesShort = super::ElasticArray2<u8>;
332
333 #[test]
334 fn it_works() {
335 let mut bytes = BytesShort::new();
336 assert_eq!(bytes.len(), 0);
337 bytes.push(1);
338 assert_eq!(bytes.len(), 1);
339 assert_eq!(bytes[0], 1);
340 bytes.push(2);
341 assert_eq!(bytes[1], 2);
342 assert_eq!(bytes.len(), 2);
343 bytes.push(3);
344 assert_eq!(bytes[2], 3);
345 assert_eq!(bytes.len(), 3);
346 assert_eq!(bytes.pop(), Some(3));
347 assert_eq!(bytes.len(), 2);
348 assert_eq!(bytes.pop(), Some(2));
349 assert_eq!(bytes.pop(), Some(1));
350 assert_eq!(bytes.pop(), None);
351 }
352
353 #[test]
354 fn test_insert_slice() {
355 let mut bytes = BytesShort::new();
356 bytes.push(1);
357 bytes.push(2);
358 bytes.insert_slice(1, &[3, 4]);
359 assert_eq!(bytes.len(), 4);
360 let r: &[u8] = &bytes;
361 assert_eq!(r, &[1, 3, 4, 2]);
362 }
363
364 #[test]
365 fn append_slice() {
366 let mut bytes = BytesShort::new();
367 bytes.push(1);
368 bytes.append_slice(&[3, 4]);
369 let r: &[u8] = &bytes;
370 assert_eq!(r.len(), 3);
371 assert_eq!(r, &[1, 3 ,4]);
372 }
373
374 #[test]
375 fn use_in_map() {
376 #[cfg(feature = "std")]
377 use std::collections::BTreeMap;
378 #[cfg(not(feature = "std"))]
379 use alloc::collections::BTreeMap;
380 use ::core_::borrow::Borrow;
381 let mut map: BTreeMap<BytesShort, i32> = Default::default();
382 let mut bytes = BytesShort::new();
383 bytes.append_slice(&[3, 4]);
384 assert_eq!(bytes.borrow() as &[u8], &[3, 4][..]);
385 map.insert(bytes, 1);
386 assert_eq!(map.get(&[3, 4][..]), Some(&1i32));
387 }
388
389}