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

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.vim.local/signature
.vim.local/data
output/*

View file

@ -0,0 +1 @@
let g:ycm_global_ycm_extra_conf = g:vim_local_path . "/ycm_extra_conf.py"

View file

@ -0,0 +1 @@
NeoBundle "Valloric/YouCompleteMe"

View file

@ -0,0 +1,2 @@
let g:uncrustify_cfg_file_path = g:vim_local_path . "/../coding-style-uncrustify.cfg"

View file

@ -0,0 +1 @@
NeoBundle "cofyc/vim-uncrustify"

View file

@ -0,0 +1,42 @@
let g:vimmake_path = g:vim_local_path . 'scripts'
let g:vimmake_mode = {}
let g:vimmake_mode['clean'] = 'async'
let g:vimmake_mode['build'] = 'async'
let g:vimmake_mode['rebuild'] = 'async'
let g:vimmake_mode['test'] = 'async'
function! DoBuild(full)
silent call vimmake#toggle_quickfix(12,1)
if a:full == 0
VimTool build
else
VimTool rebuild
endif
endfunc
function! KillBuild()
silent call vimmake#toggle_quickfix(0)
VimStop
endfunc
function! RunTest()
silent call vimmake#toggle_quickfix(12,1)
VimTool test
endfunc
augroup QuickfixStatus
au! BufWinEnter quickfix setlocal
\ statusline=%t\ [%{g:vimmake_build_status}]\ %{exists('w:quickfix_title')?\ '\ '.w:quickfix_title\ :\ ''}\ %=%-15(%l,%c%V%)\ %P
augroup END
noremap <F12> :silent call vimmake#toggle_quickfix(12)<cr>
inoremap <F12> <esc>:silent call vimmake#toggle_quickfix(12)<cr>li
noremap <F10> :silent call DoBuild(0)<cr>
inoremap <F10> <esc>:silent call DoBuild(0)<cr>li
noremap <S-F10> :silent call DoBuild(1)<cr>
inoremap <S-F10> <esc>:silent call DoBuild(1)<cr>li
noremap <C-F10> :silent call KillBuild()<cr>
inoremap <C-F10> <esc>:silent call KillBuild()<cr>li
noremap <F11> :silent call RunTest()<cr>
inoremap <F11> <esc>:silent call RunTest()<cr>li

View file

@ -0,0 +1 @@
NeoBundle 'skywind3000/vimmake'

View file

@ -0,0 +1,3 @@
setlocal colorcolumn=121
noremap <buffer> <C-f> :call Uncrustify('cpp')<CR>
vnoremap <buffer> <C-f> :call RangeUncrustify('cpp')<CR>

1
.vim.local/ftplugin/srd.vim Symbolic link
View file

@ -0,0 +1 @@
../../data/srd-ftplugin.vim

View file

@ -0,0 +1,2 @@
#!/bin/sh
make -j 8 all

View file

@ -0,0 +1,2 @@
#!/bin/sh
make clean-extra

View file

@ -0,0 +1,3 @@
#!/bin/sh
make clean-extra
make -j 8 all

14
.vim.local/scripts/vimmake.test Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
if [ "$VIM_RELDIR" = "tests" ] && [ "$VIM_FILEEXT" = ".cc" ]; then
if make -j 8 all; then
if [ -f "output/fast/test-$VIM_FILENOEXT" ]; then
LD_LIBRARY_PATH=./output/fast \
./output/fast/test-$VIM_FILENOEXT 2>&1 \
| sed -e s/"$VIM_FILENAME"/'tests\/'"$VIM_FILENAME"/g
else
LD_LIBRARY_PATH=./output/fast \
./output/fast/run-all-tests 2>&1 \
| sed -e 's/^\([a-z\-]\+\.cc\)/tests\/\1/g'
fi
fi
fi

1
.vim.local/syntax/srd.vim Symbolic link
View file

@ -0,0 +1 @@
../../data/srd-syntax.vim

7
.vim.local/vimrc Normal file
View file

@ -0,0 +1,7 @@
let g:vim_local = {
\ "vardata" : g:vim_local_path . "/data"
\ }
au BufNewFile,BufRead *.srd setf srd
"let &wildignore=&wildignore . ',glef.c,glef.h'

View file

@ -0,0 +1,143 @@
# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-std=c++14',
'-x',
'c++',
'-I' ,
'./include'
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.dirname( os.path.abspath( __file__ ) ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return { 'flags': final_flags }

240
include/ebcl/Alloc.hh Normal file
View file

@ -0,0 +1,240 @@
/******************************************************************************/
/* ALLOCATORS *****************************************************************/
/******************************************************************************/
#ifndef _H_EBCL_ALLOC
#define _H_EBCL_ALLOC
#include <lw/lib/Config.hh>
#include <lw/lib/Utilities.hh>
#include <atomic>
namespace lw {
/* Helpers for pool allocators. */
struct T_PoolHelper
{
/* Storage type for an object */
template<
size_t ObjectSize ,
size_t ObjectAlign
> using T_Object = std::aligned_storage_t< ObjectSize , ObjectAlign >;
/* List of object storage items. The storage type is assumed to
* have a void* field called list.
*/
template<
typename T_Storage ,
size_t ListSize
> struct T_List final
{
static constexpr size_t BitmapSize
= ( ListSize / 8 ) + ( ListSize % 8 ? 1 : 0 );
using T_Self = T_List< T_Storage , ListSize >;
T_Storage storage[ ListSize ]; // Stored data
T_Self* next; // Next list in chain
size_t free; // Free objects
uint8_t bitmap[ BitmapSize ]; // Allocation map
T_List( ) = delete;
T_List( T_Self const& ) = delete;
T_List( T_Self&& ) = delete;
// Create a new list, replacing the chain's head
explicit T_List( T_Self*& head ) noexcept;
// Find an unused item in the list. The list must have free
// items.
T_Storage* findUnused( ) noexcept;
// Find the index of an item. The item must be part of the list.
size_t indexOf( T_Storage const* item ) noexcept;
// Destroy a complete chain of lists
static void destroy( T_Self*& head ) noexcept;
};
/* The core of a pool allocator */
template<
typename T_Storage ,
size_t PerList ,
size_t MaxFreeLists
> struct T_Allocator final
{
static_assert( PerList > 1 , "allocator lists must contain at least 2 items" );
static_assert( MaxFreeLists > 0 , "allocator must have at least 1 free list" );
using T_List_ = T_List< T_Storage , PerList >;
using T_Self = T_Allocator< T_Storage , PerList , MaxFreeLists >;
// The chains
T_List_* free_;
T_List_* partial_;
T_List_* full_;
size_t nFree_;
T_Allocator( ) noexcept;
~T_Allocator( );
T_Allocator( T_Self const& ) = delete;
T_Allocator( T_Self&& ) = delete;
/* Allocate an object. */
T_Storage* allocate( ) noexcept;
/* Free an object */
void free( T_Storage* item ) noexcept;
/* Get the amount of lists. Mostly used for testing. */
size_t countFreeLists( ) const noexcept;
size_t countPartialLists( ) const noexcept;
size_t countFullLists( ) const noexcept;
/* Get the amount of total, free and used objects */
void getUsage( size_t& total ,
size_t& free ,
size_t& used ) const noexcept;
private:
/* Move a list of objects from one of the allocation lists to another. */
static void moveList(
T_List_* list ,
T_List_*& from ,
T_List_*& to ) noexcept;
/* Count the amount of lists in an allocation list */
static size_t countLists(
T_List_ const* head ) noexcept;
};
};
/*============================================================================*/
/* The pool allocator implements a thread-unsafe pool of objects, similar to a
* slab allocator.
*/
template<
size_t ObjectSize , size_t ObjectAlign ,
size_t PerList = std::max( size_t( 8 ) , 4096u / ObjectSize ) ,
size_t MaxFreeLists = 4
>
class T_PoolAllocator
{
public:
using T_Self = T_PoolAllocator< ObjectSize , ObjectAlign , PerList , MaxFreeLists >;
private:
// Structure that stores a single allocated item
struct T_Storage_ final
{
T_PoolHelper::T_Object< ObjectSize , ObjectAlign > data;
void* list;
};
using T_Alloc_ = T_PoolHelper::T_Allocator< T_Storage_ , PerList , MaxFreeLists >;
T_Alloc_ alloc_;
public:
T_PoolAllocator( ) noexcept = default;
T_PoolAllocator( T_Self const& ) = delete;
T_PoolAllocator( T_Self&& ) = delete;
/* Allocate an object. */
void* allocate( size_t requested ) noexcept;
/* Free an object */
void free( void* item ) noexcept;
/* Get the amount of lists. Mostly used for testing. */
size_t countFreeLists( ) const noexcept;
size_t countPartialLists( ) const noexcept;
size_t countFullLists( ) const noexcept;
/* Get the amount of total, free and used objects */
void getUsage( size_t& total ,
size_t& free ,
size_t& used ) const noexcept;
};
/*============================================================================*/
/* Pool allocator with multithreading support. Allocation is performed from
* a thread-specific pool allocator; when the memory is freed, the memory is
* either returned directly to the pool if the freeing thread is the same as
* the allocating thread, or queued for the original thread to free later.
*/
template<
size_t ObjectSize , size_t ObjectAlign ,
size_t PerList = std::max( size_t( 8 ) , 4096u / ObjectSize ) ,
size_t MaxFreeLists = 4
>
class T_ThreadedPoolAllocator
{
public:
using T_Self = T_ThreadedPoolAllocator<
ObjectSize , ObjectAlign , PerList , MaxFreeLists >;
private:
// Pointer to either the owning pool or the next object in the
// pending list
struct T_Storage_;
union T_ExtraPointer_
{
T_Storage_* next;
T_Self* pool;
};
// Structure that stores a single allocated item
struct T_Storage_ final
{
T_PoolHelper::T_Object< ObjectSize , ObjectAlign > data;
void* list;
T_ExtraPointer_ extra;
};
// The head for the "remote" freeing stack
struct T_FreeHead_ final
{
uintptr_t aba{ 0 };
T_Storage_* head{ nullptr };
};
// Atomic stack head, plus padding to prevent false sharing between
// the stack head and the actual allocator.
char padding_0_[ 64 ];
std::atomic< T_FreeHead_ > freeHead_;
char padding_1_[ 64 - sizeof( std::atomic< T_FreeHead_ > ) ];
using T_Alloc_ = T_PoolHelper::T_Allocator<
T_Storage_ , PerList , MaxFreeLists >;
T_Alloc_ alloc_;
public:
T_ThreadedPoolAllocator( ) noexcept = default;
T_ThreadedPoolAllocator( T_Self const& ) = delete;
T_ThreadedPoolAllocator( T_Self&& ) = delete;
/* Allocate an object. */
void* allocate( size_t requested ) noexcept;
/* Free an object */
void free( void* item ) noexcept;
/* Get the amount of lists. Mostly used for testing. */
size_t countFreeLists( ) const noexcept;
size_t countPartialLists( ) const noexcept;
size_t countFullLists( ) const noexcept;
/* Get the amount of total, free and used objects */
void getUsage( size_t& total ,
size_t& free ,
size_t& used ) const noexcept;
private:
// Try to take an item from the stack.
T_Storage_* takeFromStack( ) noexcept;
// Add an item to the stack
void addToStack( T_Storage_* item ) noexcept;
};
}
#endif //_H_EBCL_ALLOC
#include <lw/lib/inline/Alloc.hh>

