mayda_macros 0.1.1

Macros to generate basic encoding and decoding functions used by mayda
docs.rs failed to build mayda_macros-0.1.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: mayda_macros-0.1.4

Compiler plugins to generate basic encoding and decoding functions. The functions generated by the encode! and decode! syntax extensions follow the convention encode_T_a_b. The functions generated by the encode_simd! and decode_simd! syntax extensions follow the convention encode_simd_T_a. The functions generated by the encode_util! syntax extention follow the conventions encode_delta_T and encode_zz_shift_T. T is one of the unsigned integer types, a is the number of bits per integer, and b is the number of integers encoded.

encode! and decode! take as arguments the unsigned integer type width in bits and a step for the number of integers (a divisor of 32). Functions are generated for numbers of bits in the interval 0...max_bits, and for numbers of integers in multiples of the step up to 32. encode_simd! and decode_simd! take as arguments the unsigned integer type width in bits and a path to the relevant simd module. Functions are generated for numbers of bits in the interval 0...max_bits, and for exactly 128 integers. encode_util! takes as arguments the unsigned integer type width in bits and a path to the relevant simd module. Functions are generated for the type width and for an arbitrary number of integers.

Pointers to the functions generated by encode! and decode! are available in ENCODE_T and DECODE_T, respectively, with the pointer for encode_T_a_b at ENCODE_T[a][b / c - 1] where c is the step. Pointers to the functions generated by encode_simd! and decode_simd! are availabe in ENCODE_SIMD_T and DECODE_SIMD_T, respectively, with the pointer for encode_simd_T_a at ENCODE_SIMD_T[a]. The functions generated by encode_util! are public. All arrays are public and constant.

Safety

The functions generated by this crate use wildly unsafe pointer operations. You must verify that enough memory is already allocated after the pointers that the offsets are valid. They are not intended to be used outside the mayda crate.

Examples

The syntax extensions defined in this crate can be invoked as

encode!(u32, 32, 8);
decode!(u32, 32, 8);

This is replaced by 128 functions that encode u32 integers and 128 functions that decode u32 integers. For example, the functions that encode and decode the 24 least significant bits of 8 u32 integers are

unsafe fn encode_u32_24_8(i_ptr: *const u32, s_ptr: *mut u32) {
    let mut i_ptr = i_ptr;
    let mut s_ptr = s_ptr;
    let mut out = *i_ptr as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 24usize;
    *s_ptr = out;
    s_ptr = s_ptr.offset(1);
    out = (*i_ptr >> 8usize) as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 16usize;
    *s_ptr = out;
    s_ptr = s_ptr.offset(1);
    out = (*i_ptr >> 16usize) as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 8usize;
    i_ptr = i_ptr.offset(1);
    *s_ptr = out;
    s_ptr = s_ptr.offset(1);
    out = *i_ptr as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 24usize;
    *s_ptr = out;
    s_ptr = s_ptr.offset(1);
    out = (*i_ptr >> 8usize) as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 16usize;
    *s_ptr = out;
    s_ptr = s_ptr.offset(1);
    out = (*i_ptr >> 16usize) as u32;
    i_ptr = i_ptr.offset(1);
    out |= (*i_ptr as u32) << 8usize;
    *s_ptr = out;
}

unsafe fn decode_u32_24_8(s_ptr: *const u32, o_ptr: *mut u32) {
    let mut s_ptr = s_ptr;
    let mut o_ptr = o_ptr;
    let mask: u32 = !0 >> 8usize;
    let mut out;
    out = *s_ptr as u32;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 24usize) as u32;
    s_ptr = s_ptr.offset(1);
    out |= (*s_ptr as u32) << 8usize;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 16usize) as u32;
    s_ptr = s_ptr.offset(1);
    out |= (*s_ptr as u32) << 16usize;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 8usize) as u32;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    s_ptr = s_ptr.offset(1);
    out = *s_ptr as u32;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 24usize) as u32;
    s_ptr = s_ptr.offset(1);
    out |= (*s_ptr as u32) << 8usize;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 16usize) as u32;
    s_ptr = s_ptr.offset(1);
    out |= (*s_ptr as u32) << 16usize;
    *o_ptr = out & mask;
    o_ptr = o_ptr.offset(1);
    out = (*s_ptr >> 8usize) as u32;
    *o_ptr = out & mask;
}