1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use core::sync::atomic::Ordering; /// An array of arbitrary (sized) values that can be safely initialized. /// /// # Example /// /// ```rust /// # use heaparray::*; /// let array = HeapArray::<usize,()>::new(100, |i| i * i); /// for i in 0..array.len() { /// assert!(array[i] == i * i); /// } /// ``` pub trait MakeArray<'a, E>: containers::Array<'a, E> where E: 'a, { /// Create a new array, with values initialized using a provided function. fn new<F>(len: usize, func: F) -> Self where F: FnMut(usize) -> E; } /// Array with an optional label struct stored next to the data. pub trait LabelledArray<'a, E, L>: containers::Array<'a, E> where E: 'a, { /// Create a new array, with values initialized using a provided function, and label /// initialized to a provided value. fn with_label<F>(label: L, len: usize, func: F) -> Self where F: FnMut(&mut L, usize) -> E; /// Create a new array, without initializing the values in it. unsafe fn with_label_unsafe(label: L, len: usize) -> Self; /// Get immutable access to the label. fn get_label(&self) -> &L; /// Get mutable reference to the label. fn get_label_mut(&mut self) -> &mut L; /// Get a mutable reference to the label. Implementations of this /// method shouldn't do any safety checks. unsafe fn get_label_unsafe(&self) -> &mut L; /// Get a mutable reference to the element at a specified index. /// Implementations of this method shouldn't do any safety checks. unsafe fn get_unsafe(&self, idx: usize) -> &mut E; } /// Trait for a labelled array with a default value. pub trait DefaultLabelledArray<'a, E, L>: LabelledArray<'a, E, L> where E: 'a + Default, { /// Create a new array, initialized to default values. fn with_len(label: L, len: usize) -> Self; } /// A basic reference to a heap-allocated array. Should be paired with exactly /// one of either `heaparray::UnsafeArrayRef` or `heaparray::ArrayRef`. pub trait BaseArrayRef { /// Returns whether the array pointer that this contains is null. fn is_null(&self) -> bool; } /// A reference to a heap-allocated array whose safe API guarrantees it to /// always be non-null. pub trait UnsafeArrayRef<'a, B>: BaseArrayRef where B: ?Sized, { /// Creates a new array from a raw pointer to a memory block. unsafe fn from_raw_parts(ptr: &'a mut B) -> Self; /// Sets the internal pointer to null, without deallocating it, and returns /// reference to the associated memory block. /// Causes all sorts of undefined behavior, use with caution. unsafe fn to_null<'b>(&mut self) -> &'b mut B; /// Creates a null array. All kinds of UB associated with this, use /// with caution. unsafe fn null_ref() -> Self; } /// A reference to an array, whose clone points to the same data. /// /// Allows for idiomatic cloning of array references: /// /// ```rust /// # use heaparray::naive_rc::*; /// let array_ref = FpRcArray::new(10, |_| 0); /// let another_ref = ArrayRef::clone(&array_ref); /// /// assert!(array_ref.len() == another_ref.len()); /// for i in 0..another_ref.len() { /// let r1 = &array_ref[i] as *const i32; /// let r2 = &another_ref[i] as *const i32; /// assert!(r1 == r2); /// } /// ``` pub trait ArrayRef: BaseArrayRef + Clone { // Should this be stricter? It really shouldn't be implemented by other // crates, but the type system could definitely make that somewhat of a // guarrantee without making the usage of this trait any less ergonomic. fn clone(ptr: &Self) -> Self { ptr.clone() } fn to_null(&mut self); fn null_ref() -> Self; } /// Atomically modified array reference. Guarrantees that all operations on the /// array reference are atomic (i.e. all changes to the internal array pointer). pub trait AtomicArrayRef: BaseArrayRef + Sized { fn compare_and_swap(&self, current: Self, new: Self, order: Ordering) -> Self; fn compare_exchange( &self, current: Self, new: Self, success: Ordering, failure: Ordering, ) -> Result<Self, Self>; fn compare_exchange_weak( &self, current: Self, new: Self, success: Ordering, failure: Ordering, ) -> Result<Self, Self>; fn load(&self, order: Ordering) -> Self; fn store(&self, ptr: Self, order: Ordering); fn swap(&self, ptr: Self, order: Ordering) -> Self; }