heap_array/
lib.rs

1#![cfg_attr(feature = "allocator-api", feature(allocator_api))]
2#![cfg_attr(feature = "dropck", feature(dropck_eyepatch))]
3
4#![warn(missing_docs)]
5#![no_std]
6
7//! # HeapArray
8//! An Implementation of a variable length array, with its main benefit over [`Vec`] is taking up less space
9//! as [`HeapArray`] is represented as (pointer, len) while [`Vec`] is a (pointer, len, capacity)
10//! and is meant as a replacement for `Box<[T]>`
11//!
12//! nice to have: compatible with serde
13//!
14//! # Examples
15//! ```
16//! use heap_array::{heap_array, HeapArray};
17//! let arr = heap_array![1, 2, 5, 8];
18//!
19//! assert_eq!(arr[0], 1);
20//! assert_eq!(arr[1], 2);
21//! assert_eq!(arr[2], 5);
22//! assert_eq!(arr[3], 8);
23//! assert_eq!(arr.len(), 4);
24//!
25//! let arr = HeapArray::from_fn(10, |i| i);
26//! assert_eq!(*arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
27//! ```
28//!
29//! [`Vec`]: Vec
30//! [`HeapArray`]: HeapArray
31
32mod try_me;
33mod guard;
34
35#[cfg(feature = "serde")]
36extern crate serde;
37extern crate alloc;
38
39use core::{
40    ptr::{self, NonNull},
41    fmt::{Debug, Formatter},
42    mem::{self, ManuallyDrop, MaybeUninit},
43    ops::{Deref, DerefMut, ControlFlow},
44    cmp::Ordering,
45    slice::{Iter, IterMut},
46    marker::PhantomData,
47    panic::{RefUnwindSafe, UnwindSafe},
48    alloc::Layout,
49    fmt
50};
51
52use alloc::{
53    boxed::Box,
54    vec::Vec,
55    alloc::{handle_alloc_error},
56    vec::IntoIter,
57    vec
58};
59
60#[cfg(feature = "allocator-api")]
61use alloc::alloc::{Allocator, Global};
62use core::slice::SliceIndex;
63use core::ops::{Index, IndexMut};
64use core::hash::{Hash, Hasher};
65use likely_stable::unlikely;
66use crate::guard::Guard;
67use crate::try_me::{NeverShortCircuit, Try};
68
69/// # HeapArray
70/// An Implementation of a variable length array, with its main benefit over [`Vec`] is taking up less space
71/// as [`HeapArray`] is represented as (pointer, len) while [`Vec`] is a (pointer, len, capacity)
72/// and is meant as a replacement for `Box<[T]>`
73///
74/// nice to have: compatible with serde
75///
76/// # Examples
77/// ```
78/// use heap_array::{heap_array, HeapArray};
79/// let arr = heap_array![1, 2, 5, 8];
80///
81/// assert_eq!(arr[0], 1);
82/// assert_eq!(arr[1], 2);
83/// assert_eq!(arr[2], 5);
84/// assert_eq!(arr[3], 8);
85/// assert_eq!(arr.len(), 4);
86///
87/// let arr = HeapArray::from_fn(10, |i| i);
88/// assert_eq!(*arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
89/// ```
90///
91/// [`Vec`]: Vec
92/// [`HeapArray`]: HeapArray
93
94#[cfg(not(feature = "allocator-api"))]
95pub struct HeapArray<T> {
96    ptr: NonNull<T>,
97    len: usize,
98
99    // NOTE: this marker has no consequences for variance, but is necessary
100    // for dropck to understand that we logically own a `T`.
101    //
102    // For details, see:
103    // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
104    __marker: PhantomData<T>
105}
106
107/// # HeapArray
108/// An Implementation of a variable length array, with its main benefit over [`Vec`] is taking up less space
109/// as [`HeapArray`] is represented as (pointer, len) while [`Vec`] is a (pointer, len, capacity)
110/// and is meant as a replacement for `Box<[T]>`
111///
112/// nice to have: compatible with serde
113///
114/// # Examples
115/// ```
116/// use heap_array::{heap_array, HeapArray};
117/// let arr = heap_array![1, 2, 5, 8];
118///
119/// assert_eq!(arr[0], 1);
120/// assert_eq!(arr[1], 2);
121/// assert_eq!(arr[2], 5);
122/// assert_eq!(arr[3], 8);
123/// assert_eq!(arr.len(), 4);
124///
125/// let arr = HeapArray::from_fn(10, |i| i);
126/// assert_eq!(*arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
127/// ```
128///
129/// [`Vec`]: Vec
130/// [`HeapArray`]: HeapArray
131#[cfg(feature = "allocator-api")]
132pub struct HeapArray<T, #[cfg(feature = "allocator-api")] A: Allocator = Global> {
133    ptr: NonNull<T>,
134    len: usize,
135
136
137    // this is manually drop, so we can run the destructor for the allocation but not the [T] we own
138    #[cfg(feature = "allocator-api")]
139    alloc: ManuallyDrop<A>,
140
141    // NOTE: this marker has no consequences for variance, but is necessary
142    // for dropck to understand that we logically own a `T`.
143    //
144    // For details, see:
145    // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
146    __marker: PhantomData<T>
147}
148
149
150macro_rules! assume {
151    ($cond:expr $(,)?) => {
152        match cfg!(debug_assertions) {
153            true  => assert!($cond, "bad assumption"),
154            false => if !$cond { core::hint::unreachable_unchecked() },
155        }
156    };
157}
158
159pub(crate) use assume;
160
161
162macro_rules! try_from_fn_impl {
163    ($T: ty, $R: ty, $len:expr, $f: expr $(, $alloc:ident)?) => {{
164        let len = $len;
165        
166        if mem::size_of::<$T>() == 0 { 
167            for i in 0..len {
168                // Safety: this loop runs from 0..len
169                unsafe { assume!(i < len) }
170                if let ControlFlow::Break(r) =  $f(i).branch() { 
171                    return <$R>::from_residual(r)
172                }
173            }
174            
175            let ret = 'scope: {
176                #[cfg(feature = "allocator-api")]
177                break 'scope (unsafe { Self::from_raw_parts_in(NonNull::dangling(), len, $($alloc)?) });
178                
179                #[cfg(not(feature = "allocator-api"))]
180                break 'scope (unsafe { Self::from_raw_parts(NonNull::dangling(), len) });
181            };
182            
183            return <$R>::from_element(ret);
184        }
185        
186        
187        let ptr: NonNull<MaybeUninit<$T>> = match alloc_uninit(len $(, &$alloc)?) {
188            Some(ptr) => ptr,
189            None => {
190                #[cfg(feature = "allocator-api")]
191                return <$R>::from_element(Self::new_in($($alloc)?));
192
193                #[cfg(not(feature = "allocator-api"))]
194                return <$R>::from_element(Self::new());
195            },
196        };
197
198        // We use Guard to avoid memory leak in panic's
199        let mut guard = Guard {
200            ptr,
201            len,
202            $(alloc: $alloc,)?
203            initialized: 0
204        };
205        for i in 0..len {
206            // Safety: this loop runs from 0..len
207            unsafe { assume!(i < len) }
208            match $f(i).branch() {
209                ControlFlow::Continue(output) => unsafe { guard.push_unchecked(output) }
210                ControlFlow::Break(r) => { return <$R>::from_residual(r) }
211            }
212        }
213
214        // SAFETY: All elements are initialized
215        <$R>::from_element(unsafe { guard.into_heap_array_unchecked() })
216    }};
217}
218
219macro_rules! from_array_impl {
220    ($T:ty, $array:ident, $N:ident $(, $alloc:ident)?) => {{
221        if mem::size_of::<$T>() == 0 { 
222            #[cfg(feature = "allocator-api")]
223            return unsafe { Self::from_raw_parts_in(NonNull::dangling(), $N, $($alloc)?) };
224            
225            #[cfg(not(feature = "allocator-api"))]
226            return unsafe { Self::from_raw_parts(NonNull::dangling(), $N) };
227        }
228        
229        let ptr: NonNull<MaybeUninit<$T>> = match alloc_uninit($N $(, &$alloc)?) {
230            Some(ptr) => ptr,
231            None => {
232                #[cfg(feature = "allocator-api")]
233                return Self::new_in($($alloc)?);
234
235                #[cfg(not(feature = "allocator-api"))]
236                return Self::new();
237            }
238        };
239
240        let array = ManuallyDrop::new($array);
241        unsafe { ptr::copy_nonoverlapping(array.as_ptr(), ptr.as_ptr() as *mut $T, $N) }
242
243        #[cfg(feature = "allocator-api")]
244        return unsafe { Self::from_raw_parts_in(ptr.cast(), $N, $($alloc)?) };
245
246        #[cfg(not(feature = "allocator-api"))]
247        return unsafe { Self::from_raw_parts(ptr.cast(), $N) };
248    }};
249}
250
251macro_rules! impl_heap_array_inner {
252    // base case for recursion
253    () => {};
254
255    ($(#[$($meta_data:tt)*])* both $item:item $($rest:tt)*) => {
256        $(#[$($meta_data)*])*
257        $item
258
259        impl_heap_array_inner! {$($rest)*}
260    };
261
262    ($(#[$($meta_data:tt)*])* allocator-api $item:item $($rest:tt)*) => {
263        #[cfg(feature = "allocator-api")]
264        $(#[$($meta_data)*])*
265        $item
266
267        impl_heap_array_inner! {$($rest)*}
268    };
269    ($(#[$($meta_data:tt)*])* not(allocator-api) $item:item $($rest:tt)*) => {
270        #[cfg(not(feature = "allocator-api"))]
271        $(#[$($meta_data)*])*
272        $item
273
274
275        impl_heap_array_inner! {$($rest)*}
276    };
277}
278
279macro_rules! impl_heap_array {
280    (impl<$T:ident, Maybe<$A:ident>> HeapArray { $($rest:tt)* } ) => {
281        #[cfg(feature = "allocator-api")]
282        impl<$T, $A: Allocator> HeapArray<$T, $A> {
283            impl_heap_array_inner! {$($rest)*}
284        }
285
286        #[cfg(not(feature = "allocator-api"))]
287        impl<$T> HeapArray<$T> {
288            impl_heap_array_inner! {$($rest)*}
289        }
290    };
291}
292
293impl_heap_array! {
294    impl<T, Maybe<A>> HeapArray {
295        /// Constructs a new, empty [`HeapArray`] without allocating, but bound to an allocator.
296        /// you can get back the allocator by calling [`into_raw_parts_with_alloc`]
297        /// or get a reference to the
298        /// # Examples
299        ///
300        /// ```
301        /// use std::alloc::System;
302        /// use heap_array::HeapArray;
303        /// let vec: HeapArray<i32, System> = HeapArray::new_in(System);
304        /// ```
305        /// [`HeapArray`]: HeapArray
306        /// [`into_raw_parts_with_alloc`]: HeapArray::into_raw_parts_with_alloc
307        #[inline]
308        allocator-api pub const fn new_in(alloc: A) -> Self {
309            unsafe { Self::from_raw_parts_in(NonNull::<T>::dangling(), 0, alloc) }
310        }
311
312        /// Returns `true` if the vector contains no elements.
313        ///
314        /// # Examples
315        ///
316        /// ```
317        /// # use std::any::Any;
318        /// # use heap_array::{heap_array, HeapArray};
319        /// let av: HeapArray<&dyn Any> = HeapArray::new();
320        /// assert!(av.is_empty());
321        ///
322        /// let av = heap_array![1, 2, 3];
323        /// assert!(!av.is_empty());
324        /// ```
325        #[inline]
326        both pub const fn is_empty(&self) -> bool { self.len == 0 }
327
328        /// Returns the number of elements in the heap-array, also referred to
329        /// as its 'length'.
330        ///
331        /// # Examples
332        ///
333        /// ```
334        /// # use heap_array::heap_array;
335        /// let a = heap_array![1, 2, 3];
336        /// assert_eq!(a.len(), 3);
337        /// ```
338        #[inline]
339        both pub const fn len(&self) -> usize { self.len }
340
341        /// Returns a reference to the underlying allocator.
342        #[inline]
343        allocator-api pub fn allocator(&self) -> &A { &self.alloc }
344
345        /// Returns an unsafe mutable pointer to the heap-array's buffer, or a dangling
346        /// raw pointer valid for zero sized reads if the heap-array didn't allocate.
347        ///
348        /// The caller must ensure that the heap-array outlives the pointer this
349        /// function returns, or else it will end up pointing to garbage.
350        /// making any pointers to it invalid.
351        ///
352        /// # Examples
353        ///
354        /// ```
355        /// # use heap_array::HeapArray;
356        /// let len = 6;
357        /// let mut arr: HeapArray<u8> = HeapArray::from_element(len, 0);
358        /// let arr_ptr = arr.as_mut_ptr();
359        ///
360        /// // Change elements via raw pointer writes
361        /// for i in 0..len {
362        ///     unsafe {*arr_ptr.add(i) = i as u8;}
363        /// }
364        /// assert_eq!(*arr, [0, 1, 2, 3, 4, 5]);
365        /// ```
366        #[inline(always)]
367        both pub fn as_mut_ptr(&mut self) -> *mut T {
368            // We shadow the slice method of the same name to avoid going through
369            // `deref_mut`, which creates an intermediate reference.
370            self.ptr.as_ptr()
371        }
372
373        /// Returns a raw pointer to the heap-array's buffer, or a dangling raw pointer
374        /// valid for zero sized reads if the heap-array didn't allocate.
375        ///
376        /// The caller must ensure that the heap-array outlives the pointer this
377        /// function returns, or else it will end up pointing to garbage.
378        /// Modifying the heap-array may cause it's buffer to be reallocated,
379        /// which would also make any pointers to it invalid.
380        ///
381        /// The caller must also ensure that the memory the pointer (non-transitively) points to
382        /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
383        /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
384        ///
385        /// # Examples
386        ///
387        /// ```
388        /// # use heap_array::heap_array;
389        /// let x = heap_array![0, 2, 4, 6, 8];
390        /// let x_ptr = x.as_ptr();
391        ///
392        /// for i in 0..x.len() {
393        ///     unsafe {assert_eq!(*x_ptr.add(i), i * 2);}
394        /// }
395        /// ```
396        ///
397        /// [`as_mut_ptr`]: HeapArray::as_mut_ptr
398        #[inline(always)]
399        both pub const fn as_ptr(&self) -> *const T {
400            // We shadow the slice method of the same name to avoid going through
401            // `deref`, which creates an intermediate reference.
402            self.ptr.as_ptr()
403        }
404
405        /// Extracts a slice containing the entire array.
406        ///
407        /// Equivalent to `&s[..]`.
408        ///
409        /// # Examples
410        ///
411        /// ```
412        /// # use heap_array::heap_array;
413        /// use std::io::{self, Write};
414        /// let buffer = heap_array![1, 2, 3, 5, 8];
415        /// io::sink().write(buffer.as_slice()).unwrap();
416        /// ```
417        #[inline(always)]
418        both pub fn as_slice(&self) -> &[T] { self }
419
420        /// Extracts a mutable slice of the entire array.
421        ///
422        /// Equivalent to `&mut s[..]`.
423        ///
424        /// # Examples
425        ///
426        /// ```
427        /// use std::io::{self, Read};
428        /// # use heap_array::heap_array;
429        /// let mut buffer = heap_array![0; 3];
430        /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
431        /// ```
432        #[inline(always)]
433        both pub fn as_mut_slice(&mut self) -> &mut [T] { self }
434
435        /// Consumes and leaks the [`HeapArray`], returning a mutable reference to the contents,
436        /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
437        /// `'a`. If the type has only static references, or none at all, then this
438        /// may be chosen to be `'static`.
439        ///
440        /// This function is mainly useful for data that lives for the remainder of
441        /// the program's life. Dropping the returned reference will cause a memory
442        /// leak.
443        ///
444        /// # Examples
445        ///
446        /// Simple usage:
447        ///
448        /// ```
449        /// # use heap_array::heap_array;
450        /// # if cfg!(miri) { std::process::exit(0) } // miri doesn't like the leak
451        /// let x = heap_array![1, 2, 3];
452        /// let static_ref: &'static mut [usize] = x.leak();
453        /// static_ref[0] += 1;
454        /// assert_eq!(static_ref, &[2, 2, 3]);
455        /// ```
456        /// [`HeapArray`]: HeapArray
457        allocator-api pub fn leak<'a>(self) -> &'a mut [T] where A: 'a {
458            let (ptr, len) = self.into_raw_parts();
459            unsafe { core::slice::from_raw_parts_mut(ptr.as_ptr(), len) }
460        }
461
462        /// Consumes and leaks the [`HeapArray`], returning a mutable reference to the contents,
463        /// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
464        /// `'a`. If the type has only static references, or none at all, then this
465        /// may be chosen to be `'static`.
466        ///
467        /// This function is mainly useful for data that lives for the remainder of
468        /// the program's life. Dropping the returned reference will cause a memory
469        /// leak.
470        ///
471        /// # Examples
472        ///
473        /// Simple usage:
474        ///
475        /// ```
476        /// # use heap_array::heap_array;
477        /// # if cfg!(miri) { std::process::exit(0) } // miri doesn't like the leak
478        /// let x = heap_array![1, 2, 3];
479        /// let static_ref: &'static mut [usize] = x.leak();
480        /// static_ref[0] += 1;
481        /// assert_eq!(static_ref, &[2, 2, 3]);
482        /// ```
483        /// [`HeapArray`]: HeapArray
484        #[inline]
485        not(allocator-api) pub fn leak<'a>(self) -> &'a mut [T] {
486            let (ptr, len) = self.into_raw_parts();
487            unsafe { core::slice::from_raw_parts_mut(ptr.as_ptr(), len) }
488        }
489
490        /// Decomposes a [`HeapArray`] into its raw components.
491        ///
492        /// Returns the raw pointer to the underlying data, the length of
493        /// the heap-array (in elements) These are the same arguments in the same
494        /// order as the arguments to [`from_raw_parts`].
495        ///
496        /// After calling this function, the caller is responsible for the
497        /// memory previously managed by the [`HeapArray`]. The only way to do
498        /// this is to convert the raw pointer, length back
499        /// into a [`HeapArray`] with the [`from_raw_parts`] function, allowing
500        /// the destructor to perform the cleanup.
501        ///
502        /// # Examples
503        ///
504        /// ```
505        /// # use heap_array::{heap_array, HeapArray};
506        /// let v: HeapArray<i32> = heap_array![-1, 0, 1];
507        ///
508        /// let (ptr, len) = v.into_raw_parts();
509        ///
510        /// let rebuilt = unsafe {
511        ///     // We can now make changes to the components, such as
512        ///     // transmuting the raw pointer to a compatible type.
513        ///     let ptr = ptr.cast::<u32>();
514        ///
515        ///     HeapArray::from_raw_parts(ptr, len)
516        /// };
517        /// assert_eq!(*rebuilt, [4294967295, 0, 1]);
518        /// ```
519        /// [`from_raw_parts`]: HeapArray::from_raw_parts
520        /// [`HeapArray`]: HeapArray
521        #[inline]
522        both pub fn into_raw_parts(self) -> (NonNull<T>, usize) {
523            let this = ManuallyDrop::new(self);
524            (this.ptr, this.len)
525        }
526
527        /// Decomposes a `HeapArray<T>` into its raw components.
528        ///
529        /// Returns the raw pointer to the underlying data, the length of the vector (in elements),
530        /// and the allocator. These are the same arguments in the same order as the arguments to
531        /// [`from_raw_parts_in`].
532        ///
533        /// After calling this function, the caller is responsible for the
534        /// memory previously managed by the `HeapArray`. The only way to do
535        /// this is to convert the raw pointer, length, and capacity back
536        /// into a `HeapArray` with the [`from_raw_parts_in`] function, allowing
537        /// the destructor to perform the cleanup.
538        ///
539        /// [`from_raw_parts_in`]: HeapArray::from_raw_parts_in
540        ///
541        /// # Examples
542        ///
543        /// ```
544        /// #![feature(allocator_api)]
545        ///
546        /// use std::alloc::System;
547        /// use heap_array::HeapArray;
548        ///
549        /// let mut v: HeapArray<i32, System> = HeapArray::from_array_in([-1, 0, 1], System);
550        ///
551        /// let (ptr, len, alloc) = v.into_raw_parts_with_alloc();
552        ///
553        /// let rebuilt = unsafe {
554        ///     // We can now make changes to the components, such as
555        ///     // transmuting the raw pointer to a compatible type.
556        ///     let ptr = ptr.cast::<u32>();
557        ///
558        ///     HeapArray::from_raw_parts_in(ptr, len, alloc)
559        /// };
560        ///
561        /// assert_eq!(*rebuilt, [4294967295, 0, 1]);
562        /// ```
563        #[inline]
564        allocator-api pub fn into_raw_parts_with_alloc(self) -> (NonNull<T>, usize, A) {
565            let this = ManuallyDrop::new(self);
566            // we never use alloc again, and it doesn't get dropped
567            (this.ptr, this.len, unsafe { ptr::read(&*this.alloc) })
568        }
569
570        /// Composes a [`HeapArray`] from its raw components, with an allocator.
571        ///
572        /// After calling this function, the [`HeapArray`] is responsible for the
573        /// memory management. The only way to get this back and get back
574        /// the raw pointer, length and allocator back is with the [`into_raw_parts_with_alloc`] function, granting you
575        /// control of the allocation, and allocator again.
576        /// 
577        /// # Safety:
578        /// must be given from [`into_raw_parts_with_alloc`]
579        /// 
580        /// # Examples
581        ///
582        /// ```
583        /// #![feature(allocator_api)]
584        ///
585        /// use std::alloc::System;
586        /// use heap_array::HeapArray;
587        ///
588        /// let mut v: HeapArray<i32, System> = HeapArray::from_array_in([-1, 0, 1], System);
589        ///
590        /// let (ptr, len, alloc) = v.into_raw_parts_with_alloc();
591        ///
592        /// let rebuilt = unsafe {
593        ///     // We can now make changes to the components, such as
594        ///     // transmuting the raw pointer to a compatible type.
595        ///     let ptr = ptr.cast::<u32>();
596        ///
597        ///     HeapArray::from_raw_parts_in(ptr, len, alloc)
598        /// };
599        ///
600        /// assert_eq!(*rebuilt, [4294967295, 0, 1]);
601        /// ```
602        /// [`into_raw_parts`]: HeapArray::into_raw_parts_with_alloc
603        /// [`HeapArray`]: HeapArray
604        #[inline(always)]
605        allocator-api pub const unsafe fn from_raw_parts_in(ptr: NonNull<T>, len: usize, alloc: A) -> Self {
606            Self { ptr, len, __marker: PhantomData, alloc: ManuallyDrop::new(alloc) }
607        }
608
609        /// Composes a [`HeapArray`] from its raw components.
610        ///
611        /// After calling this function, the [`HeapArray`] is responsible for the
612        /// memory management. The only way to get this back and get back
613        /// the raw pointer and length back is with the [`into_raw_parts`] function, granting you
614        /// control of the allocation again.
615        ///
616        /// # Safety:
617        /// must be given from [`into_raw_parts`]
618        ///
619        /// # Examples
620        ///
621        /// ```
622        /// # use heap_array::{heap_array, HeapArray};
623        /// let v: HeapArray<i32> = heap_array![-1, 0, 1];
624        ///
625        /// let (ptr, len) = v.into_raw_parts();
626        ///
627        /// let rebuilt = unsafe {
628        ///     // We can now make changes to the components, such as
629        ///     // transmuting the raw pointer to a compatible type.
630        ///     let ptr = ptr.cast::<u32>();
631        ///
632        ///     HeapArray::from_raw_parts(ptr, len)
633        /// };
634        /// assert_eq!(*rebuilt, [4294967295, 0, 1]);
635        /// ```
636        /// [`into_raw_parts`]: HeapArray::into_raw_parts
637        /// [`HeapArray`]: HeapArray
638        #[inline(always)]
639        not(allocator-api) pub const unsafe fn from_raw_parts(ptr: NonNull<T>, len: usize) -> Self {
640            Self { ptr, len, __marker: PhantomData }
641        }
642
643        /// Converts `self` into a Box<[T]> without clones or allocation.
644        ///
645        /// The resulting box can be converted back into an [`HeapArray`] via
646        /// `Box<[T]>`'s `into()` method or by calling `HeapArray::from(box)`.
647        ///
648        /// this is usually due to a library requiring `Box<[T]>` to be used
649        /// as HeapArray is supposed to be the replacement for `Box<[T]>`
650        ///
651        /// # Examples
652        ///
653        /// ```
654        /// # use heap_array::{heap_array, HeapArray};
655        /// let s: HeapArray<u32> = heap_array![10, 40, 30];
656        /// let x = s.into_boxed_slice();
657        /// // `s` cannot be used anymore because it has been converted into `x`.
658        ///
659        /// let y: Box<[u32]> = Box::new([10, 40, 30]);
660        /// assert_eq!(x, y);
661        /// ```
662        #[inline]
663        allocator-api pub fn into_boxed_slice(self) -> Box<[T], A> {
664            let (ptr, len, alloc) = self.into_raw_parts_with_alloc();
665            let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), len);
666            unsafe { Box::from_raw_in(ptr, alloc) }
667        }
668
669        /// Converts `self` into a Box<[T]> without clones or allocation.
670        ///
671        /// The resulting box can be converted back into an [`HeapArray`] via
672        /// `Box<[T]>`'s `into()` method or by calling `HeapArray::from(box)`.
673        ///
674        /// this is usually due to a library requiring `Box<[T]>` to be used
675        /// as HeapArray is supposed to be the replacement for `Box<[T]>`
676        ///
677        /// # Examples
678        ///
679        /// ```
680        /// # use heap_array::{heap_array, HeapArray};
681        /// let s: HeapArray<u32> = heap_array![10, 40, 30];
682        /// let x = s.into_boxed_slice();
683        /// // `s` cannot be used anymore because it has been converted into `x`.
684        ///
685        /// let y: Box<[u32]> = Box::new([10, 40, 30]);
686        /// assert_eq!(x, y);
687        /// ```
688        #[inline]
689        not(allocator-api) pub fn into_boxed_slice(self) -> Box<[T]> {
690            let (ptr, len) = self.into_raw_parts();
691            let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), len);
692            unsafe { Box::from_raw(ptr) }
693        }
694
695        /// Converts `self` into a vector without clones or allocation.
696        ///
697        /// The resulting vector can be converted back into an [`HeapArray`] via
698        /// `Vec<T>`'s `into()` method or by calling `HeapArray::from(vec)`.
699        ///
700        /// Should only be used if you plan to resizing, otherwise use `into_boxed_slice` for a smaller
701        /// type
702        /// # Examples
703        ///
704        /// ```
705        /// # use heap_array::{heap_array, HeapArray};
706        /// let s: HeapArray<u32> = heap_array![10, 40, 30];
707        /// let x = s.into_vec();
708        /// // `s` cannot be used anymore because it has been converted into `x`.
709        ///
710        /// assert_eq!(x, vec![10, 40, 30]);
711        /// ```
712        #[inline]
713        allocator-api pub fn into_vec(self) -> Vec<T, A> {
714            self.into()
715        }
716
717        /// Converts `self` into a vector without clones or allocation.
718        ///
719        /// The resulting vector can be converted back into an [`HeapArray`] via
720        /// `Vec<T>`'s `into()` method or by calling `HeapArray::from(vec)`.
721        ///
722        /// Should only be used if you plan to resizing, otherwise use `into_boxed_slice` for a smaller
723        /// type
724        /// # Examples
725        ///
726        /// ```
727        /// # use heap_array::{heap_array, HeapArray};
728        /// let s: HeapArray<u32> = heap_array![10, 40, 30];
729        /// let x = s.into_vec();
730        /// // `s` cannot be used anymore because it has been converted into `x`.
731        ///
732        /// assert_eq!(x, vec![10, 40, 30]);
733        /// ```
734        #[inline]
735        not(allocator-api) pub fn into_vec(self) -> Vec<T> {
736            self.into()
737        }
738
739        /// Creates a [`HeapArray`], where each element `T` is the returned value from `f`
740        /// using that element's index.
741        ///
742        /// # Arguments
743        ///
744        /// * `len`: length of the array.
745        /// * `f`: function where the passed argument is the current array index.
746        /// * `alloc`: the allocator used to allocate the heap array
747        ///
748        /// # Example
749        ///
750        /// ```rust
751        /// #![feature(allocator_api)]
752        ///
753        /// use std::alloc::{System};
754        /// use heap_array::HeapArray;
755        /// let array: HeapArray<i32, System> = HeapArray::from_fn_in(5, |i| i as i32, System);
756        /// // indexes are:     0  1  2  3  4
757        /// assert_eq!(*array, [0, 1, 2, 3, 4]);
758        ///
759        /// let array2: HeapArray<i32, System> = HeapArray::from_fn_in(8, |i| i as i32 * 2, System);
760        /// // indexes are:     0  1  2  3  4  5   6   7
761        /// assert_eq!(*array2, [0, 2, 4, 6, 8, 10, 12, 14]);
762        ///
763        /// let bool_arr: HeapArray<bool, System> = HeapArray::from_fn_in(5, |i| i % 2 == 0, System);
764        /// // indexes are:       0     1      2     3      4
765        /// assert_eq!(*bool_arr, [true, false, true, false, true]);
766        /// ```
767        /// [`HeapArray`]: HeapArray
768        #[inline]
769        allocator-api pub fn from_fn_in(len: usize, f: impl FnMut(usize) -> T, alloc: A) -> Self {
770            Self::try_from_fn_in(len, NeverShortCircuit::wrap_fn(f), alloc)
771        }
772
773        /// Creates a [`HeapArray`] in an allocator, where each element `T` is the returned value from `cb`
774        /// using that element's index.
775        /// Unlike [`from_fn_in`], where the element creation can't fail, this version will return an error
776        /// if any element creation was unsuccessful.
777        ///
778        /// The return type of this function depends on the return type of the closure.
779        /// If you return `Result<T, E>` from the closure, you'll get a `Result<HeapArray<T>, E>`.
780        /// If you return `Option<T>` from the closure, you'll get an `Option<HeapArray<T>>`.
781        /// # Arguments
782        ///
783        /// * `len`: length of the array.
784        /// * `f`: function where the passed argument is the current array index, and it is guaranteed to run with values from 0..`len` in ascending order.
785        /// * `alloc`: allocator used to allocate the array
786        ///
787        /// # Example
788        ///
789        /// ```rust
790        /// use std::alloc::System;
791        /// use heap_array::HeapArray;
792        /// let array: Result<HeapArray<u8, System>, _> = HeapArray::try_from_fn_in(5, |i| i.try_into(), System);
793        /// assert_eq!(array.as_deref(), Ok([0, 1, 2, 3, 4].as_ref()));
794        ///
795        /// let array: Result<HeapArray<i8, System>, _> = HeapArray::try_from_fn_in(200, |i| i.try_into(), System);
796        /// assert!(array.is_err());
797        ///
798        /// let array: Option<HeapArray<usize, System>> = HeapArray::try_from_fn_in(4, |i| i.checked_add(100), System);
799        /// assert_eq!(array.as_deref(), Some([100, 101, 102, 103].as_ref()));
800        ///
801        /// let array: Option<HeapArray<usize, System>> = HeapArray::try_from_fn_in(4, |i| i.checked_sub(100), System);
802        /// assert_eq!(array, None);
803        /// ```
804        /// [`HeapArray`]: HeapArray
805        /// [`from_fn`]: HeapArray::from_fn
806        allocator-api pub fn try_from_fn_in<R>(
807            len: usize,
808            mut f: impl FnMut(usize) -> R,
809            alloc: A
810        ) -> R::TryType<Self> where R: Try<Output=T>
811        { try_from_fn_impl!(T, R, len, f, alloc) }
812
813        /// Create a [`HeapArray`] from a given element and size.
814        ///
815        ///
816        /// This is a specialization of `HeapArray::from_fn(len, |_| element.clone())`
817        /// and may result in a minor speed up over it.
818        ///
819        /// This will use `clone` to duplicate an expression, so one should be careful
820        /// using this with types having a nonstandard `Clone` implementation. For
821        /// example, `HeapArray::from_element(5, Rc::new(1))` will create a heap-array of five references
822        /// to the same boxed integer value, not five references pointing to independently
823        /// boxed integers.
824        ///
825        /// Also, note that `HeapArray::from_element(0, expr)` is allowed, and produces an empty HeapArray.
826        /// This will still evaluate `expr`, however, and immediately drop the resulting value, so
827        /// be mindful of side effects.
828        ///
829        /// # Example
830        ///
831        /// ```rust
832        /// # use heap_array::HeapArray;
833        /// let array: HeapArray<u8> = HeapArray::from_element(5, 68);
834        /// assert_eq!(*array, [68, 68, 68, 68, 68])
835        /// ```
836        /// [`HeapArray`]: HeapArray
837        /// [`heap_array`]: heap_array
838        #[inline]
839        allocator-api pub fn from_element_in(len: usize, element: T, alloc: A) -> Self
840            where T: Clone
841        {
842            // We use vec![] rather than Self::from_fn(len, |_| element.clone())
843            // as it has specialization traits for manny things Such as zero initialization
844            // as well as avoid an extra copy (caused by not using element except for cloning)
845            vec::from_elem_in(element, len, alloc).into()
846        }
847        /// Copies a slice into a new `HeapArray` with an allocator.
848        ///
849        /// # Examples
850        ///
851        /// ```
852        /// #![feature(allocator_api)]
853        ///
854        /// use std::alloc::System;
855        /// use heap_array::HeapArray;
856        ///
857        /// let s = [10, 40, 30];
858        /// let x = HeapArray::from_slice_in(&s, System);
859        /// // Here, `s` and `x` can be modified independently.
860        /// ```
861        #[inline]
862        allocator-api pub fn from_slice_in(slice: &[T], alloc: A) -> HeapArray<T, A>
863            where T: Clone
864        {
865            // HeapArray::from_fn_in(slice.len(), |i| {
866            //     // Safety: from_fn provides values 0..len
867            //     // and all values gotten should be within that range
868            //     match cfg!(debug_assertions) {
869            //         true => slice.get(i).expect("heapArray cloning out of bounds").clone(),
870            //         false => unsafe { slice.get_unchecked(i).clone() }
871            //     }
872            // }, alloc)
873
874
875            // we use this for specialization on Copy T
876            <[T]>::to_vec_in(slice, alloc).into()
877        }
878
879        /// Allocate a `HeapArray<T>` with a custom allocator and move the array's items into it.
880        ///
881        /// # Examples
882        ///
883        /// ```
884        /// use heap_array::{heap_array, HeapArray};
885        ///
886        /// assert_eq!(HeapArray::from_array([1, 2, 3]), heap_array![1, 2, 3]);
887        /// ```
888        allocator-api pub fn from_array_in<const N: usize>(array: [T; N], alloc: A) -> HeapArray<T, A> {
889            from_array_impl!(T, array, N, alloc)
890        }
891
892        /// Constructs a new, empty [`HeapArray`] without allocating.
893        ///
894        /// # Examples
895        ///
896        /// ```
897        /// # use heap_array::HeapArray;
898        /// let vec: HeapArray<i32> = HeapArray::new();
899        /// ```
900        /// [`HeapArray`]: HeapArray
901        #[inline(always)]
902        not(allocator-api) pub const fn new() -> Self {
903            unsafe { HeapArray::from_raw_parts(NonNull::<T>::dangling(), 0) }
904        }
905
906        /// Creates a [`HeapArray`], where each element `T` is the returned value from `cb`
907        /// using that element's index.
908        ///
909        /// # Arguments
910        ///
911        /// * `len`: length of the array.
912        /// * `f`: function where the passed argument is the current array index.
913        ///
914        /// # Example
915        ///
916        /// ```rust
917        /// # use heap_array::HeapArray;
918        /// let array = HeapArray::from_fn(5, |i| i);
919        /// // indexes are:     0  1  2  3  4
920        /// assert_eq!(*array, [0, 1, 2, 3, 4]);
921        ///
922        /// let array2 = HeapArray::from_fn(8, |i| i * 2);
923        /// // indexes are:     0  1  2  3  4  5   6   7
924        /// assert_eq!(*array2, [0, 2, 4, 6, 8, 10, 12, 14]);
925        ///
926        /// let bool_arr = HeapArray::from_fn(5, |i| i % 2 == 0);
927        /// // indexes are:       0     1      2     3      4
928        /// assert_eq!(*bool_arr, [true, false, true, false, true]);
929        /// ```
930        /// [`HeapArray`]: HeapArray
931        #[inline]
932        not(allocator-api) pub fn from_fn(len: usize, f: impl FnMut(usize) -> T) -> Self {
933            HeapArray::try_from_fn(len, NeverShortCircuit::wrap_fn(f))
934        }
935
936        /// Creates a [`HeapArray`], where each element `T` is the returned value from `cb`
937        /// using that element's index.
938        /// Unlike [`from_fn`], where the element creation can't fail, this version will return an error
939        /// if any element creation was unsuccessful.
940        ///
941        /// The return type of this function depends on the return type of the closure.
942        /// If you return `Result<T, E>` from the closure, you'll get a `Result<HeapArray<T>, E>`.
943        /// If you return `Option<T>` from the closure, you'll get an `Option<HeapArray<T>>`.
944        /// # Arguments
945        ///
946        /// * `len`: length of the array.
947        /// * `f`: function where the passed argument is the current array index, and it is guaranteed to run with values from 0..`len` in ascending order.
948        ///
949        /// # Example
950        ///
951        /// ```rust
952        /// # use heap_array::HeapArray;
953        /// let array: Result<HeapArray<u8>, _> = HeapArray::try_from_fn(5, |i| i.try_into());
954        /// assert_eq!(array.as_deref(), Ok([0, 1, 2, 3, 4].as_ref()));
955        ///
956        /// let array: Result<HeapArray<i8>, _> = HeapArray::try_from_fn(200, |i| i.try_into());
957        /// assert!(array.is_err());
958        ///
959        /// let array: Option<HeapArray<usize>> = HeapArray::try_from_fn(4, |i| i.checked_add(100));
960        /// assert_eq!(array.as_deref(), Some([100, 101, 102, 103].as_ref()));
961        ///
962        /// let array: Option<HeapArray<usize>> = HeapArray::try_from_fn(4, |i| i.checked_sub(100));
963        /// assert_eq!(array, None);
964        /// ```
965        /// [`HeapArray`]: HeapArray
966        /// [`from_fn`]: HeapArray::from_fn
967        not(allocator-api) pub fn try_from_fn<R>(len: usize, mut f: impl FnMut(usize) -> R) -> R::TryType<Self>
968            where R: Try<Output=T>
969        {
970            try_from_fn_impl!(T, R, len, f)
971        }
972
973        /// Create a [`HeapArray`] from a given element and size.
974        ///
975        ///
976        /// This is a specialization of `HeapArray::from_fn(len, |_| element.clone())`
977        /// and may result in a minor speed up over it.
978        ///
979        /// This will use `clone` to duplicate an expression, so one should be careful
980        /// using this with types having a nonstandard `Clone` implementation. For
981        /// example, `Self::from_element(5, Rc::new(1))` will create a heap-array of five references
982        /// to the same boxed integer value, not five references pointing to independently
983        /// boxed integers.
984        ///
985        /// Also, note that `Self::from_element(0, expr)` is allowed, and produces an empty HeapArray.
986        /// This will still evaluate `expr`, however, and immediately drop the resulting value, so
987        /// be mindful of side effects.
988        ///
989        /// Also, note `Self::from_element(n, expr)` can always be replaced with `heap_array![expr; n]`
990        /// # Example
991        ///
992        /// ```rust
993        /// # use heap_array::HeapArray;
994        /// let array: HeapArray<u8> = HeapArray::from_element(5, 68);
995        /// assert_eq!(*array, [68, 68, 68, 68, 68])
996        /// ```
997        /// [`HeapArray`]: HeapArray
998        /// [`heap_array`]: heap_array
999        #[inline(always)]
1000        not(allocator-api) pub fn from_element(len: usize, element: T) -> Self
1001            where T: Clone
1002        {
1003            // We use vec![] rather than Self::from_fn(len, |_| element.clone())
1004            // as it has specialization traits for manny things Such as zero initialization
1005            // as well as avoid an extra clone (caused by not using element except for cloning)
1006            vec::from_elem(element, len).into()
1007        }
1008
1009        /// Copies a slice into a new `HeapArray`.
1010        ///
1011        /// # Examples
1012        ///
1013        /// ```
1014        /// #![feature(allocator_api)]
1015        ///
1016        /// use std::alloc::System;
1017        /// use heap_array::HeapArray;
1018        ///
1019        /// let s = [10, 40, 30];
1020        /// let x = HeapArray::from_slice(&s);
1021        /// // Here, `s` and `x` can be modified independently.
1022        /// ```
1023        #[inline(always)]
1024        not(allocator-api) pub fn from_slice(slice: &[T]) -> Self
1025            where T: Clone
1026        {
1027            // we use this for specialization on Copy T
1028            <[T]>::to_vec(slice).into()
1029        }
1030
1031        /// Allocate a `HeapArray<T>` and move the array's items into it.
1032        ///
1033        /// # Examples
1034        ///
1035        /// ```
1036        /// use heap_array::{heap_array, HeapArray};
1037        ///
1038        /// assert_eq!(HeapArray::from_array([1, 2, 3]), heap_array![1, 2, 3]);
1039        /// ```
1040        not(allocator-api) pub fn from_array<const N: usize>(array: [T; N]) -> Self {
1041            from_array_impl!(T, array, N)
1042        }
1043
1044        /// Safety: Caller must uphold
1045        /// Must ensure the HeapArray won't be dropped afterward
1046        /// and that it won't be accessed later
1047        #[inline]
1048        both pub(crate) unsafe fn drop_memory(&mut self) {
1049            if self.len != 0 {
1050                // size is always less than isize::MAX we checked that already
1051                // By using Layout::array::<T> to allocate
1052                let size = mem::size_of::<T>().unchecked_mul(self.len);
1053                let align = mem::align_of::<T>();
1054
1055                let layout = Layout::from_size_align_unchecked(size, align);
1056                #[cfg(feature = "allocator-api")]
1057                self.alloc.deallocate(self.ptr.cast(), layout);
1058                #[cfg(not(feature = "allocator-api"))]
1059                alloc::alloc::dealloc(self.ptr.as_ptr() as *mut u8, layout);
1060            }
1061            #[cfg(feature = "allocator-api")]
1062            if mem::needs_drop::<A>() { unsafe { ManuallyDrop::drop(&mut self.alloc) } }
1063        }
1064    }
1065}
1066
1067#[cfg(feature = "allocator-api")]
1068impl<T> HeapArray<T, Global> {
1069    /// Copies a slice into a new `HeapArray`.
1070    ///
1071    /// # Examples
1072    ///
1073    /// ```
1074    /// #![feature(allocator_api)]
1075    ///
1076    /// use std::alloc::System;
1077    /// use heap_array::HeapArray;
1078    ///
1079    /// let s = [10, 40, 30];
1080    /// let x = HeapArray::from_slice(&s);
1081    /// // Here, `s` and `x` can be modified independently.
1082    /// ```
1083    #[inline(always)]
1084    pub fn from_slice(slice: &[T]) -> Self
1085        where T: Clone
1086    { HeapArray::<T, Global>::from_slice_in(slice, Global) }
1087
1088    /// Create a [`HeapArray`] from a given element and size.
1089    ///
1090    ///
1091    /// This is a specialization of `HeapArray::from_fn(len, |_| element.clone())`
1092    /// and may result in a minor speed up over it.
1093    ///
1094    /// This will use `clone` to duplicate an expression, so one should be careful
1095    /// using this with types having a nonstandard `Clone` implementation. For
1096    /// example, `Self::from_element(5, Rc::new(1))` will create a heap-array of five references
1097    /// to the same boxed integer value, not five references pointing to independently
1098    /// boxed integers.
1099    ///
1100    /// Also, note that `Self::from_element(0, expr)` is allowed, and produces an empty HeapArray.
1101    /// This will still evaluate `expr`, however, and immediately drop the resulting value, so
1102    /// be mindful of side effects.
1103    ///
1104    /// Also, note `Self::from_element(n, expr)` can always be replaced with `heap_array![expr; n]`
1105    /// # Example
1106    ///
1107    /// ```rust
1108    /// # use heap_array::HeapArray;
1109    /// let array: HeapArray<u8> = HeapArray::from_element(5, 68);
1110    /// assert_eq!(*array, [68, 68, 68, 68, 68])
1111    /// ```
1112    /// [`HeapArray`]: HeapArray
1113    /// [`heap_array`]: heap_array
1114    #[inline(always)]
1115    pub fn from_element(len: usize, element: T) -> Self
1116        where T: Clone
1117    { HeapArray::<T, Global>::from_element_in(len, element, Global) }
1118
1119    /// Allocate a `HeapArray<T>` and move the array's items into it.
1120    ///
1121    /// # Examples
1122    ///
1123    /// ```
1124    /// use heap_array::{heap_array, HeapArray};
1125    ///
1126    /// assert_eq!(HeapArray::from_array([1, 2, 3]), heap_array![1, 2, 3]);
1127    /// ```
1128    #[inline(always)]
1129    pub fn from_array<const N: usize>(array: [T; N]) -> Self
1130    { HeapArray::<T, Global>::from_array_in(array, Global) }
1131
1132    /// Creates a [`HeapArray`], where each element `T` is the returned value from `cb`
1133    /// using that element's index.
1134    /// Unlike [`from_fn`], where the element creation can't fail, this version will return an error
1135    /// if any element creation was unsuccessful.
1136    ///
1137    /// The return type of this function depends on the return type of the closure.
1138    /// If you return `Result<T, E>` from the closure, you'll get a `Result<HeapArray<T>, E>`.
1139    /// If you return `Option<T>` from the closure, you'll get an `Option<HeapArray<T>>`.
1140    /// # Arguments
1141    ///
1142    /// * `len`: length of the array.
1143    /// * `f`: function where the passed argument is the current array index, and it is guaranteed to run with values from 0..`len` in ascending order.
1144    ///
1145    /// # Example
1146    ///
1147    /// ```rust
1148    /// # use heap_array::HeapArray;
1149    /// let array: Result<HeapArray<u8>, _> = HeapArray::try_from_fn(5, |i| i.try_into());
1150    /// assert_eq!(array.as_deref(), Ok([0, 1, 2, 3, 4].as_ref()));
1151    ///
1152    /// let array: Result<HeapArray<i8>, _> = HeapArray::try_from_fn(200, |i| i.try_into());
1153    /// assert!(array.is_err());
1154    ///
1155    /// let array: Option<HeapArray<usize>> = HeapArray::try_from_fn(4, |i| i.checked_add(100));
1156    /// assert_eq!(array.as_deref(), Some([100, 101, 102, 103].as_ref()));
1157    ///
1158    /// let array: Option<HeapArray<usize>> = HeapArray::try_from_fn(4, |i| i.checked_sub(100));
1159    /// assert_eq!(array, None);
1160    /// ```
1161    /// [`HeapArray`]: HeapArray
1162    /// [`from_fn`]: HeapArray::from_fn
1163    #[inline(always)]
1164    pub  fn try_from_fn<R>(len: usize, f: impl FnMut(usize) -> R) -> R::TryType<Self>
1165        where R: Try<Output=T>
1166    { HeapArray::<T, Global>::try_from_fn_in(len, f, Global) }
1167
1168    /// Creates a [`HeapArray`], where each element `T` is the returned value from `cb`
1169    /// using that element's index.
1170    ///
1171    /// # Arguments
1172    ///
1173    /// * `len`: length of the array.
1174    /// * `f`: function where the passed argument is the current array index.
1175    ///
1176    /// # Example
1177    ///
1178    /// ```rust
1179    /// # use heap_array::HeapArray;
1180    /// let array = HeapArray::from_fn(5, |i| i);
1181    /// // indexes are:     0  1  2  3  4
1182    /// assert_eq!(*array, [0, 1, 2, 3, 4]);
1183    ///
1184    /// let array2 = HeapArray::from_fn(8, |i| i * 2);
1185    /// // indexes are:     0  1  2  3  4  5   6   7
1186    /// assert_eq!(*array2, [0, 2, 4, 6, 8, 10, 12, 14]);
1187    ///
1188    /// let bool_arr = HeapArray::from_fn(5, |i| i % 2 == 0);
1189    /// // indexes are:       0     1      2     3      4
1190    /// assert_eq!(*bool_arr, [true, false, true, false, true]);
1191    /// ```
1192    /// [`HeapArray`]: HeapArray
1193    #[inline(always)]
1194    pub fn from_fn(len: usize, f: impl FnMut(usize) -> T) -> Self {
1195        HeapArray::<T, Global>::from_fn_in(len, f, Global)
1196    }
1197
1198    /// Constructs a new, empty [`HeapArray`] without allocating.
1199    ///
1200    /// # Examples
1201    ///
1202    /// ```
1203    /// # use heap_array::HeapArray;
1204    /// let vec: HeapArray<i32> = HeapArray::new();
1205    /// ```
1206    /// [`HeapArray`]: HeapArray
1207    #[inline(always)]
1208    pub const fn new() -> Self {
1209        HeapArray::<T, Global>::new_in(Global)
1210    }
1211
1212    /// Composes a [`HeapArray`] from its raw components.
1213    ///
1214    /// After calling this function, the [`HeapArray`] is responsible for the
1215    /// memory management. The only way to get this back and get back
1216    /// the raw pointer and length back is with the [`into_raw_parts`] function, granting you
1217    /// control of the allocation again.
1218    ///
1219    /// # Safety:
1220    /// must be given from [`into_raw_parts`]
1221    ///
1222    /// # Examples
1223    ///
1224    /// ```
1225    /// # use heap_array::{heap_array, HeapArray};
1226    /// let v: HeapArray<i32> = heap_array![-1, 0, 1];
1227    ///
1228    /// let (ptr, len) = v.into_raw_parts();
1229    ///
1230    /// let rebuilt = unsafe {
1231    ///     // We can now make changes to the components, such as
1232    ///     // transmuting the raw pointer to a compatible type.
1233    ///     let ptr = ptr.cast::<u32>();
1234    ///
1235    ///     HeapArray::from_raw_parts(ptr, len)
1236    /// };
1237    /// assert_eq!(*rebuilt, [4294967295, 0, 1]);
1238    /// ```
1239    /// [`into_raw_parts`]: HeapArray::into_raw_parts
1240    /// [`HeapArray`]: HeapArray
1241    #[inline(always)]
1242    pub const unsafe fn from_raw_parts(ptr: NonNull<T>, len: usize) -> HeapArray<T> {
1243        HeapArray::<T, Global>::from_raw_parts_in(ptr, len, Global)
1244    }
1245}
1246
1247macro_rules! identical_impl {
1248    // base case for recursion
1249    () => {  };
1250    (
1251        impl<$($time: lifetime, )?  T $(: {$($t_restrict:tt)+})?, $({$($generics:tt)*},)? Maybe<A $(: {$( $($alloc_restrict:tt)+ )&+})?>> {$($Trait:tt)+} for HeapArray<T, Maybe<A>> $(where {$($restrict:tt)*})? {
1252            $($r#impl:tt)*
1253        }
1254        $($rest:tt)*
1255    ) => {
1256        #[cfg(not(feature = "allocator-api"))]
1257        impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)?> $($Trait)+ for HeapArray<T> $(where $($restrict)*)? {
1258            $($r#impl)*
1259        }
1260        #[cfg(feature = "allocator-api")]
1261        impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)? A: Allocator $(+ $($($alloc_restrict)*)+)?> $($Trait)+ for HeapArray<T, A> $(where $($restrict)*)? {
1262            $($r#impl)*
1263        }
1264
1265        identical_impl! { $($rest)* }
1266    };
1267    (
1268        impl<$($time: lifetime, )?  T $(: {$($t_restrict:tt)+})?, $({$($generics:tt)*},)? Maybe<A $(: {$( $($alloc_restrict:tt)+ )&+})?>> {$($Trait:tt)+} for &$other_time:lifetime $(($mut:tt))? HeapArray<T, Maybe<A>> $(where {$($restrict:tt)*})? {
1269            $($r#impl:tt)*
1270        }
1271        $($rest:tt)*
1272    ) => {
1273        #[cfg(not(feature = "allocator-api"))]
1274        impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)?> $($Trait)+ for &$other_time $($mut)? HeapArray<T> $(where $($restrict)*)? {
1275            $($r#impl)*
1276        }
1277        #[cfg(feature = "allocator-api")]
1278        impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)? A: Allocator $(+ $($($alloc_restrict)*)+)?> $($Trait)+ for &$other_time $($mut)? HeapArray<T, A> $(where $($restrict)*)? {
1279            $($r#impl)*
1280        }
1281
1282        identical_impl! { $($rest)* }
1283    };
1284    (
1285        unsafe impl<$($time: lifetime, )? T $(: {$($t_restrict:tt)+})?, $({$($generics:tt)*},)? Maybe<A$(: {$( $($alloc_restrict:tt)+ )&+})?>> {$($Trait:tt)+} for HeapArray<T, Maybe<A>> $(where {$($restrict:tt)*})? {
1286            $($r#impl:tt)*
1287        }
1288        $($rest:tt)*
1289    ) => {
1290        #[cfg(not(feature = "allocator-api"))]
1291        unsafe impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)?> $($Trait)+ for HeapArray<T> $(where $($restrict)*)? {
1292            $($r#impl)*
1293        }
1294        #[cfg(feature = "allocator-api")]
1295        unsafe impl<$($time, )? T $(: $($t_restrict)+)?, $($($generics)*,)? A: Allocator $(+ $($($alloc_restrict)*)+)?> $($Trait)+ for HeapArray<T, A> $(where $($restrict)*)? {
1296            $($r#impl)*
1297        }
1298
1299        identical_impl! {$($rest)*}
1300    };
1301}
1302
1303
1304impl<T> Default for HeapArray<T> {
1305    #[inline]
1306    fn default() -> Self {
1307        Self::new()
1308    }
1309}
1310
1311impl<T: Clone> From<&[T]> for HeapArray<T> {
1312    #[inline(always)]
1313    fn from(slice: &[T]) -> Self { HeapArray::from_slice(slice) }
1314}
1315
1316impl<T, const N: usize> From<[T; N]> for HeapArray<T> {
1317    fn from(values: [T; N]) -> Self {
1318        Self::from_array(values)
1319    }
1320}
1321
1322#[cfg(not(feature = "allocator-api"))]
1323impl<T> From<Box<[T]>> for HeapArray<T> {
1324    #[inline]
1325    fn from(value: Box<[T]>) -> Self {
1326        let raw = Box::into_raw(value);
1327        unsafe {
1328            // A box pointer will always be a properly aligned non-null pointer.
1329            Self::from_raw_parts(NonNull::new_unchecked(raw.cast()), (*raw).len())
1330        }
1331    }
1332}
1333
1334#[cfg(feature = "allocator-api")]
1335impl<T, A: Allocator> From<Box<[T], A>> for HeapArray<T, A> {
1336    #[inline]
1337    fn from(value: Box<[T], A>) -> Self {
1338        let (parts, alloc) = Box::into_raw_with_allocator(value);
1339        unsafe {
1340            // A box pointer will always be a properly aligned non-null pointer.
1341            Self::from_raw_parts_in(NonNull::new_unchecked(parts.cast()), (*parts).len(), alloc)
1342        }
1343    }
1344}
1345
1346#[cfg(not(feature = "allocator-api"))]
1347impl<T> From<Vec<T>> for HeapArray<T> {
1348    #[inline]
1349    fn from(value: Vec<T>) -> Self {
1350        Self::from(value.into_boxed_slice())
1351    }
1352}
1353
1354#[cfg(feature = "allocator-api")]
1355impl<T, A: Allocator> From<Vec<T, A>> for HeapArray<T, A> {
1356    #[inline]
1357    fn from(value: Vec<T, A>) -> Self {
1358        Self::from(value.into_boxed_slice())
1359    }
1360}
1361
1362
1363
1364// error[E0210] when trying to do these with alloc-api
1365impl<T> From<HeapArray<T>> for Box<[T]> {
1366    #[inline]
1367    fn from(value: HeapArray<T>) -> Self {
1368        value.into_boxed_slice()
1369    }
1370}
1371
1372impl<T, const N: usize> TryFrom<HeapArray<T>> for Box<[T; N]> {
1373    type Error = HeapArray<T>;
1374
1375    fn try_from(value: HeapArray<T>) -> Result<Self, Self::Error> {
1376        if value.len != N {
1377            Err(value)
1378        } else {
1379            let value = ManuallyDrop::new(value);
1380            let ptr = value.ptr;
1381            
1382            let ptr = ptr.as_ptr() as *mut [T; N];
1383            Ok(unsafe { Box::from_raw(ptr) })
1384        }
1385    }
1386}
1387
1388
1389
1390#[cfg(not(feature = "allocator-api"))]
1391impl<T> From<HeapArray<T>> for Vec<T> {
1392    #[inline]
1393    fn from(value: HeapArray<T>) -> Self {
1394        let (ptr, len) = value.into_raw_parts();
1395        unsafe { Vec::from_raw_parts(ptr.as_ptr(), len, len) }
1396    }
1397}
1398
1399#[cfg(feature = "allocator-api")]
1400impl<T, A: Allocator> From<HeapArray<T, A>> for Vec<T, A> {
1401    #[inline]
1402    fn from(value: HeapArray<T, A>) -> Self {
1403        let (ptr, len, alloc) = value.into_raw_parts_with_alloc();
1404        unsafe { Vec::from_raw_parts_in(ptr.as_ptr(), len, len, alloc) }
1405    }
1406}
1407
1408
1409macro_rules! try_to_array_impl {
1410    ($T: ty, $N: expr, $value: ident) => {{
1411        if $value.len != $N {
1412            return Err($value)
1413        }
1414
1415        let mut value = ManuallyDrop::new($value);
1416        // valid ptr for at least $N values
1417        let data: [$T; $N] = unsafe { ptr::read(value.as_ptr() as *const [$T; $N]) };
1418        // Safety: value is a ManuallyDrop and so it wont be dropped
1419        // and since we take ownership of value it wont be accessed after this
1420        unsafe { value.drop_memory() }
1421
1422        Ok(data)
1423    }};
1424}
1425
1426#[cfg(feature = "allocator-api")]
1427impl<T, A: Allocator, const N: usize> TryFrom<HeapArray<T, A>> for [T; N] {
1428    type Error = HeapArray<T, A>;
1429
1430    fn try_from(value: HeapArray<T, A>) -> Result<[T; N], Self::Error> {
1431        try_to_array_impl! (T, N, value)
1432    }
1433}
1434
1435#[cfg(not(feature = "allocator-api"))]
1436impl<T, const N: usize> TryFrom<HeapArray<T>> for [T; N] {
1437    type Error = HeapArray<T>;
1438
1439    fn try_from(value: HeapArray<T>) -> Result<[T; N], Self::Error> {
1440        try_to_array_impl! (T, N, value)
1441    }
1442}
1443
1444
1445identical_impl! {
1446    impl<T: {Clone}, Maybe<A: {Clone}>> {Clone} for HeapArray<T, Maybe<A>> {
1447        fn clone(&self) -> Self {
1448            #[cfg(not(feature = "allocator-api"))]
1449            {HeapArray::from_slice(self)}
1450            #[cfg(feature = "allocator-api")]
1451            {HeapArray::from_slice_in(self, self.allocator().clone())}
1452        }
1453    }
1454
1455}
1456
1457
1458identical_impl! {
1459    impl<T: {Hash}, Maybe<A>> {Hash} for HeapArray<T, Maybe<A>> {
1460        fn hash<H: Hasher>(&self, state: &mut H) {
1461            <[T] as Hash>::hash(self.deref(), state)
1462        }
1463    }
1464
1465    impl<T, Maybe<A>> {Deref} for HeapArray<T, Maybe<A>> {
1466        type Target = [T];
1467
1468        fn deref(&self) -> &Self::Target {
1469            unsafe { core::slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
1470        }
1471    }
1472
1473    impl<T, Maybe<A>> {DerefMut} for HeapArray<T, Maybe<A>> {
1474        fn deref_mut(&mut self) -> &mut Self::Target {
1475            unsafe { core::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
1476        }
1477    }
1478
1479    impl<T, Maybe<A>> {AsRef<[T]>} for HeapArray<T, Maybe<A>> {
1480        fn as_ref(&self) -> &[T] { self }
1481    }
1482
1483    impl<T, Maybe<A>> {AsMut<[T]>} for HeapArray<T, Maybe<A>> {
1484        fn as_mut(&mut self) -> &mut [T] { self }
1485    }
1486
1487    impl<T: {Debug}, Maybe<A>> {Debug} for HeapArray<T, Maybe<A>> {
1488        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.deref().fmt(f) }
1489    }
1490
1491    impl<T, {I: SliceIndex<[T]>}, Maybe<A>> {Index<I>} for HeapArray<T, Maybe<A>> {
1492        type Output = I::Output;
1493
1494        fn index(&self, index: I) -> &Self::Output {
1495            <[T] as Index<I>>::index(self.deref(), index)
1496        }
1497    }
1498
1499    impl<T, {I: SliceIndex<[T]>}, Maybe<A>> {IndexMut<I>} for HeapArray<T, Maybe<A>> {
1500        fn index_mut(&mut self, index: I) -> &mut Self::Output {
1501            <[T] as IndexMut<I>>::index_mut(self.deref_mut(), index)
1502        }
1503    }
1504}
1505
1506
1507macro_rules! impl_deref_comp_trait {
1508    ($trait_name: ident |> fn $fn_name:ident(&self, other: &Self) -> $t: ty) => {
1509        identical_impl! {
1510            impl<T: {$trait_name}, Maybe<A>> {$trait_name} for HeapArray<T, Maybe<A>> {
1511                fn $fn_name(&self, other: &Self) -> $t { self.deref().$fn_name(other.deref()) }
1512            }
1513        }
1514    };
1515}
1516
1517impl_deref_comp_trait!(PartialEq  |> fn eq(&self, other: &Self) -> bool);
1518impl_deref_comp_trait!(Ord        |> fn cmp(&self, other: &Self) -> Ordering);
1519impl_deref_comp_trait!(PartialOrd |> fn partial_cmp(&self, other: &Self) -> Option<Ordering>);
1520identical_impl! {
1521    impl<T: {Eq}, Maybe<A>> {Eq} for HeapArray<T, Maybe<A>> {}
1522}
1523
1524macro_rules! drop_impl {
1525    () => {
1526        fn drop(&mut self) {
1527            if mem::needs_drop::<T>() {
1528                unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) };
1529            }
1530
1531            unsafe { self.drop_memory() }
1532        }
1533    };
1534}
1535
1536#[allow(missing_docs)]
1537#[cfg(all(feature = "dropck", feature = "allocator-api"))]
1538unsafe impl<#[may_dangle] T, A: Allocator> Drop for HeapArray<T, A> {
1539    drop_impl! {  }
1540}
1541
1542#[allow(missing_docs)]
1543#[cfg(all(feature = "dropck", not(feature = "allocator-api")))]
1544unsafe impl<#[may_dangle] T> Drop for HeapArray<T> {
1545    drop_impl! {  }
1546}
1547
1548#[allow(missing_docs)]
1549#[cfg(all(not(feature = "dropck"), feature = "allocator-api"))]
1550impl<T, A: Allocator> Drop for HeapArray<T, A> {
1551    drop_impl! {  }
1552}
1553
1554#[allow(missing_docs)]
1555#[cfg(all(not(feature = "dropck"), not(feature = "allocator-api")))]
1556impl<T> Drop for HeapArray<T> {
1557    drop_impl! {  }
1558}
1559
1560#[allow(unused)]
1561fn validate() {
1562    #[allow(drop_bounds)]
1563    fn check<T: Drop>() {};
1564    // can be any type
1565    check::<HeapArray<u8>>();
1566}
1567
1568identical_impl! {
1569    // Safety: the pointer we hold is unique to us and so send data is ok to be sent
1570    // and sync data is ok to be synced same goes for Unpin, RefUnwindSafe and UnwindSafe
1571    unsafe impl<T: {Send}, Maybe<A: {Send}>> {Send} for HeapArray<T, Maybe<A>> {}
1572    unsafe impl<T: {Sync}, Maybe<A: {Sync}>> {Sync} for HeapArray<T, Maybe<A>> {}
1573
1574    impl<T: {Unpin}, Maybe<A: {Unpin}>> {Unpin} for HeapArray<T, Maybe<A>>{}
1575    impl<T: {RefUnwindSafe}, Maybe<A: {RefUnwindSafe}>> {RefUnwindSafe} for HeapArray<T, Maybe<A>> {}
1576    impl<T: {UnwindSafe}, Maybe<A: {UnwindSafe}>> {UnwindSafe} for HeapArray<T, Maybe<A>> {}
1577}
1578
1579// vec dependent impls
1580#[allow(missing_docs)]
1581impl<T> FromIterator<T> for HeapArray<T> {
1582    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
1583        Vec::from_iter(iter).into()
1584    }
1585}
1586
1587#[cfg(feature = "allocator-api")]
1588#[allow(missing_docs)]
1589impl<T, A: Allocator> IntoIterator for HeapArray<T, A> {
1590    type Item = T;
1591    type IntoIter = IntoIter<Self::Item, A>;
1592
1593    fn into_iter(self) -> Self::IntoIter {
1594        self.into_vec().into_iter()
1595    }
1596}
1597
1598#[cfg(not(feature = "allocator-api"))]
1599#[allow(missing_docs)]
1600impl<T> IntoIterator for HeapArray<T> {
1601    type Item = T;
1602    type IntoIter = IntoIter<Self::Item>;
1603
1604    fn into_iter(self) -> Self::IntoIter {
1605        self.into_vec().into_iter()
1606    }
1607}
1608
1609identical_impl! {
1610    impl<'a, T, Maybe<A>> {IntoIterator} for &'a HeapArray<T, Maybe<A>> {
1611        type Item = &'a T;
1612        type IntoIter = Iter<'a, T>;
1613
1614        #[inline(always)]
1615        fn into_iter(self) -> Self::IntoIter {
1616            self.iter()
1617        }
1618    }
1619
1620    impl<'a, T, Maybe<A>> {IntoIterator} for &'a (mut) HeapArray<T, Maybe<A>> {
1621        type Item = &'a mut T;
1622        type IntoIter = IterMut<'a, T>;
1623
1624        #[inline(always)]
1625        fn into_iter(self) -> Self::IntoIter {
1626            self.iter_mut()
1627        }
1628    }
1629}
1630
1631
1632#[allow(missing_docs)]
1633#[doc(hidden)]
1634#[inline]
1635fn alloc_uninit<T, #[cfg(feature = "allocator-api")] A: Allocator>(
1636    len: usize,
1637    #[cfg(feature = "allocator-api")]
1638    alloc: &A
1639) -> Option<NonNull<MaybeUninit<T>>>
1640{
1641    if len == 0 {
1642        return None
1643    }
1644
1645    #[cold]
1646    const fn capacity_overflow() -> ! {
1647        panic!("capacity overflow")
1648    }
1649
1650    // We avoid `unwrap_or_else` here because it bloats the LLVM IR generated
1651    let layout = match Layout::array::<T>(len) {
1652        Ok(layout) => layout,
1653        Err(_) => capacity_overflow(),
1654    };
1655
1656    if usize::BITS < 64 && unlikely(layout.size() > isize::MAX as usize) {
1657        capacity_overflow()
1658    }
1659
1660    #[cfg(feature = "allocator-api")]
1661    {
1662        Some(match A::allocate(alloc, layout) {
1663            // currently allocate returns a [u8] with the same size as the one requested
1664            // and, so we can safely discard its length
1665            Ok(ptr) => NonNull::<[u8]>::cast::<MaybeUninit<T>>(ptr),
1666            Err(_) => handle_alloc_error(layout)
1667        })
1668    }
1669
1670    #[cfg(not(feature = "allocator-api"))]
1671    {
1672        Some(match NonNull::new(unsafe { alloc::alloc::alloc(layout) }) {
1673            Some(ptr) => ptr.cast(),
1674            None => handle_alloc_error(layout)
1675        })
1676    }
1677}
1678
1679
1680#[cfg(feature = "serde")]
1681use serde::{
1682    Deserialize, Deserializer, Serialize, Serializer,
1683    de::{SeqAccess, Visitor, Error, Expected},
1684};
1685
1686#[cfg(feature = "serde")]
1687identical_impl! {
1688    impl<T: {Serialize}, Maybe<A>> {Serialize} for HeapArray<T, Maybe<A>> {
1689        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
1690            serializer.collect_seq(self)
1691        }
1692    }
1693}
1694
1695
1696
1697#[cfg(feature = "serde")]
1698impl<'a, T: Deserialize<'a>> HeapArray<T> {
1699    /// Deserializes the heap array from a [`SeqAccess`]
1700    pub fn from_sequence<A: SeqAccess<'a>>(mut sequence: A) -> Result<Self, A::Error> {
1701        #[repr(transparent)]
1702        struct ExpectedLen(usize);
1703
1704        impl Expected for ExpectedLen {
1705            #[inline]
1706            fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
1707                formatter.write_str("a length of ")?;
1708                fmt::Display::fmt(&self.0, formatter)
1709            }
1710        }
1711
1712        if let Some(len) = sequence.size_hint() {
1713            HeapArray::try_from_fn(len, |i| sequence.next_element::<T>().and_then(|res| match res {
1714                Some(out) => Ok(out),
1715                None => Err(Error::invalid_length(i+1, &ExpectedLen(len)))
1716            }))
1717        } else {
1718            let mut values = Vec::<T>::new();
1719            while let Some(value) = sequence.next_element()? {
1720                values.push(value);
1721            }
1722
1723            Ok(HeapArray::from(values))
1724        }
1725    }
1726}
1727
1728
1729#[cfg(feature = "serde")]
1730impl<'de, T: Deserialize<'de>> Deserialize<'de> for HeapArray<T> {
1731    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
1732        struct HeapArrayVisitor<T> {
1733            marker: PhantomData<T>,
1734        }
1735
1736        impl<'a, T: Deserialize<'a>> Visitor<'a> for HeapArrayVisitor<T> {
1737            type Value = HeapArray<T>;
1738
1739            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
1740                formatter.write_str("a sequence")
1741            }
1742
1743            #[inline(always)]
1744            fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
1745                where A: SeqAccess<'a>,
1746            { HeapArray::from_sequence(seq) }
1747        }
1748
1749        let visitor = HeapArrayVisitor {
1750            marker: PhantomData
1751        };
1752
1753        deserializer.deserialize_seq(visitor)
1754    }
1755}
1756
1757#[cfg(feature = "simd-json")]
1758use simd_json_derive::{Serialize as SimdSerialize, Deserialize as SimdDeserialize, Tape};
1759
1760#[cfg(feature = "simd-json")]
1761extern crate std;
1762
1763#[cfg(feature = "simd-json")]
1764identical_impl! {
1765    impl<T: {SimdSerialize}, Maybe<A>> {SimdSerialize} for HeapArray<T, Maybe<A>> {
1766        fn json_write<W>(&self, writer: &mut W) -> simd_json_derive::Result where W: std::io::Write {
1767            let mut i = self.iter();
1768            if let Some(first) = i.next() {
1769                writer.write_all(b"[")?;
1770                first.json_write(writer)?;
1771                for e in i {
1772                    writer.write_all(b",")?;
1773                    e.json_write(writer)?;
1774                }
1775                writer.write_all(b"]")
1776            } else {
1777                writer.write_all(b"[]")
1778            }
1779        }
1780    }
1781}
1782
1783
1784#[cfg(feature = "simd-json")]
1785impl<'input, T: SimdDeserialize<'input> + 'input> SimdDeserialize<'input> for HeapArray<T> {
1786    fn from_tape(tape: &mut Tape<'input>) -> simd_json::Result<Self>  {
1787        if let Some(simd_json::Node::Array { len, .. }) = tape.next() {
1788            HeapArray::try_from_fn(len, |_| T::from_tape(tape))
1789        } else {
1790            Err(simd_json::Error::generic(simd_json::ErrorType::ExpectedArray))
1791        }
1792    }
1793}
1794
1795/// Creates a [`HeapArray`] containing the arguments.
1796///
1797/// `heap_array!` allows `HeapArray`'s to be defined with the same syntax as array expressions.
1798/// There are two forms of this macro:
1799///
1800/// - Create a [`HeapArray`] containing a given list of elements:
1801///
1802/// ```
1803/// # use heap_array::heap_array;
1804/// let v = heap_array![1, 2, 3];
1805/// assert_eq!(v[0], 1);
1806/// assert_eq!(v[1], 2);
1807/// assert_eq!(v[2], 3);
1808/// ```
1809///
1810/// - Create a [`HeapArray`] from a given element and size:
1811///
1812/// ```
1813/// # use heap_array::heap_array;
1814/// let v = heap_array![1; 3];
1815/// assert_eq!(*v, [1, 1, 1]);
1816/// ```
1817///
1818/// Note that unlike array expressions this syntax supports all elements
1819/// which implement [`Clone`] and the number of elements doesn't have to be
1820/// a constant.
1821///
1822/// This will use `clone` to duplicate an expression, so one should be careful
1823/// using this with types having a nonstandard `Clone` implementation. For
1824/// example, `heap_array![Rc::new(1); 5]` will create a heap-array of five references
1825/// to the same boxed integer value, not five references pointing to independently
1826/// boxed integers.
1827///
1828/// Also, note that `heap_array![expr; 0]` is allowed, and produces an empty HeapArray.
1829/// This will still evaluate `expr`, however, and immediately drop the resulting value, so
1830/// be mindful of side effects.
1831///
1832/// [`HeapArray`]: HeapArray
1833#[macro_export]
1834macro_rules! heap_array {
1835    [] => { $crate::HeapArray::new() };
1836    [$($x:expr),+] => { $crate::HeapArray::from([$($x),+]) };
1837    [$elem:expr; 0] => {{$elem; $crate::HeapArray::new()}};
1838    [$elem:expr; $n:expr] => { $crate::HeapArray::from_element($n, $elem) };
1839}