--- libecb/ecb.pod 2020/01/20 21:13:38 1.85 +++ libecb/ecb.pod 2021/06/22 00:01:15 1.90 @@ -82,7 +82,7 @@ preprocessor instructions as well as treated as a boolean (use C to ensure it's either C<0> or C<1> if you need that). -=over 4 +=over =item ECB_C @@ -166,6 +166,14 @@ not be able to deduce this correctly everywhere and might err on the safe side. +=item ECB_64BIT_NATIVE + +Evaluates to a true value (suitable for both preprocessor and C code +testing) if 64 bit integer types on this architecture are evaluated +"natively", that is, with similar speeds as 32 bit integerss. While 64 bit +integer support is very common (and in fatc required by libecb), 32 bit +cpus have to emulate operations on them, so you might want to avoid them. + =item ECB_AMD64, ECB_AMD64_X32 These two macros are defined to C<1> on the x86_64/amd64 ABI and the X32 @@ -181,7 +189,7 @@ =head2 MACRO TRICKERY -=over 4 +=over =item ECB_CONCAT (a, b) @@ -232,7 +240,7 @@ ecb_const int mysqrt (int a); ecb_unused int i; -=over 4 +=over =item ecb_unused @@ -416,7 +424,7 @@ =head2 OPTIMISATION HINTS -=over 4 +=over =item bool ecb_is_constant (expr) @@ -583,7 +591,7 @@ =head2 BIT FIDDLING / BIT WIZARDRY -=over 4 +=over =item bool ecb_big_endian () @@ -743,7 +751,7 @@ =head2 HOST ENDIANNESS CONVERSION -=over 4 +=over =item uint_fast16_t ecb_be_u16_to_host (uint_fast16_t v) @@ -781,7 +789,7 @@ In C++ the following additional template functions are supported: -=over 4 +=over =item T ecb_be_to_host (T v) @@ -791,6 +799,8 @@ =item T ecb_host_to_le (T v) +=back + These functions work like their C counterparts, above, but use templates, which make them useful in generic code. @@ -802,7 +812,7 @@ These function load or store unaligned multi-byte values. -=over 4 +=over =item uint_fast16_t ecb_peek_u16_u (const void *ptr) @@ -856,7 +866,7 @@ In C++ the following additional template functions are supported: -=over 4 +=over =item T ecb_peek (const void *ptr) @@ -908,9 +918,144 @@ =back +=head2 FAST INTEGER TO STRING + +Libecb defines a set of very fast integer to decimal string (or integer +to ascii, short C) functions. These work by converting the integer +to a fixed point representation and then successively multiplying out +the topmost digits. Unlike some other, also very fast, libraries, ecb's +algorithm should be completely branchless per digit, and does not rely on +the presence of special cpu functions (such as clz). + +There is a high level API that takes an C, C, +C or C as argument, and a low-level API, which is +harder to use but supports slightly more formatting options. + +=head3 HIGH LEVEL API + +The high level API consists of four functions, one each for C, +C, C and C: + +=over + +=item ECB_I2A_I32_DIGITS (=11) + +=item char *ecb_i2a_u32 (char *ptr, uint32_t value) + +Takes an C I and formats it as a decimal number starting +at I, using at most C characters. Returns a +pointer to just after the generated string, where you would normally put +the temrinating C<0> character. This function outputs the minimum number +of digits. + +=item ECB_I2A_U32_DIGITS (=10) + +=item char *ecb_i2a_i32 (char *ptr, int32_t value) + +Same as C, but formats a C value, including a minus +sign if needed. + +=item ECB_I2A_I64_DIGITS (=20) + +=item char *ecb_i2a_u64 (char *ptr, uint64_t value) + +=item ECB_I2A_U64_DIGITS (=21) + +=item char *ecb_i2a_i64 (char *ptr, int64_t value) + +Similar to their 32 bit counterparts, these take a 64 bit argument. + +=item ECB_I2A_MAX_DIGITS (=21) + +Instead of using a type specific length macro, youi can just use +C, which is good enough for any C function. + +=back + +=head3 LOW-LEVEL API + +The functions above use a number of low-level APIs which have some strict +limitaitons, but cna be used as building blocks (study of C +and related cunctions is recommended). + +There are three families of functions: functions that convert a number +to a fixed number of digits with leading zeroes (C, C<0> +for "leading zeroes"), functions that generate up to N digits, skipping +leading zeroes (C<_N>), and functions that can generate more digits, but +the leading digit has limited range (C<_xN>). + +None of the functions deal with negative numbera. + +=over + +=item char *ecb_i2a_02 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_03 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_04 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_05 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_06 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_07 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_08 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_09 (char *ptr, uint32_t value) // 64 bit + +The C<< ecb_i2a_0I > functions take an unsigned I and convert +them to exactly I digits, returning a pointer to the first character +after the digits. The I must be in range. The functions marked with +I<32 bit> do their calculations internally in 32 bit, the ones marked with +I<64 bit> internally use 64 bit integers, which might be slow on 32 bit +architectures (the high level API decides on 32 vs. 64 bit versions using +C). + +=item char *ecb_i2a_2 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_3 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_4 (char *ptr, uint32_t value) // 32 bit + +=item char *ecb_i2a_5 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_6 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_7 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_8 (char *ptr, uint32_t value) // 64 bit + +=item char *ecb_i2a_9 (char *ptr, uint32_t value) // 64 bit + +Similarly, the C<< ecb_i2a_I > functions take an unsigned I +and convert them to at most I digits, suppressing leading zeroes, and +returning a pointer to the first character after the digits. + +=item ECB_I2A_MAX_X5 (=59074) + +=item char *ecb_i2a_x5 (char *ptr, uint32_t value) // 32 bit + +=item ECB_I2A_MAX_X10 (=2932500665) + +=item char *ecb_i2a_x10 (char *ptr, uint32_t value) // 64 bit + +The C<< ecb_i2a_xI >> functions are similar to the C<< ecb_i2a_I > +functions, but they can generate one digit more, as long as the number +is within range, which is given by the symbols C (almost +16 bit range) and C (a bit more than 31 bit range), +respectively. + +For example, the sigit part of a 32 bit signed integer just fits into the +C range, so while C cannot convert a 10 +digit number, it can convert all 32 bit signed numbers. Sadly, it's not +good enough for 32 bit unsigned numbers. + +=back + =head2 FLOATING POINT FIDDLING -=over 4 +=over =item ECB_INFINITY [-UECB_NO_LIBM] @@ -998,7 +1143,7 @@ =head2 ARITHMETIC -=over 4 +=over =item x = ecb_mod (m, n) @@ -1039,7 +1184,7 @@ =head2 UTILITY -=over 4 +=over =item element_count = ecb_array_length (name) @@ -1057,7 +1202,7 @@ These symbols need to be defined before including F the first time. -=over 4 +=over =item ECB_NO_THREADS