1use core::marker::PhantomData;
26
27mod private {
29 pub trait Sealed {}
30}
31
32pub trait CompletenessProperty: private::Sealed + Clone + Copy + Default + 'static {}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
43pub struct Complete;
44
45impl private::Sealed for Complete {}
46impl CompletenessProperty for Complete {}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
52pub struct PreHilbert;
53
54impl private::Sealed for PreHilbert {}
55impl CompletenessProperty for PreHilbert {}
56
57pub trait BoundednessProperty: private::Sealed + Clone + Copy + Default + 'static {}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
68pub struct Bounded;
69
70impl private::Sealed for Bounded {}
71impl BoundednessProperty for Bounded {}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
77pub struct Unbounded;
78
79impl private::Sealed for Unbounded {}
80impl BoundednessProperty for Unbounded {}
81
82pub trait CompactnessProperty: private::Sealed + Clone + Copy + Default + 'static {}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
89pub struct Compact;
90
91impl private::Sealed for Compact {}
92impl CompactnessProperty for Compact {}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
96pub struct NonCompact;
97
98impl private::Sealed for NonCompact {}
99impl CompactnessProperty for NonCompact {}
100
101pub trait SymmetryProperty: private::Sealed + Clone + Copy + Default + 'static {}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
108pub struct SelfAdjoint;
109
110impl private::Sealed for SelfAdjoint {}
111impl SymmetryProperty for SelfAdjoint {}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
117pub struct Normal;
118
119impl private::Sealed for Normal {}
120impl SymmetryProperty for Normal {}
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
126pub struct Unitary;
127
128impl private::Sealed for Unitary {}
129impl SymmetryProperty for Unitary {}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
133pub struct General;
134
135impl private::Sealed for General {}
136impl SymmetryProperty for General {}
137
138pub trait SpectralProperty: private::Sealed + Clone + Copy + Default + 'static {}
144
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
149pub struct DiscreteSpectrum;
150
151impl private::Sealed for DiscreteSpectrum {}
152impl SpectralProperty for DiscreteSpectrum {}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
156pub struct ContinuousSpectrum;
157
158impl private::Sealed for ContinuousSpectrum {}
159impl SpectralProperty for ContinuousSpectrum {}
160
161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
163pub struct PurePointSpectrum;
164
165impl private::Sealed for PurePointSpectrum {}
166impl SpectralProperty for PurePointSpectrum {}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
170pub struct MixedSpectrum;
171
172impl private::Sealed for MixedSpectrum {}
173impl SpectralProperty for MixedSpectrum {}
174
175pub trait RegularityProperty: private::Sealed + Clone + Copy + Default + 'static {}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
184pub struct L2Regularity;
185
186impl private::Sealed for L2Regularity {}
187impl RegularityProperty for L2Regularity {}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
191pub struct H1Regularity;
192
193impl private::Sealed for H1Regularity {}
194impl RegularityProperty for H1Regularity {}
195
196#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
198pub struct H2Regularity;
199
200impl private::Sealed for H2Regularity {}
201impl RegularityProperty for H2Regularity {}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
205pub struct HkRegularity<const K: usize>;
206
207impl<const K: usize> private::Sealed for HkRegularity<K> {}
208impl<const K: usize> RegularityProperty for HkRegularity<K> {}
209
210pub trait FredholmProperty: private::Sealed + Clone + Copy + Default + 'static {}
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
219pub struct Fredholm;
220
221impl private::Sealed for Fredholm {}
222impl FredholmProperty for Fredholm {}
223
224#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
226pub struct SemiFredholm;
227
228impl private::Sealed for SemiFredholm {}
229impl FredholmProperty for SemiFredholm {}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
233pub struct NotFredholm;
234
235impl private::Sealed for NotFredholm {}
236impl FredholmProperty for NotFredholm {}
237
238pub type CompactSelfAdjointOperator = (Compact, SelfAdjoint, DiscreteSpectrum);
244
245pub type UnitaryOperator = (Bounded, Unitary, PurePointSpectrum);
247
248pub type HilbertSchmidtOperator = (Compact, General, DiscreteSpectrum);
250
251pub type L2SpaceProperties = (Complete, L2Regularity);
253
254pub type H1SpaceProperties = (Complete, H1Regularity);
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
266pub struct Properties<T>(PhantomData<T>);
267
268impl<T> Properties<T> {
269 pub const fn new() -> Self {
271 Self(PhantomData)
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use super::*;
278 use core::mem::size_of;
279
280 #[test]
281 fn test_phantom_types_are_zero_sized() {
282 assert_eq!(size_of::<Complete>(), 0);
283 assert_eq!(size_of::<PreHilbert>(), 0);
284 assert_eq!(size_of::<Bounded>(), 0);
285 assert_eq!(size_of::<Compact>(), 0);
286 assert_eq!(size_of::<SelfAdjoint>(), 0);
287 assert_eq!(size_of::<Normal>(), 0);
288 assert_eq!(size_of::<Unitary>(), 0);
289 assert_eq!(size_of::<DiscreteSpectrum>(), 0);
290 assert_eq!(size_of::<Fredholm>(), 0);
291 assert_eq!(size_of::<L2Regularity>(), 0);
292 assert_eq!(size_of::<HkRegularity<5>>(), 0);
293 assert_eq!(size_of::<Properties<CompactSelfAdjointOperator>>(), 0);
294 }
295
296 #[test]
297 fn test_phantom_types_implement_traits() {
298 fn assert_completeness<T: CompletenessProperty>() {}
299 fn assert_boundedness<T: BoundednessProperty>() {}
300 fn assert_compactness<T: CompactnessProperty>() {}
301 fn assert_symmetry<T: SymmetryProperty>() {}
302 fn assert_spectral<T: SpectralProperty>() {}
303 fn assert_regularity<T: RegularityProperty>() {}
304 fn assert_fredholm<T: FredholmProperty>() {}
305
306 assert_completeness::<Complete>();
307 assert_completeness::<PreHilbert>();
308
309 assert_boundedness::<Bounded>();
310 assert_boundedness::<Unbounded>();
311
312 assert_compactness::<Compact>();
313 assert_compactness::<NonCompact>();
314
315 assert_symmetry::<SelfAdjoint>();
316 assert_symmetry::<Normal>();
317 assert_symmetry::<Unitary>();
318 assert_symmetry::<General>();
319
320 assert_spectral::<DiscreteSpectrum>();
321 assert_spectral::<ContinuousSpectrum>();
322 assert_spectral::<PurePointSpectrum>();
323 assert_spectral::<MixedSpectrum>();
324
325 assert_regularity::<L2Regularity>();
326 assert_regularity::<H1Regularity>();
327 assert_regularity::<H2Regularity>();
328 assert_regularity::<HkRegularity<3>>();
329
330 assert_fredholm::<Fredholm>();
331 assert_fredholm::<SemiFredholm>();
332 assert_fredholm::<NotFredholm>();
333 }
334
335 #[test]
336 fn test_phantom_types_are_copy() {
337 let c1 = Complete;
338 let c2 = c1;
339 assert_eq!(c1, c2);
340
341 let b1 = Bounded;
342 let b2 = b1;
343 assert_eq!(b1, b2);
344 }
345
346 #[test]
347 fn test_properties_wrapper() {
348 let props: Properties<CompactSelfAdjointOperator> = Properties::new();
349 assert_eq!(size_of_val(&props), 0);
350 }
351}