I'll introduce my question using a concrete example. The actual question is at the bottom of this text.
Introduction
I'd like to extract some unaligned data from byte arrays where given are
- the start bit position
- the number of bits
- whether the data is MSB-first (big endian) or LSB-first (little endian) format
For that I created a Bitpacker
class that offers a static method
ulong ReadRaw(byte[] src, int startBit, int bitLength, Endianness endianness = Endianness.LSB_FIRST)
This method of course has to do some computation to get the desired bits out of the bytes using loops etc. which is slow. I need to evaluate the data on the order of multiple thousand times per second.
Because the arguments are compile-time known constants I could hard-code a fast variant by manually finding what bits to extract and how to shift them.
E.g. the following two assigments to raw
do the same:
ulong raw;
// Manually extract bits
raw = ((ulong)(src[5] & 0xFC) >> 2) + ((ulong)(src[6] & 0x3) << 6);
// Use the slow generic implementation
raw = Bitpacker.ReadRaw(src,42,8, Endianness.LSB_FIRST);
Hard-coding of course makes it difficult to write correct code and significantly decreases code-maintainability. That's where I thought that source-generators could come into play.
The actual question
Is it possible to use the source generator feature to somehow generate different code for each call to ReadRaw
based on the constant arguments or is it possible to replace the calls to ReadRaw
altogether using source generators?