Repo init with mostly unchanged import of LW code

This commit is contained in:
Emmanuel BENOîT 2017-11-01 20:14:23 +01:00
commit 221f0c8ef8
161 changed files with 61414 additions and 0 deletions

View file

@ -0,0 +1,376 @@
/******************************************************************************/
/* ALLOCATORS - INLINE CODE ***************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_ALLOC
#define _H_LW_LIB_INLINE_ALLOC
#include <lw/lib/Alloc.hh>
namespace lw {
/*= T_PoolHelper::T_List =====================================================*/
template< typename T , size_t P >
inline T_PoolHelper::T_List< T , P >::T_List(
T_List< T , P >*& n ) noexcept
: next( n ) , free( P )
{
for ( size_t i = 0 ; i < P ; i ++ ) {
storage[ i ].list = this;
}
for ( size_t i = 0 ; i < BitmapSize ; i ++ ) {
bitmap[ i ] = 0;
}
n = this;
}
template< typename T , size_t P >
inline T* T_PoolHelper::T_List< T , P >::findUnused( ) noexcept
{
size_t i = 0;
while ( bitmap[ i ] == 255 ) {
assert( i < BitmapSize );
i ++;
}
size_t j = 0;
while ( ( bitmap[ i ] & ( 1 << j ) ) != 0 ) {
j ++;
}
assert( i * 8 + j < P );
bitmap[ i ] = bitmap[ i ] | ( 1 << j );
free --;
return &storage[ i * 8 + j ];
}
template< typename T , size_t P >
inline size_t T_PoolHelper::T_List< T , P >::indexOf(
T const* const item ) noexcept
{
assert( item >= &storage[ 0 ] );
const size_t offset( ( (char*) item ) - ( (char*) &storage[ 0 ] ) );
assert( offset % sizeof( T ) == 0 );
const size_t index( offset / sizeof( T ) );
assert( index < P );
return index;
}
template< typename T , size_t P >
inline void T_PoolHelper::T_List< T , P >::destroy(
T_List< T , P >*& head ) noexcept
{
while ( head != nullptr ) {
T_Self* const n( head->next );
delete head;
head = n;
}
}
/*= T_PoolHelper::T_Allocator ================================================*/
template< typename T , size_t P , size_t M >
inline T_PoolHelper::T_Allocator< T , P , M >::T_Allocator( ) noexcept
: free_( nullptr ) , partial_( nullptr ) , full_( nullptr ) ,
nFree_( 1 )
{
new T_List_( free_ );
}
template< typename T , size_t P , size_t M >
inline T_PoolHelper::T_Allocator< T , P , M >::~T_Allocator( )
{
T_List_::destroy( free_ );
T_List_::destroy( partial_ );
T_List_::destroy( full_ );
}
/*----------------------------------------------------------------------------*/
template< typename T , size_t P , size_t M >
inline T* T_PoolHelper::T_Allocator< T , P , M >::allocate( ) noexcept
{
if ( partial_ == nullptr ) {
if ( free_ == nullptr ) {
new T_List_( partial_ );
} else {
assert( nFree_ > 0 );
partial_ = free_;
free_ = free_->next;
partial_->next = nullptr;
nFree_ --;
}
}
T* const data( partial_->findUnused( ) );
if ( partial_->free == 0 ) {
T_List_* const nf( partial_ );
partial_ = nf->next;
nf->next = full_;
full_ = nf;
}
return data;
}
template< typename T , size_t P , size_t M >
void T_PoolHelper::T_Allocator< T , P , M >::free(
T* const item ) noexcept
{
T_List_* const list( reinterpret_cast< T_List_* >( item->list ) );
const size_t index( list->indexOf( item ) );
list->bitmap[ index / 8 ] = list->bitmap[ index / 8 ] & ~( 1 << ( index & 7 ) );
list->free ++;
if ( list->free == 1 ) {
// Full list is now partial
moveList( list , full_ , partial_ );
} else if ( list->free == P ) {
// Partial list is now free
if ( nFree_ == M ) {
T_List_* p( nullptr );
moveList( list , partial_ , p );
delete list;
} else {
moveList( list , partial_ , free_ );
nFree_ ++;
}
}
}
/*----------------------------------------------------------------------------*/
template< typename T , size_t P , size_t M >
size_t T_PoolHelper::T_Allocator< T , P , M >::countFreeLists( ) const noexcept
{
return nFree_;
}
template< typename T , size_t P , size_t M >
size_t T_PoolHelper::T_Allocator< T , P , M >::countPartialLists( ) const noexcept
{
return countLists( partial_ );
}
template< typename T , size_t P , size_t M >
size_t T_PoolHelper::T_Allocator< T , P , M >::countFullLists( ) const noexcept
{
return countLists( full_ );
}
template< typename T , size_t P , size_t M >
void T_PoolHelper::T_Allocator< T , P , M >::getUsage(
size_t& total ,
size_t& free ,
size_t& used ) const noexcept
{
free = countFreeLists( ) * P;
used = countFullLists( ) * P;
total = free + used;
T_List_ const* p( partial_ );
while ( p != nullptr ) {
free += p->free;
used += P - p->free;
total += P;
p = p->next;
}
}
/*----------------------------------------------------------------------------*/
template< typename T , size_t P , size_t M >
void T_PoolHelper::T_Allocator< T , P , M >::moveList(
T_List_* const list ,
T_List_*& from ,
T_List_*& to ) noexcept
{
T_List_** ptr( &from );
while ( *ptr != list ) {
ptr = &( (*ptr)->next );
assert( *ptr != nullptr );
}
*ptr = list->next;
list->next = to;
to = list;
}
template< typename T , size_t P , size_t M >
size_t T_PoolHelper::T_Allocator< T , P , M >::countLists(
T_List_ const* head ) noexcept
{
size_t nLists( 0 );
while ( head != nullptr ) {
nLists ++;
head = head->next;
}
return nLists;
}
/*= T_PoolAllocator ==========================================================*/
template< size_t OS , size_t OA , size_t P , size_t M >
inline void* T_PoolAllocator< OS , OA , P , M >::allocate(
const size_t requested ) noexcept
{
#ifdef LW_CFG_NO_ALLOCATORS
return ::operator new( requested );
#else
assert( requested <= OS );
return reinterpret_cast< char* >( alloc_.allocate( ) );
#endif
}
template< size_t OS , size_t OA , size_t P , size_t M >
void T_PoolAllocator< OS , OA , P , M >::free(
void* const item ) noexcept
{
#ifdef LW_CFG_NO_ALLOCATORS
::operator delete( item );
#else
alloc_.free( reinterpret_cast< T_Storage_* >( item ) );
#endif
}
/*----------------------------------------------------------------------------*/
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_PoolAllocator< OS , OA , P , M >::countFreeLists( ) const noexcept
{
return alloc_.countFreeLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_PoolAllocator< OS , OA , P , M >::countPartialLists( ) const noexcept
{
return alloc_.countPartialLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_PoolAllocator< OS , OA , P , M >::countFullLists( ) const noexcept
{
return alloc_.countFullLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
void T_PoolAllocator< OS , OA , P , M >::getUsage(
size_t& total ,
size_t& free ,
size_t& used ) const noexcept
{
return alloc_.getUsage( total , free , used );
}
/*= T_ThreadedPoolAllocator ==================================================*/
template< size_t OS , size_t OA , size_t P , size_t M >
inline void* T_ThreadedPoolAllocator< OS , OA , P , M >::allocate(
const size_t requested ) noexcept
{
#ifdef LW_CFG_NO_ALLOCATORS
return ::operator new( requested );
#else
assert( requested <= OS );
T_Storage_* const alloc( ([this](){
T_Storage_* const fs( takeFromStack( ) );
return fs ? fs : alloc_.allocate( );
})() );
alloc->extra.pool = this;
return reinterpret_cast< char* >( alloc );
#endif
}
template< size_t OS , size_t OA , size_t P , size_t M >
void T_ThreadedPoolAllocator< OS , OA , P , M >::free(
void* const item ) noexcept
{
#ifdef LW_CFG_NO_ALLOCATORS
::operator delete( item );
#else
T_Storage_* const storage( reinterpret_cast< T_Storage_* >( item ) );
if ( storage->extra.pool == this ) {
alloc_.free( storage );
} else {
storage->extra.pool->addToStack( storage );
}
T_Storage_* const fs( takeFromStack( ) );
if ( fs ) {
alloc_.free( fs );
}
#endif
}
/*----------------------------------------------------------------------------*/
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_ThreadedPoolAllocator< OS , OA , P , M >::countFreeLists( ) const noexcept
{
return alloc_.countFreeLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_ThreadedPoolAllocator< OS , OA , P , M >::countPartialLists( ) const noexcept
{
return alloc_.countPartialLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
size_t T_ThreadedPoolAllocator< OS , OA , P , M >::countFullLists( ) const noexcept
{
return alloc_.countFullLists( );
}
template< size_t OS , size_t OA , size_t P , size_t M >
void T_ThreadedPoolAllocator< OS , OA , P , M >::getUsage(
size_t& total ,
size_t& free ,
size_t& used ) const noexcept
{
return alloc_.getUsage( total , free , used );
}
/*----------------------------------------------------------------------------*/
template< size_t OS , size_t OA , size_t P , size_t M >
typename T_ThreadedPoolAllocator< OS , OA , P , M >::T_Storage_*
T_ThreadedPoolAllocator< OS , OA , P , M >::takeFromStack( ) noexcept
{
T_FreeHead_ o( freeHead_.load( std::memory_order_relaxed ) );
if ( o.head == nullptr ) {
return nullptr;
}
T_FreeHead_ next;
do {
next.aba = o.aba + 1;
next.head = o.head->extra.next;
} while ( !freeHead_.compare_exchange_weak( o , next ,
std::memory_order_acq_rel ,
std::memory_order_acquire ) );
return o.head;
}
template< size_t OS , size_t OA , size_t P , size_t M >
void T_ThreadedPoolAllocator< OS , OA , P , M >::addToStack(
T_Storage_* storage ) noexcept
{
assert( storage->extra.pool == this );
T_FreeHead_ o( freeHead_.load( std::memory_order_relaxed ) );
T_FreeHead_ r;
do {
storage->extra.next = o.head;
r.aba = o.aba + 1;
r.head = storage;
} while ( !freeHead_.compare_exchange_weak( o , r ,
std::memory_order_acq_rel ,
std::memory_order_acquire ) );
}
}
#endif //_H_LW_LIB_INLINE_ALLOC

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,145 @@
/******************************************************************************/
/* BINARY READER/WRITER FOR STREAMS - INLINE CODE *****************************/
/******************************************************************************/
#pragma once
#include <lw/lib/BinaryStreams.hh>
namespace lw {
/*= T_BinaryReader ===========================================================*/
inline T_BinaryReader::T_BinaryReader( A_InputStream& stream , E_Endian endian ) noexcept
: stream_( stream ) , endian_( endian )
{ }
inline A_InputStream& T_BinaryReader::stream( ) const
{
return stream_;
}
inline E_Endian T_BinaryReader::endian( ) const
{
return endian_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T T_BinaryReader::readNumericNative( ) const
{
static_assert( std::is_integral< T >( ) || std::is_floating_point< T >( ) ,
"numeric type expected" );
T value = 0;
auto r = stream_.read( &value , sizeof( T ) );
if ( r != sizeof( T ) ) {
throw X_StreamError( E_StreamError::BAD_DATA );
}
return value;
}
template< typename T >
inline T T_BinaryReader::readNumericLittleEndian( ) const
{
return T_LittleEndian< T >::convert( readNumericNative< T >( ) );
}
template< typename T >
inline T T_BinaryReader::readNumericBigEndian( ) const
{
return T_BigEndian< T >::convert( readNumericNative< T >( ) );
}
template< typename T >
inline T T_BinaryReader::read( ) const
{
return T_Reader_< T >::read( *this );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T T_BinaryReader::T_Reader_< T , true >::read( T_BinaryReader const& reader )
{
if ( reader.endian_ == E_Endian::BIG ) {
return reader.readNumericBigEndian< T >( );
} else {
return reader.readNumericLittleEndian< T >( );
}
}
template< typename T >
inline T T_BinaryReader::T_Reader_< T , false >::read( T_BinaryReader const& reader )
{
typedef T_ObjectReader< T > Reader;
return Reader::read( reader );
}
/*= T_BinaryWriter ===========================================================*/
inline T_BinaryWriter::T_BinaryWriter( A_OutputStream& stream , E_Endian endian ) noexcept
: stream_( stream ) , endian_( endian )
{ }
/*----------------------------------------------------------------------------*/
inline A_OutputStream& T_BinaryWriter::stream( ) const
{
return stream_;
}
inline E_Endian T_BinaryWriter::endian( ) const
{
return endian_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_BinaryWriter::writeNumericNative( T value ) const
{
static_assert( std::is_integral< T >( ) || std::is_floating_point< T >( ) ,
"numeric type expected" );
stream_.write( &value , sizeof( T ) );
}
template< typename T >
inline void T_BinaryWriter::writeNumericLittleEndian( T const& value ) const
{
writeNumericNative( T_LittleEndian< T >::convert( value ) );
}
template< typename T >
inline void T_BinaryWriter::writeNumericBigEndian( T const& value ) const
{
writeNumericNative( T_BigEndian< T >::convert( value ) );
}
template< typename T >
inline void T_BinaryWriter::write( T const& value ) const
{
T_Writer_< T >::write( *this , value );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_BinaryWriter::T_Writer_< T , true >::write( T_BinaryWriter const& writer , T value )
{
if ( writer.endian_ == E_Endian::BIG ) {
writer.writeNumericBigEndian( value );
} else {
writer.writeNumericLittleEndian( value );
}
}
template< typename T >
inline void T_BinaryWriter::T_Writer_< T , false >::write( T_BinaryWriter const& writer , T const& value )
{
typedef T_ObjectWriter< T > Writer;
Writer::write( writer , value );
}
} // namespace

View file

@ -0,0 +1,263 @@
/******************************************************************************/
/* BUFFERS - INLINE CODE ******************************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/Buffers.hh>
namespace lw {
/*= T_BufferBase =============================================================*/
inline T_BufferBase::T_BufferBase( uint8_t* buffer ) noexcept
: data_( buffer )
{ }
inline T_BufferBase::T_BufferBase( size_t size )
: data_( ( uint8_t* ) malloc( size ) )
{
if ( size != 0 && data_ == nullptr ) {
throw std::bad_alloc( );
}
}
inline T_BufferBase::T_BufferBase( T_BufferBase&& source ) noexcept
: T_BufferBase( nullptr )
{
swap( *this , source );
}
inline T_BufferBase::~T_BufferBase( )
{
free( data_ );
}
/*----------------------------------------------------------------------------*/
inline void swap( T_BufferBase& lhs , T_BufferBase& rhs )
{
using std::swap;
swap( lhs.data_ , rhs.data_ );
}
/*----------------------------------------------------------------------------*/
inline uint8_t* T_BufferBase::data( ) const
{
return data_;
}
/*= T_FixedBuffer ============================================================*/
template< size_t S , typename T >
inline T_FixedBuffer< S , T >::T_FixedBuffer( )
: T_BufferBase( BYTES_ )
{ }
template< size_t S , typename T >
inline T_FixedBuffer< S , T >::T_FixedBuffer(
T_FixedBuffer< S , T >&& source ) noexcept
: T_BufferBase( std::move( source ) )
{ }
template< size_t S , typename T >
inline T_FixedBuffer< S , T >::T_FixedBuffer(
T_FixedBuffer< S , T > const& source )
: T_BufferBase( BYTES_ )
{
*this = source;
}
/*----------------------------------------------------------------------------*/
template< size_t S , typename T >
inline T_FixedBuffer< S , T >& T_FixedBuffer< S , T >::operator= ( T_FixedBuffer< S , T > const& other )
{
memcpy( data_ , other.data_ , BYTES_ );
return *this;
}
template< size_t S , typename T >
inline T_FixedBuffer< S , T >& T_FixedBuffer< S , T >::operator= ( T_FixedBuffer< S , T >&& other ) noexcept
{
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
template< size_t S , typename T >
inline void swap( T_FixedBuffer< S , T >& lhs , T_FixedBuffer< S , T >& rhs ) noexcept
{
swap( ( T_BufferBase& ) lhs , ( T_BufferBase& ) rhs );
}
/*----------------------------------------------------------------------------*/
template< size_t S , typename T >
inline size_t T_FixedBuffer< S , T >::bytes( ) const
{
return BYTES_;
}
template< size_t S , typename T >
inline T& T_FixedBuffer< S , T >::operator[] ( size_t index )
{
assert( index < S );
return *reinterpret_cast< T* >( data_ + index * sizeof( T ) );
}
template< size_t S , typename T >
inline T const& T_FixedBuffer< S , T >::operator[] ( size_t index ) const
{
assert( index < S );
return *reinterpret_cast< T* >( data_ + index * sizeof( T ) );
}
/*----------------------------------------------------------------------------*/
template< size_t S , typename T >
inline T_FixedBuffer< S , T >& T_FixedBuffer< S , T >::setAll( T const& value )
{
for ( size_t i = 0 ; i < S ; i ++ ) {
memcpy( &(*this)[ i ] , &value , sizeof( T ) );
}
return *this;
}
/*= T_Buffer =================================================================*/
template< typename T >
inline T_Buffer< T >::T_Buffer( ) noexcept
: T_BufferBase( nullptr ) , size_( 0 )
{ }
template< typename T >
inline T_Buffer< T >::T_Buffer( size_t size )
: T_BufferBase( size * sizeof( T ) ) , size_( size )
{ }
template< typename T >
inline T_Buffer< T >::T_Buffer( T const* data , size_t size )
: T_BufferBase( size * sizeof( T ) ) , size_( size )
{
memcpy( data_ , data , bytes( ) );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Buffer< T >::T_Buffer( T_Buffer< T > const& other )
: T_Buffer( reinterpret_cast< T const* >( other.data_ ) , other.size( ) )
{ }
template< typename T >
inline T_Buffer< T >::T_Buffer( T_Buffer< T >&& other ) noexcept
: T_Buffer( )
{
swap( *this , other );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Buffer< T >& T_Buffer< T >::operator= ( T_Buffer< T > const& other )
{
if ( size_ != other.size_ ) {
free( data_ );
size_ = other.size_;
if ( size_ == 0 ) {
data_ = nullptr;
} else {
data_ = ( uint8_t* ) malloc( bytes( ) );
if ( data_ == nullptr ) {
throw std::bad_alloc( );
}
}
}
memcpy( data_ , other.data_ , bytes( ) );
return *this;
}
template< typename T >
inline T_Buffer< T >& T_Buffer< T >::operator= ( T_Buffer< T >&& other )
{
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_Buffer< T >& lhs , T_Buffer< T >& rhs ) noexcept
{
using std::swap;
swap( ( T_BufferBase& ) lhs , ( T_BufferBase& ) rhs );
swap( lhs.size_ , rhs.size_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline size_t T_Buffer< T >::size( ) const
{
return size_;
}
template< typename T >
inline size_t T_Buffer< T >::bytes( ) const
{
return size_ * sizeof( T );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T& T_Buffer< T >::operator[] ( size_t index )
{
assert( index < size_ );
return *reinterpret_cast< T* >( data_ + index * sizeof( T ) );
}
template< typename T >
inline T const& T_Buffer< T >::operator[] ( size_t index ) const
{
assert( index < size_ );
return *reinterpret_cast< T* >( data_ + index * sizeof( T ) );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_Buffer< T >& T_Buffer< T >::resize( size_t newSize )
{
if ( newSize != size_ ) {
size_ = newSize;
data_ = ( uint8_t* ) realloc( data_ , bytes( ) );
if ( bytes( ) != 0 && data_ == nullptr ) {
throw std::bad_alloc( );
}
}
return *this;
}
template< typename T >
inline T_Buffer< T >& T_Buffer< T >::setAll( T const& value )
{
for ( size_t i = 0 ; i < size_ ; i ++ ) {
memcpy( &(*this)[ i ] , &value , sizeof( T ) );
}
return *this;
}
template< typename T >
inline T_Buffer< T >& T_Buffer< T >::copyAll( T const* data )
{
memcpy( data_ , data , bytes( ) );
return *this;
}
} // namespace

View file

@ -0,0 +1,30 @@
/******************************************************************************/
/* DYNAMIC LIBRARIES - INLINE CODE ********************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_DYNLIB
#define _H_LW_LIB_INLINE_DYNLIB
#include <lw/lib/DynLib.hh>
namespace lw {
/*= T_DynLib =================================================================*/
template< typename T >
inline T* T_DynLib::getPointer(
char const* const name ) const noexcept
{
return reinterpret_cast< T* >( getRawSymbol( name ) );
}
template< typename T >
inline std::function< T > T_DynLib::getFunction(
char const* const name ) const noexcept
{
return std::function< T >{ (F_CFunc< T >) getRawSymbol( name ) };
}
}
#endif // _H_LW_LIB_INLINE_DYNLIB

View file

@ -0,0 +1,99 @@
/******************************************************************************/
/* FILES - INLINE CODE ********************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_FILES
#define _H_LW_LIB_INLINE_FILES
#include <lw/lib/Files.hh>
namespace lw {
/*= T_File ===================================================================*/
inline T_File::~T_File( )
{
close( );
}
/*---------------------------------------------------------------------------*/
inline void swap( T_File& lhs , T_File& rhs ) noexcept
{
using std::swap;
swap( lhs.path_ , rhs.path_ );
swap( lhs.mode_ , rhs.mode_ );
swap( lhs.file_ , rhs.file_ );
swap( lhs.size_ , rhs.size_ );
swap( lhs.pos_ , rhs.pos_ );
}
/*---------------------------------------------------------------------------*/
inline T_String const& T_File::path( ) const noexcept
{
return path_;
}
inline E_FileMode T_File::mode( ) const noexcept
{
return mode_;
}
inline bool T_File::isOpen( ) const noexcept
{
return file_ != nullptr;
}
inline size_t T_File::size( ) const noexcept
{
return isOpen( ) ? size_ : 0;
}
inline size_t T_File::position( ) const noexcept
{
return isOpen( ) ? pos_ : 0;
}
/*= T_FileInputStream ========================================================*/
inline void swap( T_FileInputStream& lhs , T_FileInputStream& rhs ) noexcept
{
lhs.swap( rhs );
}
/*---------------------------------------------------------------------------*/
inline T_File& T_FileInputStream::file( ) const noexcept
{
return fileRaw_ ? *fileRaw_ : *fileOwned_;
}
inline size_t T_FileInputStream::offset( ) const noexcept
{
return start_;
}
/*= T_FileOutputStream =======================================================*/
inline void swap( T_FileOutputStream& lhs , T_FileOutputStream& rhs ) noexcept
{
lhs.swap( rhs );
}
/*---------------------------------------------------------------------------*/
inline T_File& T_FileOutputStream::file( ) const noexcept
{
return fileRaw_ ? *fileRaw_ : *fileOwned_;
}
inline size_t T_FileOutputStream::offset( ) const noexcept
{
return start_;
}
} // namespace
#endif // _H_LW_LIB_INLINE_FILES

View file

@ -0,0 +1,29 @@
/******************************************************************************/
/* HASH INDEX - INLINE CODE ***************************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/HashIndex.hh>
namespace lw {
/*= T_HashIndex ==============================================================*/
inline T_HashIndex::~T_HashIndex( )
{
free( );
}
inline uint32_t T_HashIndex::first( uint32_t key ) const
{
return hash_[ key & hashMask_ & lookupMask_ ];
}
inline uint32_t T_HashIndex::next( uint32_t index ) const
{
assert( index < indexSize_ );
return index_[ index & lookupMask_ ];
}
}

View file

@ -0,0 +1,421 @@
/******************************************************************************/
/* HASH TABLES - INLINE CODE **************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_HASHTABLES
#define _H_LW_LIB_INLINE_HASHTABLES
#include <lw/lib/HashTables.hh>
namespace lw {
/*= T_DefaultKeyMatch ========================================================*/
template< typename K >
inline bool T_DefaultKeyMatch< K >::keysMatch( K const& a , K const& b )
{
return a == b;
}
/*= T_KeyValueTable ==========================================================*/
template< typename K , typename V >
inline T_KeyValueTable< K , V >::T_KeyValueTable(
uint32_t initialSize , uint32_t hashSize , uint32_t growth ,
F_KeyMatch< K > match )
: match_( match ) , index_( hashSize , initialSize , growth ) ,
keys_( growth ) , values_( growth )
{ }
/*----------------------------------------------------------------------------*/
template< typename K , typename T >
void swap( T_KeyValueTable< K , T >& lhs , T_KeyValueTable< K , T >& rhs )
{
using std::swap;
swap( lhs.match_ , rhs.match_ );
swap( lhs.index_ , rhs.index_ );
swap( lhs.keys_ , rhs.keys_ );
swap( lhs.values_ , rhs.values_ );
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
template<
typename A , typename B ,
T_EnableIfTypesMatch< K , A > ,
T_EnableIfTypesMatch< V , B >
> inline bool T_KeyValueTable< K , V >::add(
A&& k ,
B&& v )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx != T_HashIndex::INVALID_INDEX ) {
return false;
}
keys_.add( std::forward< A >( k ) );
values_.add( std::forward< B >( v ) );
index_.add( hash );
return true;
}
template< typename K , typename V >
template< typename B , T_EnableIfTypesMatch< V , B > >
inline bool T_KeyValueTable< K , V >::update(
K const& k ,
B&& v )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return false;
}
values_[ idx ] = std::forward< B >( v );
return true;
}
template< typename K , typename V >
template<
typename A , typename B ,
T_EnableIfTypesMatch< K , A > ,
T_EnableIfTypesMatch< V , B >
> inline void T_KeyValueTable< K , V >::set(
A&& k ,
B&& v )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
keys_.add( std::forward< A >( k ) );
values_.add( std::forward< B >( v ) );
index_.add( hash );
} else {
values_[ idx ] = std::forward< B >( v );
}
}
template< typename K , typename V >
inline bool T_KeyValueTable< K , V >::remove( K const& k )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return false;
}
keys_.removeSwap( idx );
values_.removeSwap( idx );
index_.remove( idx );
return true;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline void T_KeyValueTable< K , V >::clear( )
{
values_.clear( );
keys_.clear( );
index_.clear( );
}
template< typename K , typename V >
inline void T_KeyValueTable< K , V >::free( )
{
values_.free( );
keys_.free( );
index_.free( );
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline uint32_t T_KeyValueTable< K , V >::size( ) const
{
return keys_.size( );
}
template< typename K , typename V >
T_Array< K > const& T_KeyValueTable< K , V >::keys( ) const
{
return keys_;
}
template< typename K , typename V >
T_Array< V > const& T_KeyValueTable< K , V >::values( ) const
{
return values_;
}
template< typename K , typename V >
inline uint32_t T_KeyValueTable< K , V >::indexOf( K const& k ) const
{
return find( k , ComputeHash( k ) );
}
template< typename K , typename V >
inline bool T_KeyValueTable< K , V >::contains( K const& k ) const
{
const uint32_t hash = ComputeHash( k );
return find( k , hash ) != T_HashIndex::INVALID_INDEX;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline V const* T_KeyValueTable< K , V >::get( K const& k ) const
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return nullptr;
}
return &values_[ idx ];
}
template< typename K , typename V >
inline V* T_KeyValueTable< K , V >::get( K const& k )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return nullptr;
}
return &values_[ idx ];
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline V& T_KeyValueTable< K , V >::operator[] ( uint32_t index )
{
return values_[ index ];
}
template< typename K , typename V >
inline V const& T_KeyValueTable< K , V >::operator[] ( uint32_t index ) const
{
return values_[ index ];
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline uint32_t T_KeyValueTable< K , V >::find( K const& k , uint32_t hash ) const
{
uint32_t idx = index_.first( hash );
while ( idx != T_HashIndex::INVALID_INDEX ) {
if ( match_( keys_[ idx ] , k ) ) {
break;
}
idx = index_.next( idx );
}
return idx;
}
/*= T_ObjectTable ============================================================*/
template< typename K , typename V >
inline T_ObjectTable< K , V >::T_ObjectTable(
T_ObjectTable< K , V >::F_GetKey keyGetter ,
uint32_t initialSize , uint32_t hashSize , uint32_t growth ,
T_ObjectTable< K , V >::F_Match match )
: match_( match ) , keyGetter_( keyGetter ) ,
index_( hashSize , initialSize , growth ) ,
values_( growth )
{ }
/*----------------------------------------------------------------------------*/
template< typename K , typename T >
void swap( T_ObjectTable< K , T >& lhs , T_ObjectTable< K , T >& rhs )
{
using std::swap;
swap( lhs.keyGetter_ , rhs.keyGetter_ );
swap( lhs.match_ , rhs.match_ );
swap( lhs.index_ , rhs.index_ );
swap( lhs.values_ , rhs.values_ );
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
template< typename A , T_EnableIfTypesMatch< V , A > >
inline bool T_ObjectTable< K , V >::add(
A&& v )
{
K k = keyGetter_( v );
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx != T_HashIndex::INVALID_INDEX ) {
return false;
}
values_.add( std::forward< A >( v ) );
index_.add( hash );
return true;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
template< typename A , T_EnableIfTypesMatch< V , A > >
inline bool T_ObjectTable< K , V >::update(
A&& v )
{
K k = keyGetter_( v );
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return false;
}
values_[ idx ] = std::forward< A >( v );
return true;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
template< typename A , T_EnableIfTypesMatch< V , A > >
inline void T_ObjectTable< K , V >::set(
A&& v )
{
K k = keyGetter_( v );
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
values_.add( std::forward< A >( v ) );
index_.add( hash );
} else {
values_[ idx ] = std::forward< A >( v );
}
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline bool T_ObjectTable< K , V >::remove( K const& k )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return false;
}
values_.removeSwap( idx );
index_.remove( idx );
return true;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline void T_ObjectTable< K , V >::clear( )
{
values_.clear( );
index_.clear( );
}
template< typename K , typename V >
inline void T_ObjectTable< K , V >::free( )
{
values_.free( );
index_.free( );
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline uint32_t T_ObjectTable< K , V >::size( ) const
{
return values_.size( );
}
template< typename K , typename V >
inline uint32_t T_ObjectTable< K , V >::indexOf( K const& k ) const
{
return find( k , ComputeHash( k ) );
}
template< typename K , typename V >
inline bool T_ObjectTable< K , V >::contains( K const& k ) const
{
const uint32_t hash = ComputeHash( k );
return find( k , hash ) != T_HashIndex::INVALID_INDEX;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline T_Array< K > T_ObjectTable< K , V >::keys( ) const
{
const auto sz( size( ) );
T_Array< K > k( sz ? sz : 1 );
for ( uint32_t i = 0 ; i < sz ; i ++ ) {
k.add( keyGetter_( values_[ i ] ) );
}
return k;
}
template< typename K , typename V >
inline T_Array< V > const& T_ObjectTable< K , V >::values( ) const
{
return values_;
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline V const* T_ObjectTable< K , V >::get( K const& k ) const
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return nullptr;
}
return &values_[ idx ];
}
template< typename K , typename V >
inline V* T_ObjectTable< K , V >::get( K const& k )
{
const uint32_t hash = ComputeHash( k );
uint32_t idx = find( k , hash );
if ( idx == T_HashIndex::INVALID_INDEX ) {
return nullptr;
}
return &values_[ idx ];
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline V& T_ObjectTable< K , V >::operator[] ( uint32_t index )
{
return values_[ index ];
}
template< typename K , typename V >
inline V const& T_ObjectTable< K , V >::operator[] ( uint32_t index ) const
{
return values_[ index ];
}
/*----------------------------------------------------------------------------*/
template< typename K , typename V >
inline uint32_t T_ObjectTable< K , V >::find( K const& k , uint32_t hash ) const
{
uint32_t idx = index_.first( hash );
while ( idx != T_HashIndex::INVALID_INDEX ) {
if ( match_( keyGetter_( values_[ idx ] ) , k ) ) {
break;
}
idx = index_.next( idx );
}
return idx;
}
} // namespace
#endif // _H_LW_LIB_INLINE_HASHTABLES

View file

@ -0,0 +1,43 @@
/******************************************************************************/
/* MEMORY STREAMS - INLINE CODE ***********************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/MemoryStreams.hh>
namespace lw {
/*= T_MemoryInputStream ======================================================*/
template< int S , typename T >
inline T_MemoryInputStream::T_MemoryInputStream( T_FixedBuffer< S , T > const& buffer )
: T_MemoryInputStream( buffer.data( ) , buffer.bytes( ) )
{ }
template< typename T >
inline T_MemoryInputStream::T_MemoryInputStream( T_Buffer< T > const& buffer )
: T_MemoryInputStream( buffer.data( ) , buffer.bytes( ) )
{ }
/*= T_MemoryOutputStream =====================================================*/
template< int S , typename T >
inline T_MemoryOutputStream::T_MemoryOutputStream( T_FixedBuffer< S , T >& buffer )
: T_MemoryOutputStream( buffer.data( ) , buffer.bytes( ) )
{ }
template< typename T >
inline T_MemoryOutputStream::T_MemoryOutputStream( T_Buffer< T >& buffer )
: T_MemoryOutputStream( buffer.data( ) , buffer.bytes( ) ,
[&buffer] ( uint8_t* , size_t reqSize ) -> uint8_t*
{
const size_t mod( reqSize % sizeof( T ) );
const size_t nItems( reqSize / sizeof( T ) + ( mod ? 1 : 0 ) );
buffer.resize( nItems );
return buffer.data( );
} )
{ }
} // namespace

View file

@ -0,0 +1,154 @@
/******************************************************************************/
/* UI<=>GAME MESSAGES - INLINE CODE *******************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_MESSAGES
#define _H_LW_LIB_INLINE_MESSAGES
#include <lw/lib/GameLoop.hh>
namespace lw {
/*= T_ProgressInfoPart =======================================================*/
inline T_ProgressInfoPart::T_ProgressInfoPart( T_String text ,
uint32_t progress , uint32_t total ) noexcept
: text_( std::move( text ) ) , progress_( progress ) , total_( total )
{ }
inline T_ProgressInfoPart::T_ProgressInfoPart( T_ProgressInfoPart&& other ) noexcept
: text_( std::move( other.text_ ) ) , progress_( other.progress_ ) ,
total_( other.total_ )
{ }
inline T_ProgressInfoPart::T_ProgressInfoPart( T_ProgressInfoPart const& other )
: text_( other.text_ ) , progress_( other.progress_ ) , total_( other.total_ )
{ }
/*----------------------------------------------------------------------------*/
inline T_String const& T_ProgressInfoPart::text( ) const noexcept
{
return text_;
}
inline uint32_t T_ProgressInfoPart::progress( ) const noexcept
{
return progress_;
}
inline uint32_t T_ProgressInfoPart::total( ) const noexcept
{
return total_;
}
/*= T_ProgressInfo ===========================================================*/
inline T_ProgressInfo::T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ) noexcept
: main_( std::move( text ) , progress , total ) , sub_( )
{ }
inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfoPart main ) noexcept
: main_( std::move( main ) )
{ }
inline T_ProgressInfo::T_ProgressInfo(
T_ProgressInfoPart main ,
T_ProgressInfoPart sub ) noexcept
: main_( std::move( main ) ) ,
sub_( std::move( sub ) )
{ }
inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfoPart main ,
T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept
: main_( std::move( main ) ) ,
sub_( T_ProgressInfoPart{ std::move( sText ) , sProgress , sTotal } )
{ }
inline T_ProgressInfo::T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ,
T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept
: main_( std::move( text ) , progress , total ) ,
sub_( T_ProgressInfoPart{ std::move( sText ) , sProgress , sTotal } )
{ }
inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfo&& other ) noexcept
: main_( std::move( other.main_ ) ) , sub_( std::move( other.sub_ ) )
{ }
/*----------------------------------------------------------------------------*/
inline T_ProgressInfoPart const& T_ProgressInfo::main( ) const noexcept
{
return main_;
}
inline bool T_ProgressInfo::hasSub( ) const noexcept
{
return sub_.present( );
}
inline T_ProgressInfoPart const& T_ProgressInfo::sub( ) const
{
return (T_ProgressInfoPart const&) sub_;
}
/*= T_GameMessage ============================================================*/
template< E_MessageDirection D , typename MT , typename MD >
inline constexpr T_GameMessage< D , MT , MD >::T_GameMessage( ) noexcept
: type_( ) , data_( )
{ }
template< E_MessageDirection D , typename MT , typename MD >
inline constexpr T_GameMessage< D , MT , MD >::T_GameMessage(
T_Type type ) noexcept
: type_( type ) , data_( )
{ }
template< E_MessageDirection D , typename MT , typename MD >
inline T_GameMessage< D , MT , MD >::T_GameMessage(
T_Type type ,
T_Data data ) noexcept
: type_( type ) , data_( data )
{ }
template< E_MessageDirection D , typename MT , typename MD >
inline T_GameMessage< D , MT , MD >::T_GameMessage(
T_Self_&& other ) noexcept
: type_( other.type_ ) , data_( std::move( other.data_ ) )
{ }
template< E_MessageDirection D , typename MT , typename MD >
inline T_GameMessage< D >& T_GameMessage< D , MT , MD >::operator =(
T_Self_&& other ) noexcept
{
type_ = other.type_;
data_ = std::move( other.data_ );
return *this;
}
/*----------------------------------------------------------------------------*/
template< E_MessageDirection D , typename MT , typename MD >
inline constexpr bool T_GameMessage< D , MT , MD >::hasMessage( ) const noexcept
{
return type_.present( );
}
template< E_MessageDirection D , typename MT , typename MD >
inline constexpr MT T_GameMessage< D , MT , MD >::type( ) const noexcept
{
return type_;
}
template< E_MessageDirection D , typename MT , typename MD >
template< typename T >
constexpr T const& T_GameMessage< D , MT , MD >::data( ) const
{
return (T const&)( (MD const&) data_ );
}
} // namespace lw
#endif // _H_LW_LIB_INLINE_MESSAGES

View file

@ -0,0 +1,59 @@
/******************************************************************************/
/* MODDING SYSTEM - INLINE CODE ***********************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_MODS
#define _H_LW_LIB_INLINE_MODS
#include <lw/lib/Mods.hh>
namespace lw {
/*= T_ModIdentifier ==========================================================*/
inline bool T_ModIdentifier::operator ==(
T_ModIdentifier const& other ) const noexcept
{
return &other == this || ( name == other.name
&& version == other.version );
}
inline bool T_ModIdentifier::operator !=(
T_ModIdentifier const& other ) const noexcept
{
return &other != this && ( name != other.name
|| version != other.version );
}
inline M_DEFINE_HASH( T_ModIdentifier )
{
return ComputeHash( item.name ) * 47 + item.version;
}
inline M_DEFINE_COMPARATOR( T_ModIdentifier )
{
return a.compare( b );
}
inline M_LSHIFT_OP( T_StringBuilder , T_ModIdentifier const& )
{
obj << value.name << ':' << value.version;
return obj;
}
/*= T_ModInfo ================================================================*/
inline bool T_ModInfo::isUserInterface( ) const noexcept
{
return type == E_ModType::UI;
}
inline M_LSHIFT_OP( T_StringBuilder , T_ModInfo const& )
{
obj << value.identifier << '.' << value.revision;
return obj;
}
}
#endif // _H_LW_LIB_INLINE_MODS

