#ifndef UTIL_H_
#define UTIL_H_
#include <l4/types.h>
#define ASSERT_SIZE(mystruct, size)                                         \
    namespace { inline void mystruct##_test() {                      		\
        int i=0; switch(i) { case 0: ; case (sizeof(mystruct) == (size)): ; } \
    } }
template<typename T>
inline T min(T v1, T v2)
{
	if(v1 < v2)
		return v1;
	return v2;
}
template<typename T>
inline T max(T v1, T v2)
{
	if(v1 >= v2)
		return v1;
	return v2;
}
extern inline L4_Word_t around( L4_Word_t roundee, L4_Word_t rounder )
{
	return roundee & ( ~( rounder - 1 ) );
}
extern inline L4_Word_t aroundLb( L4_Word_t roundee, L4_Word_t rounder )
{
	return around( roundee, 1UL << rounder );
}
extern inline L4_Word_t aroundUp( L4_Word_t roundee, L4_Word_t rounder )
{
	return around( roundee + ( rounder - 1 ), rounder );
}
extern inline L4_Word_t aroundUpLb(L4_Word_t roundee, L4_Word_t rounder)
{	
	return aroundUp( roundee, 1UL << rounder );
}
extern inline L4_Word_t msBit(L4_Word_t bits)
{
#define ARCH_IA32
#ifdef ARCH_IA32
	L4_Word_t res;
	asm (                            
	    "bsr %[in], %[out]       \n" 
	    "jnz 1f                  \n" 
	    "movl $0xFFFFFFFF,%[out] \n" 
	    "1:                      \n" 
	: [ out ] "=r" ( res )           
	: [ in ] "r" ( bits )            
	
	);
	
	return res;
#else
    register L4_Word_t i = ( sizeof( L4_Word_t ) * 8 - 1 );
    for ( L4_Word_t j = 1UL << ( sizeof( L4_Word_t ) * 8 - 1 ); j > 0; j >>= 1, i-- )
        if ( bits & j )
            return i;
    return ~0UL;
#endif
    }
extern inline L4_Word_t lsBit(L4_Word_t bits)
{
#ifdef ARCH_IA32
	L4_Word_t res;
	asm (                               
	    "bsf %[in], %[out]       \n" 
	    "jnz 1f                  \n" 
	    "movl $0xFFFFFFFF,%[out] \n" 
	    "1:                      \n" 
	: [ out ] "=r" ( res )                  
	: [ in ] "r" ( bits )                   
	
	);
	
	return res;
#else
	register L4_Word_t i = 0;
	for ( L4_Word_t j = 1UL; j < ( 1UL << ( sizeof( L4_Word_t ) * 8 - 1 ) ); j <<= 1, i++ ) {
		if ( bits & j )
			return i;
	}
	
	return ~0UL;
#endif
}
extern inline L4_Word_t numBits( L4_Word_t bits )
{
	int ret = 0;
	for ( L4_Word_t i = 1UL; i < ( 1UL << ( sizeof( L4_Word_t ) * 8 - 1 ) ); i <<= 1 ) {
		if ( bits & i )
			ret++;
	}
	return ret;
}    
#endif