1use core::ops::Add;
2
3pub trait Sum<Output> {
5 fn zero() -> Output;
7
8 fn owned(a: Self) -> Output;
10
11 fn u_owned<U>(_: &mut U, a: Self) -> Output;
13
14 fn add(a: Output, b: Output) -> Output;
16
17 fn u_add<U>(_: &mut U, a: Output, b: Output) -> Output;
19}
20
21impl<X> Sum<X> for X
22where
23 X: Default + Add<X, Output = X>,
24{
25 fn zero() -> X {
26 X::default()
27 }
28
29 #[inline(always)]
30 fn owned(a: Self) -> X {
31 a
32 }
33
34 #[inline(always)]
35 fn u_owned<U>(_: &mut U, a: Self) -> X {
36 a
37 }
38
39 #[inline(always)]
40 fn add(a: X, b: X) -> X {
41 a + b
42 }
43
44 #[inline(always)]
45 fn u_add<U>(_: &mut U, a: X, b: X) -> X {
46 a + b
47 }
48}
49
50impl<'a, X> Sum<X> for &'a X
51where
52 X: Default + Add<X, Output = X> + Copy,
53 &'a X: Add<&'a X, Output = X>,
54{
55 fn zero() -> X {
56 X::default()
57 }
58
59 #[inline(always)]
60 fn owned(a: Self) -> X {
61 *a
62 }
63
64 #[inline(always)]
65 fn u_owned<U>(_: &mut U, a: Self) -> X {
66 *a
67 }
68
69 #[inline(always)]
70 fn add(a: X, b: X) -> X {
71 a + b
72 }
73
74 #[inline(always)]
75 fn u_add<U>(_: &mut U, a: X, b: X) -> X {
76 a + b
77 }
78}
79
80impl<'a, X> Sum<X> for &'a mut X
81where
82 X: Default + Add<X, Output = X> + Copy,
83 &'a X: Add<&'a X, Output = X>,
84{
85 fn zero() -> X {
86 X::default()
87 }
88
89 #[inline(always)]
90 fn owned(a: Self) -> X {
91 *a
92 }
93
94 #[inline(always)]
95 fn u_owned<U>(_: &mut U, a: Self) -> X {
96 *a
97 }
98
99 #[inline(always)]
100 fn add(a: X, b: X) -> X {
101 a + b
102 }
103
104 #[inline(always)]
105 fn u_add<U>(_: &mut U, a: X, b: X) -> X {
106 a + b
107 }
108}