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]
221macro_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
299pub struct HeapArray<T> {
301 ptr: *mut T,
302 size: usize,
303
304 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 pub fn len_bytes(&self) -> usize
317 {
318 Self::element_size() * self.size
319 }
320
321 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 pub fn initialise<'a>(&'a mut self) -> init::InitIter<'a, T>
338 {
339 init::InitIter::new(self, 0)
340 }
341
342 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 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 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 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 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 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 pub fn as_slice(&self) -> &[T]
430 {
431 unsafe{slice::from_raw_parts(self.ptr, self.size)}
432 }
433
434 pub fn as_slice_mut(&mut self) -> &mut [T]
436 {
437 unsafe{slice::from_raw_parts_mut(self.ptr, self.size)}
438 }
439
440 pub fn as_ptr(&self) -> *const T
442 {
443 self.ptr as *const T
444 }
445
446 pub fn as_ptr_mut(&mut self) -> *mut T
448 {
449 self.ptr
450 }
451
452 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 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 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 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 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 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 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 #[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 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 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 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 pub fn iter<'a>(&'a self) -> slice::Iter<'a, T>
579 {
580 self.as_slice().iter()
581 }
582
583 pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, T>
585 {
586 self.as_slice_mut().iter_mut()
587 }
588
589 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 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 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 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 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 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 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 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 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 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 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
773impl<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}