corelib/include/ebcl/inline/Utilities.hh

304 lines
6.5 KiB
C++
Raw Normal View History

/******************************************************************************/
/* VARIOUS UTILITIES - INLINE CODE ********************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_UTILITIES
#define _H_LW_LIB_INLINE_UTILITIES
#include <lw/lib/Utilities.hh>
namespace lw {
template< typename T >
inline constexpr bool IsPowerOf2( T value )
{
static_assert( std::is_integral< T >( ) , "integer type only" );
return value > 0 && ( value & ( value - 1 ) ) == 0;
}
/*= ENDIAN DETECTION =========================================================*/
inline static constexpr bool IsBigEndian( )
{
return E_Endian::NATIVE == E_Endian::BIG;
}
inline static constexpr bool IsLittleEndian( )
{
return E_Endian::NATIVE == E_Endian::LITTLE;
}
static_assert( IsBigEndian( ) || IsLittleEndian( ) ,
"unsupported endianness" );
/*= ENDIAN CONVERSION ========================================================*/
template<
typename T ,
uint32_t S = sizeof( T ) ,
typename = std::enable_if_t<
std::is_integral< T >::value
|| std::is_floating_point< T >::value
>
>
struct T_ByteSwapper_ { };
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_ByteSwapper_< T , 1 >
{
static constexpr T swap( T value )
{
return value;
}
};
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_ByteSwapper_< T , 2 >
{
static T swap( T value )
{
union { T v;
uint16_t i;
} u = { value };
u.i = __builtin_bswap16( u.i );
return u.v;
}
};
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_ByteSwapper_< T , 4 >
{
static T swap( T value )
{
union { T v;
uint32_t i;
} u = { value };
u.i = __builtin_bswap32( u.i );
return u.v;
}
};
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_ByteSwapper_< T , 8 >
{
static T swap( T value );
};
template< typename T >
inline T T_ByteSwapper_< T , 8 >::swap( T value )
{
union { T v;
uint64_t i;
} u = { value };
u.i = __builtin_bswap64( u.i );
return u.v;
}
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_LittleEndian< T , E_Endian::LITTLE >
{
static T convert( T value )
{
return value;
}
};
template< typename T >
struct T_LittleEndian< T , E_Endian::BIG >
{
static T convert( T value )
{
return T_ByteSwapper_< T >::swap( value );
}
};
/*----------------------------------------------------------------------------*/
template< typename T >
struct T_BigEndian< T , E_Endian::LITTLE >
{
static T convert( T value )
{
return T_ByteSwapper_< T >::swap( value );
}
};
template< typename T >
struct T_BigEndian< T , E_Endian::BIG >
{
static T convert( T value )
{
return value;
}
};
/*= COMPARATORS AND SORTING ==================================================*/
template< typename T >
inline int T_Comparator< T >::compare( T const& a , T const& b )
{
if ( a < b ) return -1;
if ( a > b ) return 1;
return 0;
}
/*----------------------------------------------------------------------------*/
// T_Sorter_ - "Plumbing" for Sort
struct T_Sorter_
{
typedef std::function< void ( uint8_t* a , uint8_t* b ) > F_Swap;
typedef std::function< int ( uint8_t const* a , uint8_t const* b ) > F_Cmp;
static void sort( uint8_t* data , uint32_t itemSize , uint32_t items , F_Swap swap , F_Cmp cmp );
};
template< typename T >
void Sort( T* array , uint32_t items , F_Comparator< T > comparator )
{
T_Sorter_::sort( reinterpret_cast< uint8_t* >( array ) ,
sizeof( T ) , items ,
[]( uint8_t* a , uint8_t* b ) {
using std::swap;
swap( *reinterpret_cast< T* >( a ) ,
*reinterpret_cast< T* >( b ) );
} ,
[comparator]( uint8_t const* a , uint8_t const* b ) {
return comparator(
*reinterpret_cast< T const* >( a ) ,
*reinterpret_cast< T const* >( b ) );
} );
}
/*= HASHING ==================================================================*/
template< typename T , int S >
inline uint32_t T_HashFunction< T , S >::hash( T const& item )
{
return HashData( reinterpret_cast< uint8_t const* >( &item ) , sizeof( T ) );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline uint32_t ComputeHash( T const& item )
{
return T_HashFunction< T >::hash( item );
}
/*----------------------------------------------------------------------------*/
// Hash function specializations for data sizes 1, 2, 4 and 8.
template< typename T >
struct T_HashFunction< T , 1 >
{
static uint32_t hash( T const& item )
{
return *reinterpret_cast< uint8_t const* >( &item );
}
};
template< typename T >
struct T_HashFunction< T , 2 >
{
static uint32_t hash( T const& item )
{
return *reinterpret_cast< uint16_t const* >( &item );
}
};
template< typename T >
struct T_HashFunction< T , 4 >
{
static uint32_t hash( T const& item )
{
return *reinterpret_cast< uint32_t const* >( &item );
}
};
template< typename T >
struct T_HashFunction< T , 8 >
{
static uint32_t hash( T const& item )
{
uint64_t v = *reinterpret_cast< uint64_t const* >( &item );
return ( v >> 32 ) ^ v;
}
};
/*= PRIVATE IMPLEMENTATION BASE ==============================================*/
inline A_PrivateImplementation::A_PrivateImplementation( void* p , T_Destructor_ destructor )
: p_( p ) , piDestructor_( destructor )
{ }
template< typename T >
inline A_PrivateImplementation::A_PrivateImplementation( T* p )
: A_PrivateImplementation( p , []( void* ptr ) {
reinterpret_cast< T* >( ptr )->~T( );
} )
{ }
inline A_PrivateImplementation::A_PrivateImplementation( A_PrivateImplementation&& other ) noexcept
: p_( other.p_ ) , piDestructor_( other.piDestructor_ )
{
other.p_ = nullptr;
}
inline A_PrivateImplementation& A_PrivateImplementation::operator=( A_PrivateImplementation&& other ) noexcept
{
callPrivateDestructor( );
p_ = other.p_;
piDestructor_ = other.piDestructor_;
other.p_ = nullptr;
return *this;
}
inline A_PrivateImplementation::~A_PrivateImplementation( )
{
callPrivateDestructor( );
}
template< typename T >
inline T& A_PrivateImplementation::p( ) const
{
return *reinterpret_cast< T* >( p_ );
}
inline void A_PrivateImplementation::callPrivateDestructor( ) noexcept
{
if ( p_ && piDestructor_ ) {
piDestructor_( p_ );
::operator delete( p_ );
}
}
}
#endif // _H_LW_LIB_INLINE_UTILITIES