• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 // Indicates that the element is not encoded; there is no *R* factor
16 // that needs to be canceled out.
17 #[derive(Copy, Clone)]
18 pub enum Unencoded {}
19 
20 // Indicates that the element is encoded; the value has one *R*
21 // factor that needs to be canceled out.
22 #[derive(Copy, Clone)]
23 pub enum R {}
24 
25 // Indicates the element is encoded twice; the value has two *R*
26 // factors that need to be canceled out.
27 #[derive(Copy, Clone)]
28 pub enum RR {}
29 
30 // Indicates the element is inversely encoded; the value has one
31 // 1/*R* factor that needs to be canceled out.
32 #[derive(Copy, Clone)]
33 pub enum RInverse {}
34 
35 pub trait Encoding {}
36 
37 impl Encoding for RR {}
38 impl Encoding for R {}
39 impl Encoding for Unencoded {}
40 impl Encoding for RInverse {}
41 
42 /// The encoding of the result of a reduction.
43 pub trait ReductionEncoding {
44     type Output: Encoding;
45 }
46 
47 impl ReductionEncoding for RR {
48     type Output = R;
49 }
50 impl ReductionEncoding for R {
51     type Output = Unencoded;
52 }
53 impl ReductionEncoding for Unencoded {
54     type Output = RInverse;
55 }
56 
57 /// The encoding of the result of a multiplication.
58 pub trait ProductEncoding {
59     type Output: Encoding;
60 }
61 
62 impl<E: ReductionEncoding> ProductEncoding for (Unencoded, E) {
63     type Output = E::Output;
64 }
65 
66 impl<E: Encoding> ProductEncoding for (R, E) {
67     type Output = E;
68 }
69 
70 impl<E: ReductionEncoding> ProductEncoding for (RInverse, E)
71 where
72     E::Output: ReductionEncoding,
73 {
74     type Output = <<E as ReductionEncoding>::Output as ReductionEncoding>::Output;
75 }
76 
77 // XXX: Rust doesn't allow overlapping impls,
78 // TODO (if/when Rust allows it):
79 // impl<E1, E2: ReductionEncoding> ProductEncoding for
80 //         (E1, E2) {
81 //     type Output = <(E2, E1) as ProductEncoding>::Output;
82 // }
83 impl ProductEncoding for (RR, Unencoded) {
84     type Output = <(Unencoded, RR) as ProductEncoding>::Output;
85 }
86 impl ProductEncoding for (RR, RInverse) {
87     type Output = <(RInverse, RR) as ProductEncoding>::Output;
88 }
89