1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use crate::LinkType;
use funty::Integral;
use std::ops::{Div, Sub};
#[derive(Debug, Clone, Copy, Hash, PartialOrd, PartialEq, Ord, Eq)]
pub struct Hybrid<T> {
value: T,
}
impl<T: LinkType> Hybrid<T> {
pub const fn new(value: T) -> Self {
Self::internal(value)
}
pub const fn half() -> T
where
T: ~const Div<Output = T>,
{
T::MAX / T::funty(2)
}
pub(crate) const fn external(value: T) -> Self
where
T: ~const Integral + ~const Sub,
{
Self {
value: Self::extend_value(value),
}
}
pub(crate) const fn internal(value: T) -> Self {
Self { value }
}
const fn extend_value(value: T) -> T
where
T: ~const Integral + ~const Sub,
{
(T::MAX - value).wrapping_add(T::funty(1))
}
pub const fn is_zero(&self) -> bool
where
T: ~const Default + ~const PartialEq,
{
self.value == T::funty(0)
}
pub const fn is_internal(&self) -> bool
where
T: ~const Div + ~const PartialOrd,
{
self.value < Self::half()
}
pub const fn is_external(&self) -> bool
where
T: ~const Div + ~const PartialOrd + ~const PartialEq,
{
!self.is_internal() || self.value == T::funty(0)
}
pub const fn abs(&self) -> T
where
T: ~const Integral,
{
self.value.wrapping_add(T::funty(1)).wrapping_add(T::MAX)
}
pub const fn as_inner(&self) -> T {
self.value
}
}