File: main.rs

package info (click to toggle)
librsvg 2.44.10-2.1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 63,004 kB
  • sloc: ansic: 16,125; sh: 15,238; python: 1,097; makefile: 1,002; xml: 209; awk: 10
file content (179 lines) | stat: -rw-r--r-- 4,359 bytes parent folder | download | duplicates (7)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::fmt;

#[cfg(tests)]
mod tests;
mod op;

pub enum UIntCode {
    Term,
    Zero(Box<UIntCode>),
    One(Box<UIntCode>),
}

pub enum IntCode {
    Zero,
    Pos(Box<UIntCode>),
    Neg(Box<UIntCode>),
}

impl fmt::Display for UIntCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            UIntCode::Term => write!(f, "UTerm"),
            UIntCode::Zero(ref inner) => write!(f, "UInt<{}, B0>", inner),
            UIntCode::One(ref inner) => write!(f, "UInt<{}, B1>", inner),
        }
    }
}

impl fmt::Display for IntCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IntCode::Zero => write!(f, "Z0"),
            IntCode::Pos(ref inner) => write!(f, "PInt<{}>", inner),
            IntCode::Neg(ref inner) => write!(f, "NInt<{}>", inner),
        }
    }
}

pub fn gen_uint(u: u64) -> UIntCode {
    let mut result = UIntCode::Term;
    let mut x = 1u64 << 63;
    while x > u {
        x >>= 1
    }
    while x > 0 {
        result = if x & u > 0 {
            UIntCode::One(Box::new(result))
        } else {
            UIntCode::Zero(Box::new(result))
        };
        x >>= 1;
    }
    result
}

pub fn gen_int(i: i64) -> IntCode {
    if i > 0 {
        IntCode::Pos(Box::new(gen_uint(i as u64)))
    } else if i < 0 {
        IntCode::Neg(Box::new(gen_uint(i.abs() as u64)))
    } else {
        IntCode::Zero
    }
}

#[cfg_attr(feature="no_std", deprecated(
    since="1.3.0",
    note="the `no_std` flag is no longer necessary and will be removed in the future"))]
pub fn no_std() {}

// fixme: get a warning when testing without this
#[allow(dead_code)]
fn main() {
    let highest: u64 = 1024;

    let first2: u32 = (highest as f64).log(2.0).round() as u32 + 1;
    let first10: u32 = (highest as f64).log(10.0) as u32 + 1;
    let uints = (0..(highest + 1))
        .chain((first2..64).map(|i| 2u64.pow(i)))
        .chain((first10..20).map(|i| 10u64.pow(i)));

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest = Path::new(&out_dir).join("consts.rs");

    let mut f = File::create(&dest).unwrap();

    no_std();

    // Header stuff here!
    write!(
        f,
        "
/**
Type aliases for many constants.

This file is generated by typenum's build script.

For unsigned integers, the format is `U` followed by the number. We define aliases for

- Numbers 0 through {highest}
- Powers of 2 below `u64::MAX`
- Powers of 10 below `u64::MAX`

These alias definitions look like this:

```rust
use typenum::{{B0, B1, UInt, UTerm}};

# #[allow(dead_code)]
type U6 = UInt<UInt<UInt<UTerm, B1>, B1>, B0>;
```

For positive signed integers, the format is `P` followed by the number and for negative
signed integers it is `N` followed by the number. For the signed integer zero, we use
`Z0`. We define aliases for

- Numbers -{highest} through {highest}
- Powers of 2 between `i64::MIN` and `i64::MAX`
- Powers of 10 between `i64::MIN` and `i64::MAX`

These alias definitions look like this:

```rust
use typenum::{{B0, B1, UInt, UTerm, PInt, NInt}};

# #[allow(dead_code)]
type P6 = PInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
# #[allow(dead_code)]
type N6 = NInt<UInt<UInt<UInt<UTerm, B1>, B1>, B0>>;
```

# Example
```rust
# #[allow(unused_imports)]
use typenum::{{U0, U1, U2, U3, U4, U5, U6}};
# #[allow(unused_imports)]
use typenum::{{N3, N2, N1, Z0, P1, P2, P3}};
# #[allow(unused_imports)]
use typenum::{{U774, N17, N10000, P1024, P4096}};
```

We also define the aliases `False` and `True` for `B0` and `B1`, respectively.
*/
#[allow(missing_docs)]
pub mod consts {{
    use uint::{{UInt, UTerm}};
    use int::{{PInt, NInt}};

    pub use bit::{{B0, B1}};
    pub use int::Z0;

    pub type True = B1;
    pub type False = B0;
",
        highest = highest
    ).unwrap();

    for u in uints {
        write!(f, "    pub type U{} = {};\n", u, gen_uint(u)).unwrap();
        if u <= ::std::i64::MAX as u64 && u != 0 {
            let i = u as i64;
            write!(
                f,
                "    pub type P{i} = PInt<U{i}>; pub type N{i} = NInt<U{i}>;\n",
                i = i
            ).unwrap();
        }
    }
    write!(f, "}}").unwrap();

    #[cfg(tests)]
    tests::build_tests().unwrap();

    op::write_op_macro().unwrap();
}