View file

@ -0,0 +1,854 @@
/******************************************************************************/
/* POINTERS - INLINE CODE *****************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_POINTERS
#define _H_LW_LIB_INLINE_POINTERS
#include <lw/lib/Pointers.hh>
namespace lw {
/*= T_OwnPtr =================================================================*/
template< typename T >
inline T_OwnPtr< T >::T_OwnPtr( T* p ) noexcept
: p_( p )
{ }
template< typename T >
inline T_OwnPtr< T >::T_OwnPtr( )
: T_OwnPtr( nullptr )
{ }
/*----------------------------------------------------------------------------*/
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_OwnPtr< T >::T_OwnPtr( T_OwnPtr< Q >&& source ) noexcept
: p_( nullptr )
{
T* temp( source.p_ );
source.p_ = nullptr;
p_ = temp;
}
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_OwnPtr< T >::T_OwnPtr( T_OwnPtr< Q >&& source )
: p_( nullptr )
{
T* temp( dynamic_cast< T* >( source.p_ ) );
if ( source.p_ && !temp ) {
throw std::bad_cast( );
}
source.p_ = nullptr;
p_ = temp;
}
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_OwnPtr< T >& T_OwnPtr< T >::operator= ( T_OwnPtr< Q >&& source ) noexcept
{
T* temp( source.p_ );
clear( );
source.p_ = nullptr;
p_ = temp;
return *this;
}
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_OwnPtr< T >& T_OwnPtr< T >::operator= (
T_OwnPtr< Q >&& source )
{
T* temp( dynamic_cast< T* >( source.p_ ) );
if ( source.p_ && !temp ) {
throw std::bad_cast( );
}
clear( );
source.p_ = nullptr;
p_ = temp;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_OwnPtr< T >::~T_OwnPtr( )
{
clear( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_OwnPtr< T >& lhs , T_OwnPtr< T >& rhs ) noexcept
{
std::swap( lhs.p_ , rhs.p_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_OwnPtr< T >::clear( )
{
T* ptr( nullptr );
std::swap( p_ , ptr );
delete ptr;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline bool T_OwnPtr< T >::operator== ( const T* p ) const
{
return p == p_;
}
template< typename T >
inline bool T_OwnPtr< T >::operator!= ( const T* p ) const
{
return p != p_;
}
template< typename T >
inline T_OwnPtr< T >::operator bool ( ) const
{
return p_ != nullptr;
}
template< typename T >
inline bool T_OwnPtr< T >::operator! ( ) const
{
return p_ == nullptr;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T* T_OwnPtr< T >::get( ) const
{
return p_;
}
template< typename T >
inline T* T_OwnPtr< T >::operator-> ( ) const
{
assert( p_ != nullptr );
return p_;
}
template< typename T >
inline T& T_OwnPtr< T >::operator* ( ) const
{
assert( p_ != nullptr );
return *p_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_SharedPtr< T > T_OwnPtr< T >::makeShared( )
{
T* temp( nullptr );
std::swap( p_ , temp );
return T_SharedPtr< T >( temp );
}
/*= NewOwned / OwnRawPointer =================================================*/
template<
typename Type ,
typename... ArgTypes
>
inline T_OwnPtr< Type > NewOwned( ArgTypes&& ... arguments )
{
return T_OwnPtr< Type >( new Type( std::forward< ArgTypes >( arguments ) ... ) );
}
template< typename Type >
inline T_OwnPtr< Type > OwnRawPointer( Type*& pointer ) noexcept
{
assert( pointer != nullptr );
T_OwnPtr< Type > p( pointer );
pointer = nullptr;
return p;
}
template<
typename Type , typename Other ,
T_EnableForChild< Type , Other >
> inline T_OwnPtr< Type > OwnRawPointer( Other*& pointer ) noexcept
{
assert( pointer != nullptr );
T_OwnPtr< Type > p( pointer );
pointer = nullptr;
return p;
}
template<
typename Type , typename Other ,
T_EnableForParent< Type , Other >
> inline T_OwnPtr< Type > OwnRawPointer( Other*& pointer )
{
assert( pointer != nullptr );
Type* temp( dynamic_cast< Type* >( pointer ) );
if ( temp == nullptr ) {
throw std::bad_cast( );
}
T_OwnPtr< Type > p( temp );
pointer = nullptr;
return p;
}
/*= T_Reference_ =============================================================*/
// Reference counter for shared pointers
class T_Reference_
{
private:
typedef std::function< void ( void* ) > F_Destr_;
friend struct T_WeakChain_;
void* pointer_;
F_Destr_ destr_;
uint32_t count_;
T_WeakChain_* weaks_;
public:
/* References are pooled */
void* operator new( size_t count ) noexcept;
void operator delete( void* object ) noexcept;
T_Reference_( ) = delete;
T_Reference_( T_Reference_ const& ) = delete;
T_Reference_( T_Reference_&& ) = delete;
T_Reference_( void* ptr , F_Destr_ destructor );
~T_Reference_( );
void* pointer( ) const;
T_Reference_ * increase( );
void decrease( );
void* extract( );
};
/*----------------------------------------------------------------------------*/
inline void* T_Reference_::pointer( ) const
{
return pointer_;
}
inline T_Reference_* T_Reference_::increase( )
{
assert( count_ > 0 );
count_ ++;
return this;
}
inline void T_Reference_::decrease( )
{
assert( count_ > 0 );
count_ --;
if ( count_ == 0 ) {
delete this;
}
}
/*= T_BasePtr_ ===============================================================*/
template< typename T >
inline T_BasePtr_< T >::T_BasePtr_( T_Reference_* ref ) noexcept
: ref_( ref )
{ }
template< typename T >
inline T_BasePtr_< T >::operator bool ( ) const
{
return ref_ != nullptr;
}
template< typename T >
inline bool T_BasePtr_< T >::operator! ( ) const
{
return ref_ == nullptr;
}
template< typename T >
inline T* T_BasePtr_< T >::operator-> ( ) const
{
assert( ref_ != nullptr );
return reinterpret_cast< T* >( ref_->pointer( ) );
}
template< typename T >
inline T_BasePtr_< T >::operator T* ( ) const
{
return ref_ == nullptr
? nullptr
: reinterpret_cast< T* >( ref_->pointer( ) );
}
template< typename T >
inline T& T_BasePtr_< T >::operator* ( ) const
{
assert( ref_ != nullptr );
return *reinterpret_cast< T* >( ref_->pointer( ) );
}
/*= X_TooManyReferences ======================================================*/
inline X_TooManyReferences::X_TooManyReferences( )
: std::runtime_error( "too many references" )
{ }
/*= T_SharedPtr ==============================================================*/
template< typename T >
inline T_Reference_* T_SharedPtr< T >::setRef( T_Reference_* from )
{
if ( from == nullptr ) {
return nullptr;
}
return from->increase( );
}
template< typename T >
inline void T_SharedPtr< T >::clearRef( )
{
if ( ref_ != nullptr ) {
ref_->decrease( );
}
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_SharedPtr< T >::T_SharedPtr( T* ptr )
: T_Base_( new T_Reference_( ptr ,
[]( void* p ) {
delete reinterpret_cast< T* >( p );
} ) )
{ }
template< typename T >
inline T_SharedPtr< T >::T_SharedPtr( ) noexcept
: T_Base_( nullptr )
{ }
template< typename T >
inline T_SharedPtr< T >::~T_SharedPtr( )
{
clearRef( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_SharedPtr< T >::T_SharedPtr( T_Self_ const& source )
: T_Base_( setRef( source.ref_ ) )
{ }
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q > const& other )
: T_Base_( setRef( other.ref_ ) )
{ }
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q > const& other )
: T_Base_( nullptr )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
ref_ = setRef( other.ref_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q >&& other ) noexcept
: T_Base_( other.ref_ )
{
other.ref_ = nullptr;
}
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_SharedPtr< T >::T_SharedPtr( T_SharedPtr< Q >&& other )
: T_Base_( nullptr )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
using std::swap;
swap( ref_ , other.ref_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< T > const& other )
{
if ( &other != this && other.ref_ != ref_ ) {
clearRef( );
ref_ = setRef( other.ref_ );
}
return *this;
}
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q > const& other )
{
if ( other.ref_ != ref_ ) {
clearRef( );
ref_ = setRef( other.ref_ );
}
return *this;
}
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q > const& other )
{
if ( other.ref_ != ref_ ) {
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
clearRef( );
ref_ = setRef( other.ref_ );
}
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
template<
typename Q ,
T_EnableForChild< T , Q >
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q >&& other ) noexcept
{
if ( other.ref_ != ref_ ) {
clearRef( );
ref_ = nullptr;
std::swap( ref_ , other.ref_ );
}
return *this;
}
template< typename T >
template<
typename Q ,
T_EnableForParent< T , Q >
> inline T_SharedPtr< T >& T_SharedPtr< T >::operator= ( T_SharedPtr< Q >&& other )
{
if ( other.ref_ != ref_ ) {
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
clearRef( );
ref_ = nullptr;
std::swap( ref_ , other.ref_ );
}
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_SharedPtr< T >& lhs , T_SharedPtr< T >& rhs ) noexcept
{
std::swap( lhs.ref_ , rhs.ref_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline bool T_SharedPtr< T >::operator== ( T_SharedPtr< T > const& other ) const
{
return other.ref_ == ref_;
}
template< typename T >
inline bool T_SharedPtr< T >::operator!= ( T_SharedPtr< T > const& other ) const
{
return other.ref_ != ref_;
}
template< typename T >
inline bool T_SharedPtr< T >::operator== ( T_WeakPtr< T > const& other ) const
{
return other.ref_ == ref_;
}
template< typename T >
inline bool T_SharedPtr< T >::operator!= ( T_WeakPtr< T > const& other ) const
{
return other.ref_ != ref_;
}
template< typename T >
inline void T_SharedPtr< T >::clear( )
{
clearRef( );
ref_ = nullptr;
}
template< typename T >
T_OwnPtr< T > T_SharedPtr< T >::makeOwned( )
{
if ( ref_ == nullptr ) {
return T_OwnPtr< T >( );
}
void* const p( ref_->extract( ) );
ref_ = nullptr;
return T_OwnPtr< T >( reinterpret_cast< T* >( p ) );
}
/*= T_WeakPtr ================================================================*/
template< typename T >
inline T_WeakPtr< T >::T_WeakPtr( T_Reference_* ref )
: T_BasePtr_< T >( ref ) , chain_( ref_ )
{
chain_.init( );
}
template< typename T >
inline T_WeakPtr< T >::T_WeakPtr( )
: T_WeakPtr( nullptr )
{ }
template< typename T >
inline T_WeakPtr< T >::~T_WeakPtr( )
{
chain_.unchain( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< T > const& other )
: T_WeakPtr( other.ref_ )
{ }
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q > const& other )
: T_WeakPtr( other.ref_ )
{ }
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q > const& other )
: T_WeakPtr( )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
ref_ = other.ref_;
chain_.init( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q >&& other ) noexcept
: T_WeakPtr( nullptr )
{
other.chain_.unchain( );
ref_ = other.ref_;
other.ref_ = nullptr;
chain_.init( );
}
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_WeakPtr< Q >&& other )
: T_WeakPtr( nullptr )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
other.chain_.unchain( );
ref_ = other.ref_;
other.ref_ = nullptr;
chain_.init( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< T > const& shared )
: T_WeakPtr( shared.ref_ )
{ }
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< Q > const& shared )
: T_WeakPtr( shared.ref_ )
{ }
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >::T_WeakPtr( T_SharedPtr< Q > const& shared )
: T_WeakPtr( nullptr )
{
Q* const p( shared );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
ref_ = shared.ref_;
chain_.init( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_WeakPtr< T >& lhs , T_WeakPtr< T >& rhs )
{
if ( lhs.ref_ != rhs.ref_ ) {
lhs.chain_.unchain( );
rhs.chain_.unchain( );
std::swap( lhs.ref_ , rhs.ref_ );
lhs.chain_.init( );
rhs.chain_.init( );
}
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< T > const& other )
{
chain_.unchain( );
ref_ = other.ref_;
chain_.init( );
return *this;
}
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q > const& other )
{
chain_.unchain( );
ref_ = other.ref_;
chain_.init( );
return *this;
}
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q > const& other )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
chain_.unchain( );
ref_ = other.ref_;
chain_.init( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q >&& other )
{
ref_ = nullptr;
chain_.unchain( );
if ( other.ref_ ) {
other.chain_.unchain( );
ref_ = other.ref_;
other.ref_ = nullptr;
chain_.init( );
other.chain_.init( );
}
return *this;
}
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_WeakPtr< Q >&& other )
{
Q* const p( other );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
ref_ = nullptr;
chain_.unchain( );
if ( other.ref_ ) {
other.chain_.unchain( );
ref_ = other.ref_;
other.ref_ = nullptr;
chain_.init( );
other.chain_.init( );
}
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< T > const& shared )
{
chain_.unchain( );
ref_ = shared.ref_;
chain_.init( );
return *this;
}
template< typename T >
template< typename Q , T_EnableForChild< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< Q > const& shared )
{
chain_.unchain( );
ref_ = shared.ref_;
chain_.init( );
return *this;
}
template< typename T >
template< typename Q , T_EnableForParent< T , Q > >
inline T_WeakPtr< T >& T_WeakPtr< T >::operator= ( T_SharedPtr< Q > const& shared )
{
Q* const p( shared );
if ( p != nullptr && dynamic_cast< T* >( p ) == nullptr ) {
throw std::bad_cast( );
}
chain_.unchain( );
ref_ = shared.ref_;
chain_.init( );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline bool T_WeakPtr< T >::operator== ( T_WeakPtr< T > const& other ) const
{
return other.ref_ == ref_;
}
template< typename T >
inline bool T_WeakPtr< T >::operator!= ( T_WeakPtr< T > const& other ) const
{
return other.ref_ != ref_;
}
template< typename T >
inline bool T_WeakPtr< T >::operator== ( T_SharedPtr< T > const& other ) const
{
return other.ref_ == ref_;
}
template< typename T >
inline bool T_WeakPtr< T >::operator!= ( T_SharedPtr< T > const& other ) const
{
return other.ref_ != ref_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_WeakPtr< T >::clear( )
{
chain_.unchain( );
ref_ = nullptr;
}
/*= NewShared ================================================================*/
template<
typename Type ,
typename... ArgTypes
> inline T_SharedPtr< Type > NewShared( ArgTypes&& ... arguments )
{
return T_SharedPtr< Type >( new Type( std::forward< ArgTypes >( arguments ) ... ) );
}
template< typename Type >
T_SharedPtr< Type > ShareRawPointer(
Type*& pointer ) noexcept
{
assert( pointer != nullptr );
T_SharedPtr< Type > p( pointer );
pointer = nullptr;
return p;
}
template<
typename Type , typename Other ,
T_EnableForChild< Type , Other >
> inline T_SharedPtr< Type > ShareRawPointer(
Other*& pointer ) noexcept
{
assert( pointer != nullptr );
T_SharedPtr< Type > p( pointer );
pointer = nullptr;
return p;
}
template<
typename Type , typename Other ,
T_EnableForParent< Type , Other >
> inline T_SharedPtr< Type > ShareRawPointer(
Other*& pointer )
{
assert( pointer != nullptr );
Type* temp( dynamic_cast< Type* >( pointer ) );
if ( temp == nullptr ) {
throw std::bad_cast( );
}
T_SharedPtr< Type > p( temp );
pointer = nullptr;
return p;
}
} // namespace
#endif // _H_LW_LIB_INLINE_POINTERS

View file

@ -0,0 +1,124 @@
/******************************************************************************/
/* REGISTRATION SUPPORT - INLINE CODE *****************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_REGISTRATION
#define _H_LW_LIB_INLINE_REGISTRATION
#include <lw/lib/Registration.hh>
namespace lw {
/*= T_RegisteredItem ============================================================*/
inline T_RegisteredItem::T_RegisteredItem( ) noexcept
: automatic_( false ) , unregisterFunction_( ) ,
data_( nullptr ) , dataDestructor_( )
{ }
inline T_RegisteredItem::T_RegisteredItem(
SP_Unregister& unregisterFunction ,
void* data ,
F_Destructor_ destructor ) noexcept
: automatic_( true ) , unregisterFunction_( unregisterFunction ) ,
data_( data ) , dataDestructor_( destructor )
{ }
template< typename T >
inline T_RegisteredItem::T_RegisteredItem(
SP_Unregister& unregisterFunction ,
T* data ) noexcept
: T_RegisteredItem( unregisterFunction , data ,
[]( void* d ) {
reinterpret_cast< T* >( d )->~T( );
::operator delete( d );
} )
{ }
template< >
inline T_RegisteredItem::T_RegisteredItem(
SP_Unregister& unregisterFunction ,
void* data ) noexcept
: T_RegisteredItem( unregisterFunction , data , [](void*){} )
{ }
inline T_RegisteredItem::~T_RegisteredItem( )
{
clear( );
}
/*----------------------------------------------------------------------------*/
inline T_RegisteredItem::T_RegisteredItem(
T_RegisteredItem&& other ) noexcept
: T_RegisteredItem( )
{
swap( *this , other );
}
inline T_RegisteredItem& T_RegisteredItem::operator =(
T_RegisteredItem&& other ) noexcept
{
clear( );
swap( *this , other );
return *this;
}
inline M_DECLARE_SWAP( T_RegisteredItem )
{
using std::swap;
swap( lhs.automatic_ , rhs.automatic_ );
swap( lhs.unregisterFunction_ , rhs.unregisterFunction_ );
swap( lhs.data_ , rhs.data_ );
swap( lhs.dataDestructor_ , rhs.dataDestructor_ );
}
/*----------------------------------------------------------------------------*/
inline void T_RegisteredItem::automatic(
const bool v ) noexcept
{
automatic_ = v;
}
inline bool T_RegisteredItem::automatic( ) const noexcept
{
return automatic_;
}
/*----------------------------------------------------------------------------*/
inline void T_RegisteredItem::unregister( ) noexcept
{
if ( data_ && unregisterFunction_ ) {
(*unregisterFunction_)( data_ );
deleteData( );
}
}
inline T_RegisteredItem::operator bool( ) const noexcept
{
return bool( data_ );
}
inline void T_RegisteredItem::clear( ) noexcept
{
if ( automatic_ ) {
unregister( );
} else {
deleteData( );
}
}
inline void T_RegisteredItem::deleteData( ) noexcept
{
if ( data_ != nullptr ) {
if ( dataDestructor_ ) {
dataDestructor_( data_ );
}
data_ = nullptr;
}
}
} // namespace lw
#endif // _H_LW_LIB_INLINE_REGISTRATION

View file

@ -0,0 +1,33 @@
/******************************************************************************/
/* SRD - BINARY STORAGE - INLINE CODE *****************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDBINARY
#define _H_LW_LIB_INLINE_SRDBINARY
#include <lw/lib/SRDBinary.hh>
namespace lw {
inline void SRDBinaryWriteTo( A_OutputStream& output , T_SRDList const& data )
{
T_SRDBinaryWriter( output ).start( ).putList( data ).end( );
}
/*= T_SRDBinaryReader ========================================================*/
inline T_SRDBinaryReader::T_SRDBinaryReader( A_SRDReaderTarget& target )
: A_SRDReader( target )
{ }
inline T_SRDList SRDBinaryReadFrom( T_String const& name , A_InputStream& input , bool structured )
{
T_SRDErrors errors;
T_SRDMemoryTarget mt( structured );
T_SRDBinaryReader( mt ).read( name , input );
return mt.list( );
}
} // namespace
#endif // _H_LW_LIB_INLINE_SRDBINARY

View file

@ -0,0 +1,438 @@
/******************************************************************************/
/* SRD - DATA - INLINE CODE ***************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDDATA
#define _H_LW_LIB_INLINE_SRDDATA
#include <lw/lib/SRDData.hh>
namespace lw {
/*= T_SRDLocationChaining ====================================================*/
inline T_SRDLocationChaining::T_SRDLocationChaining(
const E_SRDLocationChaining how ,
const uint32_t depth ,
SP_SRDLocation const& to ) noexcept
: circumstances( how ) , depth( depth ) , location( to )
{ }
inline bool T_SRDLocationChaining::isGenerated( ) const noexcept
{
return circumstances == E_SRDLocationChaining::GENERATED
|| circumstances == E_SRDLocationChaining::SUBSTITUTED;
}
/*= T_SRDLocation ============================================================*/
inline T_SRDLocation::T_SRDLocation( ) noexcept
: source_( ) , line_( 0 ) , character_( 0 )
{ }
inline T_SRDLocation& T_SRDLocation::operator= (
T_SRDLocation&& other ) noexcept
{
swap( *this , other );
return *this;
}
inline T_SRDLocation::T_SRDLocation(
T_SRDToken const& token ) noexcept
: T_SRDLocation( )
{
if ( token.hasLocation( ) ) {
*this = token.location( );
}
}
/*----------------------------------------------------------------------------*/
inline void T_SRDLocation::chain(
const E_SRDLocationChaining how ,
SP_SRDLocation const& to ) noexcept
{
chain( how , 0 , to );
}
inline void T_SRDLocation::chain(
const E_SRDLocationChaining how ,
const uint32_t depth ,
SP_SRDLocation const& to ) noexcept
{
assert( bool( to ) );
chaining_.setNew( how , depth , to );
}
inline void T_SRDLocation::clearChain( ) noexcept
{
chaining_.clear( );
}
/*----------------------------------------------------------------------------*/
inline bool T_SRDLocation::unknown( ) const noexcept
{
return source_.size( ) == 0;
}
inline T_String const& T_SRDLocation::source( ) const noexcept
{
return source_;
}
inline bool T_SRDLocation::binary( ) const noexcept
{
return line_ == 0;
}
inline uint32_t T_SRDLocation::line( ) const noexcept
{
return line_;
}
inline size_t T_SRDLocation::character( ) const noexcept
{
return character_;
}
inline size_t T_SRDLocation::byte( ) const noexcept
{
return character_;
}
inline bool T_SRDLocation::isChained( ) const noexcept
{
return chaining_.present( );
}
inline T_SRDLocationChaining const& T_SRDLocation::chaining( ) const noexcept
{
return chaining_;
}
/*= T_SRDError ===============================================================*/
inline T_SRDError::T_SRDError(
T_String error ,
T_SRDLocation location ,
const bool details ) noexcept
: error_( std::move( error ) ) ,
location_( std::move( location ) ) ,
isDetails_( details )
{ }
/*----------------------------------------------------------------------------*/
inline T_SRDError::T_SRDError(
T_SRDError const& other ) noexcept
: error_( other.error_ ) ,
location_( other.location_ ) ,
isDetails_( other.isDetails_ )
{ }
inline T_SRDError& T_SRDError::operator= (
T_SRDError const& other ) noexcept
{
error_ = other.error_;
location_ = other.location_;
isDetails_ = other.isDetails_;
return *this;
}
/*----------------------------------------------------------------------------*/
inline T_SRDError::T_SRDError(
T_SRDError&& other ) noexcept
: error_( ) , location_( )
{
swap( *this , other );
}
inline T_SRDError& T_SRDError::operator=(
T_SRDError&& other ) noexcept
{
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
inline M_DECLARE_SWAP( T_SRDError )
{
using std::swap;
swap( lhs.error_ , rhs.error_ );
swap( lhs.location_ , rhs.location_ );
swap( lhs.isDetails_ , rhs.isDetails_ );
}
/*----------------------------------------------------------------------------*/
inline T_String const& T_SRDError::error( ) const noexcept
{
return error_;
}
inline T_SRDLocation const& T_SRDError::location( ) const noexcept
{
return location_;
}
inline bool T_SRDError::isDetails( ) const noexcept
{
return isDetails_;
}
/*= T_SRDErrors ==============================================================*/
template< typename ... ArgTypes >
inline void T_SRDErrors::add(
char const* error ,
ArgTypes&&... locationArgs )
{
add( InPlace::v , T_String::Pooled( error ) ,
T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) );
}
template< typename ... ArgTypes >
inline void T_SRDErrors::add(
T_String const& error ,
ArgTypes&&... locationArgs )
{
add( InPlace::v , error ,
T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) );
}
template< typename ... ArgTypes >
inline void T_SRDErrors::details(
char const* error ,
ArgTypes&&... locationArgs )
{
add( InPlace::v , T_String::Pooled( error ) ,
T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) ,
true );
}
template< typename ... ArgTypes >
inline void T_SRDErrors::details(
T_String const& error ,
ArgTypes&&... locationArgs )
{
add( InPlace::v , error ,
T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) ,
true );
}
template< typename ... ArgTypes >
inline void T_SRDErrors::add(
InPlace ,
ArgTypes&&... args )
{
checkAdded( errors_.addNew( std::forward< ArgTypes >( args ) ... ) );
}
inline void T_SRDErrors::add(
T_SRDError const& error )
{
checkAdded( errors_.addNew( error ) );
}
inline void T_SRDErrors::add(
T_SRDError&& error )
{
checkAdded( errors_.addNew( std::move( error ) ) );
}
/*----------------------------------------------------------------------------*/
inline uint32_t T_SRDErrors::size( ) const noexcept
{
return errors_.size( );
}
inline T_SRDError const& T_SRDErrors::operator[] (
uint32_t index ) const noexcept
{
return errors_[ index ];
}
inline void T_SRDErrors::clear( ) noexcept
{
errors_.clear( );
errCount_ = 0;
}
/*= X_SRDErrors ==============================================================*/
inline X_SRDErrors::X_SRDErrors( T_SRDErrors const& errors )
: errors( errors )
{ }
/*= T_SRDToken ===============================================================*/
inline T_SRDToken::T_SRDToken(
const E_SRDTokenType type ) noexcept
: type_( type )
{ }
inline T_SRDToken::T_SRDToken( T_SRDToken&& other ) noexcept
{
swap( *this , other );
}
inline T_SRDToken& T_SRDToken::operator= ( T_SRDToken&& other ) noexcept
{
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_SRDToken T_SRDToken::Binary(
T const* const data ,
const uint32_t count ) noexcept
{
return Binary( (uint8_t const*) data , count );
}
template< >
inline T_SRDToken T_SRDToken::Binary< uint8_t >(
uint8_t const* const data ,
const uint32_t count ) noexcept
{
return Binary( NewShared< T_Buffer< uint8_t > >( data , count ) );
}
template< typename T >
inline T_SRDToken T_SRDToken::Binary(
T_Buffer< T > const& data ) noexcept
{
if ( data.size( ) == 0 ) {
return Binary( NewShared< T_Buffer< uint8_t > >( ) );
} else {
return Binary( (uint8_t const*) &data[ 0 ] , data.bytes( ) );
}
}
/*----------------------------------------------------------------------------*/
inline E_SRDTokenType T_SRDToken::type( ) const
{
return type_;
}
inline bool T_SRDToken::isText( ) const
{
return type_ == E_SRDTokenType::WORD || type_ == E_SRDTokenType::STRING;
}
inline bool T_SRDToken::isNumeric( ) const
{
return isInteger( ) || type_ == E_SRDTokenType::FLOAT;
}
inline bool T_SRDToken::isInteger( ) const
{
return type_ == E_SRDTokenType::INT || type_ == E_SRDTokenType::LONG;
}
/*----------------------------------------------------------------------------*/
inline T_String const& T_SRDToken::text( ) const
{
return text_;
}
inline T_SRDList const& T_SRDToken::list( ) const
{
return *list_;
}
inline T_SRDList& T_SRDToken::list( )
{
return *list_;
}
inline int64_t T_SRDToken::longValue( ) const
{
return longValue_;
}
inline double T_SRDToken::floatValue( ) const
{
return floatValue_;
}
inline T_String const& T_SRDToken::stringValue( ) const
{
return stringValue_;
}
inline T_Buffer< uint8_t > const& T_SRDToken::binary( ) const
{
return *binary_;
}
/*----------------------------------------------------------------------------*/
inline bool T_SRDToken::operator ==( T_SRDToken const& other ) const
{
return compare( other ) == 0;
}
inline bool T_SRDToken::operator !=( T_SRDToken const& other ) const
{
return compare( other ) != 0;
}
inline bool T_SRDToken::operator >( T_SRDToken const& other ) const
{
return compare( other ) > 0;
}
inline bool T_SRDToken::operator <( T_SRDToken const& other ) const
{
return compare( other ) < 0;
}
inline bool T_SRDToken::operator >=( T_SRDToken const& other ) const
{
return compare( other ) >= 0;
}
inline bool T_SRDToken::operator <=( T_SRDToken const& other ) const
{
return compare( other ) <= 0;
}
inline M_DEFINE_COMPARATOR( T_SRDToken )
{
return a.compare( b );
}
/*----------------------------------------------------------------------------*/
inline bool T_SRDToken::hasLocation( ) const noexcept
{
return bool( location_ );
}
inline T_SRDLocation& T_SRDToken::location( ) noexcept
{
return *location_;
}
inline T_SRDLocation const& T_SRDToken::location( ) const noexcept
{
return *location_;
}
} // namespace
#endif // _H_LW_LIB_INLINE_SRDDATA

