Skip to main content

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 super::*;
14
15/// The collection have a quick way to access each element, where the index is copyable
16pub trait Get<Idx>: Collection
17{
18    type Output: ?Sized;
19
20    /// Returns a reference to the value.
21    fn get(&self, index: Idx) -> Option<&Self::Output>;
22    /// Returns a reference to the value.
23    #[inline(always)]
24    #[track_caller]
25    fn get_or_panic(&self, index: Idx) -> &Self::Output { self.get(index).expect("invalid index") }
26    /// Returns a reference to the value.
27    #[inline(always)]
28    #[track_caller]
29    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
30    {
31        self.get(index).expect("invalid index")
32    }
33
34    /// True if `get(index)` return [Some], false otherwise.
35    #[inline(always)]
36    fn is_index_valid(&self, index: Idx) -> bool { self.get(index).is_some() }
37    /// True if `get(index)` return [None], false otherwise.
38    #[inline(always)]
39    fn is_index_invalid(&self, index: Idx) -> bool { self.get(index).is_none() }
40
41    fn contains(&self, index: Idx) -> bool { self.get(index).is_some() }
42}
43
44pub trait TryGet<Idx>: Get<Idx>
45{
46    type Error;
47    /// Returns a reference to the value.
48    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>;
49}
50
51pub trait GetMut<Idx>: Get<Idx>
52{
53    /// Returns a mutable reference to the value.
54    fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output>;
55    #[inline(always)]
56    #[track_caller]
57    fn get_mut_or_panic(&mut self, index: Idx) -> &mut Self::Output
58    {
59        self.get_mut(index).expect("invalid index")
60    }
61    /// Returns a mutable reference to the value.
62    #[inline(always)]
63    #[track_caller]
64    unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output
65    {
66        self.get_mut(index).expect("invalid index")
67    }
68
69    /// Replace the value and return the old one.
70    ///
71    /// This operation is an [`involution`](https://en.wikipedia.org/wiki/Involution_(mathematics)):
72    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
73    #[inline(always)]
74    fn replace(&mut self, index: Idx, value: Self::Output) -> Option<Self::Output>
75    where
76        Self::Output: Sized,
77    {
78        self.get_mut(index)
79            .map(|dest| core::mem::replace(dest, value))
80    }
81    /// Replace the value and return the old one.
82    ///
83    /// This operation is an [`involution`](https://en.wikipedia.org/wiki/Involution_(mathematics)):
84    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
85    #[inline(always)]
86    #[track_caller]
87    fn replace_or_panic(&mut self, index: Idx, value: Self::Output) -> Self::Output
88    where
89        Self::Output: Sized,
90    {
91        self.replace(index, value).expect("invalid index")
92    }
93    /// Replace the value and return the old one.
94    ///
95    /// This operation is an [`involution`](https://en.wikipedia.org/wiki/Involution_(mathematics)):
96    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
97    #[inline(always)]
98    #[track_caller]
99    unsafe fn replace_unchecked(&mut self, index: Idx, value: Self::Output) -> Self::Output
100    where
101        Self::Output: Sized,
102    {
103        core::mem::replace(unsafe { self.get_unchecked_mut(index) }, value)
104    }
105
106    /// Set the value and drop the previous one.
107    #[inline(always)]
108    fn set(&mut self, index: Idx, value: Self::Output) -> bool
109    where
110        Self::Output: Sized,
111    {
112        self.replace(index, value).map(|_| ()).is_some()
113    }
114    /// Set the value and drop the previous one.
115    #[inline(always)]
116    #[track_caller]
117    fn set_or_panic(&mut self, index: Idx, value: Self::Output) -> &mut Self
118    where
119        Self::Output: Sized,
120    {
121        assert!(self.set(index, value), "invalid index");
122        self
123    }
124    #[inline(always)]
125    #[track_caller]
126    unsafe fn set_unchecked(&mut self, index: Idx, value: Self::Output) -> &mut Self
127    where
128        Self::Output: Sized,
129    {
130        unsafe { self.replace_unchecked(index, value) };
131        self
132    }
133}
134
135pub trait TryGetMut<Idx>: TryGet<Idx>
136{
137    // Should TryGetMut have it own error type ?
138
139    /// Returns a mutable reference to the value.
140    fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, Self::Error>;
141
142    /// Replace the value and return the old one.
143    ///
144    /// This operation is an [`involution`](https://en.wikipedia.org/wiki/Involution_(mathematics)):
145    /// Replacing a value twice (first with a new value, then with the previously returned value) leaves the collection unchanged.
146    #[inline(always)]
147    fn try_replace(&mut self, index: Idx, value: Self::Output) -> Result<Self::Output, Self::Error>
148    where
149        Self::Output: Sized,
150    {
151        self.try_get_mut(index)
152            .map(|dest| core::mem::replace(dest, value))
153    }
154
155    /// Set the value and drop the previous one.
156    #[inline(always)]
157    fn try_set(&mut self, index: Idx, value: Self::Output) -> Result<(), Self::Error>
158    where
159        Self::Output: Sized,
160    {
161        self.try_replace(index, value).map(|_| ())
162    }
163}
164
165pub type ManyMutError = core::slice::GetDisjointMutError;
166
167pub trait GetManyMut<Idx>: GetMut<Idx>
168{
169    /// Returns multiples mutables references to the values.
170    /// All values that can be accessed with the indices must be disjoint.
171    #[doc(alias = "get_disjoint_mut")]
172    fn get_many_mut<const N: usize>(&mut self, indices: [Idx; N])
173    -> Option<[&mut Self::Output; N]>
174    {
175        self.try_get_many_mut(indices).ok()
176    }
177
178    fn try_get_many_mut<const N: usize>(
179        &mut self,
180        indices: [Idx; N],
181    ) -> Result<[&mut Self::Output; N], ManyMutError>;
182
183    /// Returns multiples mutables references to the values.
184    /// All values that can be accessed with the indices must be disjoint.
185    #[inline(always)]
186    #[track_caller]
187    #[doc(alias = "get_disjoint_mut_or_panic")]
188    fn get_many_mut_or_panic<const N: usize>(&mut self, indices: [Idx; N])
189    -> [&mut Self::Output; N]
190    {
191        self.get_many_mut(indices).expect("invalid index")
192    }
193
194    /// Returns multiples mutables references to the values.
195    /// All values that can be accessed with the indices must be disjoint.
196    #[inline(always)]
197    #[track_caller]
198    #[doc(alias = "get_disjoint_unchecked_mut")]
199    unsafe fn get_many_unchecked_mut<const N: usize>(
200        &mut self,
201        indices: [Idx; N],
202    ) -> [&mut Self::Output; N]
203    {
204        self.get_many_mut(indices).expect("invalid index")
205    }
206
207    /// Swaps the values at two mutable locations, without deinitializing either one.
208    ///
209    /// Swap is symmetric: `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
210    ///
211    /// Do nothings if some value  overlap or don't exist.
212    #[inline(always)]
213    fn swap(&mut self, a: Idx, b: Idx) -> bool
214    where
215        Self::Output: Sized,
216    {
217        self.get_many_mut([a, b])
218            .map(|[a, b]| core::mem::swap(a, b))
219            .is_some()
220    }
221    /// Swaps the values at two mutable locations, without deinitializing either one.
222    ///
223    /// Swap is symmetric: `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
224    ///
225    /// Panics if any value overlap or don't exist
226    #[inline(always)]
227    #[track_caller]
228    fn swap_or_panic(&mut self, a: Idx, b: Idx)
229    where
230        Self::Output: Sized,
231    {
232        assert!(self.swap(a, b), "invalid index")
233    }
234    /// Swaps the values at two mutable locations, without deinitializing either one.
235    ///
236    /// Swap is symmetric: `foo.try_swap(a, b)` is equivalent to `foo.try_swap(b, a)` and vis versa
237    ///
238    /// Do nothings if some value  overlap or don't exist.
239    #[inline(always)]
240    #[track_caller]
241    unsafe fn swap_unchecked(&mut self, a: Idx, b: Idx)
242    where
243        Self::Output: Sized,
244    {
245        let [a, b] = unsafe { self.get_many_unchecked_mut([a, b]) };
246        core::mem::swap(a, b);
247    }
248}
249
250
251/*
252pub struct TypedIndex<T,Idx>
253{
254    pub index: Idx,
255    target: PhantomData<T>,
256}
257impl<T,Idx> Clone for TypedIndex<T,Idx>
258    where Idx: Clone
259{
260    fn clone(&self) -> Self { Self { index: self.index.clone(), target: PhantomData } }
261}
262// type parameter `C` must be covered by another type when it appears before the first local type ...
263impl<T,Idx,C> Index<TypedIndex<T,Idx>> for C
264    where C: Index<Idx,Output = T>
265{
266
267}
268impl<T,Idx,C> Get<TypedIndex<T,Idx>> for C
269    where C: Get<Idx,Output = T>
270{
271    type Output=T;
272    fn get(&self, index: TypedIndex<T,Idx>) -> Option<&Self::Output> { self.get(index.index) }
273}
274*/
275
276
277
278#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
279#[repr(transparent)]
280#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
281pub struct IndexInvalid<Idx = usize>
282{
283    pub index: Idx,
284}
285impl<Idx> IndexInvalid<Idx>
286{
287    pub fn new(index: Idx) -> Self { Self { index } }
288}
289
290pub type IndexOutOfRange<Idx = usize, B = core::ops::Range<Idx>> = IndexOutOfBounds<Idx, B>;
291
292#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
293#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
294pub struct IndexOutOfBounds<Idx = usize, B = core::ops::Range<Idx>>
295{
296    pub index: Idx,
297    pub bound: B,
298}
299impl<Idx, B> IndexOutOfBounds<Idx, B>
300{
301    pub fn new(index: Idx, bound: B) -> Self { Self { index, bound } }
302}
303
304impl<Idx, T> Get<Idx> for [T]
305where
306    Idx: SliceIndex<[T]>,
307{
308    type Output = <Self as Index<Idx>>::Output;
309    #[inline(always)]
310    fn get(&self, index: Idx) -> Option<&Self::Output> { self.get(index) }
311    #[inline(always)]
312    #[track_caller]
313    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
314    {
315        unsafe { self.get_unchecked(index) }
316    }
317}
318impl<Idx, T> Get<Idx> for &[T]
319where
320    Idx: SliceIndex<[T]>,
321{
322    type Output = <[T] as Index<Idx>>::Output;
323    #[inline(always)]
324    fn get(&self, index: Idx) -> Option<&Self::Output> { (*self).get(index) }
325    #[inline(always)]
326    #[track_caller]
327    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
328    {
329        unsafe { (*self).get_unchecked(index) }
330    }
331}
332impl<Idx, T> Get<Idx> for &mut [T]
333where
334    Idx: SliceIndex<[T]>,
335{
336    type Output = <[T] as Index<Idx>>::Output;
337    #[inline(always)]
338    fn get(&self, index: Idx) -> Option<&Self::Output> { (**self).get(index) }
339    #[inline(always)]
340    #[track_caller]
341    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
342    {
343        unsafe { (**self).get_unchecked(index) }
344    }
345}
346impl<Idx, T> TryGet<Idx> for [T]
347where
348    Idx: SliceIndex<[T]> + Clone,
349{
350    type Error = IndexOutOfBounds<Idx, Range<usize>>;
351    #[inline(always)]
352    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>
353    {
354        self.get(index.clone()).ok_or(IndexOutOfBounds {
355            index,
356            bound: 0..self.len(),
357        })
358    }
359}
360impl<Idx, T> TryGet<Idx> for &[T]
361where
362    Idx: SliceIndex<[T]> + Clone,
363{
364    type Error = IndexOutOfBounds<Idx, Range<usize>>;
365    #[inline(always)]
366    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error> { (*self).try_get(index) }
367}
368impl<Idx, T> TryGet<Idx> for &mut [T]
369where
370    Idx: SliceIndex<[T]> + Clone,
371{
372    type Error = IndexOutOfBounds<Idx, Range<usize>>;
373    #[inline(always)]
374    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error> { (**self).try_get(index) }
375}
376
377impl<Idx, T> GetMut<Idx> for [T]
378where
379    Idx: SliceIndex<[T]>,
380{
381    #[inline(always)]
382    fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output> { self.get_mut(index) }
383    #[inline(always)]
384    #[track_caller]
385    unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output
386    {
387        unsafe { self.get_unchecked_mut(index) }
388    }
389}
390impl<Idx, T> GetMut<Idx> for &mut [T]
391where
392    Idx: SliceIndex<[T]>,
393{
394    #[inline(always)]
395    fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output> { (*self).get_mut(index) }
396    #[inline(always)]
397    #[track_caller]
398    unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output
399    {
400        unsafe { (*self).get_unchecked_mut(index) }
401    }
402}
403impl<Idx, T> TryGetMut<Idx> for [T]
404where
405    Idx: SliceIndex<[T]> + Clone,
406{
407    #[inline(always)]
408    fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, Self::Error>
409    {
410        let len = self.len();
411        self.get_mut(index.clone()).ok_or(IndexOutOfBounds {
412            index,
413            bound: 0..len,
414        })
415    }
416}
417impl<Idx, T> TryGetMut<Idx> for &mut [T]
418where
419    Idx: SliceIndex<[T]> + Clone,
420{
421    #[inline(always)]
422    fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, Self::Error>
423    {
424        (**self).try_get_mut(index)
425    }
426}
427impl<Idx, T> GetManyMut<Idx> for [T]
428where
429    Idx: SliceIndex<[T]> + GetDisjointMutIndex,
430{
431    #[inline(always)]
432    fn get_many_mut<const N: usize>(&mut self, indices: [Idx; N])
433    -> Option<[&mut Self::Output; N]>
434    {
435        self.get_disjoint_mut(indices).ok()
436    }
437
438    #[inline(always)]
439    fn try_get_many_mut<const N: usize>(
440        &mut self,
441        indices: [Idx; N],
442    ) -> Result<[&mut Self::Output; N], ManyMutError>
443    {
444        self.get_disjoint_mut(indices)
445    }
446
447    #[inline(always)]
448    #[track_caller]
449    unsafe fn get_many_unchecked_mut<const N: usize>(
450        &mut self,
451        indices: [Idx; N],
452    ) -> [&mut Self::Output; N]
453    {
454        unsafe { self.get_disjoint_unchecked_mut(indices) }
455    }
456}
457impl<Idx, T> GetManyMut<Idx> for &mut [T]
458where
459    Idx: SliceIndex<[T]> + GetDisjointMutIndex,
460{
461    #[inline(always)]
462    fn get_many_mut<const N: usize>(&mut self, indices: [Idx; N])
463    -> Option<[&mut Self::Output; N]>
464    {
465        (*self).get_many_mut(indices)
466    }
467
468    #[inline(always)]
469    fn try_get_many_mut<const N: usize>(
470        &mut self,
471        indices: [Idx; N],
472    ) -> Result<[&mut Self::Output; N], ManyMutError>
473    {
474        (*self).try_get_many_mut(indices)
475    }
476
477    #[inline(always)]
478    #[track_caller]
479    unsafe fn get_many_unchecked_mut<const N: usize>(
480        &mut self,
481        indices: [Idx; N],
482    ) -> [&mut Self::Output; N]
483    {
484        unsafe { (*self).get_many_unchecked_mut(indices) }
485    }
486}
487
488impl<Idx, T, const N: usize> TryGet<Idx> for [T; N]
489where
490    [T]: TryGet<Idx>,
491{
492    type Error = <[T] as TryGet<Idx>>::Error;
493    #[inline(always)]
494    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>
495    {
496        TryGet::try_get(self.as_slice(), index)
497    }
498}
499
500impl<Idx, T, const N: usize> Get<Idx> for [T; N]
501where
502    [T]: Get<Idx>,
503{
504    type Output = <[T] as Get<Idx>>::Output;
505    #[inline(always)]
506    fn get(&self, index: Idx) -> Option<&Self::Output> { Get::get(self.as_slice(), index) }
507    #[inline(always)]
508    #[track_caller]
509    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
510    {
511        unsafe { Get::get_unchecked(self.as_slice(), index) }
512    }
513}
514
515impl<Idx, T, const N: usize> TryGetMut<Idx> for [T; N]
516where
517    [T]: TryGetMut<Idx>,
518{
519    #[inline(always)]
520    fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, Self::Error>
521    {
522        TryGetMut::try_get_mut(self.as_mut_slice(), index)
523    }
524}
525
526impl<Idx, T, const N: usize> GetMut<Idx> for [T; N]
527where
528    [T]: GetMut<Idx>,
529{
530    #[inline(always)]
531    fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output>
532    {
533        GetMut::get_mut(self.as_mut_slice(), index)
534    }
535    #[inline(always)]
536    unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output
537    {
538        unsafe { GetMut::get_unchecked_mut(self.as_mut_slice(), index) }
539    }
540}
541impl<Idx, T, const N: usize> GetManyMut<Idx> for [T; N]
542where
543    [T]: GetManyMut<Idx>,
544{
545    #[inline(always)]
546    fn get_many_mut<const N2: usize>(
547        &mut self,
548        indices: [Idx; N2],
549    ) -> Option<[&mut Self::Output; N2]>
550    {
551        GetManyMut::get_many_mut(self.as_mut_slice(), indices)
552    }
553
554    #[inline(always)]
555    fn try_get_many_mut<const N2: usize>(
556        &mut self,
557        indices: [Idx; N2],
558    ) -> Result<[&mut Self::Output; N2], ManyMutError>
559    {
560        GetManyMut::try_get_many_mut(self.as_mut_slice(), indices)
561    }
562
563    #[inline(always)]
564    #[track_caller]
565    unsafe fn get_many_unchecked_mut<const N2: usize>(
566        &mut self,
567        indices: [Idx; N2],
568    ) -> [&mut Self::Output; N2]
569    {
570        unsafe { GetManyMut::get_many_unchecked_mut(self.as_mut_slice(), indices) }
571    }
572}
573
574impl<Idx, T> TryGet<Idx> for Vec<T>
575where
576    [T]: TryGet<Idx>,
577{
578    type Error = <[T] as TryGet<Idx>>::Error;
579    #[inline(always)]
580    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>
581    {
582        TryGet::try_get(self.as_slice(), index)
583    }
584}
585impl<Idx, T> Get<Idx> for Vec<T>
586where
587    [T]: Get<Idx>,
588{
589    type Output = <[T] as Get<Idx>>::Output;
590    #[inline(always)]
591    fn get(&self, index: Idx) -> Option<&Self::Output> { Get::get(self.as_slice(), index) }
592    #[track_caller]
593    #[inline(always)]
594    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
595    {
596        unsafe { Get::get_unchecked(self.as_slice(), index) }
597    }
598}
599impl<Idx, T> TryGetMut<Idx> for Vec<T>
600where
601    [T]: TryGetMut<Idx>,
602{
603    #[inline(always)]
604    fn try_get_mut(&mut self, index: Idx) -> Result<&mut Self::Output, Self::Error>
605    {
606        TryGetMut::try_get_mut(self.as_mut_slice(), index)
607    }
608}
609impl<Idx, T> GetMut<Idx> for Vec<T>
610where
611    [T]: GetMut<Idx>,
612{
613    #[inline(always)]
614    fn get_mut(&mut self, index: Idx) -> Option<&mut Self::Output>
615    {
616        GetMut::get_mut(self.as_mut_slice(), index)
617    }
618    #[inline(always)]
619    unsafe fn get_unchecked_mut(&mut self, index: Idx) -> &mut Self::Output
620    {
621        unsafe { GetMut::get_unchecked_mut(self.as_mut_slice(), index) }
622    }
623}
624impl<Idx, T> GetManyMut<Idx> for Vec<T>
625where
626    [T]: GetManyMut<Idx>,
627{
628    #[track_caller]
629    #[inline(always)]
630    unsafe fn get_many_unchecked_mut<const N: usize>(
631        &mut self,
632        indices: [Idx; N],
633    ) -> [&mut Self::Output; N]
634    {
635        unsafe { GetManyMut::get_many_unchecked_mut(self.as_mut_slice(), indices) }
636    }
637
638    #[inline(always)]
639    fn try_get_many_mut<const N: usize>(
640        &mut self,
641        indices: [Idx; N],
642    ) -> Result<[&mut Self::Output; N], ManyMutError>
643    {
644        GetManyMut::try_get_many_mut(self.as_mut_slice(), indices)
645    }
646    #[inline(always)]
647    fn get_many_mut<const N: usize>(&mut self, indices: [Idx; N])
648    -> Option<[&mut Self::Output; N]>
649    {
650        GetManyMut::get_many_mut(self.as_mut_slice(), indices)
651    }
652}
653
654impl<T> TryGet<usize> for VecDeque<T>
655{
656    type Error = IndexOutOfBounds<usize, Range<usize>>;
657    #[inline(always)]
658    fn try_get(&self, index: usize) -> Result<&Self::Output, Self::Error>
659    {
660        self.get(index).ok_or(IndexOutOfBounds {
661            index,
662            bound: 0..self.len(),
663        })
664    }
665}
666impl<T> Get<usize> for VecDeque<T>
667{
668    type Output = <Self as Index<usize>>::Output;
669    #[inline(always)]
670    fn get(&self, index: usize) -> Option<&Self::Output> { self.get(index) }
671}
672impl<T> TryGetMut<usize> for VecDeque<T>
673{
674    #[inline(always)]
675    fn try_get_mut(&mut self, index: usize) -> Result<&mut Self::Output, Self::Error>
676    {
677        let len = self.len();
678        self.get_mut(index).ok_or(IndexOutOfBounds {
679            index,
680            bound: 0..len,
681        })
682    }
683}
684impl<T> GetMut<usize> for VecDeque<T>
685{
686    #[inline(always)]
687    fn get_mut(&mut self, index: usize) -> Option<&mut Self::Output> { self.get_mut(index) }
688}
689
690impl<T> GetManyMut<usize> for VecDeque<T>
691{
692    #[track_caller]
693    #[inline(always)]
694    unsafe fn get_many_unchecked_mut<const N: usize>(
695        &mut self,
696        indices: [usize; N],
697    ) -> [&mut Self::Output; N]
698    {
699        unsafe {
700            // Can probably be improved using `self.as_mut_slices()`
701            self.make_contiguous().get_disjoint_unchecked_mut(indices)
702        }
703    }
704    #[inline(always)]
705    fn try_get_many_mut<const N: usize>(
706        &mut self,
707        indices: [usize; N],
708    ) -> Result<[&mut Self::Output; N], ManyMutError>
709    {
710        self.make_contiguous().try_get_many_mut(indices)
711    }
712    #[inline(always)]
713    fn get_many_mut<const N: usize>(
714        &mut self,
715        indices: [usize; N],
716    ) -> Option<[&mut Self::Output; N]>
717    {
718        self.make_contiguous().get_many_mut(indices)
719    }
720}
721
722impl<Idx> Get<Idx> for str
723where
724    Idx: SliceIndex<str>,
725{
726    type Output = <Self as Index<Idx>>::Output;
727    #[inline(always)]
728    fn get(&self, index: Idx) -> Option<&Self::Output> { self.get(index) }
729    #[inline(always)]
730    #[track_caller]
731    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
732    {
733        unsafe { self.get_unchecked(index) }
734    }
735}
736impl<Idx> TryGet<Idx> for str
737where
738    Idx: SliceIndex<str> + Clone,
739{
740    type Error = IndexOutOfBounds<Idx, Range<usize>>;
741    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>
742    {
743        self.get(index.clone()).ok_or(IndexOutOfBounds {
744            index,
745            bound: 0..self.len(),
746        })
747    }
748}
749
750impl<Idx> Get<Idx> for &str
751where
752    Idx: SliceIndex<str>,
753{
754    type Output = <str as Index<Idx>>::Output;
755    #[inline(always)]
756    fn get(&self, index: Idx) -> Option<&Self::Output> { (*self).get(index) }
757    #[inline(always)]
758    #[track_caller]
759    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
760    {
761        unsafe { (*self).get_unchecked(index) }
762    }
763}
764impl<Idx> TryGet<Idx> for &str
765where
766    Idx: SliceIndex<str> + Clone,
767{
768    type Error = IndexOutOfBounds<Idx, Range<usize>>;
769    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error> { (*self).try_get(index) }
770}
771
772impl<Idx> Get<Idx> for &mut str
773where
774    Idx: SliceIndex<str>,
775{
776    type Output = <str as Index<Idx>>::Output;
777    #[inline(always)]
778    fn get(&self, index: Idx) -> Option<&Self::Output> { (**self).get(index) }
779    #[inline(always)]
780    #[track_caller]
781    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
782    {
783        unsafe { (**self).get_unchecked(index) }
784    }
785}
786impl<Idx> TryGet<Idx> for &mut str
787where
788    Idx: SliceIndex<str> + Clone,
789{
790    type Error = IndexOutOfBounds<Idx, Range<usize>>;
791    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error> { (**self).try_get(index) }
792}
793
794// FIXME: I'm not sure how to delegate it to `str` like delegating the TryGet for `Vec<T>` into the TryGet of `[T]`
795impl<Idx> TryGet<Idx> for String
796where
797    Idx: SliceIndex<str> + Clone,
798{
799    type Error = IndexOutOfBounds<Idx, Range<usize>>;
800    fn try_get(&self, index: Idx) -> Result<&Self::Output, Self::Error>
801    {
802        self.as_str().try_get(index)
803    }
804}
805impl<Idx> Get<Idx> for String
806where
807    Idx: SliceIndex<str>,
808{
809    type Output = <str as Get<Idx>>::Output;
810    #[inline(always)]
811    fn get(&self, index: Idx) -> Option<&Self::Output> { self.as_str().get(index) }
812    #[track_caller]
813    #[inline(always)]
814    unsafe fn get_unchecked(&self, index: Idx) -> &Self::Output
815    {
816        unsafe { self.as_str().get_unchecked(index) }
817    }
818}
819
820#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
821#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
822pub struct MissingKey<K=()>
823{
824    pub key: K,
825}
826impl<K> From<K> for MissingKey<K>
827{
828    fn from(key: K) -> Self { MissingKey { key }}
829}
830impl<K> MissingKey<K>
831{
832    pub fn new(key: K) -> Self { Self { key } }
833}
834
835#[cfg(feature = "std")]
836impl<K, V, S, Q> TryGet<&Q> for HashMap<K, V, S>
837where
838    K: Borrow<Q>,
839    Q: ?Sized + Hash + Eq + Clone,
840    K: Eq + Hash,
841    S: BuildHasher,
842{
843    type Error = MissingKey<Q>;
844
845    fn try_get(&self, key: &Q) -> Result<&Self::Output, Self::Error>
846    {
847        self.get(key).ok_or_else(|| MissingKey::new(key.clone()))
848    }
849}
850
851#[cfg(feature = "std")]
852impl<K, V, S, Q> Get<&Q> for HashMap<K, V, S>
853where
854    K: Borrow<Q>,
855    Q: ?Sized + Hash + Eq,
856    K: Eq + Hash,
857    S: BuildHasher,
858{
859    type Output = V;
860    #[inline(always)]
861    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
862}
863
864#[cfg(feature = "std")]
865impl<K, V, S, Q> TryGetMut<&Q> for HashMap<K, V, S>
866where
867    K: Borrow<Q>,
868    Q: ?Sized + Hash + Eq + Clone,
869    K: Eq + Hash,
870    S: BuildHasher,
871{
872    #[inline(always)]
873    fn try_get_mut(&mut self, key: &Q) -> Result<&mut Self::Output, Self::Error>
874    where
875        K: Borrow<Q>,
876    {
877        self.get_mut(key)
878            .ok_or_else(|| MissingKey::new(key.clone()))
879    }
880}
881#[cfg(feature = "std")]
882impl<K, V, S, Q> GetMut<&Q> for HashMap<K, V, S>
883where
884    K: Borrow<Q>,
885    Q: ?Sized + Hash + Eq,
886    K: Eq + Hash,
887    S: BuildHasher,
888{
889    #[inline(always)]
890    fn get_mut(&mut self, k: &Q) -> Option<&mut Self::Output>
891    where
892        K: Borrow<Q>,
893    {
894        self.get_mut(k)
895    }
896}
897
898#[cfg(feature = "std")]
899impl<K, V, S, Q> GetManyMut<&Q> for HashMap<K, V, S>
900where
901    K: Borrow<Q>,
902    Q: ?Sized + Hash + Eq,
903    K: Eq + Hash,
904    S: BuildHasher,
905{
906    #[inline(always)]
907    fn try_get_many_mut<const N: usize>(
908        &mut self,
909        keys: [&Q; N],
910    ) -> Result<[&mut Self::Output; N], ManyMutError>
911    {
912        // I wanted to check this is the get_many_mut fail, but the borrow checker is complaining for no reason about self being already borrowed.
913        for k in keys
914        {
915            if self.get_mut(k).is_none()
916            {
917                return Err(ManyMutError::IndexOutOfBounds);
918            }
919        }
920
921        if let Some(r) = self.get_many_mut(keys)
922        {
923            return Ok(r);
924        }
925
926        Err(ManyMutError::OverlappingIndices)
927    }
928
929    fn get_many_mut<const N: usize>(&mut self, keys: [&Q; N]) -> Option<[&mut Self::Output; N]>
930    {
931        // Use try_map https://doc.rust-lang.org/std/primitive.array.html#method.try_map when #stabilized
932        // [Option<T>, N] to Option<[T;N]> (same for result)
933        let r = self.get_disjoint_mut(keys);
934
935        if r.iter().any(|x| x.is_none())
936        {
937            None
938        }
939        else
940        {
941            Some(r.map(|x| x.unwrap()))
942        }
943    }
944}
945
946impl<K, V, Q> TryGet<&Q> for BTreeMap<K, V>
947where
948    K: Borrow<Q>,
949    Q: ?Sized + Ord + Clone,
950    K: Ord,
951{
952    type Error = MissingKey<Q>;
953    fn try_get(&self, index: &Q) -> Result<&Self::Output, Self::Error>
954    {
955        self.get(index)
956            .ok_or_else(|| MissingKey::new(index.clone()))
957    }
958}
959impl<K, V, Q> Get<&Q> for BTreeMap<K, V>
960where
961    K: Borrow<Q>,
962    Q: ?Sized + Ord,
963    K: Ord,
964{
965    type Output = V;
966    #[inline(always)]
967    fn get(&self, k: &Q) -> Option<&Self::Output>
968    where
969        K: Borrow<Q>,
970    {
971        self.get(k)
972    }
973}
974
975impl<K, V, Q> TryGetMut<&Q> for BTreeMap<K, V>
976where
977    K: Borrow<Q>,
978    Q: ?Sized + Ord + Clone,
979    K: Ord,
980{
981    fn try_get_mut(&mut self, index: &Q) -> Result<&mut Self::Output, Self::Error>
982    {
983        self.get_mut(index)
984            .ok_or_else(|| MissingKey::new(index.clone()))
985    }
986}
987impl<K, V, Q> GetMut<&Q> for BTreeMap<K, V>
988where
989    K: Borrow<Q>,
990    Q: ?Sized + Ord,
991    K: Ord,
992{
993    #[inline(always)]
994    fn get_mut(&mut self, k: &Q) -> Option<&mut Self::Output>
995    where
996        K: Borrow<Q>,
997    {
998        self.get_mut(k)
999    }
1000}
1001
1002#[cfg(feature = "std")]
1003impl<K, S, Q> TryGet<&Q> for HashSet<K, S>
1004where
1005    K: Borrow<Q>,
1006    Q: ?Sized + Hash + Eq + Clone,
1007    K: Eq + Hash,
1008    S: BuildHasher,
1009{
1010    type Error = MissingKey<Q>;
1011    fn try_get(&self, index: &Q) -> Result<&Self::Output, Self::Error>
1012    {
1013        self.get(index)
1014            .ok_or_else(|| MissingKey::new(index.clone()))
1015    }
1016}
1017#[cfg(feature = "std")]
1018impl<K, S, Q> Get<&Q> for HashSet<K, S>
1019where
1020    K: Borrow<Q>,
1021    Q: ?Sized + Hash + Eq,
1022    K: Eq + Hash,
1023    S: BuildHasher,
1024{
1025    type Output = K;
1026    #[inline(always)]
1027    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
1028}
1029
1030impl<K, Q> TryGet<&Q> for BTreeSet<K>
1031where
1032    K: Borrow<Q>,
1033    Q: ?Sized + Ord + Clone,
1034    K: Ord,
1035{
1036    type Error = MissingKey<Q>;
1037    fn try_get(&self, index: &Q) -> Result<&Self::Output, Self::Error>
1038    {
1039        self.get(index)
1040            .ok_or_else(|| MissingKey::new(index.clone()))
1041    }
1042}
1043impl<K, Q> Get<&Q> for BTreeSet<K>
1044where
1045    K: Borrow<Q>,
1046    Q: ?Sized + Ord,
1047    K: Ord,
1048{
1049    type Output = K;
1050    #[inline(always)]
1051    fn get(&self, k: &Q) -> Option<&Self::Output> { self.get(k) }
1052}