blob: eb2a3096fedb169ca4dc08b6bf8debfc02aa41f7 [file] [log] [blame]
#pragma once
#include "pstdint.h"
#include "Bitvec.h"
//-----------------------------------------------------------------------------
// If the optimizer detects that a value in a speed test is constant or unused,
// the optimizer may remove references to it or otherwise create code that
// would not occur in a real-world application. To prevent the optimizer from
// doing this we declare two trivial functions that either sink or source data,
// and bar the compiler from optimizing them.
void blackhole ( uint32_t x );
uint32_t whitehole ( void );
//-----------------------------------------------------------------------------
typedef void (*pfHash) ( const void * blob, const int len, const uint32_t seed, void * out );
//-----------------------------------------------------------------------------
template < class T >
class hashfunc
{
public:
hashfunc ( pfHash h ) : m_hash(h)
{
}
inline void operator () ( const void * key, const int len, const uint32_t seed, uint32_t * out )
{
m_hash(key,len,seed,out);
}
inline operator pfHash ( void ) const
{
return m_hash;
}
inline T operator () ( const void * key, const int len, const uint32_t seed )
{
T result;
m_hash(key,len,seed,(uint32_t*)&result);
return result;
}
pfHash m_hash;
};
//-----------------------------------------------------------------------------
template < int _bits >
class Blob
{
public:
Blob()
{
}
Blob ( int x )
{
for(int i = 0; i < nbytes; i++)
{
bytes[i] = 0;
}
*(int*)bytes = x;
}
Blob ( const Blob & k )
{
for(int i = 0; i < nbytes; i++)
{
bytes[i] = k.bytes[i];
}
}
Blob & operator = ( const Blob & k )
{
for(int i = 0; i < nbytes; i++)
{
bytes[i] = k.bytes[i];
}
return *this;
}
void set ( const void * blob, int len )
{
const uint8_t * k = (const uint8_t*)blob;
len = len > nbytes ? nbytes : len;
for(int i = 0; i < len; i++)
{
bytes[i] = k[i];
}
for(int i = len; i < nbytes; i++)
{
bytes[i] = 0;
}
}
uint8_t & operator [] ( int i )
{
return bytes[i];
}
const uint8_t & operator [] ( int i ) const
{
return bytes[i];
}
//----------
// boolean operations
bool operator < ( const Blob & k ) const
{
for(int i = 0; i < nbytes; i++)
{
if(bytes[i] < k.bytes[i]) return true;
if(bytes[i] > k.bytes[i]) return false;
}
return false;
}
bool operator == ( const Blob & k ) const
{
for(int i = 0; i < nbytes; i++)
{
if(bytes[i] != k.bytes[i]) return false;
}
return true;
}
bool operator != ( const Blob & k ) const
{
return !(*this == k);
}
//----------
// bitwise operations
Blob operator ^ ( const Blob & k ) const
{
Blob t;
for(int i = 0; i < nbytes; i++)
{
t.bytes[i] = bytes[i] ^ k.bytes[i];
}
return t;
}
Blob & operator ^= ( const Blob & k )
{
for(int i = 0; i < nbytes; i++)
{
bytes[i] ^= k.bytes[i];
}
return *this;
}
int operator & ( int x )
{
return (*(int*)bytes) & x;
}
Blob & operator &= ( const Blob & k )
{
for(int i = 0; i < nbytes; i++)
{
bytes[i] &= k.bytes[i];
}
}
Blob operator << ( int c )
{
Blob t = *this;
lshift(&t.bytes[0],nbytes,c);
return t;
}
Blob operator >> ( int c )
{
Blob t = *this;
rshift(&t.bytes[0],nbytes,c);
return t;
}
Blob & operator <<= ( int c )
{
lshift(&bytes[0],nbytes,c);
return *this;
}
Blob & operator >>= ( int c )
{
rshift(&bytes[0],nbytes,c);
return *this;
}
//----------
enum
{
nbits = _bits,
nbytes = (_bits+7)/8,
align4 = (nbytes & 2) ? 0 : 1,
align8 = (nbytes & 3) ? 0 : 1,
align16 = (nbytes & 4) ? 0 : 1,
};
private:
uint8_t bytes[nbytes];
};
typedef Blob<128> uint128_t;
//-----------------------------------------------------------------------------