28 #define FULL_ARRAY_DEBUG 0 // Note that this is not thread-safe
31 #include <emmintrin.h>
38 inline bool isfinitef(
float fp ){
float f=fp;
return ((*(
unsigned *)&f)&0x7f800000)!=0x7f800000; }
41 template<
class C >
bool IsValid(
const C& c );
43 template< >
inline bool IsValid< float >(
const float& f ) {
return isfinitef( f ) && ( f==0.f || abs(f)>1e-31f ); }
45 template< >
inline bool IsValid< float >(
const float& f ) {
return isfinitef( f ); }
47 template< >
inline bool IsValid< __m128 >(
const __m128& m )
49 const __m128* addr = &m;
50 if(
size_t(addr) & 15 )
return false;
53 template<
class C >
inline bool IsValid(
const C& c ){
return true; }
63 static std::vector< DebugMemoryInfo > memoryInfo;
64 #endif // FULL_ARRAY_DEBUG
69 void _assertBounds(
long long idx )
const
71 if( idx<min || idx>=max )
73 fprintf( stderr ,
"Array index out-of-bounds: %lld <= %lld < %lld\n" , min , idx , max );
82 static void _AddMemoryInfo(
const void* ptr ,
const char* name )
84 size_t sz = memoryInfo.size();
85 memoryInfo.resize( sz + 1 );
86 memoryInfo[sz].address = ptr;
87 if( name ) strcpy( memoryInfo[sz].name , name );
88 else memoryInfo[sz].name[0] = 0;
90 static void _RemoveMemoryInfo(
const void* ptr )
94 for( idx=0 ; idx<memoryInfo.size( ) ; idx++ )
if( memoryInfo[idx].address==ptr )
break;
95 if( idx==memoryInfo.size() )
97 fprintf( stderr ,
"Could not find memory in address table\n" );
102 memoryInfo[idx] = memoryInfo[memoryInfo.size()-1];
103 memoryInfo.pop_back( );
107 #endif // FULL_ARRAY_DEBUG
110 long long minimum(
void )
const {
return min; }
111 long long maximum(
void )
const {
return max; }
113 static inline Array New(
size_t size ,
const char* name=NULL )
116 a._data = a.data =
new C[size];
118 #pragma message( "[WARNING] Casting unsigned to signed" )
119 a.max = (
long long ) size;
121 _AddMemoryInfo( a._data , name );
122 #endif // FULL_ARRAY_DEBUG
125 static inline Array Alloc(
size_t size ,
bool clear ,
const char* name=NULL )
128 a._data = a.data = ( C* ) malloc( size *
sizeof( C ) );
129 if( clear ) memset( a.data , 0 , size *
sizeof( C ) );
132 #pragma message( "[WARNING] Casting unsigned to signed" )
133 a.max = (
long long ) size;
135 _AddMemoryInfo( a._data , name );
136 #endif // FULL_ARRAY_DEBUG
139 static inline Array AlignedAlloc(
size_t size ,
size_t alignment ,
bool clear ,
const char* name=NULL )
142 a.data = ( C* ) aligned_malloc(
sizeof(C) * size , alignment );
143 a._data = ( C* )( ( (
void** )a.data )[-1] );
144 if( clear ) memset( a.data , 0 , size *
sizeof( C ) );
147 #pragma message( "[WARNING] Casting unsigned to signed" )
148 a.max = (
long long ) size;
150 _AddMemoryInfo( a._data , name );
151 #endif // FULL_ARRAY_DEBUG
154 static inline Array ReAlloc(
Array& a ,
size_t size ,
bool clear ,
const char* name=NULL )
157 _a._data = _a.data = ( C* ) realloc( a.data , size *
sizeof( C ) );
158 if( clear ) memset( _a.data , 0 , size *
sizeof( C ) );
160 _RemoveMemoryInfo( a._data );
161 #endif // FULL_ARRAY_DEBUG
164 #pragma message( "[WARNING] Casting unsigned to signed" )
165 _a.max = (
long long ) size;
167 _AddMemoryInfo( _a._data , name );
168 #endif // FULL_ARRAY_DEBUG
189 long long szC =
sizeof( C );
190 long long szD =
sizeof( D );
192 min = ( a.minimum() * szD ) / szC;
193 max = ( a.maximum() * szD ) / szC;
194 if( min*szC!=a.minimum()*szD || max*szC!=a.maximum()*szD )
196 fprintf( stderr ,
"Could not convert array [ %lld , %lld ] * %lld => [ %lld , %lld ] * %lld\n" , a.minimum() , a.maximum() , szD , min , max , szC );
202 static Array FromPointer( C* data ,
long long max )
211 static Array FromPointer( C* data ,
long long min ,
long long max )
220 inline bool operator == (
const Array< C >& a )
const {
return data==a.data; }
221 inline bool operator != (
const Array< C >& a )
const {
return data!=a.data; }
222 inline bool operator == (
const C* c )
const {
return data==c; }
223 inline bool operator != (
const C* c )
const {
return data!=c; }
224 inline C* operator -> (
void )
229 inline const C* operator -> ( )
const
234 inline C& operator[](
long long idx )
236 _assertBounds( idx );
239 inline const C& operator[](
long long idx )
const
241 _assertBounds( idx );
244 inline Array operator + (
int idx )
const
253 inline Array operator + (
long long idx )
const
262 inline Array operator + (
unsigned int idx )
const
271 inline Array operator + (
unsigned long long idx )
const
280 inline Array& operator += (
int idx )
287 inline Array& operator += (
long long idx )
294 inline Array& operator += (
unsigned int idx )
301 inline Array& operator += (
unsigned long long idx )
308 inline Array& operator ++ (
void ) {
return (*
this) += 1; }
309 Array operator - (
int idx )
const {
return (*
this) + (-idx); }
310 Array operator - (
long long idx )
const {
return (*
this) + (-idx); }
311 Array operator - (
unsigned int idx )
const {
return (*
this) + (-idx); }
312 Array operator - (
unsigned long long idx )
const {
return (*
this) + (-idx); }
313 Array& operator -= (
int idx ) {
return (*
this) += (-idx); }
314 Array& operator -= (
long long idx ) {
return (*
this) += (-idx); }
315 Array& operator -= (
unsigned int idx ) {
return (*
this) += (-idx); }
316 Array& operator -= (
unsigned long long idx ) {
return (*
this) += (-idx); }
317 Array& operator -- (
void ) {
return (*
this) -= 1; }
318 long long operator - (
const Array& a )
const {
return (
long long )( data - a.data ); }
326 _RemoveMemoryInfo( _data );
327 #endif // FULL_ARRAY_DEBUG
337 _RemoveMemoryInfo( _data );
338 #endif // FULL_ARRAY_DEBUG
342 C* pointer(
void ){
return data; }
343 const C* pointer(
void )
const {
return data; }
344 bool operator !(
void )
const {
return data==NULL; }
345 operator bool( )
const {
return data!=NULL; }
351 void _assertBounds(
long long idx )
const
353 if( idx<min || idx>=max )
355 fprintf( stderr ,
"ConstArray index out-of-bounds: %lld <= %lld < %lld\n" , min , idx , max );
364 long long minimum(
void )
const {
return min; }
365 long long maximum(
void )
const {
return max; }
375 data = (
const C* )a.pointer( );
383 long long szC = (
long long )
sizeof( C );
384 long long szD = (
long long )
sizeof( D );
385 data = (
const C* )a.pointer( );
386 min = ( a.minimum() * szD ) / szC;
387 max = ( a.maximum() * szD ) / szC;
388 if( min*szC!=a.minimum()*szD || max*szC!=a.maximum()*szD )
391 fprintf( stderr ,
"Could not convert const array [ %lld , %lld ] * %lld => [ %lld , %lld ] * %lld\n %lld %lld %lld\n" , a.minimum() , a.maximum() , szD , min , max , szC , a.minimum() , a.minimum()*szD , (a.minimum()*szD)/szC );
400 long long szC =
sizeof( C );
401 long long szD =
sizeof( D );
402 data = (
const C*)a.pointer( );
403 min = ( a.minimum() * szD ) / szC;
404 max = ( a.maximum() * szD ) / szC;
405 if( min*szC!=a.minimum()*szD || max*szC!=a.maximum()*szD )
407 fprintf( stderr ,
"Could not convert array [ %lld , %lld ] * %lld => [ %lld , %lld ] * %lld\n" , a.minimum() , a.maximum() , szD , min , max , szC );
412 static ConstArray FromPointer(
const C* data ,
long long max )
420 static ConstArray FromPointer(
const C* data ,
long long min ,
long long max )
429 inline bool operator == (
const ConstArray< C >& a )
const {
return data==a.data; }
430 inline bool operator != (
const ConstArray< C >& a )
const {
return data!=a.data; }
431 inline bool operator == (
const C* c )
const {
return data==c; }
432 inline bool operator != (
const C* c )
const {
return data!=c; }
433 inline const C* operator -> (
void )
438 inline const C& operator[](
long long idx )
const
440 _assertBounds( idx );
443 inline ConstArray operator + (
int idx )
const
451 inline ConstArray operator + (
long long idx )
const
459 inline ConstArray operator + (
unsigned int idx )
const
467 inline ConstArray operator + (
unsigned long long idx )
const
482 inline ConstArray& operator += (
long long idx )
489 inline ConstArray& operator += (
unsigned int idx )
496 inline ConstArray& operator += (
unsigned long long idx )
503 inline ConstArray& operator ++ (
void ) {
return (*
this) += 1; }
504 ConstArray operator - (
int idx )
const {
return (*
this) + (-idx); }
505 ConstArray operator - (
long long idx )
const {
return (*
this) + (-idx); }
506 ConstArray operator - (
unsigned int idx )
const {
return (*
this) + (-idx); }
507 ConstArray operator - (
unsigned long long idx )
const {
return (*
this) + (-idx); }
508 ConstArray& operator -= (
int idx ) {
return (*
this) += (-idx); }
509 ConstArray& operator -= (
long long idx ) {
return (*
this) += (-idx); }
510 ConstArray& operator -= (
unsigned int idx ) {
return (*
this) += (-idx); }
511 ConstArray& operator -= (
unsigned long long idx ) {
return (*
this) += (-idx); }
512 ConstArray& operator -- (
void ) {
return (*
this) -= 1; }
513 long long operator - (
const ConstArray& a )
const {
return (
long long )( data - a.data ); }
514 long long operator - (
const Array< C >& a )
const {
return (
long long )( data - a.pointer() ); }
516 const C* pointer(
void )
const {
return data; }
517 bool operator !(
void ) {
return data==NULL; }
518 operator bool( ) {
return data!=NULL; }
522 inline void PrintMemoryInfo(
void ){
for(
size_t i=0 ; i<memoryInfo.size() ; i++ ) printf(
"%d] %s\n" , i , memoryInfo[i].name ); }
523 #endif // FULL_ARRAY_DEBUG
527 if( size>destination.maximum()*
sizeof(C) )
529 fprintf( stderr ,
"Size of copy exceeds destination maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( destination.maximum()*
sizeof( C ) ) );
533 if( size ) memcpy( &destination[0] , source , size );
536 template<
class C ,
class D >
539 if( size>destination.maximum()*
sizeof( C ) )
541 fprintf( stderr ,
"Size of copy exceeds destination maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( destination.maximum()*
sizeof( C ) ) );
545 if( size>source.maximum()*
sizeof( D ) )
547 fprintf( stderr ,
"Size of copy exceeds source maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( source.maximum()*
sizeof( D ) ) );
551 if( size ) memcpy( &destination[0] , &source[0] , size );
554 template<
class C ,
class D >
557 if( size>destination.maximum()*
sizeof( C ) )
559 fprintf( stderr ,
"Size of copy exceeds destination maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( destination.maximum()*
sizeof( C ) ) );
563 if( size>source.maximum()*
sizeof( D ) )
565 fprintf( stderr ,
"Size of copy exceeds source maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( source.maximum()*
sizeof( D ) ) );
569 if( size ) memcpy( &destination[0] , &source[0] , size );
573 void* memcpy(
void* destination ,
Array< D > source ,
size_t size )
575 if( size>source.maximum()*
sizeof( D ) )
577 fprintf( stderr ,
"Size of copy exceeds source maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( source.maximum()*
sizeof( D ) ) );
581 if( size ) memcpy( destination , &source[0] , size );
585 void* memcpy(
void* destination ,
ConstArray< D > source ,
size_t size )
587 if( size>source.maximum()*
sizeof( D ) )
589 fprintf( stderr ,
"Size of copy exceeds source maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( source.maximum()*
sizeof( D ) ) );
593 if( size ) memcpy( destination , &source[0] , size );
599 if( size>destination.maximum()*
sizeof( C ) )
601 fprintf( stderr ,
"Size of set exceeds destination maximum: %lld > %lld\n" , (
long long )( size ) , (
long long )( destination.maximum()*
sizeof( C ) ) );
605 if( size ) memset( &destination[0] , value , size );
610 size_t fread(
Array< C > destination ,
size_t eSize ,
size_t count , FILE* fp )
612 if( count*eSize>destination.maximum()*
sizeof( C ) )
614 fprintf( stderr ,
"Size of read exceeds source maximum: %lld > %lld\n" , (
long long )( count*eSize ) , (
long long )( destination.maximum()*
sizeof( C ) ) );
618 return fread( &destination[0] , eSize , count , fp );
621 size_t fwrite(
Array< C > source ,
size_t eSize ,
size_t count , FILE* fp )
623 if( count*eSize>source.maximum()*
sizeof( C ) )
625 fprintf( stderr ,
"Size of write exceeds source maximum: %lld > %lld\n" , (
long long )( count*eSize ) , (
long long )( source.maximum()*
sizeof( C ) ) );
629 return fwrite( &source[0] , eSize , count , fp );
632 size_t fwrite(
ConstArray< C > source ,
size_t eSize ,
size_t count , FILE* fp )
634 if( count*eSize>source.maximum()*
sizeof( C ) )
636 fprintf( stderr ,
"Size of write exceeds source maximum: %lld > %lld\n" , (
long long )( count*eSize ) , (
long long )( source.maximum()*
sizeof( C ) ) );
640 return fwrite( &source[0] , eSize , count , fp );
643 void qsort(
Array< C > base ,
size_t numElements ,
size_t elementSize ,
int (*compareFunction)(
const void* ,
const void* ) )
645 if(
sizeof(C)!=elementSize )
647 fprintf( stderr ,
"Element sizes differ: %lld != %lld\n" , (
long long )(
sizeof(C) ) , (
long long )( elementSize ) );
651 if( base.minimum()>0 || base.maximum()<numElements )
653 fprintf( stderr ,
"Array access out of bounds: %lld <= 0 <= %lld <= %lld\n" , base.minimum() , base.maximum() , (
long long )( numElements ) );
657 qsort( base.pointer() , numElements , elementSize , compareFunction );