Skip to main content

enso_generics/
generic.rs

1//! Generic representation of data types. Refer to the crate documentation to learn more.
2
3// This crate defines many helper traits and uses this flag on purpose.
4#![allow(missing_docs)]
5
6use super::hlist;
7pub use nalgebra::base::dimension::*;
8
9
10
11// ==============
12// === Traits ===
13// ==============
14
15/// Common traits.
16pub mod traits {
17    pub use super::HasRepr        as _TRAIT_HasRepr;
18    pub use super::HasFieldsCount as _TRAIT_HasFieldsCount;
19
20    pub use super::HasItemAt      as _TRAIT_HasItemAt;
21    pub use super::HasItemAt0     as _TRAIT_HasItemAt0;
22    pub use super::HasItemAt1     as _TRAIT_HasItemAt1;
23    pub use super::HasItemAt2     as _TRAIT_HasItemAt2;
24    pub use super::HasItemAt3     as _TRAIT_HasItemAt3;
25    pub use super::HasItemAt4     as _TRAIT_HasItemAt4;
26    pub use super::HasItemAt5     as _TRAIT_HasItemAt5;
27    pub use super::HasItemAt6     as _TRAIT_HasItemAt6;
28    pub use super::HasItemAt7     as _TRAIT_HasItemAt7;
29    pub use super::HasItemAt8     as _TRAIT_HasItemAt8;
30    pub use super::HasItemAt9     as _TRAIT_HasItemAt9;
31    pub use super::HasItemAt10    as _TRAIT_HasItemAt10;
32    pub use super::HasItemAt11    as _TRAIT_HasItemAt11;
33    pub use super::HasItemAt12    as _TRAIT_HasItemAt12;
34    pub use super::HasItemAt13    as _TRAIT_HasItemAt13;
35    pub use super::HasItemAt14    as _TRAIT_HasItemAt14;
36    pub use super::HasItemAt15    as _TRAIT_HasItemAt15;
37
38    pub use super::_GetItemAt     as _TRAIT__GetItemAt;
39    pub use super::GetItemAt      as _TRAIT_GetItemAt;
40    pub use super::GetItemAt0     as _TRAIT_GetItemAt0;
41    pub use super::GetItemAt1     as _TRAIT_GetItemAt1;
42    pub use super::GetItemAt2     as _TRAIT_GetItemAt2;
43    pub use super::GetItemAt3     as _TRAIT_GetItemAt3;
44    pub use super::GetItemAt4     as _TRAIT_GetItemAt4;
45    pub use super::GetItemAt5     as _TRAIT_GetItemAt5;
46    pub use super::GetItemAt6     as _TRAIT_GetItemAt6;
47    pub use super::GetItemAt7     as _TRAIT_GetItemAt7;
48    pub use super::GetItemAt8     as _TRAIT_GetItemAt8;
49    pub use super::GetItemAt9     as _TRAIT_GetItemAt9;
50    pub use super::GetItemAt10    as _TRAIT_GetItemAt10;
51    pub use super::GetItemAt11    as _TRAIT_GetItemAt11;
52    pub use super::GetItemAt12    as _TRAIT_GetItemAt12;
53    pub use super::GetItemAt13    as _TRAIT_GetItemAt13;
54    pub use super::GetItemAt14    as _TRAIT_GetItemAt14;
55    pub use super::GetItemAt15    as _TRAIT_GetItemAt15;
56
57    pub use super::ItemAt         as _TRAIT_ItemAt;
58    pub use super::ItemAt0        as _TRAIT_ItemAt0;
59    pub use super::ItemAt1        as _TRAIT_ItemAt1;
60    pub use super::ItemAt2        as _TRAIT_ItemAt2;
61    pub use super::ItemAt3        as _TRAIT_ItemAt3;
62    pub use super::ItemAt4        as _TRAIT_ItemAt4;
63    pub use super::ItemAt5        as _TRAIT_ItemAt5;
64    pub use super::ItemAt6        as _TRAIT_ItemAt6;
65    pub use super::ItemAt7        as _TRAIT_ItemAt7;
66    pub use super::ItemAt8        as _TRAIT_ItemAt8;
67    pub use super::ItemAt9        as _TRAIT_ItemAt9;
68    pub use super::ItemAt10       as _TRAIT_ItemAt10;
69    pub use super::ItemAt11       as _TRAIT_ItemAt11;
70    pub use super::ItemAt12       as _TRAIT_ItemAt12;
71    pub use super::ItemAt13       as _TRAIT_ItemAt13;
72    pub use super::ItemAt14       as _TRAIT_ItemAt14;
73    pub use super::ItemAt15       as _TRAIT_ItemAt15;
74}
75
76
77
78// ===============
79// === HasRepr ===
80// ===============
81
82/// Association of a given type with its generic representation.
83pub trait HasRepr {
84    type GenericRepr : hlist::HList;
85}
86
87/// Type level accessor of a generic representation of the given type.
88pub type Repr<T> = <T as HasRepr>::GenericRepr;
89
90/// Converts the type to its generic representation. Please note that this trait is implemented
91/// automatically for every type which implements `Into<Repr<Self>>`.
92pub trait IntoGeneric : HasRepr + Into<Repr<Self>> {
93    fn into_generic(self) -> Repr<Self> {
94        self.into()
95    }
96}
97impl<T> IntoGeneric for T where T : HasRepr + Into<Repr<T>> {}
98
99
100
101// ======================
102// === HasFieldsCount ===
103// ======================
104
105/// Information of field count of any structure implementing `Generics`. This trait is implemented
106/// automatically.
107pub trait HasFieldsCount {
108    const FIELDS_COUNT : usize;
109    fn fields_count() -> usize {
110        Self::FIELDS_COUNT
111    }
112}
113
114impl<T> HasFieldsCount for T
115where T:HasRepr {
116    const FIELDS_COUNT : usize = <Repr<T> as hlist::HasLength>::LEN;
117}
118
119
120
121// ================
122// === HasIndex ===
123// ================
124
125/// Trait for heterogeneous containers like tuples which contain element at index `Ix`.
126pub trait HasItemAt<Ix> { type Item; }
127pub trait HasItemAt0  = HasItemAt<U0>;
128pub trait HasItemAt1  = HasItemAt<U1>;
129pub trait HasItemAt2  = HasItemAt<U2>;
130pub trait HasItemAt3  = HasItemAt<U3>;
131pub trait HasItemAt4  = HasItemAt<U4>;
132pub trait HasItemAt5  = HasItemAt<U5>;
133pub trait HasItemAt6  = HasItemAt<U6>;
134pub trait HasItemAt7  = HasItemAt<U7>;
135pub trait HasItemAt8  = HasItemAt<U8>;
136pub trait HasItemAt9  = HasItemAt<U9>;
137pub trait HasItemAt10 = HasItemAt<U10>;
138pub trait HasItemAt11 = HasItemAt<U11>;
139pub trait HasItemAt12 = HasItemAt<U12>;
140pub trait HasItemAt13 = HasItemAt<U13>;
141pub trait HasItemAt14 = HasItemAt<U14>;
142pub trait HasItemAt15 = HasItemAt<U15>;
143
144/// Type of element at index `Ix`. Useful for heterogeneous containers like tuples.
145pub type ItemAt<Ix,T> = <T as HasItemAt<Ix>>::Item;
146pub type ItemAt0  <T> = ItemAt <U0  , T>;
147pub type ItemAt1  <T> = ItemAt <U1  , T>;
148pub type ItemAt2  <T> = ItemAt <U2  , T>;
149pub type ItemAt3  <T> = ItemAt <U3  , T>;
150pub type ItemAt4  <T> = ItemAt <U4  , T>;
151pub type ItemAt5  <T> = ItemAt <U5  , T>;
152pub type ItemAt6  <T> = ItemAt <U6  , T>;
153pub type ItemAt7  <T> = ItemAt <U7  , T>;
154pub type ItemAt8  <T> = ItemAt <U8  , T>;
155pub type ItemAt9  <T> = ItemAt <U9  , T>;
156pub type ItemAt10 <T> = ItemAt <U10 , T>;
157pub type ItemAt11 <T> = ItemAt <U11 , T>;
158pub type ItemAt12 <T> = ItemAt <U12 , T>;
159pub type ItemAt13 <T> = ItemAt <U13 , T>;
160pub type ItemAt14 <T> = ItemAt <U14 , T>;
161pub type ItemAt15 <T> = ItemAt <U15 , T>;
162
163/// Accessor for element at index `Ix`.
164pub trait GetItemAt<Ix> : HasItemAt<Ix> + _GetItemAt {
165    fn get_item_at(&self) -> &ItemAt<Ix,Self>;
166}
167
168/// Smart wrapper for `GetItemAt`. Enables syntax `lst.item_at::<U0>()`.
169impl<T>   _GetItemAt for T {}
170pub trait _GetItemAt {
171    fn item_at<Ix>(&self) -> &ItemAt<Ix,Self> where Self:GetItemAt<Ix> {
172        GetItemAt::<Ix>::get_item_at(self)
173    }
174}
175
176pub trait GetItemAt0  : GetItemAt <U0> { fn  _0(&self) -> &ItemAt0  <Self> {self.item_at::<U0> ()} }
177pub trait GetItemAt1  : GetItemAt <U1> { fn  _1(&self) -> &ItemAt1  <Self> {self.item_at::<U1> ()} }
178pub trait GetItemAt2  : GetItemAt <U2> { fn  _2(&self) -> &ItemAt2  <Self> {self.item_at::<U2> ()} }
179pub trait GetItemAt3  : GetItemAt <U3> { fn  _3(&self) -> &ItemAt3  <Self> {self.item_at::<U3> ()} }
180pub trait GetItemAt4  : GetItemAt <U4> { fn  _4(&self) -> &ItemAt4  <Self> {self.item_at::<U4> ()} }
181pub trait GetItemAt5  : GetItemAt <U5> { fn  _5(&self) -> &ItemAt5  <Self> {self.item_at::<U5> ()} }
182pub trait GetItemAt6  : GetItemAt <U6> { fn  _6(&self) -> &ItemAt6  <Self> {self.item_at::<U6> ()} }
183pub trait GetItemAt7  : GetItemAt <U7> { fn  _7(&self) -> &ItemAt7  <Self> {self.item_at::<U7> ()} }
184pub trait GetItemAt8  : GetItemAt <U8> { fn  _8(&self) -> &ItemAt8  <Self> {self.item_at::<U8> ()} }
185pub trait GetItemAt9  : GetItemAt <U9> { fn  _9(&self) -> &ItemAt9  <Self> {self.item_at::<U9> ()} }
186pub trait GetItemAt10 : GetItemAt<U10> { fn _10(&self) -> &ItemAt10 <Self> {self.item_at::<U10>()} }
187pub trait GetItemAt11 : GetItemAt<U11> { fn _11(&self) -> &ItemAt11 <Self> {self.item_at::<U11>()} }
188pub trait GetItemAt12 : GetItemAt<U12> { fn _12(&self) -> &ItemAt12 <Self> {self.item_at::<U12>()} }
189pub trait GetItemAt13 : GetItemAt<U13> { fn _13(&self) -> &ItemAt13 <Self> {self.item_at::<U13>()} }
190pub trait GetItemAt14 : GetItemAt<U14> { fn _14(&self) -> &ItemAt14 <Self> {self.item_at::<U14>()} }
191pub trait GetItemAt15 : GetItemAt<U15> { fn _15(&self) -> &ItemAt15 <Self> {self.item_at::<U15>()} }
192
193impl<T:GetItemAt<U0>>  GetItemAt0  for T {}
194impl<T:GetItemAt<U1>>  GetItemAt1  for T {}
195impl<T:GetItemAt<U2>>  GetItemAt2  for T {}
196impl<T:GetItemAt<U3>>  GetItemAt3  for T {}
197impl<T:GetItemAt<U4>>  GetItemAt4  for T {}
198impl<T:GetItemAt<U5>>  GetItemAt5  for T {}
199impl<T:GetItemAt<U6>>  GetItemAt6  for T {}
200impl<T:GetItemAt<U7>>  GetItemAt7  for T {}
201impl<T:GetItemAt<U8>>  GetItemAt8  for T {}
202impl<T:GetItemAt<U9>>  GetItemAt9  for T {}
203impl<T:GetItemAt<U10>> GetItemAt10 for T {}
204impl<T:GetItemAt<U11>> GetItemAt11 for T {}
205impl<T:GetItemAt<U12>> GetItemAt12 for T {}
206impl<T:GetItemAt<U13>> GetItemAt13 for T {}
207impl<T:GetItemAt<U14>> GetItemAt14 for T {}
208impl<T:GetItemAt<U15>> GetItemAt15 for T {}