View file

@ -0,0 +1,525 @@
/******************************************************************************/
/* SRD - PARSER DEFINITIONS - INLINE CODE *************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDDEFINITIONS
#define _H_LW_LIB_INLINE_SRDDEFINITIONS
#include <lw/lib/SRDDefinitions.hh>
namespace lw {
/*= T_SRDEnum ================================================================*/
inline T_SRDEnum::T_SRDEnum( T_String name )
: name_( std::move( name ) ) , index_( 32 , 32 , 32 ) , words_( 32 )
{ }
/*----------------------------------------------------------------------------*/
inline T_SRDEnum& T_SRDEnum::operator<< ( char const* word )
{
return operator<< ( T_String::Pooled( word ) );
}
/*----------------------------------------------------------------------------*/
inline T_String const& T_SRDEnum::name( ) const
{
return name_;
}
inline auto T_SRDEnum::size( ) const
{
return words_.size( );
}
/*----------------------------------------------------------------------------*/
inline T_String const& T_SRDEnum::operator[] ( int index ) const
{
return words_[ index ];
}
inline T_String const& T_SRDEnum::operator[] ( uint32_t index ) const
{
return words_[ index ];
}
/*----------------------------------------------------------------------------*/
inline bool T_SRDEnum::contains( T_String const& word ) const
{
return (*this)[ word ] != T_HashIndex::INVALID_INDEX;
}
inline bool T_SRDEnum::contains( char const* word ) const
{
return (*this)[ word ] != T_HashIndex::INVALID_INDEX;
}
/*= T_SRDInputItem ===========================================================*/
inline T_SRDInputItem::T_ListHelper::T_ListHelper( )
: items( 16 )
{ }
inline T_SRDInputItem::T_ListHelper& T_SRDInputItem::T_ListHelper::operator <<( T_SRDInputItem item )
{
items.add( std::move( item ) );
return *this;
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputItem::T_SRDInputItem( )
: type_( E_SRDInputItem::ALTERNATIVE ) , items_( 32 )
{ }
inline T_SRDInputItem::T_SRDInputItem( T_String wordOrName , bool isWord )
: type_( isWord ? E_SRDInputItem::WORD : E_SRDInputItem::ENUM ) , word_( std::move( wordOrName ) )
{ }
inline T_SRDInputItem::T_SRDInputItem( char const* cString )
: T_SRDInputItem( T_String::Pooled( cString ) , true )
{ }
inline T_SRDInputItem::T_SRDInputItem( E_SRDTokenType type )
: type_( E_SRDInputItem::TOKEN ) , token_( type )
{ }
inline T_SRDInputItem::T_SRDInputItem( uint32_t min , uint32_t max )
: type_( E_SRDInputItem::REPETITION ) , items_( 32 ) , min_( min ) , max_( max )
{
if ( min > max ) {
throw std::invalid_argument( "min > max" );
} else if ( min == 0 && max == 0 ) {
throw std::invalid_argument( "min = max = 0" );
}
}
/*----------------------------------------------------------------------------*/
inline E_SRDInputItem T_SRDInputItem::type( ) const
{
return type_;
}
inline T_String const& T_SRDInputItem::word( ) const
{
return word_;
}
inline E_SRDTokenType T_SRDInputItem::token( ) const
{
return token_;
}
inline T_Array< T_SRDInputItem > T_SRDInputItem::items( ) const
{
return items_;
}
inline uint32_t T_SRDInputItem::min( ) const
{
return min_;
}
inline uint32_t T_SRDInputItem::max( ) const
{
return max_;
}
/*----------------------------------------------------------------------------*/
inline bool T_SRDInputItem::operator ==( T_SRDInputItem const& ) const
{
return false;
}
/*----------------------------------------------------------------------------*/
inline T_Array< T_SRDInputItem >& operator <<(
T_Array< T_SRDInputItem >& items ,
T_SRDInputItem::T_ListHelper& list )
{
items << T_SRDInputItem( E_SRDTokenType::START );
items.addAll( list.items );
items << T_SRDInputItem( E_SRDTokenType::END );
return items;
}
inline T_SRDInputItem& T_SRDInputItem::operator <<( T_ListHelper list )
{
items_ << list;
return *this;
}
/*= T_SRDInputRule ===========================================================*/
inline T_SRDInputRule::T_SetContextExecutor::T_SetContextExecutor( bool exit , F_SRDHandler executor )
: exit( exit ) , executor( executor )
{ }
inline T_SRDInputRule::T_SetContext::T_SetContext( T_String string )
: name( std::move( string ) )
{ }
/*----------------------------------------------------------------------------*/
inline T_SRDInputRule& T_SRDInputRule::operator<< ( F_SRDHandler executor )
{
executor_ = executor;
return *this;
}
inline T_SRDInputRule& T_SRDInputRule::operator<< ( T_SetContextExecutor sce )
{
if ( sce.exit ) {
contextExit_ = sce.executor;
} else {
contextEnter_ = sce.executor;
}
return *this;
}
inline T_SRDInputRule& T_SRDInputRule::operator<< ( T_SetContext sc )
{
context_ = sc.name;
return *this;
}
inline T_SRDInputRule& T_SRDInputRule::operator <<( T_SRDInputItem::T_ListHelper lh )
{
items_ << lh;
return *this;
}
/*----------------------------------------------------------------------------*/
inline F_SRDHandler const& T_SRDInputRule::handler( ) const
{
return executor_;
}
inline T_Array< T_SRDInputItem > const& T_SRDInputRule::rule( ) const
{
return items_;
}
inline T_String const& T_SRDInputRule::context( ) const
{
return context_;
}
inline F_SRDHandler const& T_SRDInputRule::onEnter( ) const
{
return contextEnter_;
}
inline F_SRDHandler const& T_SRDInputRule::onExit( ) const
{
return contextExit_;
}
/*= T_SRDContext =============================================================*/
inline T_String const& T_SRDContext::name( ) const
{
return name_;
}
inline T_String const& T_SRDContext::parent( ) const
{
return parent_;
}
inline T_Array< T_SRDInputRule > const& T_SRDContext::rules( ) const
{
return rules_;
}
/*= T_SRDParserDefs ==========================================================*/
inline T_SRDParserDefs::SetHandler::SetHandler( F_SRDHandler const& handler , bool start )
: handler( handler ) , start( start )
{ }
/*----------------------------------------------------------------------------*/
inline T_SRDParserDefs::T_SRDParserDefs( char const* name )
: T_SRDParserDefs( T_String::Pooled( name ) )
{ }
/*----------------------------------------------------------------------------*/
inline T_String const& T_SRDParserDefs::defaultContext( ) const
{
return dfCtx_;
}
inline void T_SRDParserDefs::defaultContext( char const* name )
{
defaultContext( T_String::Pooled( name ) );
}
inline F_SRDHandler const& T_SRDParserDefs::onStart( ) const
{
return onStart_;
}
inline F_SRDHandler const& T_SRDParserDefs::onFinish( ) const
{
return onFinish_;
}
/*----------------------------------------------------------------------------*/
inline uint32_t T_SRDParserDefs::contexts( ) const
{
return ctx_.size( );
}
inline T_SRDContext& T_SRDParserDefs::operator[] ( uint32_t idx )
{
return ctx_[ idx ];
}
inline T_SRDContext const& T_SRDParserDefs::operator[] ( uint32_t idx ) const
{
return ctx_[ idx ];
}
inline T_SRDContext& T_SRDParserDefs::context( char const* name )
{
return context( T_String::Pooled( name ) );
}
inline T_SRDContext& T_SRDParserDefs::context( char const* name , char const* parent )
{
return context( T_String::Pooled( name ) , T_String::Pooled( parent ) );
}
/*----------------------------------------------------------------------------*/
inline uint32_t T_SRDParserDefs::enums( ) const
{
return enums_.size( );
}
inline T_SRDEnum & T_SRDParserDefs::enumeration( char const* name )
{
return enumeration( T_String::Pooled( name ) );
}
/*= SRD::* ===================================================================*/
namespace SRD {
inline T_SRDParserDefs::SetHandler OnStart( F_SRDHandler const& handler )
{
return T_SRDParserDefs::SetHandler( handler , true );
}
inline T_SRDParserDefs::SetHandler OnFinish( F_SRDHandler const& handler )
{
return T_SRDParserDefs::SetHandler( handler , false );
}
/*----------------------------------------------------------------------------*/
inline T_SRDContext Context( T_String name )
{
return T_SRDContext( std::move( name ) );
}
inline T_SRDContext Context( char const* name )
{
return T_SRDContext( T_String::Pooled( name ) );
}
inline T_SRDContext Context( char const* name , char const* parent )
{
return T_SRDContext( T_String::Pooled( name ) , T_String::Pooled( parent ) );
}
inline T_SRDContext Context( T_String name , T_String parent )
{
return T_SRDContext( std::move( name ) , std::move( parent ) );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputRule Rule( )
{
return T_SRDInputRule( );
}
/*----------------------------------------------------------------------------*/
inline T_SRDEnum CreateEnum( T_String name )
{
return T_SRDEnum( std::move( name ) );
}
inline T_SRDEnum CreateEnum( char const* name )
{
return T_SRDEnum( T_String::Pooled( name ) );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputItem Word( T_String const& word )
{
return T_SRDInputItem( word , true );
}
inline T_SRDInputItem Word( char const* word )
{
return T_SRDInputItem( T_String::Pooled( word ) , true );
}
inline T_SRDInputItem Word( )
{
return T_SRDInputItem( E_SRDTokenType::WORD );
}
inline T_SRDInputItem String( )
{
return T_SRDInputItem( E_SRDTokenType::STRING );
}
inline T_SRDInputItem Binary( )
{
return T_SRDInputItem( E_SRDTokenType::BINARY );
}
inline T_SRDInputItem LStart( )
{
return T_SRDInputItem( E_SRDTokenType::START );
}
inline T_SRDInputItem LEnd( )
{
return T_SRDInputItem( E_SRDTokenType::END );
}
inline T_SRDInputItem Int32( )
{
return T_SRDInputItem( E_SRDTokenType::INT );
}
inline T_SRDInputItem Int64( )
{
return T_SRDInputItem( E_SRDTokenType::LONG );
}
inline T_SRDInputItem Float( )
{
return T_SRDInputItem( E_SRDTokenType::FLOAT );
}
inline T_SRDInputItem Enum( T_String name )
{
return T_SRDInputItem( std::move( name ) , false );
}
inline T_SRDInputItem Enum( char const* name )
{
return T_SRDInputItem( T_String::Pooled( name ) , false );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputItem::T_ListHelper List( )
{
return T_SRDInputItem::T_ListHelper( );
}
inline T_SRDInputItem Alt( )
{
return T_SRDInputItem( );
}
inline T_SRDInputItem Sub( )
{
return T_SRDInputItem( 1 , 1 );
}
inline T_SRDInputItem Opt( )
{
return T_SRDInputItem( 0 , 1 );
}
inline T_SRDInputItem Opt( T_SRDInputItem item )
{
return Opt( ) << std::move( item );
}
inline T_SRDInputItem AtLeast( uint32_t n )
{
return T_SRDInputItem( n , UINT32_MAX );
}
inline T_SRDInputItem AtMost( uint32_t n )
{
return T_SRDInputItem( 0 , n );
}
inline T_SRDInputItem Times( uint32_t n )
{
return T_SRDInputItem( n , n );
}
inline T_SRDInputItem Between( uint32_t a , uint32_t b )
{
return T_SRDInputItem( a > b ? b : a , a > b ? a : b );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputItem Integer( )
{
return Alt( ) << Int32( ) << Int64( );
}
inline T_SRDInputItem Numeric( )
{
return Alt( ) << Integer( ) << Float( );
}
inline T_SRDInputItem Text( )
{
return Alt( ) << String( ) << Word( );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputRule::T_SetContext EnterContext( T_String name )
{
return T_SRDInputRule::T_SetContext( std::move( name ) );
}
inline T_SRDInputRule::T_SetContext EnterContext( char const* name )
{
return EnterContext( T_String::Pooled( name ) );
}
/*----------------------------------------------------------------------------*/
inline T_SRDInputRule::T_SetContextExecutor OnEnter( F_SRDHandler f )
{
return T_SRDInputRule::T_SetContextExecutor( false , f );
}
inline T_SRDInputRule::T_SetContextExecutor OnExit( F_SRDHandler f )
{
return T_SRDInputRule::T_SetContextExecutor( true , f );
}
} // namespace SRD
} // namespace
#endif // _H_LW_LIB_INLINE_SRDDEFINITIONS

View file

@ -0,0 +1,80 @@
/******************************************************************************/
/* SRD - INPUT AND OUTPUT - INLINE CODE ***************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDIO
#define _H_LW_LIB_INLINE_SRDIO
#include <lw/lib/SRDIO.hh>
namespace lw {
/*= A_SRDWriter ==============================================================*/
inline A_SRDWriter::~A_SRDWriter( )
{ }
/*= A_SRDReaderTarget ========================================================*/
inline A_SRDReaderTarget::~A_SRDReaderTarget( )
{ }
/*= A_SRDReader ==============================================================*/
inline A_SRDReader::A_SRDReader( A_SRDReaderTarget& target )
: target_( target )
{ }
inline A_SRDReader::~A_SRDReader( )
{ }
/*= X_SRDWriterError =========================================================*/
inline X_SRDWriterError::X_SRDWriterError( char const* msg ) noexcept
: std::exception( ) , msg_( msg )
{ }
/*= T_SRDReaderTargetHelper ==================================================*/
inline T_SRDReaderTargetHelper::T_SRDReaderTargetHelper( A_SRDReaderTarget& target , T_SRDErrors& errors )
: target_( target ) , errors_( errors )
{
target_.start( errors_ );
}
inline T_SRDReaderTargetHelper::~T_SRDReaderTargetHelper( )
{
target_.end( errors_ );
}
/*= T_SRDMemoryTarget ========================================================*/
inline void T_SRDMemoryTarget::clearFlushToken(
bool clearIt ) noexcept
{
clearFlushToken_ = clearIt;
}
inline bool T_SRDMemoryTarget::clearFlushToken( ) const noexcept
{
return clearFlushToken_;
}
inline T_SRDList const& T_SRDMemoryTarget::list( ) const
{
return list_.list( );
}
inline bool T_SRDMemoryTarget::complete( ) const
{
return current_ != nullptr && stack_.size( ) == 0 && list_.list( ).size( ) != 0;
}
} // namespace
#endif // _H_LW_LIB_INLINE_SRDIO

View file

@ -0,0 +1,33 @@
/******************************************************************************/
/* SRD - PARSER CONFIGURATION - INLINE CODE ***********************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDPARSERCONFIG
#define _H_LW_LIB_INLINE_SRDPARSERCONFIG
#include <lw/lib/SRDParserConfig.hh>
namespace lw {
/*= T_SRDTransition ==========================================================*/
inline T_SRDTransition::T_SRDTransition( E_SRDTokenType tokenType , uint32_t next )
: type( E_SRDTransitionType::TOKEN ) , tokenType( tokenType ) ,
next( next )
{ }
inline T_SRDTransition::T_SRDTransition( E_SRDTransitionType type , uint32_t index , uint32_t next )
: type( type ) , index( index ) , next( next )
{ }
/*= T_SRDParserConfig ========================================================*/
inline T_Optional< uint32_t > T_SRDParserConfig::enumValue(
char const* name , T_String const& member ) const noexcept
{
return enumValue( T_String::Pooled( name ) , member );
}
} // namespace
#endif // _H_LW_LIB_INLINE_SRDPARSERCONFIG

View file

@ -0,0 +1,25 @@
/******************************************************************************/
/* SRD - TEXT STORAGE - INLINE CODE *******************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDTEXT
#define _H_LW_LIB_INLINE_SRDTEXT
#include <lw/lib/SRDText.hh>
namespace lw {
inline void SRDWriteAsText( A_OutputStream& output , T_SRDList const& data )
{
T_SRDTextWriter( output ).start( ).putList( data ).end( );
}
/*= T_SRDTextReader ==========================================================*/
inline T_SRDTextReader::T_SRDTextReader( A_SRDReaderTarget& target )
: A_SRDReader( target )
{ }
} // namespace
#endif // _H_LW_LIB_INLINE_SRDTEXT

View file

@ -0,0 +1,98 @@
/******************************************************************************/
/* STREAMS - INLINE CODE ******************************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/Streams.hh>
namespace lw {
/*= X_StreamError ============================================================*/
inline X_StreamError::X_StreamError( E_StreamError e )
: std::exception( ) , error_( e ) , sysError_( -1 )
{ }
inline X_StreamError::X_StreamError( int error )
: std::exception( ) , error_( E_StreamError::SYSTEM_ERROR ) , sysError_( error )
{ }
/*----------------------------------------------------------------------------*/
inline E_StreamError X_StreamError::code( ) const
{
return error_;
}
inline int X_StreamError::systemError( ) const
{
return sysError_;
}
/*= A_Stream =================================================================*/
inline A_Stream::A_Stream( bool isInput , size_t position ) noexcept
: isInput_( isInput ) , knownSize_( false ) , position_( position )
{ }
inline A_Stream::A_Stream( bool isInput , size_t position , size_t size ) noexcept
: isInput_( isInput ) , knownSize_( true ) , size_( size ) ,
position_( position )
{ }
/*----------------------------------------------------------------------------*/
inline A_Stream::~A_Stream( )
{ }
/*----------------------------------------------------------------------------*/
inline bool A_Stream::isInput( ) const
{
return isInput_;
}
inline bool A_Stream::isSizeKnown( ) const
{
return knownSize_;
}
inline size_t A_Stream::position( ) const
{
return position_;
}
inline size_t A_Stream::size( ) const
{
if ( knownSize_ ) {
return size_;
} else {
throw X_StreamError( E_StreamError::NOT_SUPPORTED );
}
}
/*= A_InputStream ============================================================*/
inline A_InputStream::A_InputStream( size_t position ) noexcept
: A_Stream( true , position )
{ }
inline A_InputStream::A_InputStream( size_t position , size_t size ) noexcept
: A_Stream( true , position , size )
{ }
/*= A_OutputStream ===========================================================*/
inline A_OutputStream::A_OutputStream( size_t position ) noexcept
: A_Stream( false , position )
{ }
inline A_OutputStream::A_OutputStream( size_t position , size_t size ) noexcept
: A_Stream( false , position , size )
{ }
} // namespace

View file

@ -0,0 +1,591 @@
/******************************************************************************/
/* STRINGS AND RELATED UTILITIES - INLINE CODE ********************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_STRINGS
#define _H_LW_LIB_INLINE_STRINGS
#include <lw/lib/Strings.hh>
namespace lw {
/*= T_Character ==============================================================*/
inline T_Character::T_Character( ) noexcept
: codepoint( 0 )
{ }
inline T_Character::T_Character( const T_Character& other ) noexcept
: codepoint( other.codepoint )
{ }
template< typename T , typename >
inline T_Character::T_Character( T codepoint ) noexcept
: codepoint( uint32_t( codepoint ) )
{
assert( codepoint >= 0 );
}
/*----------------------------------------------------------------------------*/
inline bool T_Character::isValid( ) const
{
return codepoint < 0x110000;
}
inline bool T_Character::isAscii( ) const
{
return codepoint < 128;
}
inline bool T_Character::isControl( ) const
{
return codepoint < 32;
}
inline bool T_Character::isUppercase( ) const
{
return codepoint >= 'A' && codepoint <= 'Z';
}
inline bool T_Character::isLowercase( ) const
{
return codepoint >= 'a' && codepoint <= 'z';
}
inline bool T_Character::isAlpha( ) const
{
return isUppercase( ) || isLowercase( );
}
inline bool T_Character::isNumeric( ) const
{
return codepoint >= '0' && codepoint <= '9';
}
inline bool T_Character::isAlphanumeric( ) const
{
return isAlpha( ) || isNumeric( );
}
inline bool T_Character::isWhitespace( ) const
{
return codepoint == 32 || codepoint == '\t'
|| codepoint == '\n' || codepoint == '\r';
}
/*----------------------------------------------------------------------------*/
inline bool T_Character::operator== ( T_Character const& other ) const
{
return codepoint == other.codepoint;
}
inline bool T_Character::operator!= ( T_Character const& other ) const
{
return codepoint != other.codepoint;
}
inline bool T_Character::operator< ( T_Character const& other ) const
{
return codepoint < other.codepoint;
}
inline bool T_Character::operator> ( T_Character const& other ) const
{
return codepoint > other.codepoint;
}
inline bool T_Character::operator<= ( T_Character const& other ) const
{
return codepoint <= other.codepoint;
}
inline bool T_Character::operator>= ( T_Character const& other ) const
{
return codepoint >= other.codepoint;
}
/*----------------------------------------------------------------------------*/
template< typename T , typename >
inline bool T_Character::operator== ( T other ) const
{
return codepoint == uint32_t( other );
}
template< typename T , typename >
inline bool T_Character::operator!= ( T other ) const
{
return codepoint != uint32_t( other );
}
template< typename T , typename >
inline bool T_Character::operator< ( T other ) const
{
return codepoint < uint32_t( other );
}
template< typename T , typename >
inline bool T_Character::operator<= ( T other ) const
{
return codepoint <= uint32_t( other );
}
template< typename T , typename >
inline bool T_Character::operator> ( T other ) const
{
return codepoint > uint32_t( other );
}
template< typename T , typename >
inline bool T_Character::operator>= ( T other ) const
{
return codepoint >= uint32_t( other );
}
/*----------------------------------------------------------------------------*/
inline T_Character::operator uint32_t ( ) const
{
return codepoint;
}
/*----------------------------------------------------------------------------*/
inline uint32_t T_Character::writeTo( char* output , uint32_t avail ) const
{
return UTF8PutCodepoint( output , avail , codepoint );
}
/*----------------------------------------------------------------------------*/
inline T_Character T_Character::toUpper( ) const
{
if ( isLowercase( ) ) {
return *this & (~0x20);
} else {
return *this;
}
}
inline T_Character T_Character::toLower( ) const
{
if ( isUppercase( ) ) {
return *this | 0x20;
} else {
return *this;
}
}
/*= A_StringData =============================================================*/
inline bool A_StringData::valid( ) const
{
return valid_;
}
inline char const* A_StringData::data( ) const
{
return data_;
}
inline uint32_t A_StringData::length( ) const
{
return length_;
}
inline uint32_t A_StringData::size( ) const
{
return size_;
}
/*= T_String =================================================================*/
inline T_String T_String::Pooled( char const* string )
{
return Pooled( string , strlen( string ) );
}
/*----------------------------------------------------------------------------*/
inline bool T_String::valid( ) const
{
return data_->valid( );
}
inline uint32_t T_String::size( ) const
{
return data_->size( );
}
inline uint32_t T_String::length( ) const
{
return data_->length( );
}
inline char const* T_String::data( ) const
{
return data_->data( );
}
inline T_String::operator bool ( ) const
{
return size( ) != 0;
}
inline bool T_String::operator! ( ) const
{
return size( ) == 0;
}
/*----------------------------------------------------------------------------*/
inline T_Character T_String::operator[] ( uint32_t index ) const
{
assert( index < length( ) );
char const* const d( data( ) );
return UTF8GetCodepoint( d + UTF8GetMemoryOffset( d , index ) );
}
inline T_String T_String::range( uint32_t start , uint32_t end ) const
{
if ( start > end ) {
return T_String( );
}
return substr( start , end == UINT32_MAX ? UINT32_MAX : ( end - start + 1 ) );
}
/*----------------------------------------------------------------------------*/
inline bool T_String::equals( T_String const& other ) const
{
return data_ == other.data_ || ( other.size( ) == size( )
&& ( size( ) == 0 || !memcmp( other.data( ) , data( ) , size( ) ) ) );
}
inline bool T_String::equals( char const* string ) const
{
const auto l( strlen( string ) );
return size( ) == l && ( l == 0 || !memcmp( string , data( ) , l ) );
}
/*----------------------------------------------------------------------------*/
inline bool T_String::operator== ( T_String const& other ) const
{
return equals( other );
}
inline bool T_String::operator!= ( T_String const& other ) const
{
return !equals( other );
}
inline bool T_String::operator< ( T_String const& other ) const
{
return compare( other ) < 0;
}
inline bool T_String::operator> ( T_String const& other ) const
{
return compare( other ) > 0;
}
inline bool T_String::operator>= ( T_String const& other ) const
{
return compare( other ) >= 0;
}
inline bool T_String::operator<= ( T_String const& other ) const
{
return compare( other ) <= 0;
}
/*----------------------------------------------------------------------------*/
inline bool T_String::operator== ( char const* string ) const
{
return equals( string );
}
inline bool T_String::operator!= ( char const* string ) const
{
return !equals( string );
}
/*----------------------------------------------------------------------------*/
inline int64_t T_String::toInteger( bool * ok , int base , bool useSep ,
T_Character separator ) const
{
return UTF8ToInteger( data( ) , size( ) , ok , base , useSep , separator );
}
inline uint64_t T_String::toUnsignedInteger( bool * ok , int base , bool useSep ,
T_Character separator ) const
{
return UTF8ToUnsignedInteger( data( ) , size( ) , ok , base , useSep , separator );
}
inline double T_String::toDouble( bool * ok , T_Character decimalPoint ,
bool useSep , T_Character separator ) const
{
return UTF8ToDouble( data( ) , size( ) , ok , decimalPoint , useSep , separator );
}
/*----------------------------------------------------------------------------*/
inline T_StringIterator T_String::getIterator( uint32_t offset ) const
{
if ( offset >= data_->size( ) ) {
return T_StringIterator( nullptr , 0 );
}
return T_StringIterator( data_ , offset );
}
inline T_String::operator T_StringIterator( ) const
{
return getIterator( 0 );
}
/*= T_String helpers =========================================================*/
inline M_DEFINE_HASH( T_String )
{
return HashData(
reinterpret_cast< uint8_t const* >( item.data( ) ) ,
item.size( ) );
}
inline M_DEFINE_COMPARATOR( T_String )
{
return a.compare( b );
}
/*= T_StringIterator =========================================================*/
inline T_StringIterator::T_StringIterator( T_StringIterator&& other ) noexcept
: data_( other.data_ ) , pos_( other.pos_ ) ,
index_( other.index_ ) ,
codepoint_( other.codepoint_ ) ,
bytes_( other.bytes_ )
{
other.data_ = nullptr;
}
inline T_StringIterator& T_StringIterator::operator= ( T_StringIterator&& other ) noexcept
{
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
inline uint32_t T_StringIterator::index( ) const
{
return index_;
}
inline bool T_StringIterator::atEnd( ) const
{
return data_ == nullptr || pos_ == data_->size( );
}
/*----------------------------------------------------------------------------*/
inline T_Character T_StringIterator::character( ) const
{
return codepoint_;
}
inline T_StringIterator::operator T_Character ( ) const
{
return codepoint_;
}
/*= T_StringBuilder ==========================================================*/
inline T_StringBuilder::T_StringBuilder( ) noexcept
: data_( nullptr ) , capacity_( 0 ) , size_( 0 ) , length_( 0 )
{ }
inline T_StringBuilder::T_StringBuilder( char const* string )
: T_StringBuilder( string , strlen( string ) )
{ }
/*----------------------------------------------------------------------------*/
inline char const* T_StringBuilder::data( ) const
{
return data_;
}
inline uint32_t T_StringBuilder::capacity( ) const
{
return capacity_;
}
inline uint32_t T_StringBuilder::size( ) const
{
return size_;
}
inline uint32_t T_StringBuilder::length( ) const
{
return length_;
}
inline T_StringBuilder::operator bool ( ) const
{
return size_ != 0;
}
inline bool T_StringBuilder::operator! ( ) const
{
return size_ == 0;
}
/*----------------------------------------------------------------------------*/
inline T_StringBuilder& T_StringBuilder::clear( )
{
size_ = length_ = 0;
return *this;
}
/*----------------------------------------------------------------------------*/
inline bool T_StringBuilder::operator== ( T_StringBuilder const& other ) const
{
return other.size_ == size_ && ( size_ == 0 || !memcmp( other.data_ , data_ , size_ ) );
}
inline bool T_StringBuilder::operator!= ( T_StringBuilder const& other ) const
{
return other.size_ != size_ || ( size_ != 0 && memcmp( other.data_ , data_ , size_ ) );
}
/*----------------------------------------------------------------------------*/
inline bool T_StringBuilder::operator== ( T_String const& string ) const
{
return string.size( ) == size_ && ( size_ == 0 || !memcmp( string.data( ) , data_ , size_ ) );
}
inline bool T_StringBuilder::operator!= ( T_String const& string ) const
{
return string.size( ) != size_ || ( size_ != 0 && memcmp( string.data( ) , data_ , size_ ) );
}
/*----------------------------------------------------------------------------*/
inline bool T_StringBuilder::operator== ( char const* string ) const
{
return strlen( string ) == size_ && ( size_ == 0 || !memcmp( string , data_ , size_ ) );
}
inline bool T_StringBuilder::operator!= ( char const* string ) const
{
return strlen( string ) != size_ || ( size_ != 0 && memcmp( string , data_ , size_ ) );
}
/*----------------------------------------------------------------------------*/
inline int64_t T_StringBuilder::toInteger( bool * ok , int base , bool useSep ,
T_Character separator ) const
{
return UTF8ToInteger( data_ , size_ , ok , base , useSep , separator );
}
inline uint64_t T_StringBuilder::toUnsignedInteger( bool * ok , int base , bool useSep ,
T_Character separator ) const
{
return UTF8ToUnsignedInteger( data_ , size_ , ok , base , useSep , separator );
}
inline double T_StringBuilder::toDouble( bool * ok , T_Character decimalPoint ,
bool useSep , T_Character separator ) const
{
return UTF8ToDouble( data( ) , size( ) , ok , decimalPoint , useSep , separator );
}
/*----------------------------------------------------------------------------*/
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_StringBuilder const& value )
{
return sb.append( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_StringBuilder&& value )
{
return sb.append( std::move( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_String const& value )
{
return sb.append( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , char const* value )
{
return sb.append( value , strlen( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , char value )
{
return sb.append( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_Character value )
{
return sb.append( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int16_t value )
{
return sb.appendNumeric( int64_t( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int32_t value )
{
return sb.appendNumeric( int64_t( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int64_t value )
{
return sb.appendNumeric( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint16_t value )
{
return sb.appendNumeric( uint64_t( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint32_t value )
{
return sb.appendNumeric( uint64_t( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint64_t value )
{
return sb.appendNumeric( value );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , float value )
{
return sb.appendDouble( double( value ) );
}
inline T_StringBuilder& operator<< ( T_StringBuilder& sb , double value )
{
return sb.appendDouble( value );
}
} // namespace
#endif // _H_LW_LIB_INLINE_STRINGS

View file

@ -0,0 +1,352 @@
/******************************************************************************/
/* THREADING - INLINE CODE ****************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_THREADING
#define _H_LW_LIB_INLINE_THREADING
#include <lw/lib/Threading.hh>
namespace lw {
/*= T_ReadWriteMutex =========================================================*/
inline T_ReadWriteMutex::T_ReadWriteMutex( )
: state_( 0 )
{ }
inline T_ReadWriteMutex::~T_ReadWriteMutex( )
{
assert( state_ == 0 );
}
/*----------------------------------------------------------------------------*/
inline void T_ReadWriteMutex::lock( )
{
T_ExclusiveLock lock( mutex_ );
writerBlock_.wait( lock , [this]( ) {
return ( state_ & C_WLOCKED_ ) == 0;
} );
state_ |= C_WLOCKED_;
readerBlock_.wait( lock , [this]( ) {
return ( state_ & C_READERS_ ) == 0;
} );
}
inline bool T_ReadWriteMutex::try_lock( )
{
T_ExclusiveLock lock( mutex_ , std::try_to_lock );
if ( lock.owns_lock( ) && state_ == 0 ) {
state_ = C_WLOCKED_;
return true;
}
return false;
}
inline void T_ReadWriteMutex::unlock( )
{
T_ScopeLock lock( mutex_ );
assert( ( state_ & C_WLOCKED_ ) != 0 );
state_ = 0;
writerBlock_.notify_all( );
}
/*----------------------------------------------------------------------------*/
inline void T_ReadWriteMutex::lock_shared( )
{
T_ExclusiveLock lock( mutex_ );
writerBlock_.wait( lock , [this]( ) {
return state_ < C_READERS_;
} );
state_ ++;
}
inline bool T_ReadWriteMutex::try_lock_shared( )
{
T_ExclusiveLock lock( mutex_ , std::try_to_lock );
if ( !lock.owns_lock( ) && state_ < C_READERS_ ) {
state_ ++;
return true;
}
return false;
}
inline void T_ReadWriteMutex::unlock_shared( )
{
T_ScopeLock lock( mutex_ );
assert( ( state_ & C_READERS_ ) != 0 );
auto previous( state_ -- );
if ( previous == ( C_WLOCKED_ & 1 ) ) {
readerBlock_.notify_one( );
} else if ( previous == C_READERS_ ) {
writerBlock_.notify_one( );
}
}
/*----------------------------------------------------------------------------*/
inline void T_ReadWriteMutex::upgradeLock( )
{
T_ExclusiveLock lock( mutex_ );
assert( ( state_ & C_READERS_ ) != 0 );
state_ --;
writerBlock_.wait( lock , [this]( ) {
return ( state_ & C_WLOCKED_ ) == 0;
} );
state_ |= C_WLOCKED_;
readerBlock_.wait( lock , [this]( ) {
return ( state_ & C_READERS_ ) == 0;
} );
}
/*= T_ReadLock ===============================================================*/
inline T_ReadLock::T_ReadLock( ) noexcept
: std::shared_lock< T_ReadWriteMutex >( )
{ }
inline T_ReadLock::T_ReadLock( T_ReadLock&& other )
: std::shared_lock< T_ReadWriteMutex >( std::move( other ) )
{ }
inline T_ReadLock::T_ReadLock( T_ReadWriteMutex& m )
: std::shared_lock< T_ReadWriteMutex >( m )
{ }
inline T_ReadLock::T_ReadLock( T_ReadWriteMutex& m , std::defer_lock_t t )
: std::shared_lock< T_ReadWriteMutex >( m , t )
{ }
inline T_ReadLock::T_ReadLock( T_ReadWriteMutex& m , std::try_to_lock_t t )
: std::shared_lock< T_ReadWriteMutex >( m , t )
{ }
inline T_ReadLock::T_ReadLock( T_ReadWriteMutex& m , std::adopt_lock_t t )
: std::shared_lock< T_ReadWriteMutex >( m , t )
{ }
/*----------------------------------------------------------------------------*/
inline T_WriteLock T_ReadLock::upgrade( )
{
assert( owns_lock( ) );
RP_ReadWriteMutex mutex( release( ) );
mutex->upgradeLock( );
return T_WriteLock( *mutex , std::adopt_lock );
}
/*= T_RingBuffer =============================================================*/
template< typename T >
inline T_RingBuffer< T >::T_RingBuffer( uint32_t expand )
: expand_( expand ) , data_( nullptr ) , allocated_( 0 ) ,
used_( 0 ) , readPos_( 0 )
{
assert( expand );
}
template< typename T >
inline T_RingBuffer< T >::T_RingBuffer( T_RingBuffer< T > const& other )
: expand_( other.expand_ ) , allocated_( other.allocated_ ) ,
used_( other.used_ ) , readPos_( 0 )
{
if ( allocated_ ) {
data_ = reinterpret_cast< T* >( ::operator new( sizeof( T ) * allocated_ ) );
for ( uint32_t i = 0 ; i < other.used_ ; i ++ ) {
const auto sidx( ( i + other.readPos_ ) % allocated_ );
new ( reinterpret_cast< char* >( &data_[ i ] ) ) T( other.data_[ sidx ] );
}
} else {
data_ = nullptr;
}
}
template< typename T >
inline T_RingBuffer< T >::T_RingBuffer( T_RingBuffer< T >&& other ) noexcept
: T_RingBuffer( other.growth( ) )
{
swap( *this , other );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_RingBuffer< T >::~T_RingBuffer( )
{
free( );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline T_RingBuffer< T >& T_RingBuffer< T >::operator =( T_RingBuffer< T > const& other )
{
free( );
expand_ = other.expand_;
allocated_ = other.allocated_;
used_ = other.used_;
readPos_ = 0;
if ( allocated_ ) {
data_ = reinterpret_cast< T* >( ::operator new( sizeof( T ) * allocated_ ) );
for ( uint32_t i = 0 ; i < other.used_ ; i ++ ) {
const auto sidx( ( i + other.readPos_ ) % allocated_ );
new ( reinterpret_cast< char* >( &data_[ i ] ) ) T( other.data_[ sidx ] );
}
}
return *this;
}
template< typename T >
inline T_RingBuffer< T >& T_RingBuffer< T >::operator =( T_RingBuffer< T >&& other ) noexcept
{
free( );
expand_ = other.expand_;
swap( *this , other );
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void swap( T_RingBuffer< T >& lhs , T_RingBuffer< T >& rhs ) noexcept
{
using std::swap;
swap( lhs.expand_ , rhs.expand_ );
swap( lhs.data_ , rhs.data_ );
swap( lhs.allocated_ , rhs.allocated_ );
swap( lhs.used_ , rhs.used_ );
swap( lhs.readPos_ , rhs.readPos_ );
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_RingBuffer< T >::free( )
{
for ( uint32_t i = 0 ; i < used_ ; i ++ ) {
const auto idx( ( readPos_ + i ) % allocated_ );
data_[ idx ].~T( );
}
::operator delete( (void*) data_ );
data_ = nullptr;
allocated_ = 0;
used_ = 0;
readPos_ = 0;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline uint32_t T_RingBuffer< T >::size( ) const
{
return used_;
}
template< typename T >
inline uint32_t T_RingBuffer< T >::capacity( ) const
{
return allocated_;
}
template< typename T >
inline uint32_t T_RingBuffer< T >::growth( ) const
{
return expand_;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline bool T_RingBuffer< T >::readNext( T& output )
{
if ( used_ == 0 ) {
return false;
}
output = std::move( data_[ readPos_ ] );
data_[ readPos_ ].~T( );
readPos_ = ( readPos_ + 1 ) % allocated_;
used_ --;
return true;
}
template< typename T >
inline bool T_RingBuffer< T >::readAll( T_Array< T >& output )
{
if ( used_ == 0 ) {
return false;
}
for ( uint32_t i = 0 ; i < used_ ; i ++ ) {
output.add( std::move( data_[ ( readPos_ + i ) % allocated_ ] ) );
}
for ( uint32_t i = 0 ; i < used_ ; i ++ ) {
data_[ ( readPos_ + i ) % allocated_ ].~T( );
}
used_ = 0;
return true;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_RingBuffer< T >::put( T const& input )
{
if ( used_ == allocated_ ) {
expand( );
}
const auto idx( ( readPos_ + used_ ) % allocated_ );
new ( reinterpret_cast< char* >( &data_[ idx ] ) ) T( input );
used_ ++;
}
template< typename T >
inline void T_RingBuffer< T >::put( T&& input )
{
if ( used_ == allocated_ ) {
expand( );
}
const auto idx( ( readPos_ + used_ ) % allocated_ );
new ( reinterpret_cast< char* >( &data_[ idx ] ) ) T( std::move( input ) );
used_ ++;
}
template< typename T >
template< typename... ArgTypes >
inline void T_RingBuffer< T >::putNew( ArgTypes&&... arguments )
{
if ( used_ == allocated_ ) {
expand( );
}
const auto idx( ( readPos_ + used_ ) % allocated_ );
new ( reinterpret_cast< char* >( &data_[ idx ] ) ) T( std::forward< ArgTypes >( arguments ) ... );
used_ ++;
}
/*----------------------------------------------------------------------------*/
template< typename T >
inline void T_RingBuffer< T >::expand( )
{
const auto nsz( allocated_ + expand_ );
T* nData( reinterpret_cast< T* >( ::operator new( sizeof( T ) * nsz ) ) );
for ( uint32_t i = 0 ; i < used_ ; i ++ ) {
const auto idx( ( readPos_ + i ) % allocated_ );
new( reinterpret_cast< char* >( &nData[ i ] ) ) T( std::move( data_[ idx ] ) );
data_[ idx ].~T( );
}
using std::swap;
swap( data_ , nData );
allocated_ = nsz;
readPos_ = 0;
::operator delete( (void*) nData );
}
}
#endif // _H_LW_LIB_INLINE_THREADING

1000
include/ebcl/inline/Types.hh Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,303 @@
/******************************************************************************/
/* 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