multidimension/
coat.rs

1use super::{NonTuple};
2
3/// `Coated<I>` behaves like `I` in most respects, but implements [`NonTuple`].
4#[derive(Debug, Default, Copy, Clone, Hash, PartialEq, Eq)]
5#[repr(transparent)]
6pub struct Coated<I>(pub I);
7
8impl<I> NonTuple for Coated<I>{}
9
10impl<I> std::ops::Deref for Coated<I> {
11    type Target = I;
12    fn deref(&self) -> &Self::Target { &self.0 }
13}
14
15impl<I> std::ops::DerefMut for Coated<I> {
16    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
17}
18
19// ----------------------------------------------------------------------------
20
21/// Implemented by types that differ from `T` by adding or removing at most one
22/// level of [`Coated`].
23pub trait Coat<I: Coat<Self>>: Sized {
24    fn coat(self) -> I;
25}
26
27impl<I> Coat<I> for Coated<I> {
28    #[inline(always)]
29    fn coat(self) -> I { self.0 }
30}
31
32impl<I> Coat<Coated<I>> for I {
33    #[inline(always)]
34    fn coat(self) -> Coated<I> { Coated(self) }
35}
36
37impl<I: NonTuple> Coat<Self> for I {
38    #[inline(always)]
39    fn coat(self) -> Self { self }
40}
41
42impl Coat<()> for () {
43    #[inline(always)]
44    fn coat(self) -> () { () }
45}
46
47impl<
48    I: Coat<CI>, CI: Coat<I>,
49> Coat<(CI,)> for (I,) {
50    #[inline(always)]
51    fn coat(self) -> (CI,) { (self.0.coat(),) }
52}
53
54impl<
55    I: Coat<CI>, CI: Coat<I>,
56    J: Coat<CJ>, CJ: Coat<J>,
57> Coat<(CI, CJ)> for (I, J) {
58    #[inline(always)]
59    fn coat(self) -> (CI, CJ) { (self.0.coat(), self.1.coat()) }
60}
61
62impl<
63    I: Coat<CI>, CI: Coat<I>,
64    J: Coat<CJ>, CJ: Coat<J>,
65    K: Coat<CK>, CK: Coat<K>,
66> Coat<(CI, CJ, CK)> for (I, J, K) {
67    #[inline(always)]
68    fn coat(self) -> (CI, CJ, CK) { (self.0.coat(), self.1.coat(), self.2.coat()) }
69}