五、实现

 #include "DynamicDLA.h" #ifndef __cplusplus #include <stdlib.h> #include <string.h> #else #include <cstdlib> #include <cstring> namespace dynamic_dimensionality_length_array { #endif struct arrayinfo { struct arrayinfo *Next; char* ElementAddr; void** PtrBuffer; size_t ElementSize; size_t *DimenLength; size_t Dimen; }; static struct arrayinfo *Head = NULL; static void* newarray( size_t, size_t, size_t*, bool ); static struct arrayinfo* search( void *PtrBuffer ); static void** build( void **, char *, size_t, size_t*, size_t, size_t ); static void process( struct arrayinfo *, size_t, size_t*, void ( * )(void*, size_t* ) ); static void* address( void*, size_t, size_t* ); static size_t size( void*, size_t, size_t* ); void* new_a( size_t ElementSize, size_t Dimen, ... ) { return newarray( ElementSize, Dimen, &Dimen + 1, 1 ); } void* new0_a( size_t ElementSize, size_t Dimen, ... ) { return newarray( ElementSize, Dimen, &Dimen + 1, 0 ); } void* new_pa( size_t ElementSize, size_t Dimen, size_t *DimenLength ) { return newarray( ElementSize, Dimen, DimenLength, 1 ); } void* resize_pa( void *PtrBuffer, size_t Dimen, size_t *DimenLength ) { size_t i, Product = 1, Sum = 0; struct arrayinfo *TempArray, *TempSearch, **TempNext = &Head; char *TempElement; void ** TempBuffer; if( !PtrBuffer || !Dimen ) return NULL; for( i = 0; i < Dimen; ++i ) if( !DimenLength[i] ) return NULL; for( TempSearch = Head; TempSearch ; TempSearch = TempSearch->Next ) { if( TempSearch->PtrBuffer == PtrBuffer ) break; TempNext = &TempSearch->Next; } if( !TempSearch ) return NULL; TempArray = ( struct arrayinfo * )malloc( sizeof( struct arrayinfo ) + Dimen * sizeof( size_t ) ); if( !TempArray ) return NULL; for( i = 0; i < Dimen - 1; ++i ) Sum += ( Product *= DimenLength[i] ); Product *= DimenLength[Dimen-1] * TempSearch->ElementSize; TempBuffer = ( void** )malloc( Sum * sizeof( void* ) ); if( !TempBuffer ) return NULL; TempElement = ( char* )realloc( TempSearch->ElementAddr, Product * sizeof( char ) ); if( !TempElement ) return NULL; build( TempBuffer, TempElement, TempSearch->ElementSize, DimenLength, 0, Dimen ); TempArray->ElementAddr = TempElement; TempArray->PtrBuffer = TempBuffer; TempArray->ElementSize = TempSearch->ElementSize; TempArray->DimenLength = &TempArray->Dimen + 1; memcpy( TempArray->DimenLength, DimenLength, Dimen * sizeof( size_t ) ); TempArray->Dimen = Dimen; TempArray->Next = TempSearch->Next; free( TempSearch->PtrBuffer ); free( TempSearch ); *TempNext = TempArray; return ( void* )TempBuffer; } void* resize_a( void *PtrBuffer, size_t Dimen, ... ) { return resize_pa( PtrBuffer, Dimen, &Dimen + 1 ); } bool assign_pa( void *PtrBuffer, void *Padding, size_t *DimenLength ) { size_t i; struct arrayinfo *TempArray; if( !PtrBuffer || !Padding || !DimenLength || !( TempArray = search( PtrBuffer ) ) ) return false; for( i = 0; i < TempArray->Dimen; ++i ) if( DimenLength[i] >= TempArray->DimenLength[i] ) return false; memcpy( address_pa( PtrBuffer, TempArray->Dimen, DimenLength ), Padding, TempArray->ElementSize ); return true; } bool assign_va( void *PtrBuffer, void *Padding, ... ) { return assign_pa( PtrBuffer, Padding, ( size_t* )( &Padding + 1 ) ); } bool value_pa( void *PtrBuffer, void *Padding, size_t *DimenLength ) { size_t i; struct arrayinfo *TempArray; if( !PtrBuffer || !Padding || !DimenLength || !( TempArray = search( PtrBuffer ) ) ) return false; for( i = 0; i < TempArray->Dimen; ++i ) if( DimenLength[i] >= TempArray->DimenLength[i] ) return false; memcpy( Padding, address_pa( PtrBuffer, TempArray->Dimen, DimenLength ), TempArray->ElementSize ); return true; } bool value_va( void *PtrBuffer, void *Padding, ... ) { return value_pa( PtrBuffer, Padding, ( size_t* )( &Padding + 1 ) ); } bool process_a( void *PtrBuffer, void ( *CallBack )(void*, size_t* ) ) { size_t *DimenLength; struct arrayinfo *TempArray; if( !PtrBuffer || !CallBack || !( TempArray = search( PtrBuffer) ) ) return false; DimenLength = ( size_t* )malloc( TempArray->Dimen * sizeof( size_t ) ); if( !DimenLength ) return false; process( TempArray, 0, DimenLength, CallBack ); free( DimenLength ); return true; } void* address_va( void *PtrBuffer, size_t Dimen, ... ) { return address( PtrBuffer, Dimen, &Dimen + 1 ); } void* address_pa( void *PtrBuffer, size_t Dimen, size_t *DimenLength ) { return address( PtrBuffer, Dimen, DimenLength ); } size_t dimen_a( void *PtrBuffer ) { struct arrayinfo *TempArray; if( !PtrBuffer || !( TempArray = search( PtrBuffer ) ) ) return 0; return TempArray->Dimen; } size_t sizeof_a( void *PtrBuffer ) { struct arrayinfo *TempArray = Head; size_t i; if( !PtrBuffer ) return 0; for( ; TempArray; TempArray = TempArray->Next ) { size_t Product = 1, Sum = 0; for( i = 0; i < TempArray->Dimen - 1; ++i ) Sum += Product *= TempArray->DimenLength[i]; Product *= TempArray->DimenLength[i]; if( TempArray->PtrBuffer == ( void** )PtrBuffer ) return Product * TempArray->ElementSize; for( i = 0; i < Sum; ++i ) if( TempArray->PtrBuffer[i] == PtrBuffer ) { size_t j; size_t TempSum = 0, TempPrdct = 1; for( j = 0; j < TempArray->Dimen - 1; ++j ) { TempSum += TempPrdct *= TempArray->DimenLength[j]; Product /= TempArray->DimenLength[j]; if( TempSum > i ) return Product * TempArray->ElementSize; } } } return 0; } size_t sizeof_pa( void *PtrBuffer, size_t Dimen, size_t *DimenLength ) { return size( PtrBuffer, Dimen, DimenLength ); } size_t sizeof_va( void *PtrBuffer, size_t Dimen, ... ) { return size( PtrBuffer, Dimen, &Dimen + 1 ); } size_t* dimenlen_a( void *PtrBuffer, size_t *DimenLength ) { struct arrayinfo *TempArray; if( !PtrBuffer || !( TempArray = search( PtrBuffer ) ) ) return NULL; memcpy( DimenLength, TempArray->DimenLength, TempArray->Dimen ); return DimenLength; } size_t elmntsize_a( void *PtrBuffer ) { struct arrayinfo *TempArray; if( !PtrBuffer || !( TempArray = search( PtrBuffer ) ) ) return 0; return TempArray->ElementSize; } void delete_a( void *PtrBuffer ) { struct arrayinfo *TempArray, **TempNext = &Head; if( !PtrBuffer ) return; for( TempArray = Head; TempArray ; TempArray = TempArray->Next ) { if( TempArray->PtrBuffer == PtrBuffer ) break; TempNext = &TempArray->Next; } if( !TempArray ) return; free( TempArray->ElementAddr ); free( TempArray->PtrBuffer ); *TempNext = TempArray->Next; free( TempArray ); return; } void delete_all() { struct arrayinfo *TempArray = Head, *TempNext; for( ; TempArray; TempArray = TempNext ) { TempNext = TempArray->Next; free( TempArray->ElementAddr ); free( TempArray->PtrBuffer ); free( TempArray ); } } static void* newarray( size_t ElementSize, size_t Dimen, size_t *DimenLength, bool Flag ) { size_t i, Product = 1, Sum = 0; struct arrayinfo *TempArray; char *TempElement; void ** TempBuffer; if( !ElementSize || !Dimen ) return NULL; for( i = 0; i < Dimen; ++i ) if( !DimenLength[i] ) return NULL; for( i = 0; i < Dimen - 1; ++i ) Sum += Product *= DimenLength[i]; Product *= DimenLength[Dimen-1] * ElementSize; if( Flag ) TempElement = ( char* )malloc( Product * sizeof( char ) ); else TempElement = ( char* )calloc( Product, sizeof( char ) ); if( Dimen != 1 ) TempBuffer = ( void** )malloc( Sum * sizeof( void* ) ); else TempBuffer = ( void** )TempElement; TempArray = ( struct arrayinfo * )malloc( sizeof( struct arrayinfo ) + Dimen * sizeof( size_t ) ); if( !TempElement || !TempBuffer || !TempArray ) { free( TempElement ); if( Dimen != 1 ) free( TempBuffer ); free( TempArray ); return NULL; } build( TempBuffer, TempElement, ElementSize, DimenLength, 0, Dimen ); TempArray->ElementAddr = TempElement; TempArray->PtrBuffer = TempBuffer; TempArray->ElementSize = ElementSize; TempArray->DimenLength = &TempArray->Dimen + 1; memcpy( TempArray->DimenLength, DimenLength, Dimen * sizeof( size_t ) ); TempArray->Dimen = Dimen; TempArray->Next = Head; Head = TempArray; return ( void* )TempBuffer; } static void** build( void **PtrBuffer, char *ElementAddr, size_t ElementSize, size_t *DimenLength, size_t CurDimen, size_t Dimen ) { size_t i; if( CurDimen == Dimen - 1 ) return ( void** )ElementAddr; for( i = 0; i < DimenLength[CurDimen]; ++i ) { size_t j; size_t Product = 1; void **NextPtr; char *NextData; for( j = 0; j <= CurDimen; ++j ) Product *= DimenLength[j]; NextPtr = PtrBuffer + Product + i * DimenLength[CurDimen + 1]; Product = 1; for( j = CurDimen + 1; j < Dimen; ++j ) Product *= DimenLength[j]; NextData = ElementAddr + i * Product * ElementSize; PtrBuffer[i] = ( void* )build( NextPtr, NextData, ElementSize, DimenLength, CurDimen + 1, Dimen ); } return PtrBuffer; } static void process( struct arrayinfo *TempArray, size_t CurDimen, size_t *DimenLength, void ( *CallBack )(void*, size_t* ) ) { size_t i; for( i = 0; i < TempArray->DimenLength[CurDimen]; ++i ) { DimenLength[CurDimen] = i; if( CurDimen == TempArray->Dimen - 1 ) CallBack( TempArray->PtrBuffer, DimenLength ); else process( TempArray, CurDimen + 1, DimenLength, CallBack ); } return; } static struct arrayinfo* search( void *PtrBuffer ) { struct arrayinfo *TempArray = Head; for( ; TempArray; TempArray = TempArray->Next ) if( TempArray->PtrBuffer == PtrBuffer ) return TempArray; return NULL; } static void* address( void *PtrBuffer, size_t Dimen, size_t *DimenLength ) { size_t i, Sum = 0, Product = 1; struct arrayinfo *TempArray; if( ( Dimen && !DimenLength ) || !PtrBuffer || !( TempArray = search( PtrBuffer ) ) || TempArray->Dimen < Dimen ) return NULL; for( i = 0; i < Dimen; ++i ) if( DimenLength[i] >= TempArray->DimenLength[i] ) return NULL; if( !Dimen ) return ( void* )TempArray->ElementAddr; for( i = 0; i < TempArray->Dimen; ++i ) Product *= TempArray->DimenLength[i]; for( i = 0; i < Dimen; ++i ) Sum += DimenLength[i] * ( Product /= TempArray->DimenLength[i] ); return TempArray->ElementAddr + Sum * TempArray->ElementSize; } static size_t size( void *PtrBuffer, size_t Dimen, size_t *DimenLength ) { struct arrayinfo *TempArray; size_t i, Product = 1; if( ( Dimen && !DimenLength ) || !PtrBuffer || !( TempArray = search( PtrBuffer ) ) || TempArray->Dimen < Dimen ) return 0; for( i = 0; i < Dimen; ++i ) if( DimenLength[i] >= TempArray->DimenLength[i] ) return 0; if( !Dimen ) { for( i = 0; i < TempArray->Dimen; ++i ) Product *= TempArray->DimenLength[i]; return Product * TempArray->ElementSize; } for( i = Dimen; i < TempArray->Dimen; ++i ) Product *= TempArray->DimenLength[i]; return Product * TempArray->ElementSize; } #ifdef __cplusplus } #endif

你可能感兴趣的:(struct,null,delete,search,Build,callback)