hexga_core/collections/
get.rs

1//! Generalisation over collection, such as `get`, `get_mut`, `get_many_mut`, `swap`, `replace`, `set`...
2//! 
3//! Each trait follow this convention when adding a new function `foo`  :
4//!
5//! `fn try_get_foo(...) -> Result<O,E>`
6//! 
7//! `fn foo(...) -> Option<O>` (or `bool` instead of `Option<()>` when `try_get_foo` return a `Result<(), E>`)
8//! 
9//! `fn foo_or_panic(...) -> O`
10//! 
11//! `unsafe fn foo_unchecked(...) -> O`
12
13use crate::*;
14
15
16
17/// The collection have a quick way to access each element, where the index is copyable
18pub trait Get<Idx> //where Idx : Borrow<Q> //: Index<Idx>
19{
20    type Output : ?Sized;
21
22    // Returns a reference to the value.
23    fn try_get(&self, index : Idx) -> Result<&Self::Output, ()>; // #proper_error
24    // Returns a reference to the value.
25    fn get(&self, index : Idx) -> Option<&Self::Output> { self.try_get(index).ok() }
26    // Returns a reference to the value.
27    #[inline(always)]
28    #[track_caller]
29    fn get_or_panic(&self, index : Idx) -> &Self::Output { self.get(index).expect("invalid index") }
30    // Returns a reference to the value.
31    #[inline(always)]
32    #[track_caller]
33    unsafe fn get_unchecked(&self, index : Idx) -> &Self::Output { self.get(index).expect("invalid index") }
34
35    /// True if `get(index)` return [Some], false otherwise.
36    #[inline(always)]
37    fn is_index_valid(&self, index : Idx) -> bool { self.get(index).is_some() }
38    /// True if `get(index)` return [None], false otherwise.
39    #[inline(always)]
40    fn is_index_invalid(&self, index : Idx) -> bool { self.get(index).is_none() }
41}
42/*
43impl<Idx,C> Get<&Idx> for C where C : Get<Idx>, Idx : Copy
44{
45    type Output=<C as Get<Idx>>::Output;
46
47    fn try_get(&self, index : &Idx) -> Result<&Self::Output, ()> { self.try_get(*index) }
48    fn get(&self, index : &Idx) -> Option<&Self::Output> { self.get(*index) }
49    fn get_or_panic(&self, index : &Idx) -> &Self::Output { self.get_or_panic(*index) }
50    unsafe fn get_unchecked(&self, index : &Idx) -> &Self::Output { unsafe { self.get_unchecked(*index) } }
51}
52impl<Idx,C> Get<&mut Idx> for C where C : Get<Idx>, Idx : Copy
53{
54    type Output=<C as Get<Idx>>::Output;
55
56    fn try_get(&self, index : &mut Idx) -> Result<&Self::Output, ()> { self.try_get(*index) }
57    fn get(&self, index : &mut Idx) -> Option<&Self::Output> { self.get(*index) }
58    fn get_or_panic(&self, index : &mut Idx) -> &Self::Output { self.get_or_panic(*index) }
59    unsafe fn get_unchecked(&self, index : &mut Idx) -> &Self::Output { unsafe { self.get_unchecked(*index) } }
60}
61    */
62
63pub trait GetMut<Idx> : Get<Idx>
64{
65    // Returns a mutable reference to the value.
66    fn try_get_mut(&mut self, index : Idx) -> Result<&mut Self::Output, ()>; // #proper_error
67    // Returns a mutable reference to the value.
68    #[inline(always)]
69    fn get_mut(&mut self, index : Idx) -> Option<&mut Self::Output> { self.try_get_mut(index).ok() }
70    #[inline(always)]
71    #[track_caller]
72    fn get_mut_or_panic(&mut self, idx : Idx) -> &mut Self::Output { self.get_mut(idx).expect("invalid index") }
73    // Returns a mutable reference to the value.
74    #[inline(always)]
75    #[track_caller]
76    unsafe fn get_unchecked_mut(&mut self, idx : Idx) -> &mut Self::Output { self.get_mut(idx).expect("invalid index") }
77
78
79    /// Replace the value and return the old one.
80    /// 
81    /// This operation is an [involution](https://en.wikipedia.org/wiki/Involution_(mathematics)): 
82    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
83    #[inline(always)]
84    fn try_replace(&mut self, index : Idx, value : Self::Output) -> Result<Self::Output, ()> where Self::Output : Sized { self.try_get_mut(index).map(|dest| std::mem::replace(dest, value)) } // #proper_error
85    /// Replace the value and return the old one.
86    /// 
87    /// This operation is an [involution](https://en.wikipedia.org/wiki/Involution_(mathematics)): 
88    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
89    #[inline(always)]
90    fn replace(&mut self, index : Idx, value : Self::Output) -> Option<Self::Output> where Self::Output : Sized { self.get_mut(index).map(|dest| std::mem::replace(dest, value)) }
91    /// Replace the value and return the old one.
92    /// 
93    /// This operation is an [involution](https://en.wikipedia.org/wiki/Involution_(mathematics)): 
94    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
95    #[inline(always)]
96    #[track_caller]
97    fn replace_or_panic(&mut self, index : Idx, value : Self::Output) -> Self::Output where Self::Output : Sized { self.replace(index, value).expect("invalid index") }
98    /// Replace the value and return the old one.
99    /// 
100    /// This operation is an [involution](https://en.wikipedia.org/wiki/Involution_(mathematics)): 
101    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
102    #[inline(always)]
103    #[track_caller]
104    unsafe fn replace_unchecked(&mut self, index : Idx, value : Self::Output) -> Self::Output where Self::Output : Sized { std::mem::replace(unsafe { self.get_unchecked_mut(index) }, value) }
105
106    /// Set the value and drop the previous one.
107    #[inline(always)]
108    fn try_set(&mut self, index : Idx, value : Self::Output) -> Result<(), ()> where Self::Output : Sized { self.try_replace(index, value).map(|_| ()) } // #proper_error
109    /// Set the value and drop the previous one.
110    #[inline(always)]
111    fn set(&mut self, index : Idx, value : Self::Output) -> bool where Self::Output : Sized { self.replace(index, value).map(|_| ()).is_some() }
112    /// Set the value and drop the previous one.
113    #[inline(always)]
114    #[track_caller]
115    fn set_or_panic(&mut self, index : Idx, value : Self::Output) -> &mut Self where Self::Output : Sized { assert!(self.set(index, value), "invalid index"); self }
116    #[inline(always)]
117    #[track_caller]
118    unsafe fn set_unchecked(&mut self, index : Idx, value : Self::Output) -> &mut Self where Self::Output : Sized { unsafe { self.replace_unchecked(index, value) }; self }
119}
120
121pub trait GetManyMut<Idx> : GetMut<Idx>
122{
123    /// Returns multiples mutables references to the values.
124    /// All values that can be accessed with the indices must be disjoint.
125    #[doc(alias = "try_get_disjoint_mut")]
126    fn try_get_many_mut<const N: usize>(&mut self, indices: [Idx; N]) -> Result<[&mut Self::Output;N], ()>; // #proper_error
127    /// Returns multiples mutables references to the values.
128    /// All values that can be accessed with the indices must be disjoint.
129    #[inline(always)]
130    #[doc(alias = "get_disjoint_mut")]
131    fn get_many_mut<const N: usize>(&mut self, indices: [Idx; N]) -> Option<[&mut Self::Output;N]> { self.try_get_many_mut(indices).ok() }
132    /// Returns multiples mutables references to the values.
133    /// All values that can be accessed with the indices must be disjoint.
134    #[inline(always)]
135    #[track_caller]
136    #[doc(alias = "get_disjoint_mut_or_panic")]
137    fn get_many_mut_or_panic<const N: usize>(&mut self, indices: [Idx; N]) -> [&mut Self::Output;N] { self.get_many_mut(indices).expect("invalid index") }
138    /// Returns multiples mutables references to the values.
139    /// All values that can be accessed with the indices must be disjoint.
140    #[inline(always)]
141    #[track_caller]
142    #[doc(alias = "get_disjoint_unchecked_mut")]
143    unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices: [Idx; N]) -> [&mut Self::Output;N] { self.get_many_mut(indices).expect("invalid index") }
144
145    /// Swaps the values at two mutable locations, without deinitializing either one.
146    /// 
147    /// Swap is symmetric : `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
148    #[inline(always)]
149    fn try_swap(&mut self, a : Idx, b : Idx) -> Result<(), ()> where Self::Output : Sized { self.try_get_many_mut([a, b]).map(|[a,b]| std::mem::swap(a, b)) } // #proper_error
150    /// Swaps the values at two mutable locations, without deinitializing either one.
151    /// 
152    /// Swap is symmetric : `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
153    /// 
154    /// Do nothings if some value  overlap or don't exist.
155    #[inline(always)]
156    fn swap(&mut self, a : Idx, b : Idx) -> bool where Self::Output : Sized { self.get_many_mut([a, b]).map(|[a,b]| std::mem::swap(a, b)).is_some() }
157    /// Swaps the values at two mutable locations, without deinitializing either one.
158    ///
159    /// Swap is symmetric : `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
160    /// 
161    /// Panics if any value overlap or don't exist
162    #[inline(always)]
163    #[track_caller]
164    fn swap_or_panic(&mut self, a : Idx, b : Idx) where Self::Output : Sized { assert!(self.swap(a, b), "invalid index") }
165    /// Swaps the values at two mutable locations, without deinitializing either one.
166    /// 
167    /// Swap is symmetric : `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
168    /// 
169    /// Do nothings if some value  overlap or don't exist.
170    #[inline(always)]
171    #[track_caller]
172    unsafe fn swap_unchecked(&mut self, a : Idx, b : Idx) where Self::Output : Sized { let [a,b] = unsafe { self.get_many_unchecked_mut([a, b]) }; std::mem::swap(a, b); }
173}
174
175impl<Idx,T> Get<Idx> for [T] where Idx : SliceIndex<[T]>
176{
177    type Output = <Self as Index<Idx>>::Output;
178    #[inline(always)]
179    fn try_get(&self, idx : Idx) -> Result<&Self::Output,()> { self.get(idx).ok_or_void() }
180    #[inline(always)]
181    fn get(&self, idx : Idx) -> Option<&Self::Output> { self.get(idx) }
182    #[inline(always)]
183    unsafe fn get_unchecked(&self, idx : Idx) -> &Self::Output { unsafe { self.get_unchecked(idx) } }
184}
185impl<Idx,T> GetMut<Idx> for [T] where Idx : SliceIndex<[T]>
186{
187    #[inline(always)]
188    fn try_get_mut(&mut self, idx : Idx) -> Result<&mut Self::Output, ()> { self.get_mut(idx).ok_or_void() }
189    #[inline(always)]
190    fn get_mut(&mut self, idx : Idx) -> Option<&mut Self::Output> { self.get_mut(idx) }
191    #[inline(always)]
192    unsafe fn get_unchecked_mut(&mut self, idx : Idx) -> &mut Self::Output { unsafe { self.get_unchecked_mut(idx) } }
193
194}
195impl<Idx,T> GetManyMut<Idx> for [T] where Idx : SliceIndex<[T]> + GetDisjointMutIndex
196{
197    #[inline(always)]
198    fn try_get_many_mut<const N: usize>(&mut self, indices: [Idx; N]) -> Result<[&mut Self::Output;N], ()> { self.get_disjoint_mut(indices).ok_or_void() }
199    #[inline(always)]
200    #[track_caller]
201    unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices: [Idx; N]) -> [&mut Self::Output;N]  { unsafe { self.get_disjoint_unchecked_mut(indices) } }
202}
203
204
205impl<Idx,T,const N : usize> Get<Idx> for [T;N] where [T] : Get<Idx>
206{
207    type Output =  <[T] as Get<Idx>>::Output;
208    #[inline(always)]
209    fn try_get(&self, idx : Idx) -> Result<&Self::Output, ()> { Get::try_get(self.as_slice(), idx) }
210    #[inline(always)]
211    fn get(&self, idx : Idx) -> Option<&Self::Output> { Get::get(self.as_slice(), idx) }
212    #[inline(always)]
213    unsafe fn get_unchecked(&self, idx : Idx) -> &Self::Output { unsafe { Get::get_unchecked(self.as_slice(), idx) } }
214}
215impl<Idx,T,const N : usize> GetMut<Idx> for [T;N] where [T] : GetMut<Idx>
216{
217    #[inline(always)]
218    fn try_get_mut(&mut self, idx : Idx) -> Result<&mut Self::Output, ()> { GetMut::try_get_mut(self.as_mut_slice(), idx) }
219    #[inline(always)]
220    fn get_mut(&mut self, idx : Idx) -> Option<&mut Self::Output> { GetMut::get_mut(self.as_mut_slice(), idx) }
221    #[inline(always)]
222    unsafe fn get_unchecked_mut(&mut self, idx : Idx) -> &mut Self::Output { unsafe { GetMut::get_unchecked_mut(self.as_mut_slice(), idx) } }
223}
224impl<Idx,T,const N : usize> GetManyMut<Idx> for [T;N] where [T] : GetManyMut<Idx>
225{
226    #[inline(always)]
227    unsafe fn get_many_unchecked_mut<const N2: usize>(&mut self, indices: [Idx; N2]) -> [&mut Self::Output;N2] { unsafe { GetManyMut::get_many_unchecked_mut(self.as_mut_slice(), indices) } }
228    #[inline(always)]
229    fn try_get_many_mut<const N2: usize>(&mut self, indices: [Idx; N2]) -> Result<[&mut Self::Output;N2], ()> { GetManyMut::try_get_many_mut(self.as_mut_slice(), indices) }
230}
231
232
233impl<Idx,T> Get<Idx> for Vec<T> where [T] : Get<Idx>
234{
235    type Output = <[T] as Get<Idx>>::Output;
236    #[inline(always)]
237    fn try_get(&self, idx : Idx) -> Result<&Self::Output, ()> { Get::try_get(self.as_slice(), idx) }
238    #[inline(always)]
239    unsafe fn get_unchecked(&self, idx : Idx) -> &Self::Output { unsafe { Get::get_unchecked(self.as_slice(), idx) } }
240}
241impl<Idx,T> GetMut<Idx> for Vec<T> where [T] : GetMut<Idx>
242{
243    #[inline(always)]
244    fn try_get_mut(&mut self, idx : Idx) -> Result<&mut Self::Output, ()> { GetMut::try_get_mut(self.as_mut_slice(), idx) }
245    #[inline(always)]
246    fn get_mut(&mut self, idx : Idx) -> Option<&mut Self::Output> { GetMut::get_mut(self.as_mut_slice(), idx) }
247    #[inline(always)]
248    unsafe fn get_unchecked_mut(&mut self, idx : Idx) -> &mut Self::Output { unsafe { GetMut::get_unchecked_mut(self.as_mut_slice(), idx) } }
249}
250impl<Idx,T> GetManyMut<Idx> for Vec<T> where [T] : GetManyMut<Idx>
251{
252    #[inline(always)]
253    unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices: [Idx; N]) -> [&mut Self::Output;N] { unsafe { GetManyMut::get_many_unchecked_mut(self.as_mut_slice(), indices) } }
254    #[inline(always)]
255    fn try_get_many_mut<const N: usize>(&mut self, indices: [Idx; N]) -> Result<[&mut Self::Output;N], ()> { GetManyMut::try_get_many_mut(self.as_mut_slice(), indices) }
256}
257
258
259impl<T> Get<usize> for VecDeque<T>
260{
261    type Output = <Self as Index<usize>>::Output;
262    #[inline(always)]
263    fn try_get(&self, index : usize) -> Result<&Self::Output, ()> { self.get(index).ok_or_void() }
264    #[inline(always)]
265    fn get(&self, idx : usize) -> Option<&Self::Output> { self.get(idx) }
266}
267impl<T> GetMut<usize> for VecDeque<T>
268{
269    #[inline(always)]
270    fn try_get_mut(&mut self, idx : usize) -> Result<&mut Self::Output, ()> { self.get_mut(idx).ok_or_void() }
271    #[inline(always)]
272    fn get_mut(&mut self, idx : usize) -> Option<&mut Self::Output> { self.get_mut(idx) }
273}
274
275impl<T> GetManyMut<usize> for VecDeque<T>
276{
277    #[inline(always)]
278    unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices : [usize; N]) -> [&mut Self::Output;N] 
279    {
280        unsafe 
281        { 
282            // Can probably be improved using `self.as_mut_slices()`
283            self.make_contiguous().get_disjoint_unchecked_mut(indices) 
284        }
285    }
286    #[inline(always)]
287    fn try_get_many_mut<const N: usize>(&mut self, indices : [usize; N]) -> Result<[&mut Self::Output;N], ()> { self.make_contiguous().try_get_many_mut(indices) }
288}
289
290impl<Idx> Get<Idx> for str where Idx : SliceIndex<str>
291{
292    type Output = <Self as Index<Idx>>::Output;
293    #[inline(always)]
294    fn try_get(&self, idx : Idx) -> Result<&Self::Output, ()> { self.get(idx).ok_or_void() }
295    #[inline(always)]
296    fn get(&self, idx : Idx) -> Option<&Self::Output> { self.get(idx) }
297    #[inline(always)]
298    unsafe fn get_unchecked(&self, idx : Idx) -> &Self::Output { unsafe { self.get_unchecked(idx) } }
299}
300
301impl<Idx> Get<Idx> for String where Idx : SliceIndex<str>
302{
303    type Output = <Self as Index<Idx>>::Output;
304    #[inline(always)]
305    fn try_get(&self, idx : Idx) -> Result<&Self::Output, ()> { self.as_str().try_get(idx) }
306    #[inline(always)]
307    fn get(&self, idx : Idx) -> Option<&Self::Output> { self.as_str().get(idx) }
308    #[inline(always)]
309    unsafe fn get_unchecked(&self, idx : Idx) -> &Self::Output { unsafe { self.as_str().get_unchecked(idx) } }
310}
311
312
313impl<K,V,S,Q> Get<&Q> for HashMap<K,V,S> where K : Borrow<Q>, Q : ?Sized + Hash + Eq, K: Eq + Hash, S: BuildHasher
314{
315    type Output = V;
316    #[inline(always)]
317    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
318    #[inline(always)]
319    fn try_get(&self, k: &Q) -> Result<&Self::Output, ()> { self.get(k).ok_or_void() }
320}
321
322impl<K,V,S,Q> GetMut<&Q> for HashMap<K,V,S> where K : Borrow<Q>, Q : ?Sized + Hash + Eq, K: Eq + Hash, S: BuildHasher
323{
324    #[inline(always)]
325    fn try_get_mut(&mut self, k: &Q) -> Result<&mut Self::Output, ()> where K : Borrow<Q> { self.get_mut(k).ok_or_void() }
326    #[inline(always)]
327    fn get_mut(&mut self, k: &Q) -> Option<&mut Self::Output> where K : Borrow<Q> { self.get_mut(k) }
328}
329
330impl<K,V,S,Q> GetManyMut<&Q> for HashMap<K,V,S> where K : Borrow<Q>, Q : ?Sized + Hash + Eq, K: Eq + Hash, S: BuildHasher
331{
332    #[inline(always)]
333    fn try_get_many_mut<const N: usize>(&mut self, indices: [&Q; N]) -> Result<[&mut Self::Output;N], ()> 
334    {
335        // Use try_map https://doc.rust-lang.org/std/primitive.array.html#method.try_map when #stabilized
336        // [Option<T>, N] to Option<[T;N]> (same for result)
337        let r = self.get_disjoint_mut(indices);
338        
339        if r.iter().any(|x| x.is_none()) 
340        {
341            Err(())
342        } else 
343        {
344            Ok(r.map(|x| x.unwrap()))
345        }
346    }
347
348    #[inline(always)]
349    unsafe fn get_many_unchecked_mut<const N: usize>(&mut self, indices: [&Q; N]) -> [&mut Self::Output;N] {
350        let r = self.get_disjoint_mut(indices);
351        r.map(|x| x.expect("missing key"))
352    }
353}
354
355impl<K,V,Q> Get<&Q> for BTreeMap<K,V> where K : Borrow<Q>, Q : ?Sized + Ord, K: Ord
356{
357    type Output = V;
358    #[inline(always)]
359    fn try_get(&self, k: &Q) -> Result<&Self::Output, ()> where K : Borrow<Q> { self.get(k).ok_or_void() }
360    #[inline(always)]
361    fn get(&self, k: &Q) -> Option<&Self::Output> where K : Borrow<Q> { self.get(k) }
362}
363
364impl<K,V,Q> GetMut<&Q> for BTreeMap<K,V> where K : Borrow<Q>, Q : ?Sized + Ord, K: Ord
365{
366    #[inline(always)]
367    fn try_get_mut(&mut self, k: &Q) -> Result<&mut Self::Output, ()> where K : Borrow<Q> { self.get_mut(k).ok_or_void() }
368    #[inline(always)]
369    fn get_mut(&mut self, k: &Q) -> Option<&mut Self::Output> where K : Borrow<Q> { self.get_mut(k) }
370}
371
372impl<K,S,Q> Get<&Q> for HashSet<K,S> where K : Borrow<Q>, Q : ?Sized + Hash + Eq, K: Eq + Hash, S: BuildHasher
373{
374    type Output = K;
375    #[inline(always)]
376    fn try_get(&self, k: &Q) -> Result<&Self::Output, ()> where K : Borrow<Q> { self.get(k).ok_or_void() }
377    #[inline(always)]
378    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
379}
380
381impl<K,Q> Get<&Q> for BTreeSet<K> where K : Borrow<Q>, Q : ?Sized + Ord, K: Ord
382{
383    type Output = K;
384    #[inline(always)]
385    fn try_get(&self, k: &Q) -> Result<&Self::Output, ()> where K : Borrow<Q> { self.get(k).ok_or_void() }
386    #[inline(always)]
387    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
388}