malloc_array/
lib.rs

1#![allow(dead_code)]
2
3extern crate libc;
4#[cfg(feature="jemalloc")]
5extern crate jemalloc_sys;
6
7
8#[cfg(test)]
9mod tests {
10    use super::*;
11
12    #[test]
13    fn from_bytes()
14    {
15	unsafe {
16	    let heap = HeapArray::<i32>::from_bytes(&[0xff,0xff,0xff,0xff,0,0,0,0,0xff,0xff,0xff,0xff]);
17	    assert_eq!(heap[0], -1);
18	    assert_eq!(heap[1], 0);
19	    assert_eq!(heap[2], -1);
20	}
21    }
22    
23    #[test]
24    fn copy() {
25	let heap = heap![unsafe 1u16; 10];
26	let mut heap2 = heap![unsafe 10u16; 20];
27
28	unsafe {
29	    assert_eq!(heap2.memory_from_raw(heap.as_ptr(), heap.len()), 10);
30	}
31
32	assert_eq!(heap2[0], 1);
33	assert_eq!(heap2[10], 10);
34
35	unsafe {
36	    let heap3 = HeapArray::from_raw_copied(heap2.as_ptr(), 15);
37	    assert_eq!(heap3.len(), 15);
38	    assert_eq!(heap3[0], 1);
39	    assert_eq!(heap3[10], 10);
40	}
41    }
42    
43    #[test]
44    fn as_slice() {
45	let heap = heap![unsafe 0, 1, 2, 3u8];
46
47	assert_eq!(heap.as_slice(), [0,1,2,3u8]);
48    }
49    
50    #[test]
51    fn non_trivial_type() {
52	let heap = heap!["test one".to_owned(), "test two".to_owned()];
53	let refs = heap![unsafe "test three"; 2];
54	
55	assert_eq!(&refs[..], &["test three", "test three"]);
56	assert_eq!(heap.as_slice(), ["test one", "test two"]);
57    }
58
59    struct Unit;
60
61    #[test]
62    fn reinterpret()
63    {
64	let heap = heap![0u8; 32];
65	unsafe {
66	    let heap = heap.reinterpret::<i32>();
67	    assert_eq!(heap.len(), 8);
68	    let heap = heap.reinterpret::<u8>();
69	    assert_eq!(heap.len(), 32);
70	}
71    }
72    
73    #[test]
74    fn zero_size() {
75	let heap: HeapArray<u8> = heap![];
76	let heap_zst: HeapArray<()> = heap![(); 3];
77
78	assert_eq!(&heap.as_slice(), &[]);
79	assert_eq!(&heap_zst.as_slice(), &[(),(),()]);
80
81	let heap = heap![Unit; 32];
82	let mut i=0;
83	for _x in heap.into_iter()
84	{
85	    i+=1;
86	}
87	assert_eq!(i, 32);
88    }
89
90    #[test]
91    fn into_iter() {
92	let primitive = heap![1,3,5,7,9u32];
93
94	let iter = primitive.into_iter();
95	assert_eq!(iter.len(), 5);
96	for x in iter
97	{
98	    assert_eq!(x % 2, 1);
99	}
100
101	let non = heap!["string one".to_owned(), "string two!".to_owned(), "string".to_owned()];
102
103	let iter = non.into_iter();
104	assert_eq!(iter.len(), 3);
105	for x in iter
106	{
107	    assert_eq!(&x[..6], "string");	    
108	}
109
110	let non = heap!["strings".to_owned(), "strings!!!".to_owned()];
111	let iter = non.into_iter();
112	drop(iter);
113    }
114    
115    #[test]
116    fn vec()
117    {
118	let heap = heap![0,1,2,3,4u8];
119	let vec = vec![0,1,2,3,4u8];
120
121	assert_eq!(&vec[..], &heap[..]);
122
123	let heap = Vec::from(heap);
124
125	assert_eq!(vec,heap);
126
127	let heap = HeapArray::from(heap);
128
129	assert_eq!(&vec[..], &heap[..]);
130    }
131    
132    #[test]
133    fn boxed_slices() {
134	let array = [0,1,2,3,4];
135	let vector = vec![0,1,2,3,4];
136	assert_eq!(&vector[..], &array[..]);
137	let slice = vector.into_boxed_slice();
138	assert_eq!(&slice[..], &array[..]);
139	let heap = HeapArray::from_boxed_slice(slice);
140	assert_eq!(&heap[..], &array[..]);
141	let slice = heap.into_boxed_slice();
142	assert_eq!(&slice[..], &array[..]);
143	let vector = Vec::from(slice);
144	assert_eq!(&vector[..], &array[..]);
145    }
146
147    #[test]
148    fn init()
149    {
150	let mut array = heap![String; 32];
151	for mut string in array.initialise()
152	{
153	    string.put("Hiya".to_owned());
154	}
155	assert_eq!(array.len(), 32);
156	for x in array.into_iter()
157	{
158	    assert_eq!(x, "Hiya");
159	}
160
161	let mut array = heap![String; 10];
162	array.initialise().fill("wowe".to_owned());
163	for x in array.into_iter()
164	{
165	    assert_eq!(x, "wowe");
166	}
167
168	
169
170	let mut array = heap![String; 10];
171	array.initialise().fill_with(|| "wow".to_owned());
172	for x in array.into_iter()
173	{
174	    assert_eq!(x, "wow");
175	}
176
177	
178
179	let mut array = heap![String; 10];
180	array.initialise().fill_default();
181	for x in array.into_iter()
182	{
183	    assert_eq!(x, "");
184	}
185    }
186}
187
188mod ptr;
189mod alloc;
190mod reinterpret;
191pub mod init;
192pub use init::InitIterExt;
193pub mod store;
194
195use std::{
196    ops::{
197	Drop,
198	Index,IndexMut,
199	Deref,DerefMut,
200    },
201    borrow::{
202	Borrow,BorrowMut,
203    },
204    slice::{
205	self,
206	SliceIndex,
207    },
208    marker::{
209	Send,
210	Sync,
211    },
212};
213use crate::{
214    ptr::{
215	VoidPointer,
216	ConstVoidPointer,
217    },
218};
219
220#[macro_export]
221/// `vec![]`-like macro for creating `HeapArray<T>` instances.
222///
223/// Provides methods for creating safely accessable arrays using `malloc()` with a `Vec<T>` like interface.
224/// Also provides methods of optimising deallocations.
225///
226/// # Usage
227///
228/// Works like array definitions `[type; size]`, and like the `vec![]` macro `[value; size]`. Prepend the statement with `unsafe` (`[unsafe type|value; size]`) to prevent potentially redundant `drop()` calls.
229///
230/// # Examples
231///
232/// ```rust
233///  use malloc_array::{heap, HeapArray};
234///  let ints = heap![unsafe 4u32; 32]; // Creates a 32 element `u32` array with each element set to `4`.
235///  let ints = heap![unsafe u32; 32]; // Creates an uninitialised 32 element `u32` array.
236///  let ints = heap![u32; 32]; // Same as above, except when `ints` is dropped, each element will be also dropped redundantly.
237///  let strings = heap!["string one".to_owned(), "string two".to_owned()]; //Creates a 2 element string array.
238///  let strings = heap![unsafe "memory".to_owned(), "leak".to_owned()]; //Same as above, except `drop()` will not be called on the 2 strings, potentially causing a memory leak.
239///  let strings: HeapArray<u8> = heap![]; //Creates an empty `u8` array.
240/// ```
241macro_rules! heap {
242    () => {
243	$crate::HeapArray::new_uninit(0)
244    };
245    (@) => (0usize);
246    (@ $x:tt $($xs:tt)* ) => (1usize + $crate::heap!(@ $($xs)*));
247
248    (unsafe $($xs:tt)*) => {
249	{
250	    #[allow(unused_unsafe)]
251	    unsafe {
252		let mut output = $crate::heap!($($xs)*);
253		output.drop_check = false;
254		output
255	    }
256	}
257    };
258    
259    ($type:ty; $number:expr) => {
260	{
261	    $crate::HeapArray::<$type>::new($number)
262	}
263    };
264    ($value:expr; $number:expr) => {
265	{
266	    let num = $number;
267	    let mut ha = $crate::HeapArray::new_uninit(num);
268
269	    if ha.len() == ha.len_bytes() && ha.len() > 0 {
270		unsafe {
271		    let mut vl = $value;
272		    
273		    ha.set_memory(*std::mem::transmute::<_, &mut u8>(&mut vl));
274		}
275	    } else {
276		for x in 0..num {
277		    ha.replace_and_forget(x, $value);
278		}
279	    }
280	    
281	    ha
282	}
283    };
284    ($($n:expr),*) => {
285	{
286	    let mut ha = $crate::HeapArray::new_uninit($crate::heap!(@ $($n)*));
287	    {
288		let fp = 0;
289		$(
290		    let fp = fp + 1; 
291		    ha.replace_and_forget(fp-1, $n);
292		)*
293	    }
294	    ha
295	}
296    };
297}
298
299/// Array created by libc `malloc()` and dropped by libc `free()`.
300pub struct HeapArray<T> {
301    ptr: *mut T,
302    size: usize,
303
304    /// Call `drop()` on sub-elements when `drop`ping the array. This is not needed for types that implement `Copy`.
305    pub drop_check: bool,
306}
307
308unsafe impl<T> Sync for HeapArray<T>
309where T: Sync{}
310unsafe impl<T> Send for HeapArray<T>
311where T: Send{}
312
313impl<T> HeapArray<T>
314{
315    /// Size of memory of this instance in bytes.
316    pub fn len_bytes(&self) -> usize
317    {
318	Self::element_size() * self.size
319    }
320
321    /// Number of elements in this instance.
322    pub fn len(&self) -> usize
323    {
324	self.size
325    }
326    
327    const fn element_size() -> usize
328    {
329	std::mem::size_of::<T>()
330    }
331    const fn is_single() -> bool
332    {
333	std::mem::size_of::<T>() == 1
334    }
335
336    /// Create an iterator for safely setting potentially uninitialised values within the instance.
337    pub fn initialise<'a>(&'a mut self) -> init::InitIter<'a, T>
338    {
339	init::InitIter::new(self, 0)
340    }
341
342    /// Set each byte to a value.
343    pub unsafe fn set_memory(&mut self, value: u8)
344    {
345	ptr::memset(self.ptr as *mut u8, value, self.len_bytes());
346    }
347
348    /// Creates a new `HeapArray<T>` from zeroed memory.
349    pub fn new(size: usize) -> Self
350    {
351	Self {
352	    ptr: unsafe{alloc::calloc(size, Self::element_size()).expect("calloc()")} as *mut T,
353	    size,
354	    drop_check: true,
355	}
356    }
357
358    /// Creates a new `HeapArray<T>` from uninitialised memory.
359    pub fn new_uninit(size: usize) -> Self
360    {
361	Self {
362	    ptr: unsafe{alloc::malloc(size * Self::element_size()).expect("malloc()")} as *mut T,
363	    size,
364	    drop_check: true,
365	}
366    }
367
368    /// Consumes the instance, returning a new instance after calling `realloc()` on the underlying memory.
369    pub fn resize(self, size: usize) -> Self
370    {
371	unsafe {
372	    let ptr = alloc::realloc(self.ptr as VoidPointer, size).expect("realloc()") as *mut T;
373	    
374	    let output = Self {
375		ptr,
376		size,
377		drop_check: self.drop_check
378	    };
379	    std::mem::forget(self);
380	    output
381	}
382    }
383
384    /// Creates a new `HeapArray<T>` from an initial element and a size.
385    pub fn new_repeat(initial: T, size: usize) -> Self
386    where T: Copy
387    {
388	let this = Self::new_uninit(size);
389	if size > 0 {
390	    if Self::is_single() {
391		unsafe {
392		    ptr::memset(this.ptr as *mut u8, reinterpret::bytes(initial), this.len_bytes());
393		}
394	    } else {
395		unsafe {
396		    for x in 0..size {
397			*this.ptr.offset(x as isize) = initial;
398		    }
399		}
400	    }
401	}
402	this
403    }
404
405    /// Creates a new `HeapArray<T>` from a range of elements and a size, repeating if needed.
406    pub fn new_range<U>(initial: U, size: usize) -> Self
407    where T: Copy,
408	  U: AsRef<[T]>
409    {
410	let initial = initial.as_ref();
411	if size > 0 {
412	    if initial.len() == 1 {
413		Self::new_repeat(initial[0], size)
414	    } else {
415		let this = Self::new_uninit(size);
416		unsafe {
417		    for x in 0..size {
418			*this.ptr.offset(x as isize) = initial[x % initial.len()];
419		    }
420		    this
421		}
422	    }
423	} else {
424	    Self::new_uninit(size)
425	}
426    }
427
428    /// As an immutable slice of `T`.
429    pub fn as_slice(&self) -> &[T]
430    {
431	unsafe{slice::from_raw_parts(self.ptr, self.size)}
432    }
433
434    /// As a mutable slice of `T`.
435    pub fn as_slice_mut(&mut self) -> &mut [T]
436    {
437	unsafe{slice::from_raw_parts_mut(self.ptr, self.size)}
438    }
439
440    /// As immutable raw pointer.
441    pub fn as_ptr(&self) -> *const T
442    {
443	self.ptr as *const T
444    }
445
446    /// As mutable raw pointer.
447    pub fn as_ptr_mut(&mut self) -> *mut T
448    {
449	self.ptr
450    }
451
452    /// An immutable slice of the memory.
453    pub fn memory(&self) -> &[u8]
454    {
455	unsafe {
456	    slice::from_raw_parts(self.ptr as *const u8, self.len_bytes())
457	}
458    }
459
460    /// A mutable slice of the memory.
461    pub unsafe fn memory_mut(&mut self) -> &mut [u8]
462    {
463	slice::from_raw_parts_mut(self.ptr as *mut u8, self.len_bytes())
464    }
465
466
467    /// Consumes the instance. Returns a raw pointer and the number of elements.
468    pub fn into_raw_parts(self) -> (*mut T, usize)
469    {
470	let op = (self.ptr, self.size);
471	std::mem::forget(self);
472	op
473    }
474
475    /// Create a `HeapArray<T>` from a raw pointer and a number of elements.
476    pub unsafe fn from_raw_parts(ptr: *mut T, size: usize) -> Self
477    {
478	Self {
479	    ptr,
480	    size,
481	    drop_check: true,
482	}
483    }
484
485    /// Consumes the instance. Frees the memory without dropping the items.
486    pub fn free(self)
487    {
488	if self.ptr != ptr::null() {
489	    unsafe {
490		alloc::free(self.ptr as VoidPointer);
491	    }
492	}
493	std::mem::forget(self);
494    }
495
496    /// Consumes the instance, moving all elements into a slice.
497    pub fn into_slice(self, slice: &mut [T])
498    {
499	let ptr = &mut slice[0] as *mut T;
500	assert!(slice.len() >= self.len());
501	unsafe{
502	    ptr::memmove(ptr as ptr::VoidPointer, self.ptr as ptr::VoidPointer, self.len_bytes());
503	}
504	self.free();
505    }
506
507    /// Coerce or clone memory from a boxed slice.
508    pub fn from_boxed_slice(bx: Box<[T]>) -> Self
509    {
510	#[cfg(feature="assume_libc")]
511	unsafe {
512	    let len = bx.len();
513	    Self::from_raw_parts(Box::<[T]>::into_raw(bx) as *mut T, len)
514	}
515	#[cfg(not(feature="assume_libc"))]
516	{
517	    let len = bx.len();
518	    let out = Self::from(Vec::from(bx));
519	    assert_eq!(len, out.len());
520	    out
521	}
522    }
523
524    /// Coerce or clone memory into a boxed slice.
525    #[allow(unused_mut)]
526    pub fn into_boxed_slice(mut self) -> Box<[T]>
527    {
528	#[cfg(feature="assume_libc")]
529	unsafe {
530	    let bx = Box::from_raw(self.as_slice_mut() as *mut [T]);
531	    std::mem::forget(self);
532	    bx
533	}
534	#[cfg(not(feature="assume_libc"))]
535	{
536	    let len = self.len();
537	    let vec = Vec::from(self);
538	    assert_eq!(vec.len(), len);
539	    vec.into_boxed_slice()
540	}
541    }
542
543    /// Reinterpret the memory of this instance into an insteance of a different type
544    /// # Panics
545    /// If `U` cannot fit into `T`.  
546    pub unsafe fn reinterpret<U>(self) -> HeapArray<U>
547    {
548	assert!(self.len_bytes() % std::mem::size_of::<U>() == 0);
549	let output = HeapArray {
550	    size: self.len_bytes() / std::mem::size_of::<U>(),
551	    ptr: self.ptr as *mut U,
552	    drop_check: self.drop_check,
553	};
554	std::mem::forget(self);
555	output
556    }
557
558    /// Reinterpret the memory of this instance into an immutable slice of a different type.
559    /// # Panics
560    /// If `U` cannot fit into `T`.  
561    pub fn reinterpret_ref<U>(&self) -> &[U]
562    {
563	assert!(self.len_bytes() % std::mem::size_of::<U>() == 0);
564	unsafe {
565	    slice::from_raw_parts(self.ptr as *const U, self.len_bytes() / std::mem::size_of::<U>())
566	}
567    }
568    /// Reinterpret the memory of this instance into a mutable slice of a different type.
569    /// # Panics
570    /// If `U` cannot fit into `T`.  
571    pub unsafe fn reinterpret_mut<U>(&mut self) -> &mut [U]
572    {
573	assert!(self.len_bytes() % std::mem::size_of::<U>() == 0);
574	slice::from_raw_parts_mut(self.ptr as *mut U, self.len_bytes() / std::mem::size_of::<U>())
575    }
576
577    /// Immutable slice iterator for this instance
578    pub fn iter<'a>(&'a self) -> slice::Iter<'a, T>
579    {
580	self.as_slice().iter()
581    }
582
583    /// Mutable slice iterator for this instance
584    pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, T>
585    {
586	self.as_slice_mut().iter_mut()
587    }
588
589    /// Replace the element at `index` with `value`, and `forget` the old one.
590    /// Useful with `new_uninit()`.
591    pub fn replace_and_forget(&mut self, index: usize, value: T)
592    {
593	assert!(index<self.len());
594	unsafe {
595	    ptr::put(self.as_ptr_mut().offset(index as isize), value);
596	}
597    }
598
599
600    /// Clone the memory to a new instance.
601    pub unsafe fn clone_mem(&self) -> Self
602    {
603	let mut output = Self::new_uninit(self.len());
604	output.drop_check = self.drop_check;
605	ptr::memcpy(output.ptr as VoidPointer, self.ptr as VoidPointer, self.len_bytes());
606
607	output
608    }
609
610    /// Leak the memory to a static slice reference.
611    pub fn leak(mut self) -> &'static mut [T]
612    {
613	unsafe {
614	    let bx = Box::from_raw(self.as_slice_mut() as *mut [T]);
615	    std::mem::forget(self);
616	    Box::leak(bx)
617	}
618    }
619
620    /// Copy memory in from a slice of bytes.
621    pub unsafe fn memory_from_bytes<U: AsRef<[u8]>>(&mut self, from: U) -> usize
622    {
623	let from = from.as_ref();
624	let size = std::cmp::min(from.len(), self.len_bytes());
625	ptr::memcpy(self.ptr as VoidPointer, &from[0] as *const u8 as ConstVoidPointer, size);
626	size
627    }
628
629    /// Copy memory in from a pointer to bytes.
630    pub unsafe fn memory_from_raw_bytes(&mut self, from: *const u8, size: usize) -> usize
631    {
632	let size = std::cmp::min(size, self.len_bytes());
633	ptr::memcpy(self.ptr as VoidPointer, from as *const u8 as ConstVoidPointer, size);
634	size
635    }
636
637    /// Copy memory in from a raw pointer.
638    pub unsafe fn memory_from_slice<U: AsRef<[T]>>(&mut self, from: U) -> usize
639    {
640	let from = from.as_ref();
641	let size = std::cmp::min(from.len(), self.len());
642	ptr::memcpy(self.ptr as VoidPointer, &from[0] as *const T as ConstVoidPointer, size * std::mem::size_of::<T>());
643	size
644    }
645    
646    /// Copy memory in from a raw pointer.
647    pub unsafe fn memory_from_raw(&mut self, from: *const T, size: usize) -> usize
648    {
649	let size = std::cmp::min(size, self.len());
650	ptr::memcpy(self.ptr as VoidPointer, from as *const T as ConstVoidPointer, size * std::mem::size_of::<T>());
651	size
652    }
653
654    /// Create a new instance with memory copied from a raw pointer.
655    pub unsafe fn from_raw_copied(from: *const T, size: usize) -> Self
656    {
657	let mut inp = Self::new_uninit(size);
658	inp.memory_from_raw(from, size);
659	inp
660    }
661    
662    /// Create a new instance with memory copied from a slice.
663    pub unsafe fn from_slice_copied<U: AsRef<[T]>>(from: U) -> Self
664    where T: Copy
665    {
666	let from = from.as_ref();
667	Self::from_raw_copied(&from[0] as *const T, from.len())
668    }
669
670    /// Create a new instance with memory bytes copied from a raw pointer.
671    pub unsafe fn from_raw_bytes(from: *const u8, size: usize) -> Self
672    {
673	assert_eq!(size % Self::element_size(),0,"Cannot fit T into this size.");
674	
675	let mut inp = Self::new_uninit(size / Self::element_size());
676	inp.memory_from_raw_bytes(from, size);
677	inp
678    }
679    
680    /// Create a new instance with memory bytes copied from a slice.
681    pub unsafe fn from_bytes<U: AsRef<[u8]>>(from: U) -> Self
682    {
683	let from = from.as_ref();
684	Self::from_raw_bytes(&from[0], from.len())
685    }
686}
687
688impl<T, I> Index<I> for HeapArray<T>
689where I: SliceIndex<[T]>
690{
691    type Output = <I as SliceIndex<[T]>>::Output;
692    fn index(&self, index: I) -> &Self::Output
693    {
694	&self.as_slice()[index]
695    }
696}
697
698
699impl<T, I> IndexMut<I> for HeapArray<T>
700where I: SliceIndex<[T]>
701{
702    fn index_mut(&mut self, index: I) -> &mut <Self as Index<I>>::Output
703    {
704	&mut self.as_slice_mut()[index]
705    }
706}
707
708impl<T> Drop for HeapArray<T>
709{
710    fn drop(&mut self)
711    {
712	if self.ptr != ptr::null::<T>() {
713	    if self.drop_check {
714		for i in 0..self.size
715		{
716		    unsafe {
717			drop(ptr::take(self.ptr.offset(i as isize)));
718		    }
719		}
720	    }
721	    unsafe{alloc::free(self.ptr as VoidPointer)};
722	    self.ptr = ptr::null::<T>();
723	}
724    }
725}
726
727impl<T> AsMut<[T]> for HeapArray<T>
728{
729    fn as_mut(&mut self) -> &mut [T]
730    {
731	self.as_slice_mut()
732    }
733}
734impl<T> AsRef<[T]> for HeapArray<T>
735{
736    fn as_ref(&self) -> &[T]
737    {
738	self.as_slice()
739    }
740}
741
742impl<T> Deref for HeapArray<T>
743{
744    type Target = [T];
745    fn deref(&self) -> &Self::Target
746    {
747	self.as_slice()
748    }
749}
750impl<T> DerefMut for HeapArray<T>
751{
752    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target
753    {
754	self.as_slice_mut()
755    }
756}
757
758impl<T> Borrow<[T]> for HeapArray<T>
759{
760    fn borrow(&self) -> &[T]
761    {
762	self.as_slice()
763    }
764}
765impl<T> BorrowMut<[T]> for HeapArray<T>
766{
767    fn borrow_mut(&mut self) -> &mut [T]
768    {
769	self.as_slice_mut()
770    }
771}
772
773// `From`s
774
775impl<T> From<HeapArray<T>> for Vec<T>
776{
777    fn from(ha: HeapArray<T>) -> Self
778    {
779	let mut output = Vec::with_capacity(ha.len());
780	unsafe {
781	    ptr::memmove(output.as_mut_ptr() as ptr::VoidPointer, ha.ptr as ptr::VoidPointer, ha.len_bytes());
782	    output.set_len(ha.len());
783	}
784	ha.free();
785	output
786    }
787}
788impl<T> From<Vec<T>> for HeapArray<T>
789{
790    fn from(vec: Vec<T>) -> Self
791    {
792	let mut output = HeapArray::new_uninit(vec.len());
793	for (i,x) in (0..vec.len()).zip(vec.into_iter())
794	{
795	    output[i] = x;
796	}
797	output
798    }
799}
800
801impl<T> From<Box<[T]>> for HeapArray<T>
802{
803    fn from(sl: Box<[T]>) -> Self
804    {
805	Self::from_boxed_slice(sl)
806    }
807}
808impl<T> From<HeapArray<T>> for Box<[T]>
809{
810    fn from(ha: HeapArray<T>) -> Self
811    {
812	ha.into_boxed_slice()
813    }
814}
815
816mod iter;
817pub use iter::*;
818
819impl<T> std::cmp::Eq for HeapArray<T>
820where T: std::cmp::Eq {}
821impl<T, U> std::cmp::PartialEq<U> for HeapArray<T>
822where T: std::cmp::PartialEq,
823      U: AsRef<[T]>
824{
825    fn eq(&self, other: &U) -> bool
826    {
827	let other = other.as_ref();
828	self.len() == other.len() &&
829	{
830	    for (x, y) in self.iter().zip(0..other.len()) {
831		if x != &other[y] {return false;}
832	    }
833	    true
834	}
835    }
836}
837
838impl<T> std::hash::Hash for HeapArray<T>
839where T: std::hash::Hash
840{
841    fn hash<H: std::hash::Hasher>(&self, state: &mut H)
842    {
843	self.size.hash(state);
844	self.as_slice().hash(state);
845    }
846}
847
848impl<T> Clone for HeapArray<T>
849where T: Clone
850{
851    fn clone(&self) -> Self
852    where T: Clone
853    {
854	let mut output = Self::new_uninit(self.len());
855	output.drop_check = self.drop_check;
856
857	unsafe {
858	    for (i,x) in (0..self.len()).zip(self.iter())
859	    {   
860		ptr::put(output.as_ptr_mut().offset(i as isize), x.clone());
861	    }
862	}
863	output
864    }
865}
866
867use std::fmt;
868impl<T> fmt::Debug for HeapArray<T>
869where T: fmt::Debug
870{
871    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
872    {
873	write!(f, "{}: (", std::any::type_name::<Self>())?;
874	let len = self.len();
875	for (x,i) in self.iter().zip(0..len)
876	{
877	    write!(f, "{:?}", x)?;
878	    if i < len-1 {
879		write!(f, " ")?;
880	    }
881	}
882	write!(f, ")")
883    }
884}