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