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}