Re: [PATCH 4/3] Introduce 'convert_path_to_git()'
- From
Linus Torvalds <torvalds@linux-foundation.org>
- Date
- May 16, 2009, 17:27 UTC
- Message-ID
- <alpine.LFD.2.01.0905161008190.3301@localhost.localdomain>
- In-Reply-To
- <7vy6sxpn2q.fsf@alter.siamese.dyndns.org>
On Fri, 15 May 2009, Junio C Hamano wrote:
> > "Ugly" is not quite the word I am looking for. "My gut feels that there > has to be a way to write this more cleanly, but I am frustrated that I > cannot come up with one" might be the word...
Well, we can certainly make it even more interesting, and more prone to work even when the word-size grows.
#define MAX_SHIFT (8*sizeof(unsigned long)) #define SHIFT_BITS(x,y) ((x) << ((y) & (MAX_SHIFT-1)))
#define EXPAND(x,bits) ((x) | SHIFT_BITS(x,bits)) #define EXPAND2(x,bits) EXPAND(EXPAND(x,bits),bits*2) #define EXPAND4(x,bits) EXPAND2(EXPAND2(x,bits),bits*4) #define MASK80 EXPAND4(0x80808080ul,32)
and now it should work up to 256 bits without warnings or undefined behavior (shifting by the word-size or more is not well-specified, which is why it has the "MAX_SHIFT/SHIFT_BIT" magic)
Untested, of course. But it seems to work on 32-bit and 64-bit cases. I can only hope that it works for 128-bit and 256-bit cases too.
And yes, it depends on "sizeof(unsigned long)" being a power of two. We could avoid that dependency by turning the "& (MAX_SHIFT-1)" into a ?: operation that actually compares with the value, and then it would work for a 6-byte "unsigned long" too.
It fundamentally does depend on 8-bit bytes, of course, but so does the whole algorithm, so that's not much of a dependency.
IOW, I'm not claiming it's "truly portable". Just reasonably so.
Linus