446
include/ebcl/Arrays.hh Normal file
View file

@ -0,0 +1,446 @@
/******************************************************************************/
/* ARRAYS *********************************************************************/
/******************************************************************************/
#ifndef _H_EBCL_ARRAYS
#define _H_EBCL_ARRAYS
#include <lw/lib/Externals.hh>
#include <lw/lib/Pointers.hh>
#include <lw/lib/Utilities.hh>
#include <lw/lib/Types.hh>
namespace lw {
/*= DYNAMIC ARRAYS ===========================================================*/
template< class T >
class T_Array final
{
public:
static constexpr uint32_t DEFAULT_GROWTH( )
{
return std::max< uint32_t >( 1 , 4096 / sizeof( T ) );
}
private:
typedef T_Array< T > MyType_;
T* data_;
uint32_t capacity_;
uint32_t size_;
uint32_t growth_;
public:
M_TEMPLATE_POINTERS( MyType_ );
T_Array( ) noexcept;
explicit T_Array( uint32_t growth ) noexcept;
// ---------------------------------------------------------------------
T_Array( MyType_ const& source ) noexcept;
MyType_& operator= ( MyType_ const& other ) noexcept;
T_Array( MyType_&& source ) noexcept;
MyType_& operator= ( MyType_&& other ) noexcept;
template< typename TP >
friend void swap( T_Array< TP >& lhs ,
T_Array< TP >& rhs ) noexcept;
// ---------------------------------------------------------------------
~T_Array( );
MyType_& clear( ) noexcept;
MyType_& free( ) noexcept;
// ---------------------------------------------------------------------
uint32_t capacity( ) const noexcept;
uint32_t size( ) const noexcept;
uint32_t growth( ) const noexcept;
MyType_& ensureCapacity( uint32_t capacity ) noexcept;
// ---------------------------------------------------------------------
T& operator[] ( uint32_t index ) noexcept;
T const& operator[] ( uint32_t index ) const noexcept;
int32_t indexOf( T const& item ) const noexcept;
bool contains( T const& item ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( T const& item ) noexcept;
uint32_t add( T&& item ) noexcept;
template< typename... Args >
T& addNew( Args&& ... args );
// ---------------------------------------------------------------------
MyType_& addAll( MyType_ const& other ) noexcept;
MyType_& addAll( MyType_&& other ) noexcept;
// ---------------------------------------------------------------------
MyType_& operator<< ( T const& item ) noexcept;
MyType_& operator<< ( T&& item ) noexcept;
MyType_& operator<< ( MyType_ const& other ) noexcept;
MyType_& operator<< ( MyType_&& other ) noexcept;
// ---------------------------------------------------------------------
void insert( uint32_t index ,
T const& item ) noexcept;
void insert( uint32_t index ,
T&& item ) noexcept;
template< typename... Args >
T& insertNew( uint32_t index ,
Args&& ... args );
// ---------------------------------------------------------------------
void remove( uint32_t index ) noexcept;
void removeSwap( uint32_t index ) noexcept;
// ---------------------------------------------------------------------
void sort( F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
void sort( uint32_t first ,
uint32_t items ,
F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
// ---------------------------------------------------------------------
MyType_ copyRange( uint32_t first ,
uint32_t last = UINT32_MAX ) const noexcept;
MyType_ moveRange( uint32_t first ,
uint32_t last = UINT32_MAX ) noexcept;
};
// Instantiate some common types directly
extern template class T_Array< uint32_t >;
/*= STATICALLY ALLOCATED ARRAYS ==============================================*/
/* These arrays offer the same interface as dynamic arrays, but are in fact
* implemented as in-place storage.
*/
template< typename Type , uint32_t Size >
class T_StaticArray final
{
static_assert( Size > 0 , "Size must be greater than 0" );
public:
using T_Self = T_StaticArray< Type , Size >;
private:
// Actual storage type
using T_Storage_ = std::aligned_storage_t<
sizeof( Type ) , alignof( Type )
>;
T_Storage_ storage_[ Size ];
uint32_t size_;
public:
M_TEMPLATE_POINTERS( T_Self );
T_StaticArray( ) noexcept;
// Copy
T_StaticArray( T_Self const& source ) noexcept;
T_Self& operator= ( T_Self const& other ) noexcept;
// Move
T_StaticArray( T_Self&& source ) noexcept;
T_Self& operator= ( T_Self&& other ) noexcept;
~T_StaticArray( ) noexcept;
T_Self& clear( ) noexcept;
template< typename T , uint32_t S >
friend void swap(
T_StaticArray< T , S >& lhs ,
T_StaticArray< T , S >& rhs ) noexcept;
// ---------------------------------------------------------------------
constexpr uint32_t capacity( ) const noexcept;
uint32_t size( ) const noexcept;
// ---------------------------------------------------------------------
Type& operator[] ( uint32_t index ) noexcept;
Type const& operator[] ( uint32_t index ) const noexcept;
int32_t indexOf( Type const& item ) const noexcept;
bool contains( Type const& item ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( Type&& item ) noexcept;
uint32_t add( Type const& item ) noexcept;
template< typename... Args >
Type& addNew( Args&& ... args );
// ---------------------------------------------------------------------
T_Self& addAll( T_Self const& other ) noexcept;
T_Self& addAll( T_Self&& other ) noexcept;
// ---------------------------------------------------------------------
T_Self& operator<< ( Type const& item ) noexcept;
T_Self& operator<< ( Type&& item ) noexcept;
T_Self& operator<< ( T_Self const& other ) noexcept;
T_Self& operator<< ( T_Self&& other ) noexcept;
// ---------------------------------------------------------------------
void insert( uint32_t index ,
Type&& item ) noexcept;
void insert( uint32_t index ,
Type const& item ) noexcept;
template< typename... Args >
Type& insertNew( uint32_t index ,
Args&& ... args );
// ---------------------------------------------------------------------
void remove( uint32_t index ) noexcept;
void removeSwap( uint32_t index ) noexcept;
// ---------------------------------------------------------------------
void sort( F_Comparator< Type > cmp = T_Comparator< Type >::compare ) noexcept;
void sort( uint32_t first ,
uint32_t items ,
F_Comparator< Type > cmp = T_Comparator< Type >::compare ) noexcept;
// ---------------------------------------------------------------------
T_Self copyRange( uint32_t first ,
uint32_t last = UINT32_MAX ) const noexcept;
T_Self moveRange( uint32_t first ,
uint32_t last = UINT32_MAX ) noexcept;
};
/*= MULTI-ARRAYS ============================================================-*/
/*
* Arrays that allow storing multiple values for one entry. Values must be
* added in order.
*/
template< typename T >
class T_MultiArray
{
public:
using T_Data = T_Array< T >;
private:
typedef T_MultiArray< T > MyType_;
T_Array< uint32_t > meta_;
T_Data values_;
public:
M_TEMPLATE_POINTERS( T_MultiArray );
template< typename TP >
friend void swap( T_MultiArray< TP >& lhs , T_MultiArray< TP >& rhs );
// Start the next entry
void next( );
// Add a value to the current entry
void add( T value );
// Add a value, calling its constructor
template<
typename Q = T ,
typename... Args ,
typename = std::enable_if_t< std::is_class< Q >::value >
>
Q& addNew( Args&& ... args );
// Copy an array's contents into the current entry
void copyFrom( T_Data const& source );
// Returns the amount of entries
uint32_t size( ) const;
// Returns the index of the first value for an entry
uint32_t firstOf( uint32_t item ) const;
// Returns the amount of values for an entry
uint32_t sizeOf( uint32_t item ) const;
// Access a value in an entry
T const& get( uint32_t item , uint32_t sub ) const;
T& get( uint32_t item , uint32_t sub );
// Access a value using its index
T const& operator[] ( uint32_t index ) const;
T& operator[] ( uint32_t index );
// Is a value present in an entry?
bool contains( uint32_t index , T const& value ) const;
// Reset storage, don't free memory
void clear( );
// Reset storage and free memory
void free( );
// Copy values from an entry into the current entry
void copyFrom( uint32_t index );
// Copy another multi-array's entry into the current entry
void copyFrom( MyType_ const& other , uint32_t index );
// Copy values from another entry into the current entry if
// they are not already present. Duplicate entries in the
// source array are still copied, though.
void copyUnique( uint32_t index );
// Copy another multi-array's entry into the current entry,
// ignoring values that are already present. Duplicates in
// the source array are still copied.
void copyUnique( MyType_ const& other , uint32_t index );
// Sort an entry's values
void sort( uint32_t index , F_Comparator< T > cmp = T_Comparator< T >::compare );
};
// Instantiate some common types directly
extern template class T_MultiArray< uint32_t >;
/*= AUTOMATIC ARRAYS =========================================================*/
/* Arrays that are stored in-place up to some limit, then transform into
* dynamic arrays if necessary.
*/
template<
typename T , uint32_t StaticSize ,
uint32_t DynamicGrowth = StaticSize * 4
> class T_AutoArray
{
public:
using T_Self = T_AutoArray< T , StaticSize , DynamicGrowth >;
private:
using T_Static_ = T_StaticArray< T , StaticSize >;
using T_Dynamic_ = T_Array< T >;
T_Union< T_Static_ , T_Dynamic_ > array_;
// ---------------------------------------------------------------------
public:
M_TEMPLATE_POINTERS( T_Self );
T_AutoArray( ) noexcept;
T_AutoArray( T_Self const& source ) noexcept;
T_Self& operator =( T_Self const& source ) noexcept;
T_AutoArray( T_Self&& source ) noexcept;
T_Self& operator =( T_Self&& source ) noexcept;
// ---------------------------------------------------------------------
template< typename TP , uint32_t S , uint32_t G >
friend void swap(
T_AutoArray< TP , S , G >& lhs ,
T_AutoArray< TP , S , G >& rhs ) noexcept;
// ---------------------------------------------------------------------
T_Self& clear( ) noexcept;
T_Self& free( ) noexcept;
// ---------------------------------------------------------------------
uint32_t capacity( ) const noexcept;
uint32_t size( ) const noexcept;
constexpr uint32_t growth( ) const noexcept;
bool isStatic( ) const noexcept;
T_Self& ensureCapacity( uint32_t capacity ) noexcept;
// ---------------------------------------------------------------------
T& operator[] ( uint32_t index ) noexcept;
T const& operator[] ( uint32_t index ) const noexcept;
int32_t indexOf( T const& item ) const noexcept;
bool contains( T const& item ) const noexcept;
// ---------------------------------------------------------------------
uint32_t add( T const& item ) noexcept;
uint32_t add( T&& item ) noexcept;
template< typename... Args >
T& addNew( Args&& ... args );
// ---------------------------------------------------------------------
T_Self& addAll( T_Self const& other ) noexcept;
T_Self& addAll( T_Self&& other ) noexcept;
// ---------------------------------------------------------------------
T_Self& operator<< ( T const& item ) noexcept;
T_Self& operator<< ( T&& item ) noexcept;
T_Self& operator<< ( T_Self const& other ) noexcept;
T_Self& operator<< ( T_Self&& other ) noexcept;
// ---------------------------------------------------------------------
void insert( uint32_t index ,
T const& item ) noexcept;
void insert( uint32_t index ,
T&& item ) noexcept;
template< typename... Args >
T& insertNew( uint32_t index ,
Args&& ... args );
// ---------------------------------------------------------------------
void remove( uint32_t index ) noexcept;
void removeSwap( uint32_t index ) noexcept;
// ---------------------------------------------------------------------
void sort( F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
void sort( uint32_t first ,
uint32_t items ,
F_Comparator< T > cmp = T_Comparator< T >::compare ) noexcept;
// ---------------------------------------------------------------------
T_Self copyRange( uint32_t first ,
uint32_t last = UINT32_MAX ) const noexcept;
T_Self moveRange( uint32_t first ,
uint32_t last = UINT32_MAX ) noexcept;
// ---------------------------------------------------------------------
private:
void convertToDynamic_( uint32_t capacity ) noexcept;
T_Static_& static_( ) noexcept;
T_Static_ const& static_( ) const noexcept;
T_Dynamic_& dynamic_( ) noexcept;
T_Dynamic_ const& dynamic_( ) const noexcept;
};
}
#endif // _H_EBCL_ARRAYS
#include <lw/lib/inline/Arrays.hh>

View file

@ -0,0 +1,169 @@
/******************************************************************************/
/* BINARY READER/WRITER FOR STREAMS *******************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/Streams.hh>
namespace lw {
/*= OBJECT READER/WRITER TEMPLATES ===========================================*/
/*
* This pair of templates must be specialized to handle specific types.
*/
struct T_BinaryReader;
struct T_BinaryWriter;
template< typename T >
struct T_ObjectReader
{
static T read( T_BinaryReader const& reader );
};
template< typename T >
struct T_ObjectWriter
{
static void write( T_BinaryWriter const& writer , T const& string );
};
// Helper macros to declare and define readers and writers
#define M_DECLARE_OBJECT_READER( Type ) \
template< > \
struct T_ObjectReader< Type > \
{ \
static Type read( T_BinaryReader const& ); \
}
#define M_DEFINE_OBJECT_READER( Type ) \
Type T_ObjectReader< Type >::read( T_BinaryReader const & reader )
#define M_DECLARE_OBJECT_WRITER( Type ) \
template< > \
struct T_ObjectWriter< Type > \
{ \
static void write( T_BinaryWriter const& , \
Type const& ); \
}
#define M_DEFINE_OBJECT_WRITER( Type ) \
void T_ObjectWriter< Type >::write( T_BinaryWriter const & writer , \
Type const & item )
/*= READER ===================================================================*/
struct T_BinaryReader
{
private:
A_InputStream& stream_;
const E_Endian endian_;
public:
T_BinaryReader( ) = delete;
explicit T_BinaryReader( A_InputStream& stream , E_Endian endian = E_Endian::NATIVE ) noexcept;
T_BinaryReader( T_BinaryReader const& other ) noexcept = delete;
T_BinaryReader( T_BinaryReader&& other ) noexcept = delete;
A_InputStream& stream( ) const;
E_Endian endian( ) const;
template< typename T >
T readNumericNative( ) const;
template< typename T >
T readNumericLittleEndian( ) const;
template< typename T >
T readNumericBigEndian( ) const;
template< typename T >
T read( ) const;
private:
template<
typename T ,
bool IsNum = std::is_integral< T >::value
|| std::is_floating_point< T >::value
>
struct T_Reader_ { };
template< typename T >
struct T_Reader_< T , true >
{
static T read( T_BinaryReader const& reader );
};
template< typename T >
struct T_Reader_< T , false >
{
static T read( T_BinaryReader const& reader );
};
};
/*= WRITER ===================================================================*/
struct T_BinaryWriter
{
private:
A_OutputStream& stream_;
const E_Endian endian_;
public:
T_BinaryWriter( ) noexcept = delete;
explicit T_BinaryWriter( A_OutputStream& stream , E_Endian endian = E_Endian::NATIVE ) noexcept;
T_BinaryWriter( T_BinaryWriter const& other ) noexcept = delete;
T_BinaryWriter( T_BinaryWriter&& other ) noexcept = delete;
A_OutputStream& stream( ) const;
E_Endian endian( ) const;
template< typename T >
void writeNumericNative( T value ) const;
template< typename T >
void writeNumericLittleEndian( T const& value ) const;
template< typename T >
void writeNumericBigEndian( T const& value ) const;
template< typename T >
void write( T const& value ) const;
private:
template<
typename T ,
bool IsNum = std::is_integral< T >::value
|| std::is_floating_point< T >::value
>
struct T_Writer_ { };
template< typename T >
struct T_Writer_< T , true >
{
static void write( T_BinaryWriter const& writer , T value );
};
template< typename T >
struct T_Writer_< T , false >
{
static void write( T_BinaryWriter const& writer , T const& value );
};
};
}
#include <lw/lib/inline/BinaryStreams.hh>

104
include/ebcl/Buffers.hh Normal file
View file

@ -0,0 +1,104 @@
/******************************************************************************/
/* BUFFERS ********************************************************************/
/******************************************************************************/
/* Buffers can be used to manipulate raw data. No constructors or destructors
* will ever be called.
*
* Buffers are available in two flavors: fixed size (where the size of the
* buffer is a template argument) and dynamic (where the size can be changed).
*/
#pragma once
#include <lw/lib/Externals.hh>
namespace lw {
/*============================================================================*/
class T_BufferBase
{
protected:
uint8_t* data_;
T_BufferBase( ) = delete;
explicit T_BufferBase( uint8_t* buffer ) noexcept;
explicit T_BufferBase( size_t size );
T_BufferBase( T_BufferBase&& source ) noexcept;
public:
~T_BufferBase( );
friend void swap( T_BufferBase& lhs , T_BufferBase& rhs );
uint8_t * data( ) const;
};
/*============================================================================*/
template< size_t SIZE , class T >
class T_FixedBuffer : public T_BufferBase
{
private:
typedef T_FixedBuffer< SIZE , T > MyType_;
static constexpr size_t BYTES_ = SIZE * sizeof( T );
public:
T_FixedBuffer( );
T_FixedBuffer( MyType_&& source ) noexcept;
T_FixedBuffer( MyType_ const& source );
template< size_t SZ , typename TP >
friend void swap( T_FixedBuffer< SZ , TP >& lhs , T_FixedBuffer< SZ , TP >& rhs ) noexcept;
MyType_& operator= ( MyType_ const& other );
MyType_& operator= ( MyType_&& other ) noexcept;
size_t bytes( ) const;
T& operator[] ( size_t index );
T const& operator[] ( size_t index ) const;
MyType_& setAll( T const& value );
};
/*============================================================================*/
template< class T >
class T_Buffer : public T_BufferBase
{
private:
typedef T_Buffer< T > MyType_;
protected:
size_t size_;
public:
T_Buffer( ) noexcept;
T_Buffer( size_t size );
T_Buffer( T const* data , size_t size );
T_Buffer( MyType_ const& other );
T_Buffer( MyType_&& other ) noexcept;
MyType_& operator= ( MyType_ const& other );
MyType_& operator= ( MyType_&& other );
template< typename TP >
friend void swap( T_Buffer< TP >& lhs , T_Buffer< TP >& rhs ) noexcept;
size_t size( ) const;
size_t bytes( ) const;
T& operator[] ( size_t index );
T const& operator[] ( size_t index ) const;
MyType_& resize( size_t newSize );
MyType_& setAll( T const& value );
MyType_& copyAll( T const* data );
};
} // namespace
#include <lw/lib/inline/Buffers.hh>

25
include/ebcl/Config.hh Normal file
View file

@ -0,0 +1,25 @@
/******************************************************************************/
/* CONFIGURATION FOR THE BUILD ************************************************/
/******************************************************************************/
#ifndef _H_EBCL_CONFIG
#define _H_EBCL_CONFIG
/*= DEBUGGING OPTIONS ========================================================*/
/* Disable memory allocators */
//#define EBCL_CFG_NO_ALLOCATORS
/*= TUNING ===================================================================*/
/* Pool allocator parameters for shared pointer references */
#define EBCL_CFG_SHAREDPTR_REFPOOL_SIZE 512
#define EBCL_CFG_SHAREDPTR_REFPOOL_MAXFREE 2
/*----------------------------------------------------------------------------*/
#endif // _H_EBCL_CONFIG

48
include/ebcl/DynLib.hh Normal file
View file

@ -0,0 +1,48 @@
/******************************************************************************/
/* DYNAMIC LIBRARIES **********************************************************/
/******************************************************************************/
#ifndef _H_EBCL_DYNLIB
#define _H_EBCL_DYNLIB
#include <lw/lib/Strings.hh>
#include <lw/lib/Utilities.hh>
namespace lw {
/*= DYNAMIC LIBRARY SUPPORT ==================================================*/
class T_DynLib : public A_PrivateImplementation
{
public:
T_DynLib( ) = delete;
T_DynLib( T_DynLib const& ) = delete;
T_DynLib& operator =( T_DynLib const& ) = delete;
/* Initialise and set the name of the library to load */
explicit T_DynLib( T_String const& name );
explicit T_DynLib( char const* const name );
/* Load/unload the library */
bool load( );
void unload( );
/* Check whether the library has been loaded */
bool isLoaded( ) const noexcept;
/* Obtain the last error that was encoutered */
T_String lastError( ) const noexcept;
/* Symbol access. The library MUST be loaded. */
void* getRawSymbol( char const* name ) const noexcept;
template< typename T >
T* getPointer( char const* name ) const noexcept;
template< typename T >
std::function< T > getFunction(
char const* name ) const noexcept;
};
M_CLASS_POINTERS( DynLib );
} // namespace lw
#endif // _H_EBCL_DYNLIB
#include <lw/lib/inline/DynLib.hh>

19
include/ebcl/Externals.hh Normal file
View file

@ -0,0 +1,19 @@
/******************************************************************************/
/* EXTERNAL HEADER FILES ******************************************************/
/******************************************************************************/
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <cassert>
#include <condition_variable>
#include <functional>
#include <malloc.h>
#include <mutex>
#include <new>
#include <shared_mutex>
#include <thread>
#include <utility>

187
include/ebcl/Files.hh Normal file
View file

@ -0,0 +1,187 @@
/******************************************************************************/
/* FILES **********************************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_FILES
#define _H_LW_LIB_FILES
#include <lw/lib/Streams.hh>
#include <lw/lib/Strings.hh>
namespace lw {
/*= FILE ACCESS ==============================================================*/
enum class E_FileMode {
READ_ONLY ,
READ_WRITE ,
OVERWRITE
};
class T_File final
{
private:
T_String path_;
E_FileMode mode_;
FILE* file_;
size_t size_ , pos_;
T_File( );
public:
// Construct from a file path. Does not open the file.
T_File( T_String const& path , E_FileMode mode );
// Move constructor and assignment
T_File( T_File&& other ) noexcept;
T_File& operator= ( T_File&& other ) noexcept;
// Disabled copy constructor / assignment operator
T_File( T_File const& ) = delete;
T_File& operator= ( T_File const& ) = delete;
// Destructor - must close the file if it is open
~T_File( );
// Swapping
friend void swap( T_File& lhs , T_File& rhs ) noexcept;
// -------------------------------------------------------------------
// Get the path
T_String const& path( ) const noexcept;
// Get the mode
E_FileMode mode( ) const noexcept;
// Open the file. Throws an exception if that fails. Will be called
// automatically by most methods.
virtual void open( );
// Close the file. Never throws, even if the file's already closed or
// if closing fails.
void close( ) noexcept;
// Check if the file is open
bool isOpen( ) const noexcept;
// -------------------------------------------------------------------
// Get the file's size
size_t size( ) const noexcept;
// Get the current file position
size_t position( ) const noexcept;
// Set the position relative to the start or the end of the file
void position( size_t position , bool fromEnd = false );
// Set the position relative to the current position
void move( ssize_t offset );
// Read/write methods
size_t read( void* data , size_t size );
size_t write( void const* data , size_t size );
// Flushing
void flush( );
};
M_CLASS_POINTERS( File );
/*= FILE STREAMS =============================================================*/
class T_FileInputStream final : public A_InputStream
{
protected:
RP_File fileRaw_;
OP_File fileOwned_;
size_t start_;
public:
T_FileInputStream( ) = delete;
// Construct from a file instance
explicit T_FileInputStream( T_File& file , ssize_t offset = 0 ,
size_t limit = SIZE_MAX );
// Construct from a file owning pointer
explicit T_FileInputStream( OP_File&& file , ssize_t offset = 0 ,
size_t limit = SIZE_MAX );
// Copy constructor and assignment
T_FileInputStream( T_FileInputStream const& );
T_FileInputStream& operator= ( T_FileInputStream const& );
// Move constructor and assignment
T_FileInputStream( T_FileInputStream&& other ) noexcept;
T_FileInputStream& operator= ( T_FileInputStream&& other ) noexcept;
// Swapping
void swap( T_FileInputStream& rhs ) noexcept;
// Get the file
T_File& file( ) const noexcept;
// Get the start offset
size_t offset( ) const noexcept;
// -------------------------------------------------------------------
size_t read( void* data , size_t size ) override;
// -------------------------------------------------------------------
private:
void init( ssize_t offset , size_t limit );
};
M_CLASS_POINTERS( FileInputStream );
/*---------------------------------------------------------------------------*/
class T_FileOutputStream final : public A_OutputStream
{
protected:
RP_File fileRaw_;
OP_File fileOwned_;
size_t start_;
public:
T_FileOutputStream( ) = delete;
// Construct from a file.
explicit T_FileOutputStream( T_File& file , ssize_t offset = 0 );
// Construct from a file owning pointer
explicit T_FileOutputStream( OP_File&& file , ssize_t offset = 0 );
// Copy constructor and assignment
T_FileOutputStream( T_FileOutputStream const& );
T_FileOutputStream& operator= ( T_FileOutputStream const& );
// Move constructor and assignment
T_FileOutputStream( T_FileOutputStream&& other ) noexcept;
T_FileOutputStream& operator= ( T_FileOutputStream&& other ) noexcept;
// Swapping
void swap( T_FileOutputStream& rhs ) noexcept;
// Get the file
T_File& file( ) const noexcept;
// Get the start offset
size_t offset( ) const noexcept;
// -------------------------------------------------------------------
size_t write( void const* data , size_t size ) override;
void flush( ) override;
// -------------------------------------------------------------------
private:
void init( ssize_t offset );
};