linearize/
map.rs

1use {
2    crate::{
3        copy_map::StaticCopyMap,
4        map::iters::{IntoIter, IntoValues, Iter, IterMut},
5        storage::Storage,
6        variants::Variants,
7        Linearize, LinearizeExt, Linearized,
8    },
9    core::{
10        array::TryFromSliceError,
11        borrow::{Borrow, BorrowMut},
12        cmp::Ordering,
13        fmt::{Debug, Formatter},
14        hash::{Hash, Hasher},
15        mem,
16        ops::{Deref, DerefMut, Index, IndexMut},
17    },
18};
19
20pub(crate) mod iters;
21
22/// An array-backed map with complex keys.
23///
24/// This type is an optimized version of [HashMap](std::collections::HashMap).
25///
26/// # Example
27///
28/// ```rust
29/// # use linearize::{StaticMap, Linearize};
30/// #[derive(Linearize)]
31/// enum Format {
32///     R,
33///     Rgb,
34///     Rgba,
35/// }
36///
37/// let mut channels = StaticMap::default();
38/// channels[Format::R] = 1;
39/// channels[Format::Rgb] = 3;
40/// channels[Format::Rgba] = 4;
41/// assert_eq!(channels[Format::R], 1);
42/// ```
43///
44/// # Keys
45///
46/// The key type, `L`, must implement the [Linearize] trait. This trait is implemented for
47/// a number of standard library types:
48///
49/// - `bool`
50/// - `u8`
51/// - `()`
52/// - `Infallible`
53/// - etc.
54///
55/// See the rustdoc for a full list of types.
56///
57/// You can implement this trait for your own types, either manually or by using the
58/// [proc macro](linearize_derive::Linearize).
59///
60/// # Storage
61///
62/// A `StaticMap` is a transparent wrapper around `[T; L::LENGTH]`.
63/// [LENGTH](Linearize::LENGTH) is an associated constant of the [Linearize] trait.
64///
65/// # Runtime Performance
66///
67/// Indexing into the map needs to compute the index into the array.
68///
69/// If the key type is an enum without fields, the index is the discriminant of the enum
70/// variant, making this computation a no-op.
71///
72/// For complex types, such as enums with fields, this computation is not always free. If
73/// you index with the same key multiple times, you can pre-compute the array index.
74///
75/// ```rust
76/// # use linearize::{Linearize, LinearizeExt, StaticMap};
77/// fn dynamic_access<L: Linearize>(map: &mut StaticMap<L, u8>, key: &L) {
78///     map[key] = map[key] + 1;
79/// }
80///
81/// fn pre_computed_access<L: Linearize>(map: &mut StaticMap<L, u8>, key: &L) {
82///     let key = key.linearized();
83///     map[key] = map[key] + 1;
84/// }
85/// ```
86///
87/// # Traits
88///
89/// `StaticMap` unconditionally implements the following traits by forwarding to the
90/// underlying `[T; L::LENGTH]`:
91///
92/// - `AsMut<[T]>`
93/// - `AsRef<[T]>`
94/// - `Borrow<[T]>`
95/// - `BorrowMut<[T]>`
96/// - `Deref<Target=[T]>`
97/// - `DerefMut`
98/// - `TryFrom`
99/// - `IntoIterator`
100///
101/// The following traits are implemented unconditionally and behave as they behave for a
102/// map:
103///
104/// - `Extend`
105/// - `FromIterator`
106/// - `Index<L>`
107/// - `Index<&L>`
108/// - `IndexMut<L>`
109/// - `IndexMut<&L>`
110///
111/// The following traits are implemented if `T` implements them by forwarding to the
112/// underlying `[T; L::LENGTH]`:
113///
114/// - [`Arbitrary`](arbitrary_1::Arbitrary) if the `arbitrary-1` feature is enabled.
115/// - `Clone`
116/// - `Default`
117/// - `Eq`
118/// - `Hash`
119/// - `Ord`
120/// - `PartialEq`
121/// - `PartialOrd`
122///
123/// The following traits are implemented if both `L` and `T` implement them and their
124/// implementation behaves as they behave for a map:
125///
126/// - `Debug`
127/// - [`Deserialize`](serde_1::Deserialize) if the `serde-1` feature is enabled.
128/// - [`Serialize`](serde_1::Serialize) if the `serde-1` feature is enabled.
129///
130/// The `Deserialize` implementation requires that the input contains all possible keys.
131/// You can modify this behavior by using the tools in the [serde_1](crate::serde_1)
132/// module.
133///
134/// If the `rand-0_8` feature is enabled, the
135/// [`Distribution<StaticMap<L, T>>`](rand_0_8::distributions::Distribution) trait is
136/// implemented for the following distributions by forwarding to the underlying
137/// `[T; L::LENGTH]`:
138///
139/// - [`Bernoulli`](rand_0_8::distributions::Bernoulli)
140/// - [`Open01`](rand_0_8::distributions::Open01)
141/// - [`OpenClosed01`](rand_0_8::distributions::OpenClosed01)
142/// - [`Standard`](rand_0_8::distributions::Standard)
143/// - [`Uniform`](rand_0_8::distributions::Uniform)
144/// - [`WeightedIndex`](rand_0_8::distributions::WeightedIndex)
145///
146/// If the `rand-0_9` feature is enabled, the
147/// [`Distribution<StaticMap<L, T>>`](rand_0_9::distr::Distribution) trait is
148/// implemented for the following distributions by forwarding to the underlying
149/// `[T; L::LENGTH]`:
150///
151/// - [`Bernoulli`](rand_0_9::distr::Bernoulli)
152/// - [`Open01`](rand_0_9::distr::Open01)
153/// - [`OpenClosed01`](rand_0_9::distr::OpenClosed01)
154/// - [`Standard`](rand_0_9::distr::StandardUniform)
155/// - [`Uniform`](rand_0_9::distr::Uniform)
156/// - [`WeightedIndex`](rand_0_9::distr::weighted::WeightedIndex)
157///
158/// # Copy Trait
159///
160/// This type **never** implements `Copy`. This is due to a limitation of the rust type
161/// system.
162///
163/// Use [`StaticCopyMap`] if `T` is `Copy` and you want the map to be `Copy` as well.
164#[repr(transparent)]
165pub struct StaticMap<L, T>(
166    /// The underlying `[T; L::LENGTH]`.
167    pub <L as Linearize>::Storage<T>,
168)
169where
170    L: Linearize + ?Sized;
171
172impl<L, T> StaticMap<L, T>
173where
174    L: Linearize + ?Sized,
175{
176    /// Creates a map from a callback.
177    ///
178    /// # Example
179    ///
180    /// ```rust
181    /// # use linearize::StaticMap;
182    /// let map = StaticMap::from_fn(|l: bool| l as u32);
183    /// ```
184    #[inline]
185    pub fn from_fn(mut cb: impl FnMut(L) -> T) -> Self
186    where
187        L: Sized,
188    {
189        Self(<L::Storage<T> as Storage<L, T>>::from_fn(|i| unsafe {
190            // SAFETY:
191            // - Storage::from_fn has only one implementation implementation and it calls
192            //   core::array::from_fn::<[T; L::LENGTH]>.
193            // - Therefore i is less that L::LENGTH.
194            cb(L::from_linear_unchecked(i))
195        }))
196    }
197
198    /// Creates a map from a reference to the underlying storage.
199    ///
200    /// Due to limitations of the rust type system, the underlying type is opaque in code
201    /// that is generic over `L`. However, in code with concrete `L`s, this function can
202    /// be used to turn any `[T; L::LENGTH]` into a map.
203    ///
204    /// # Example
205    ///
206    /// ```rust
207    /// # use linearize::StaticMap;
208    /// let array = [0, 1];
209    /// let map = StaticMap::from_ref(&array);
210    /// assert_eq!(map[false], 0);
211    /// assert_eq!(map[true], 1);
212    /// ```
213    #[inline]
214    pub const fn from_ref(storage: &<L as Linearize>::Storage<T>) -> &Self {
215        unsafe {
216            // SAFETY: Self is a transparent wrapper around L::Storage<T>.
217            mem::transmute(storage)
218        }
219    }
220
221    /// Creates a map from a mutable reference to the underlying storage.
222    ///
223    /// Due to limitations of the rust type system, the underlying type is opaque in code
224    /// that is generic over `L`. However, in code with concrete `L`s, this function can
225    /// be used to turn any `[T; L::LENGTH]` into a map.
226    ///
227    /// # Example
228    ///
229    /// ```rust
230    /// # use linearize::StaticMap;
231    /// let mut array = [0, 1];
232    /// let map = StaticMap::from_mut(&mut array);
233    /// map[false] = 1;
234    /// map[true] = 0;
235    /// assert_eq!(array, [1, 0]);
236    /// ```
237    #[inline]
238    pub fn from_mut(storage: &mut <L as Linearize>::Storage<T>) -> &mut Self {
239        unsafe {
240            // SAFETY: Self is a transparent wrapper around L::Storage<T>.
241            mem::transmute(storage)
242        }
243    }
244
245    /// Fallibly collects an iterator into a map. Returns Err if some key is not produced by
246    /// the iterator.
247    ///
248    /// # Example
249    ///
250    /// ```rust
251    /// use linearize::StaticMap;
252    /// let map = StaticMap::try_from_iter([(false, 0), (true, 1)]);
253    /// assert_eq!(map, Ok(StaticMap([0, 1])));
254    ///
255    /// let map = StaticMap::try_from_iter([(false, 0)]);
256    /// assert_eq!(map, Err(StaticMap([Some(0), None])));
257    /// ```
258    #[inline]
259    pub fn try_from_iter(
260        iter: impl IntoIterator<Item = (L, T)>,
261    ) -> Result<Self, StaticMap<L, Option<T>>>
262    where
263        L: Sized,
264    {
265        let mut res = StaticMap::<L, Option<T>>::default();
266        for (k, v) in iter {
267            res[k] = Some(v);
268        }
269        if res.values().any(|v| v.is_none()) {
270            return Err(res);
271        }
272        Ok(res.map_values(|v| v.unwrap()))
273    }
274
275    /// Converts this map to a [StaticCopyMap].
276    ///
277    /// This is a zero-cost conversion.
278    ///
279    /// # Example
280    ///
281    /// ```rust
282    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
283    /// let map: StaticMap<_, _> = static_map! {
284    ///     false => 0,
285    ///     true => 1,
286    /// };
287    /// let map: StaticCopyMap<_, _> = map.into_copy();
288    /// assert_eq!(map[false], 0);
289    /// assert_eq!(map[true], 1);
290    /// ```
291    #[inline]
292    pub fn into_copy(self) -> StaticCopyMap<L, T>
293    where
294        T: Copy,
295    {
296        StaticCopyMap(self.0.into_copy())
297    }
298
299    /// Converts a [StaticCopyMap] to a [StaticMap].
300    ///
301    /// This is a zero-cost conversion.
302    ///
303    /// # Example
304    ///
305    /// ```rust
306    /// # use linearize::{static_copy_map, StaticCopyMap, StaticMap};
307    /// let map: StaticCopyMap<_, _> = static_copy_map! {
308    ///     false => 0,
309    ///     true => 1,
310    /// };
311    /// let map: StaticMap<_, _> = StaticMap::from_copy(map);
312    /// assert_eq!(map[false], 0);
313    /// assert_eq!(map[true], 1);
314    /// ```
315    #[inline]
316    pub fn from_copy(map: StaticCopyMap<L, T>) -> Self
317    where
318        T: Copy,
319    {
320        map.into_static_map()
321    }
322
323    /// Converts a reference to this map to a reference to a [StaticCopyMap].
324    ///
325    /// This is a zero-cost re-interpretation conversion.
326    ///
327    /// # Example
328    ///
329    /// ```rust
330    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
331    /// let map: StaticMap<_, _> = static_map! {
332    ///     false => 0,
333    ///     true => 1,
334    /// };
335    /// let map: &StaticCopyMap<_, _> = map.as_copy();
336    /// assert_eq!(map[false], 0);
337    /// assert_eq!(map[true], 1);
338    /// ```
339    #[inline]
340    pub fn as_copy(&self) -> &StaticCopyMap<L, T>
341    where
342        T: Copy,
343    {
344        StaticCopyMap::from_ref(self.0.as_copy())
345    }
346
347    /// Converts a mutable reference to this map to a mutable reference to a [StaticCopyMap].
348    ///
349    /// This is a zero-cost re-interpretation conversion.
350    ///
351    /// # Example
352    ///
353    /// ```rust
354    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
355    /// let mut map: StaticMap<_, _> = static_map! {
356    ///     false => 0,
357    ///     true => 1,
358    /// };
359    /// assert_eq!(map[false], 0);
360    /// assert_eq!(map[true], 1);
361    /// {
362    ///     let map: &mut StaticCopyMap<_, _> = map.as_copy_mut();
363    ///     map[false] = 1;
364    ///     map[true] = 0;
365    /// }
366    /// assert_eq!(map[false], 1);
367    /// assert_eq!(map[true], 0);
368    /// ```
369    #[inline]
370    pub fn as_copy_mut(&mut self) -> &mut StaticCopyMap<L, T>
371    where
372        T: Copy,
373    {
374        StaticCopyMap::from_mut(self.0.as_copy_mut())
375    }
376
377    /// Creates a new map whose values are references to the values in this map.
378    ///
379    /// # Example
380    ///
381    /// ```rust
382    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
383    /// let map: StaticMap<_, u8> = static_map! {
384    ///     false => 0,
385    ///     true => 1,
386    /// };
387    /// let map: StaticCopyMap<_, &u8> = map.each_ref();
388    /// assert_eq!(map[false], &0);
389    /// assert_eq!(map[true], &1);
390    /// ```
391    #[inline]
392    pub fn each_ref(&self) -> StaticCopyMap<L, &T> {
393        StaticCopyMap(self.0.each_ref().into_copy())
394    }
395
396    /// Creates a new map whose values are mutable references to the values in this map.
397    ///
398    /// # Example
399    ///
400    /// ```rust
401    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
402    /// let mut map: StaticMap<_, u8> = static_map! {
403    ///     false => 0,
404    ///     true => 1,
405    /// };
406    /// assert_eq!(map[false], 0);
407    /// assert_eq!(map[true], 1);
408    /// {
409    ///     let mut map: StaticMap<_, &mut u8> = map.each_mut();
410    ///     *map[false] = 1;
411    ///     *map[true] = 0;
412    /// }
413    /// assert_eq!(map[false], 1);
414    /// assert_eq!(map[true], 0);
415    /// ```
416    #[inline]
417    pub fn each_mut(&mut self) -> StaticMap<L, &mut T> {
418        StaticMap(self.0.each_mut())
419    }
420
421    /// Remaps the values of this type.
422    ///
423    /// # Example
424    ///
425    /// ```rust
426    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
427    /// let map: StaticMap<_, u8> = static_map! {
428    ///     false => 0,
429    ///     true => 1,
430    /// };
431    /// assert_eq!(map[false], 0);
432    /// assert_eq!(map[true], 1);
433    /// let map = map.map(|b, v| b as u8 + v);
434    /// assert_eq!(map[false], 0);
435    /// assert_eq!(map[true], 2);
436    /// ```
437    #[inline]
438    pub fn map<U>(self, mut map: impl FnMut(L, T) -> U) -> StaticMap<L, U>
439    where
440        L: Sized,
441    {
442        StaticMap(self.0.map(|i, t| {
443            let l = unsafe {
444                // SAFETY:
445                // - L::Storage<T> is required to be [T; L::LENGTH].
446                // - The implementation of Storage<T> for [T; N] calls this callback only
447                //   with i < N.
448                // - Therefore i < N = L::LENGTH.
449                L::from_linear_unchecked(i)
450            };
451            map(l, t)
452        }))
453    }
454
455    /// Remaps the values of this type without retrieving the keys.
456    ///
457    /// If you don't need access to the keys, this function can be more efficient.
458    ///
459    /// # Example
460    ///
461    /// ```rust
462    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
463    /// let map: StaticMap<_, u8> = static_map! {
464    ///     false => 0,
465    ///     true => 1,
466    /// };
467    /// assert_eq!(map[false], 0);
468    /// assert_eq!(map[true], 1);
469    /// let map = map.map_values(|v| 3 * v);
470    /// assert_eq!(map[false], 0);
471    /// assert_eq!(map[true], 3);
472    /// ```
473    #[inline]
474    pub fn map_values<U>(self, mut map: impl FnMut(T) -> U) -> StaticMap<L, U> {
475        StaticMap(self.0.map(|_, t| map(t)))
476    }
477
478    /// Resets all values in this map to their defaults.
479    ///
480    /// # Example
481    ///
482    /// ```rust
483    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
484    /// let mut map: StaticMap<_, u8> = static_map! {
485    ///     false => 0,
486    ///     true => 1,
487    /// };
488    /// assert_eq!(map[false], 0);
489    /// assert_eq!(map[true], 1);
490    /// map.clear();
491    /// assert_eq!(map[false], 0);
492    /// assert_eq!(map[true], 0);
493    /// ```
494    #[inline]
495    pub fn clear(&mut self)
496    where
497        T: Default,
498    {
499        for v in self.0.as_mut() {
500            *v = Default::default();
501        }
502    }
503
504    /// Returns an iterator over the keys in this map.
505    ///
506    /// # Example
507    ///
508    /// ```rust
509    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
510    /// let map: StaticMap<_, u8> = static_map! {
511    ///     false => 0,
512    ///     true => 1,
513    /// };
514    /// let mut iter = map.keys();
515    /// assert_eq!(iter.next(), Some(false));
516    /// assert_eq!(iter.next(), Some(true));
517    /// assert_eq!(iter.next(), None);
518    /// ```
519    #[inline]
520    pub fn keys(&self) -> Variants<L>
521    where
522        L: Sized,
523    {
524        L::variants()
525    }
526
527    /// Returns an iterator over references to the values in this map.
528    ///
529    /// # Example
530    ///
531    /// ```rust
532    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
533    /// let map: StaticMap<_, u8> = static_map! {
534    ///     false => 0,
535    ///     true => 1,
536    /// };
537    /// let mut iter = map.values();
538    /// assert_eq!(iter.next(), Some(&0));
539    /// assert_eq!(iter.next(), Some(&1));
540    /// assert_eq!(iter.next(), None);
541    /// ```
542    #[inline]
543    pub fn values(&self) -> core::slice::Iter<'_, T> {
544        self.as_ref().iter()
545    }
546
547    /// Returns an iterator over mutable references to the values in this map.
548    ///
549    /// # Example
550    ///
551    /// ```rust
552    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
553    /// let mut map: StaticMap<_, u8> = static_map! {
554    ///     false => 0,
555    ///     true => 1,
556    /// };
557    /// let mut iter = map.values_mut();
558    /// assert_eq!(iter.next(), Some(&mut 0));
559    /// assert_eq!(iter.next(), Some(&mut 1));
560    /// assert_eq!(iter.next(), None);
561    /// ```
562    #[inline]
563    pub fn values_mut(&mut self) -> core::slice::IterMut<'_, T> {
564        self.as_mut().iter_mut()
565    }
566
567    /// Returns an iterator over references to the entries in this map.
568    ///
569    /// # Example
570    ///
571    /// ```rust
572    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
573    /// let map: StaticMap<_, u8> = static_map! {
574    ///     false => 0,
575    ///     true => 1,
576    /// };
577    /// let mut iter = map.iter();
578    /// assert_eq!(iter.next(), Some((false, &0)));
579    /// assert_eq!(iter.next(), Some((true, &1)));
580    /// assert_eq!(iter.next(), None);
581    /// ```
582    #[inline]
583    pub fn iter(&self) -> Iter<'_, L, T>
584    where
585        L: Sized,
586    {
587        Iter::new(&self.0)
588    }
589
590    /// Returns an iterator over mutable references to the entries in this map.
591    ///
592    /// # Example
593    ///
594    /// ```rust
595    /// # use linearize::{static_map, StaticCopyMap, StaticMap};
596    /// let mut map: StaticMap<_, u8> = static_map! {
597    ///     false => 0,
598    ///     true => 1,
599    /// };
600    /// let mut iter = map.iter_mut();
601    /// assert_eq!(iter.next(), Some((false, &mut 0)));
602    /// assert_eq!(iter.next(), Some((true, &mut 1)));
603    /// assert_eq!(iter.next(), None);
604    /// ```
605    #[inline]
606    pub fn iter_mut(&mut self) -> IterMut<'_, L, T>
607    where
608        L: Sized,
609    {
610        IterMut::new(&mut self.0)
611    }
612
613    /// Consumes the map and returns an iterator over the values.
614    ///
615    /// # Example
616    ///
617    /// ```rust
618    /// # use linearize::{static_map, StaticMap};
619    /// let mut map: StaticMap<_, u8> = static_map! {
620    ///     false => 0,
621    ///     true => 1,
622    /// };
623    /// let mut iter = map.into_values();
624    /// assert_eq!(iter.next(), Some(0));
625    /// assert_eq!(iter.next(), Some(1));
626    /// assert_eq!(iter.next(), None);
627    /// ```   
628    pub fn into_values(self) -> IntoValues<L, T>
629    where
630        L: Sized,
631    {
632        IntoValues::new(self.0)
633    }
634}
635
636impl<L, T> Deref for StaticMap<L, T>
637where
638    L: Linearize + ?Sized,
639{
640    type Target = [T];
641
642    #[inline]
643    fn deref(&self) -> &Self::Target {
644        self.0.as_ref()
645    }
646}
647
648impl<L, T> DerefMut for StaticMap<L, T>
649where
650    L: Linearize + ?Sized,
651{
652    #[inline]
653    fn deref_mut(&mut self) -> &mut Self::Target {
654        self.0.as_mut()
655    }
656}
657
658impl<L, T> FromIterator<(L, T)> for StaticMap<L, T>
659where
660    L: Linearize,
661    T: Default,
662{
663    #[inline]
664    fn from_iter<I: IntoIterator<Item = (L, T)>>(iter: I) -> Self {
665        let mut res = StaticMap::<L, Option<T>>::default();
666        for (k, v) in iter {
667            res[k] = Some(v);
668        }
669        res.map_values(|v| v.unwrap_or_default())
670    }
671}
672
673impl<'a, L, T> FromIterator<(&'a L, T)> for StaticMap<L, T>
674where
675    L: Linearize,
676    T: Default,
677{
678    #[inline]
679    fn from_iter<I: IntoIterator<Item = (&'a L, T)>>(iter: I) -> Self {
680        let mut res = StaticMap::<L, Option<T>>::default();
681        for (k, v) in iter {
682            res[k] = Some(v);
683        }
684        res.map_values(|v| v.unwrap_or_default())
685    }
686}
687
688impl<L, T> Clone for StaticMap<L, T>
689where
690    L: Linearize + ?Sized,
691    T: Clone,
692{
693    #[inline]
694    fn clone(&self) -> Self {
695        Self(<L::Storage<T> as Storage<L, T>>::clone(&self.0))
696    }
697
698    #[inline]
699    fn clone_from(&mut self, source: &Self) {
700        <L::Storage<T> as Storage<L, T>>::clone_from(&mut self.0, &source.0);
701    }
702}
703
704impl<L, T> Index<&'_ L> for StaticMap<L, T>
705where
706    L: Linearize + ?Sized,
707{
708    type Output = T;
709
710    #[inline]
711    fn index(&self, index: &L) -> &Self::Output {
712        self.index(index.linearized())
713    }
714}
715
716impl<L, T> Index<L> for StaticMap<L, T>
717where
718    L: Linearize,
719{
720    type Output = T;
721
722    #[inline]
723    fn index(&self, index: L) -> &Self::Output {
724        self.index(index.linearized())
725    }
726}
727
728impl<L, T> Index<Linearized<L>> for StaticMap<L, T>
729where
730    L: Linearize + ?Sized,
731{
732    type Output = T;
733
734    #[inline(always)]
735    fn index(&self, index: Linearized<L>) -> &Self::Output {
736        unsafe {
737            // SAFETY:
738            // - self.0 is L::Storage which is required to be [T; L::LENGTH].
739            // - [T; L::LENGTH]: AsRef<[T]> returns &[T] with length L::LENGTH.
740            // - Key::<L>::get returns a value less than L::LENGTH.
741            <L::Storage<T> as AsRef<[T]>>::as_ref(&self.0).get_unchecked(index.get())
742        }
743    }
744}
745
746impl<L, T> IndexMut<&'_ L> for StaticMap<L, T>
747where
748    L: Linearize + ?Sized,
749{
750    #[inline]
751    fn index_mut(&mut self, index: &L) -> &mut Self::Output {
752        self.index_mut(index.linearized())
753    }
754}
755
756impl<L, T> IndexMut<L> for StaticMap<L, T>
757where
758    L: Linearize,
759{
760    #[inline]
761    fn index_mut(&mut self, index: L) -> &mut Self::Output {
762        self.index_mut(index.linearized())
763    }
764}
765
766impl<L, T> IndexMut<Linearized<L>> for StaticMap<L, T>
767where
768    L: Linearize + ?Sized,
769{
770    #[inline(always)]
771    fn index_mut(&mut self, index: Linearized<L>) -> &mut Self::Output {
772        unsafe {
773            // SAFETY:
774            // - self.0 is L::Storage which is required to be [T; L::LENGTH].
775            // - [T; L::LENGTH]: AsMut<[T]> returns &mut [T] with length L::LENGTH.
776            // - Key::<L>::get returns a value less than L::LENGTH.
777            <L::Storage<T> as AsMut<[T]>>::as_mut(&mut self.0).get_unchecked_mut(index.get())
778        }
779    }
780}
781
782impl<L, T> AsMut<[T]> for StaticMap<L, T>
783where
784    L: Linearize + ?Sized,
785{
786    #[inline]
787    fn as_mut(&mut self) -> &mut [T] {
788        self.0.as_mut()
789    }
790}
791
792impl<L, T> AsRef<[T]> for StaticMap<L, T>
793where
794    L: Linearize + ?Sized,
795{
796    #[inline]
797    fn as_ref(&self) -> &[T] {
798        self.0.as_ref()
799    }
800}
801
802impl<L, T> Borrow<[T]> for StaticMap<L, T>
803where
804    L: Linearize + ?Sized,
805{
806    #[inline]
807    fn borrow(&self) -> &[T] {
808        self.0.borrow()
809    }
810}
811
812impl<L, T> BorrowMut<[T]> for StaticMap<L, T>
813where
814    L: Linearize + ?Sized,
815{
816    #[inline]
817    fn borrow_mut(&mut self) -> &mut [T] {
818        self.0.borrow_mut()
819    }
820}
821
822impl<L, T> Debug for StaticMap<L, T>
823where
824    L: Linearize,
825    L: Debug,
826    T: Debug,
827{
828    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
829        let mut map = f.debug_map();
830        for (k, v) in self {
831            map.key(&k).value(v);
832        }
833        map.finish()
834    }
835}
836
837impl<L, T> Default for StaticMap<L, T>
838where
839    L: Linearize + ?Sized,
840    T: Default,
841{
842    #[inline]
843    fn default() -> Self {
844        Self(Storage::default())
845    }
846}
847
848impl<L, T> Eq for StaticMap<L, T>
849where
850    L: Linearize + ?Sized,
851    T: Eq,
852{
853}
854
855impl<L, T> Hash for StaticMap<L, T>
856where
857    L: Linearize + ?Sized,
858    T: Hash,
859{
860    #[inline]
861    fn hash<H: Hasher>(&self, state: &mut H) {
862        self.0.as_hash().hash(state)
863    }
864}
865
866impl<L, T> Ord for StaticMap<L, T>
867where
868    L: Linearize + ?Sized,
869    T: Ord,
870{
871    #[inline]
872    fn cmp(&self, other: &Self) -> Ordering {
873        self.0.cmp(&other.0)
874    }
875
876    #[inline]
877    fn max(self, other: Self) -> Self
878    where
879        Self: Sized,
880    {
881        Self(self.0.max(other.0))
882    }
883
884    #[inline]
885    fn min(self, other: Self) -> Self
886    where
887        Self: Sized,
888    {
889        Self(self.0.min(other.0))
890    }
891
892    #[inline]
893    fn clamp(self, min: Self, max: Self) -> Self
894    where
895        Self: Sized,
896        Self: PartialOrd,
897    {
898        Self(self.0.clamp(min.0, max.0))
899    }
900}
901
902impl<L, T> PartialEq for StaticMap<L, T>
903where
904    L: Linearize + ?Sized,
905    T: PartialEq,
906{
907    #[inline]
908    fn eq(&self, other: &Self) -> bool {
909        self.0.eq(&other.0)
910    }
911}
912
913impl<L, T> PartialOrd for StaticMap<L, T>
914where
915    L: Linearize + ?Sized,
916    T: PartialOrd,
917{
918    #[inline]
919    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
920        self.0.partial_cmp(&other.0)
921    }
922}
923
924impl<'a, L, T> TryFrom<&'a [T]> for &'a StaticMap<L, T>
925where
926    L: Linearize + ?Sized,
927{
928    type Error = TryFromSliceError;
929
930    #[inline]
931    fn try_from(value: &'a [T]) -> Result<Self, Self::Error> {
932        <L::Storage<T>>::ref_try_from(value).map(StaticMap::from_ref)
933    }
934}
935
936impl<'a, L, T> TryFrom<&'a mut [T]> for &'a mut StaticMap<L, T>
937where
938    L: Linearize + ?Sized,
939    T:,
940{
941    type Error = TryFromSliceError;
942
943    #[inline]
944    fn try_from(value: &'a mut [T]) -> Result<Self, Self::Error> {
945        <L::Storage<T>>::mut_try_from(value).map(StaticMap::from_mut)
946    }
947}
948
949impl<L, T> TryFrom<&[T]> for StaticMap<L, T>
950where
951    L: Linearize + ?Sized,
952    T: Copy,
953{
954    type Error = TryFromSliceError;
955
956    #[inline]
957    fn try_from(value: &[T]) -> Result<Self, Self::Error> {
958        <L::Storage<T>>::copy_ref_try_from(value).map(Self)
959    }
960}
961
962impl<L, T> TryFrom<&mut [T]> for StaticMap<L, T>
963where
964    L: Linearize + ?Sized,
965    T: Copy,
966{
967    type Error = TryFromSliceError;
968
969    #[inline]
970    fn try_from(value: &mut [T]) -> Result<Self, Self::Error> {
971        <L::Storage<T>>::copy_mut_try_from(value).map(Self)
972    }
973}
974
975#[cfg(feature = "std")]
976impl<L, T> TryFrom<Vec<T>> for StaticMap<L, T>
977where
978    L: Linearize + ?Sized,
979{
980    type Error = Vec<T>;
981
982    #[inline]
983    fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
984        <L::Storage<T>>::vec_try_from(value).map(Self)
985    }
986}
987
988impl<L, T> Extend<(L, T)> for StaticMap<L, T>
989where
990    L: Linearize,
991{
992    #[inline]
993    fn extend<I: IntoIterator<Item = (L, T)>>(&mut self, iter: I) {
994        for (k, v) in iter {
995            self[k] = v;
996        }
997    }
998}
999
1000impl<'a, L, T> Extend<(&'a L, &'a T)> for StaticMap<L, T>
1001where
1002    L: Linearize + ?Sized,
1003    T: Clone,
1004{
1005    #[inline]
1006    fn extend<I: IntoIterator<Item = (&'a L, &'a T)>>(&mut self, iter: I) {
1007        for (k, v) in iter {
1008            self[k] = v.clone();
1009        }
1010    }
1011}
1012
1013impl<'a, L, T> IntoIterator for &'a StaticMap<L, T>
1014where
1015    L: Linearize,
1016    T: 'a,
1017{
1018    type Item = (L, &'a T);
1019    type IntoIter = Iter<'a, L, T>;
1020
1021    #[inline]
1022    fn into_iter(self) -> Self::IntoIter {
1023        self.iter()
1024    }
1025}
1026
1027impl<'a, L, T> IntoIterator for &'a mut StaticMap<L, T>
1028where
1029    L: Linearize,
1030{
1031    type Item = (L, &'a mut T);
1032    type IntoIter = IterMut<'a, L, T>;
1033
1034    #[inline]
1035    fn into_iter(self) -> Self::IntoIter {
1036        self.iter_mut()
1037    }
1038}
1039
1040impl<L, T> IntoIterator for StaticMap<L, T>
1041where
1042    L: Linearize,
1043{
1044    type Item = (L, T);
1045    type IntoIter = IntoIter<L, T>;
1046
1047    #[inline]
1048    fn into_iter(self) -> Self::IntoIter {
1049        IntoIter::new(self.0.into_storage())
1050    }
1051}
1052
1053impl<L, T> From<StaticCopyMap<L, T>> for StaticMap<L, T>
1054where
1055    L: Linearize,
1056    T: Copy,
1057{
1058    fn from(value: StaticCopyMap<L, T>) -> Self {
1059        value.into_static_map()
1060    }
1061}
1062
1063impl<L, T> AsRef<StaticCopyMap<L, T>> for StaticMap<L, T>
1064where
1065    L: Linearize,
1066    T: Copy,
1067{
1068    fn as_ref(&self) -> &StaticCopyMap<L, T> {
1069        self.as_copy()
1070    }
1071}
1072
1073impl<L, T> AsMut<StaticCopyMap<L, T>> for StaticMap<L, T>
1074where
1075    L: Linearize,
1076    T: Copy,
1077{
1078    fn as_mut(&mut self) -> &mut StaticCopyMap<L, T> {
1079        self.as_copy_mut()
1080    }
1081}
1082
1083impl<L, T> Borrow<StaticCopyMap<L, T>> for StaticMap<L, T>
1084where
1085    L: Linearize,
1086    T: Copy,
1087{
1088    fn borrow(&self) -> &StaticCopyMap<L, T> {
1089        self.as_copy()
1090    }
1091}
1092
1093impl<L, T> BorrowMut<StaticCopyMap<L, T>> for StaticMap<L, T>
1094where
1095    L: Linearize,
1096    T: Copy,
1097{
1098    fn borrow_mut(&mut self) -> &mut StaticCopyMap<L, T> {
1099        self.as_copy_mut()
1100    }
1101}