#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>
#include "ctl/pp.h"
#include "ctl/debug.h"
#include "ctl/iterate.h"
#include "ctl/ctlnew.h"
#include "ctl/array.h"
#include "ctl/ctlstring.h"
Go to the source code of this file.
Data Structures | |
union | ctl_scalar_union |
A union of all the scalars, handy for certain things. mbool, mint8, mfloat32, etc. More... | |
Defines | |
#define | abs_mod(type, v, d) type_abs(type,(v)%(d)) |
#define | sign_mod(type, v, d) ((v)%(d)) |
#define | float64_compare_epsilon 0.000001 |
Smaller differences than this are 'same'. | |
#define | float32_compare_epsilon 0.000001f |
Smaller differences than this are 'same'. | |
#define | NumPlaces(type, val) ppConcat(type,_NumPlaces)( (type)val ) |
#define | NumXPlaces(type, val) ppConcat(type,_XNumPlaces)( (type)val ) |
Calculate number of hexadecimal places a value will take. | |
#define | type_min(type) ppConcat(type,_min) |
Get the lowest value of a type. | |
#define | type_max(type) ppConcat(type,_max) |
Get the highest value of a type. | |
#define | type_epsilon(type) ppConcat(type,_epsilon) |
Get minimum next-higher value for a type. | |
#define | type_bits(type) ppConcat(type,_bits) |
Get count of bits for a scalar type. | |
#define | type_issigned(type) ppConcat(type,_issigned) |
Find out if type supports signed values. | |
#define | type_isunsigned(type) (!ppConcat(type,_issigned)) |
Find out if type does not support signed values. | |
#define | type_isscalar(type) ppConcat(type,_isscalar) |
Tell us if a type is a scalar. | |
#define | if_signed(type, eval) ppConcat(type(eval),_ifsigned) |
#define | if_unsigned(type, eval) ppConcat(type(eval),_ifunsigned) |
#define | type_isfloat(type) ppConcat(type,_isfloat) |
Find out if type supports signed values. | |
#define | if_float(type, eval) ppConcat(type,_iffloat)(eval) |
#define | if_int(type, eval) ppConcat(type,_ifint)(eval) |
#define | type_signedtype(type) ppConcat(type,_signedtype) |
Get signed version of scalar type. | |
#define | type_unsignedtype(type) ppConcat(type,_unsignedtype) |
Get unsigned version of scalar type. | |
#define | type_printf(tchar, type) ppConcat(type,_fmt)(tchar) |
Get appropriate printf format specifier, by type. | |
#define | typecast_printf(type) ppConcat(type,_castfmt) |
Get appropriate printf format type for parameter. | |
#define | type_xprintf(tchar, type) ppConcat(type,_xfmt)(tchar) |
Get appropriate hexadecimal printf format specifier, by type. | |
#define | type_get_sign(type, value) ppConcat(type,_sign)(value) |
Get signed scalar value. | |
#define | type_set_sign(type, value, sign) ppConcat(type,_setsign)(value,sign) |
Set sign of types that support it. | |
#define | type_abs(type, v) ppConcat(type,_abs)(v) |
Get absolute value by type. | |
#define | type_rand(type) ppConcat(type,_rand)() |
Get random value by type; fills type with random bits and negates randomly as appropriate. | |
#define | DEF_ENUMTYPES(def, param) |
Enumerate types for template code auto-generations. | |
#define | DEF_ENUMTYPES_INNER(def, param) |
This must be a copy/paste clone of DEF_ENUMTYPES CPP won't recursively expand a macro... Anyway, used to do some type conversions in record handling stuff. | |
#define | roundup_signed(val, mod) (((val)+((val)<0?-(mod)+1:(mod)-1))/(mod)*(mod)) |
Round a value up to a preferred modulus. | |
#define | rounddown(val, mod) ((val)/(mod)*(mod)) |
Round a value down to a preferred modulus. | |
#define | nextround(val, mod) (rounddown(val,(mod))+(mod)) |
Get the next round value after the present value. | |
#define | ispow2(val) (0 == ((val)-1) & (val)) |
Determine if an integer type is a power of 2. | |
#define | incwrap(val, limit) (++(val) > (limit) ? ((val) = 0) : (val)) |
Increment and wrap an unsigned value at a limit. | |
#define | decwrap(val, limit) (--(val) < (0) ? ((val) = (limit)) : (val)) |
Decrement a value and wrap at zero to some limit value. | |
#define | valid(val, lmin, lmax) ((val)>=(lmin)&&(val)<=lmax) |
Tell us if a value is within a range. | |
#define | limit(val, lmin, lmax) ((val)<(lmin)?(lmin):((val)>(lmax)?(lmax):(val))) |
Limit a value between lmin and lmax. | |
#define | wrap(val, lmin, lmax) ( (val)=( (val)<(lmin) ? ( 1+(lmax) - (((lmin)-(val))%(1+(lmax)-(lmin))) ) : ((val)%(1+(lmax)-(lmin))) ) ) |
Wrap a value between two limits. | |
#define | further(val, distance) ((val)<0?(val)-(distance):(val)+(distance)) |
Moves a value 'distance' further away from zero Caution: Macro parameters may be evaluated multiple times. | |
#define | rand_count(type, count) (type_rand(type)%(count)) |
Get a random value between low and high, from rand(). | |
#define | rand_between(type, low, high) ( (low) + rand_count(type_unsignedtype(type),1+(high)-(low)) ) |
Get a random value between low and high, from rand(). | |
#define | rand32() ((float32)type_rand(uint32)*(1.0f/type_max(uint32))) |
Get a random value between 0.0f and not quite 1.0f. | |
#define | rand64() ((float32)type_rand(uint64)*(1.0f/type_max(uint64))) |
Get a random value between 0.0 and not quite 1.0. | |
#define | randnegate(val) ( rand()&1 ? (val) : -(val) ) |
Negate a value 50/50 Caution: Macro parameters may be evaluated multiple times. | |
#define | quintillion(QQQ, qqq, TTT, bbb, mmm, ttt, hhh) QQQ##qqq##TTT##bbb##mmm##ttt##hhh |
Define values from 10^18~(10^21-1). | |
#define | quadrillion(qqq, TTT, bbb, mmm, ttt, hhh) qqq##TTT##bbb##mmm##ttt##hhh |
Define values from 10^15~(10^18-1). | |
#define | trillion(TTT, bbb, mmm, ttt, hhh) TTT##bbb##mmm##ttt##hhh |
Define values from 10^12~(10^15-1). | |
#define | billion(bbb, mmm, ttt, hhh) bbb##mmm##ttt##hhh |
Define values from 10^9~(10^12-1). | |
#define | million(mmm, ttt, hhh) mmm##ttt##hhh |
Define values from 10^6~(10^9-1). | |
#define | thousand(ttt, hhh) ttt##hhh |
Define values from 10^3~(10^6-1). | |
#define | ppBits8_msb(b7, b6, b5, b4, b3, b2, b1, b0) ( (unsigned)(b0)|(unsigned)((b1)<<1)|(unsigned)((b2)<<2)|(unsigned)((b3)<<3) | (unsigned)((b4)<<4)|(unsigned)((b5)<<5)|(unsigned)((b6)<<6)|(unsigned)((b7)<<7) ) |
Make an 8-bit mask value, msb->lsb a little easier to read, or build from other things. | |
#define | ppBits8_lsb(b0, b1, b2, b3, b4, b5, b6, b7) ( (unsigned)(b0)|(unsigned)((b1)<<1)|(unsigned)((b2)<<2)|(unsigned)((b3)<<3) | (unsigned)((b4)<<4)|(unsigned)((b5)<<5)|(unsigned)((b6)<<6)|(unsigned)((b7)<<7) ) |
Make an 8-bit mask value, lsb->msb a little easier to read, or build from other things. | |
#define | ppBits16_msb(bf, be, bd, bc, bb, ba, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0) |
Make a 16-bit mask value, msb->lsb a little easier to read, or build from other things. | |
#define | ppBits16_lsb(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf) |
Make a 16-bit mask value, lsb->msb a little easier to read, or build from other things. | |
#define | ppBits32_msb(bv, bu, bt, bs, br, bq, bp, bo, bn, bm, bl, bk, bj, bi, bh, bg, bf, be, bd, bc, bb, ba, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0) |
Make a 32-bit mask value a little easier to read, or build from other things. | |
#define | ppBits32_lsb(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv) |
Make a 32-bit mask value a little easier to read. | |
Typedefs | |
typedef int32 | ppRandSeed_T |
Functions | |
bool | _dummy_true (void) |
size_t | int32_NumPlaces (int32 val) |
Calculate number of decimal places a signed 32 bit value will take in text output. | |
size_t | uint32_NumPlaces (uint32 val) |
Calculate number of decimal places an unsigned 32 bit value will take in text output. | |
size_t | uint32_XNumPlaces (uint32 val) |
Calculate number of hexadecimal places an unsigned 32 bit value will take in text output. | |
size_t | int64_NumPlaces (int64 val) |
Calculate number of decimal places a signed 64 bit value will take in text output. | |
size_t | uint64_NumPlaces (uint64 val) |
Calculate number of decimal places an unsigned 64 bit value will take in text output. | |
size_t | uint64_XNumPlaces (uint64 val) |
Calculate number of hexadecimal places an unsigned 64 bit value will take in text output. |
This file thoroughly and repetitively defines what can be done to basic scalar types for their definition in structures, and for IO. It is also possible to query data types for their properties at compile-time.
Definition in file ctldef.h.
#define abs_mod | ( | type, | |||
v, | |||||
d | ) | type_abs(type,(v)%(d)) |
#define decwrap | ( | val, | |||
limit | ) | (--(val) < (0) ? ((val) = (limit)) : (val)) |
#define float64_compare_epsilon 0.000001 |
Smaller differences than this are 'same'.
Comparison notes The default comparison resolution is kept fairly low to maintain compatibility with text I/O, such as for XML, which loses much of its original resolution when the data is encoded/decoded.
If you won't be doing that sort of thing, then feel free to redefine these to a proper 'epsilon' before this header is included, and get better accuracy when sorting/comparing floats.
Definition at line 149 of file ctldef.h.
Referenced by float64_compare(), and float64_rcompare().
#define if_float | ( | type, | |||
eval | ) | ppConcat(type,_iffloat)(eval) |
#define if_int | ( | type, | |||
eval | ) | ppConcat(type,_ifint)(eval) |
#define if_signed | ( | type, | |||
eval | ) | ppConcat(type(eval),_ifsigned) |
#define if_unsigned | ( | type, | |||
eval | ) | ppConcat(type(eval),_ifunsigned) |
#define incwrap | ( | val, | |||
limit | ) | (++(val) > (limit) ? ((val) = 0) : (val)) |
#define ispow2 | ( | val | ) | (0 == ((val)-1) & (val)) |
#define limit | ( | val, | |||
lmin, | |||||
lmax | ) | ((val)<(lmin)?(lmin):((val)>(lmax)?(lmax):(val))) |
#define nextround | ( | val, | |||
mod | ) | (rounddown(val,(mod))+(mod)) |
Get the next round value after the present value.
val | value to round up | |
mod | The value you want v to be divisible by |
#define NumPlaces | ( | type, | |||
val | ) | ppConcat(type,_NumPlaces)( (type)val ) |
#define NumXPlaces | ( | type, | |||
val | ) | ppConcat(type,_XNumPlaces)( (type)val ) |
#define rand_between | ( | type, | |||
low, | |||||
high | ) | ( (low) + rand_count(type_unsignedtype(type),1+(high)-(low)) ) |
Get a random value between low and high, from rand().
type | Scalar type to retrieve | |
low | The lowest value this should return | |
high | The highest value this should return |
#define rand_count | ( | type, | |||
count | ) | (type_rand(type)%(count)) |
#define rounddown | ( | val, | |||
mod | ) | ((val)/(mod)*(mod)) |
#define roundup_signed | ( | val, | |||
mod | ) | (((val)+((val)<0?-(mod)+1:(mod)-1))/(mod)*(mod)) |
#define sign_mod | ( | type, | |||
v, | |||||
d | ) | ((v)%(d)) |
#define type_abs | ( | type, | |||
v | ) | ppConcat(type,_abs)(v) |
#define type_bits | ( | type | ) | ppConcat(type,_bits) |
#define type_epsilon | ( | type | ) | ppConcat(type,_epsilon) |
#define type_get_sign | ( | type, | |||
value | ) | ppConcat(type,_sign)(value) |
#define type_isfloat | ( | type | ) | ppConcat(type,_isfloat) |
#define type_isscalar | ( | type | ) | ppConcat(type,_isscalar) |
#define type_issigned | ( | type | ) | ppConcat(type,_issigned) |
#define type_isunsigned | ( | type | ) | (!ppConcat(type,_issigned)) |
#define type_max | ( | type | ) | ppConcat(type,_max) |
Get the highest value of a type.
type | Scalar type to check |
Definition at line 180 of file ctldef.h.
Referenced by BMI_Clut_AddColor().
#define type_min | ( | type | ) | ppConcat(type,_min) |
#define type_printf | ( | tchar, | |||
type | ) | ppConcat(type,_fmt)(tchar) |
Get appropriate printf format specifier, by type.
tchar | Type of character, char or wchar_t | |
type | Scalar type for printf argument "Hello %" "d" is the same as "Hello %d"... so "Hello %" type_printf(char,uint32) is "Hello %u" |
#define type_rand | ( | type | ) | ppConcat(type,_rand)() |
#define type_set_sign | ( | type, | |||
value, | |||||
sign | ) | ppConcat(type,_setsign)(value,sign) |
#define type_signedtype | ( | type | ) | ppConcat(type,_signedtype) |
#define type_unsignedtype | ( | type | ) | ppConcat(type,_unsignedtype) |
#define type_xprintf | ( | tchar, | |||
type | ) | ppConcat(type,_xfmt)(tchar) |
Get appropriate hexadecimal printf format specifier, by type.
tchar | Type of character, char or wchar_t | |
type | Scalar type for printf argument "Hello %" "x" is the same as "Hello %x"... so "Hello %" type_printf(char,uint64) is "Hello %llx" or "Hello %I64x" |
#define typecast_printf | ( | type | ) | ppConcat(type,_castfmt) |
#define valid | ( | val, | |||
lmin, | |||||
lmax | ) | ((val)>=(lmin)&&(val)<=lmax) |
#define wrap | ( | val, | |||
lmin, | |||||
lmax | ) | ( (val)=( (val)<(lmin) ? ( 1+(lmax) - (((lmin)-(val))%(1+(lmax)-(lmin))) ) : ((val)%(1+(lmax)-(lmin))) ) ) |
Wrap a value between two limits.
val | value to limit | |
lmin | Minimum value val is allowed to have | |
lmax | Maximum value val is allowed to have |
Definition at line 830 of file ctldef.h.
Referenced by ExportCData().
typedef int32 ppRandSeed_T |
bool _dummy_true | ( | void | ) |
Helpers to remove 'invariant' warnings
size_t int32_NumPlaces | ( | int32 | val | ) |
Calculate number of decimal places a signed 32 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 349 of file ctldef.c.
References uint32_NumPlaces().
00350 { 00351 size_t ret = 0; 00352 if( val < 0 ) 00353 { 00354 val = -val; 00355 ret = 1; 00356 if( val < 0 ) /* int32 min */ 00357 return 11; 00358 } 00359 return ret + uint32_NumPlaces( val ); 00360 }
size_t int64_NumPlaces | ( | int64 | val | ) |
Calculate number of decimal places a signed 64 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 406 of file ctldef.c.
References uint64_NumPlaces().
00407 { 00408 size_t ret = 0; 00409 if( val < 0 ) 00410 { 00411 val = -val; 00412 ret = 1; 00413 if( val < 0 ) 00414 return 20; 00415 } 00416 return ret + uint64_NumPlaces( val ); 00417 }
size_t uint32_NumPlaces | ( | uint32 | val | ) |
Calculate number of decimal places an unsigned 32 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 366 of file ctldef.c.
Referenced by int32_NumPlaces(), and uint64_NumPlaces().
00367 { 00368 if( val >= 100000u ) 00369 { 00370 if( val >= 100000000u ) 00371 { 00372 if( val >= 1000000000u ) 00373 { 00374 return 10; 00375 } 00376 return 9; 00377 } 00378 else if( val >= 1000000u ) 00379 { 00380 if( val >= 10000000u ) 00381 return 8; 00382 return 7; 00383 } 00384 return 6; 00385 } 00386 else if( val >= 1000u ) 00387 { 00388 if( val >= 10000u ) 00389 return 5; 00390 return 4; 00391 } 00392 else if( val >= 10u ) 00393 { 00394 if( val >= 100u ) 00395 return 3; 00396 return 2; 00397 } 00398 return 1; 00399 }
size_t uint32_XNumPlaces | ( | uint32 | val | ) |
Calculate number of hexadecimal places an unsigned 32 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 476 of file ctldef.c.
Referenced by uint64_XNumPlaces().
00477 { 00478 size_t ret = 1; 00479 if( val >= 0xffff0000 ) 00480 { 00481 ret += 4; 00482 val >>= 16; 00483 } 00484 if( val >= 0xff00 ) 00485 { 00486 ret += 2; 00487 val >>= 8; 00488 } 00489 if( val >= 0xf0 ) 00490 { 00491 ret++; 00492 } 00493 return ret; 00494 }
size_t uint64_NumPlaces | ( | uint64 | val | ) |
Calculate number of decimal places an unsigned 64 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 424 of file ctldef.c.
References billion, quadrillion, quintillion, trillion, and uint32_NumPlaces().
Referenced by int64_NumPlaces().
00425 { 00426 /*18,446,744,073,709,551,616 */ 00427 if( val > uint64const(billion(1,000,000,000)) ) 00428 { 00429 if( val >= uint64const(quadrillion(1,000,000,000,000,000)) ) 00430 { 00431 if( val >= uint64const(quintillion(1,000,000,000,000,000,000)) ) 00432 { 00433 if( val >= uint64const(quintillion(10,000,000,000,000,000,000)) ) 00434 return 20; 00435 /* else uint64const(quintillion(1,000,000,000,000,000,000)) */ 00436 return 19; 00437 } 00438 else /* if( val >= uint64const(quadrillion(1,000,000,000,000,000)) ) */ 00439 { 00440 if( val >= uint64const(quadrillion(100,000,000,000,000,000)) ) 00441 return 18; 00442 if( val >= uint64const(quadrillion(10,000,000,000,000,000)) ) 00443 return 17; 00444 /* else uint64const(quadrillion(1,000,000,000,000,000)) */ 00445 return 16; 00446 } 00447 } 00448 else if( val >= uint64const(trillion(1,000,000,000,000)) ) 00449 { 00450 if( val >= uint64const(trillion(100,000,000,000,000)) ) 00451 return 15; 00452 if( val >= uint64const(trillion(10,000,000,000,000)) ) 00453 return 14; 00454 /* else uint64const(trillion(1,000,000,000,000)) */ 00455 return 13; 00456 } 00457 else /* if( val >= uint64const(billion(1,000,000,000)) ) */ 00458 { 00459 if( val >= uint64const(billion(100,000,000,000)) ) 00460 return 12; 00461 if( val >= uint64const(billion(10,000,000,000)) ) 00462 return 11; 00463 /* else uint64const(billion(1,000,000,000)) */ 00464 return 10; 00465 } 00466 } 00467 return uint32_NumPlaces( (uint32)val ); 00468 00469 }
size_t uint64_XNumPlaces | ( | uint64 | val | ) |
Calculate number of hexadecimal places an unsigned 64 bit value will take in text output.
val | Value we're counting decimal places on |
Definition at line 500 of file ctldef.c.
References uint32_XNumPlaces().
00501 { 00502 if( val > 0xffffffff ) 00503 { 00504 val >>= 32; 00505 return 32+uint32_XNumPlaces( (uint32)val ); 00506 } 00507 return uint32_XNumPlaces( (uint32)val ); 00508 }