Moving Up To 64 Bits by Arch D. Robison Listing One // Big-endian code. Presumes 8-bit bytes and 64-bit type long. size_t strlen( const char * s ) { typedef unsigned long word; // Align on word boundary // Presumes that sizeof(word) is power of 2. const char * t = s; for( ; (unsigned long)s & sizeof(word)-1; ++t ) if( !*t ) return t-s; // Search for word containing a byte equal to zero. word b; const word m = ((word)-1 / 0xFF)<<7; const word * u = (word*)(void*)t; do { word w =~*u++; // For each byte in b, set high bit of byte if corresponding byte // in w is a zero. Do this by adding high bits of each byte to // other 7 bits of each byte, and look for carry into high bit. // There are many other possible sequences -- the best depends // upon your compiler and target machine. b = ((w&~m) + ((w&m)>>7)) & m; } while( !b ); t = (char*)(void*)(u); // t now points to word *after* the word with the zero. // Binary search b for position of high-order 1. // The logic here is for big-endian machines with 64-bit words. if( b&0xFFFFFFFF00000000UL ) { b >>= 32; t -= 4; } if( b&0xFFFF0000UL ) { b >>=16; t -= 2; } if( b&0xFF00UL ) { b >>=8; t -= 1; } return (char*)(void*)t-s-1; } Listing Two // The functions below are written as templates so that they // employ the signed or unsigned format according to whether // type T is a signed or unsigned integral type respectively. // The idiom "-(T)1>0" is a way of asking "is T an unsigned type?" // For simplicity, the routines below presume that when type T // is a signed integral type, operator>> does sign extension. // This is widely common behavior, but not mandated by ISO C/C++. typedef unsigned char byte; // Template function "encode" writes the encoding of value i to // the sequence starting at p, and returns an iterator that points // to the end of the sequence. template Iterator encode( Iterator p, T i ) { // If T is unsigned type, loop while u is outside range 0..127 // If T is signed type, loop while u is outside range -64...63. for(; (-(T)1>0 ? i : i+64u)>127u; >>=7 ) *p++ = i&127|128; *p++ = i&127; return p; } // Template function "decode" sets "result" to the value decoded // from a byte sequence starting at p, and returns an iterator // that points to the end of the sequence. template Iterator decode( Iterator p, T& result ) { T u = 0; int s = 0; byte c; // Accumulate value in u from bytes until terminator is found. do { c = *p++; u |= (c&127)<0 ? u : u - (c>>6&<