Modular Bitfields for Rust
Continuous Integration | Documentation | Crates.io | LoC |
---|---|---|---|
Description
Allows to have bitfield structs and enums as bitfield specifiers that work very similar to C and C++ bitfields.
Advantages
- Safety: Macro embraced enums and structs are checked for valid structure during compilation time.
- Speed: Generated code is as fast as handwritten code. (See benchmarks below.)
- Modularity: Enums can be used modular within bitfield structs.
Attribution
Implements the #[bitfield]
macros introduced and specified in David Tolnay's procedural macro workshop.
Thanks go to David Tolnay for designing the specification for the macros implemented in this crate.
Example
use *;
// Works with aliases - just for the showcase.
type Vitamin = B12;
/// Bitfield struct with 32 bits in total.
/// Enums that derive from `BitfieldSpecifier`
/// can also be used within bitfield structs
/// as shown above.
Benchmarks
Below are some benchmarks between the hand-written code and the macro-generated code for some example getters and setters that cover a decent variety of use cases.
We can conclude that the macro-generated code is as fast as hand-written code would be. Please file a PR if you see a way to improve either side.
cargo bench
to run the benchmarkscargo test --benches
to run the benchmark tests
We tested the following struct
:
Note: All benchmarks timing results sum 10 runs each.
Getter Performance
cmp_get_a/generated time: [3.0490 ns 3.0628 ns 3.0791 ns]
cmp_get_a/handwritten time: [3.0640 ns 3.0782 ns 3.0928 ns]
cmp_get_b/generated time: [3.0600 ns 3.0731 ns 3.0871 ns]
cmp_get_b/handwritten time: [3.0457 ns 3.0592 ns 3.0744 ns]
cmp_get_c/generated time: [3.0762 ns 3.1040 ns 3.1368 ns]
cmp_get_c/handwritten time: [3.0638 ns 3.0782 ns 3.0934 ns]
cmp_get_d/generated time: [3.0603 ns 3.0729 ns 3.0869 ns]
cmp_get_d/handwritten time: [3.0833 ns 3.1358 ns 3.2064 ns]
cmp_get_e/generated time: [3.0688 ns 3.0915 ns 3.1203 ns]
cmp_get_e/handwritten time: [3.0634 ns 3.0753 ns 3.0877 ns]
Setter Performance
cmp_set_a/generated time: [15.643 ns 15.707 ns 15.775 ns]
cmp_set_a/handwritten time: [15.593 ns 15.661 ns 15.736 ns]
cmp_set_b/generated time: [20.334 ns 20.439 ns 20.550 ns]
cmp_set_b/handwritten time: [20.262 ns 20.327 ns 20.397 ns]
cmp_set_c/generated time: [19.634 ns 19.847 ns 20.111 ns]
cmp_set_c/handwritten time: [19.544 ns 19.632 ns 19.729 ns]
cmp_set_d/generated time: [20.316 ns 20.376 ns 20.437 ns]
cmp_set_d/handwritten time: [20.291 ns 20.371 ns 20.457 ns]
cmp_set_e/generated time: [6.1394 ns 6.1640 ns 6.1873 ns]
cmp_set_e/handwritten time: [6.1172 ns 6.1459 ns 6.1767 ns]
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this codebase by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.