### 2 releases

0.1.1 | Sep 6, 2023 |
---|---|

0.1.0 | Apr 27, 2020 |

#**1116** in Algorithms

**MIT/Apache**

17KB

191 lines

Represents a non-negative power of 2, by storing its exponent.

The

type is limited in range to `Pow2`

(inclusive). It is simply a wrapper around
`1` `..` `2``^``255`

, which stores the exponent.`u8`

is typically used for aligning integer values, such as I/O buffer sizes, page sizes,
etc.`Pow2`

Negative powers of 2 are not supported because they have little or no application in managing memory, quick multiplication, etc.

can represent values outside of the range of specific integer types. For example,
`Pow2`

cannot be converted to `Pow2 ::`from_exponent

`(`

`40`

`)`

`u32`

. The conversion implementations treat
this in a way similar to arithmetic overflow for operations such as `x ``*` y

; the operation is
defined, but may fail at runtime.It would be possible to define a family of

variants, one for each primitive integer type.
However, the ergonomics of that design might be undesireable; it is left for future study.`Pow2`

The operators defined for

are defined in terms of the value of the power of 2, not the
exponent. For example, `Pow2`

results in adding the exponents, not in multiplying the
exponents.`Pow2 * Pow2`

# Examples

`const` `PAGE_SIZE``:` Pow2 `=` `Pow2``::`from_exponent`(``12``)``;`
`assert_eq!``(``u32``::`from`(``PAGE_SIZE``)``,` `0x1000``)``;`
`let` x`:` `u32` `=` `0x1eee``;`
`assert_eq!``(``PAGE_SIZE``.``align_down``(`x`)``,` `0x1000``)``;`
`assert_eq!``(``PAGE_SIZE``.``align_up``(`x`)``,` `Some``(``0x2000``)``)``;`
`assert_eq!``(``PAGE_SIZE``.``align_up_unchecked``(`x`)``,` `0x2000``)``;`

The

macro can be used for writing constant powers of 2, using a value rather than
an exponent. Due to current limitations of const fns, the `pow2_const !`

`pow2_const``!`

macro does not check
whether the input is a valid power of 2. If it is not a power of 2, then its behavior is
undefined.`use` `pow2``::``{`Pow2`,` pow2_const`}``;`
`const` `PAGE_SIZE``:` Pow2 `=` `pow2_const!``(``0x1000``)``;`
`assert_eq!``(``PAGE_SIZE``.``exponent``(``)``,` `12``)``;`

# Signed examples

works with signed types as well as unsigned.`Pow2`

`use` `pow2``::`Pow2`;`
`const` `ALIGN4``:` Pow2 `=` `Pow2``::`from_exponent`(``2``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``4``i32``)``,` `Some``(``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``3``i32``)``,` `Some``(``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``2``i32``)``,` `Some``(``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``1``i32``)``,` `Some``(``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``0``i32``)``,` `Some``(``0``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``1``i32``)``,` `Some``(``0``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``2``i32``)``,` `Some``(``0``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``3``i32``)``,` `Some``(``0``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``4``i32``)``,` `Some``(``-``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``5``i32``)``,` `Some``(``-``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``6``i32``)``,` `Some``(``-``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``7``i32``)``,` `Some``(``-``4``i32``)``)``;`
`assert_eq!``(``ALIGN4``.``align_up``(``-``8``i32``)``,` `Some``(``-``8``i32``)``)``;`

# Unsafe code examples

This library does not contain unsafe code, but it can be used by unsafe code to operate on pointers. This is because Rust allows safe code to operate on the values of unsafe pointers, but not to dereference them.

`use` `pow2``::``{`Pow2`,` pow2_const`}``;`
`const` `U32_ALIGN``:` Pow2 `=` `Pow2``::``align_of``::``<``u32``>``(``)``;`
`let` array`:` `[``u32``;` `4``]` `=` `[` `111``,` `222``,` `333``,` `444` `]``;`
`let` item_0_address`:` `*const` `u8` `=` `&`array`[``0``]` `as` `*const` `u32` `as` `*const` `u8``;`
`let` item_1_address`:` `*const` `u8` `=` `&`array`[``1``]` `as` `*const` `u32` `as` `*const` `u8``;`
`assert_eq!``(`
`U32_ALIGN``.``align_up``(``(`item_0_address `as` `usize` `+` `1``)` `as` `*const` `u8``)``.``unwrap``(``)``,`
item_1_address
`)``;`

#### Dependencies

~1–1.6MB

~28K SLoC