1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
This commit is contained in:
stefanocasazza 2016-11-23 19:02:34 +01:00
parent 5b1ead608a
commit cb6232406a
12 changed files with 184 additions and 129 deletions

View File

@ -1,8 +1,8 @@
#dist: trusty
dist: trusty
language: cpp
compiler:
- gcc
- clang
# - clang
#before_install:
# - sudo pip install cpp-coveralls
#install:

View File

@ -460,8 +460,7 @@ static inline uint32_t u_strftime2(char* restrict buffer, uint32_t buffer_size,
/* conversion number to string */
extern U_EXPORT const char* u_ctn2s;
extern U_EXPORT const double u_pow10[309]; /* 1e-0...1e308: 309 * 8 bytes = 2472 bytes */
extern U_EXPORT const char* u_ctn2s;
extern U_EXPORT pcPFdpc u_dbl2str;
extern U_EXPORT pcPFu32pc u_num2str32;

View File

@ -224,8 +224,8 @@ public:
U_INTERNAL_ASSERT(u_now->tv_sec % U_ONE_HOUR_IN_SECOND)
U_NUM2STR16(ptr, (u_now->tv_sec / 60) % 60);
U_NUM2STR16(ptr+3,u_now->tv_sec % 60);
u_put_unalignedp16(ptr, u_dd((u_now->tv_sec / 60) % 60));
u_put_unalignedp16(ptr+3, u_dd( u_now->tv_sec % 60));
}
// The daysTo() function returns the number of days between two date

View File

@ -2612,7 +2612,7 @@ next:
else (void) db_user->insertDataStorage(*uid);
}
static const char* getPointerToConnection(UStringRep* data)
static const char* getPointerToConnection(UStringRep* data) __pure
{
U_TRACE(5, "WiAuthUser::getPointerToConnection(%p)", data)
@ -2630,7 +2630,7 @@ next:
return ptr;
}
static bool isConnected(UStringRep* data)
static bool isConnected(UStringRep* data) __pure
{
U_TRACE(5, "WiAuthUser::isConnected(%p)", data)
@ -7463,7 +7463,7 @@ static void GET_admin_status_nodog_and_user_as_csv()
// TAVARNELLE
int WiAuthNodog::dbNodogFilter(UStringRep* key, UStringRep* data)
__pure int WiAuthNodog::dbNodogFilter(UStringRep* key, UStringRep* data)
{
U_TRACE(5, "WiAuthNodog::dbNodogFilter(%p,%p)", key, data)

View File

@ -165,6 +165,29 @@ private:
U_DISALLOW_COPY_AND_ASSIGN(ULib)
};
extern U_EXPORT const double u_pow10[309]; /* 1e-0...1e308: 309 * 8 bytes = 2472 bytes */
#ifndef HAVE_CXX11
static inline uint16_t u_dd(uint8_t i) { return U_MULTICHAR_CONSTANT16(u_ctn2s[i], u_ctn2s[i+1]); }
#else
static inline constexpr uint16_t u_dd(uint8_t i)
{
return U_MULTICHAR_CONSTANT16('0' + ((i%2) ? ((i/2)%10) : ((i/2)/10)),
'0' + (((i+1)%2) ? (((i+1)/2)%10) : (((i+1)/2)/10)));
}
static_assert( u_dd(0) == U_MULTICHAR_CONSTANT16('0','0'), "should be U_MULTICHAR_CONSTANT16('0','0')" );
static_assert( u_dd(1) == U_MULTICHAR_CONSTANT16('0','0'), "should be U_MULTICHAR_CONSTANT16('0','0')" );
static_assert( u_dd(2) == U_MULTICHAR_CONSTANT16('0','1'), "should be U_MULTICHAR_CONSTANT16('0','1')" );
static_assert( u_dd(3) == U_MULTICHAR_CONSTANT16('1','0'), "should be U_MULTICHAR_CONSTANT16('1','0')" );
static_assert( u_dd(4) == U_MULTICHAR_CONSTANT16('0','2'), "should be U_MULTICHAR_CONSTANT16('0','2')" );
template<typename T> static constexpr T pow10(size_t x) { return x ? 10*pow10<T>(x-1) : 1; }
static_assert( pow10<double>(29) == 1e+29, "should be 1e+29" ); // NB: fail for exponent >= 30
static_assert( pow10<uint64_t>(19) == 10000000000000000000ULL, "should be 1e+19" );
#endif
// Init library
#define U_ULIB_INIT(argv) U_SET_LOCATION_INFO, ULib::init(0, argv)

View File

@ -103,26 +103,6 @@ const char* u_ctn2s = "00010203040506070809"
"80818283848586878889"
"90919293949596979899";
const double u_pow10[309] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
1,
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
};
/* Startup */
bool u_is_tty;

View File

@ -42,6 +42,26 @@ U_EXPORT void operator delete[](void* p, long unsigned int) { free(p); }
# endif
#endif
const double u_pow10[309] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
1,
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
};
#if defined(USE_LIBSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
# include <openssl/ssl.h>
# include <openssl/rand.h>
@ -82,7 +102,7 @@ void ULib::init(const char* mempool, char** argv)
// conversion number => string
#ifndef HAVE_OLD_IOSTREAM
u_dbl2str = dtoa_rapidjson;
u_dbl2str = dtoa_rapidjson;
#endif
#ifdef DEBUG
char buffer[32];
@ -90,11 +110,11 @@ void ULib::init(const char* mempool, char** argv)
UMemoryPool::obj_class = "";
UMemoryPool::func_call = __PRETTY_FUNCTION__;
U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10)
U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0)
U_INTERNAL_ASSERT_EQUALS(u_dbl2str(1234567890, buffer)-buffer, 12)
U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890.0", 12), 0)
U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10)
U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0)
#endif
#if defined(HAVE_CXX14) && GCC_VERSION_NUM > 60100 && defined(HAVE_ARCH64)
@ -102,6 +122,7 @@ void ULib::init(const char* mempool, char** argv)
u_num2str64 = itoa_fwd;
U_INTERNAL_ASSERT_EQUALS(u_num2str64(1234567890, buffer)-buffer, 10)
U_INTERNAL_DUMP("buffer = %.10S", buffer)
U_INTERNAL_ASSERT_EQUALS(memcmp(buffer, "1234567890", 10), 0)
#endif

View File

@ -27,9 +27,6 @@
#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
extern const char* u_ctn2s;
extern const double u_pow10[309];
struct DiyFp {
DiyFp() : f(), e() {}
@ -337,7 +334,11 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
if (tmp <= delta) {
*K += kappa;
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(u_pow10[kappa]) << -one.e, wp_w.f);
# ifdef HAVE_CXX11
GrisuRound(buffer, *len, delta, tmp, pow10<uint64_t>(kappa) << -one.e, wp_w.f);
# else
GrisuRound(buffer, *len, delta, tmp, (uint64_t)u_pow10[kappa] << -one.e, wp_w.f);
# endif
return;
}
}
@ -354,92 +355,17 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
if (p2 < delta) {
*K += kappa;
int index = -static_cast<int>(kappa);
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? (const uint32_t)u_pow10[-static_cast<int>(kappa)] : 0));
# ifdef HAVE_CXX11
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? pow10<uint64_t>(index) : 0));
# else
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? (uint64_t)u_pow10[index] : 0));
# endif
return;
}
}
}
inline void Grisu2(double value, char* buffer, int* length, int* K) {
const DiyFp v(value);
DiyFp w_m, w_p;
v.NormalizedBoundaries(&w_m, &w_p);
const DiyFp c_mk = GetCachedPower(w_p.e, K);
const DiyFp W = v.Normalize() * c_mk;
DiyFp Wp = w_p * c_mk;
DiyFp Wm = w_m * c_mk;
Wm.f++;
Wp.f--;
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
}
inline char* WriteExponent(int K, char* buffer) {
if (K < 0) {
*buffer++ = '-';
K = -K;
}
if (K >= 100) {
*buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));
K %= 100;
const char* d = u_ctn2s + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else if (K >= 10) {
const char* d = u_ctn2s + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else
*buffer++ = static_cast<char>('0' + static_cast<char>(K));
return buffer;
}
inline char* Prettify(char* buffer, int length, int k) {
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
if (0 <= k && kk <= 21) {
// 1234e7 -> 12340000000
for (int i = length; i < kk; i++)
buffer[i] = '0';
buffer[kk] = '.';
buffer[kk + 1] = '0';
return &buffer[kk + 2];
}
else if (0 < kk && kk <= 21) {
// 1234e-2 -> 12.34
memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
buffer[kk] = '.';
return &buffer[length + 1];
}
else if (-6 < kk && kk <= 0) {
// 1234e-6 -> 0.001234
const int offset = 2 - kk;
memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
buffer[0] = '0';
buffer[1] = '.';
for (int i = 2; i < offset; i++)
buffer[i] = '0';
return &buffer[length + offset];
}
else if (length == 1) {
// 1e30
buffer[1] = 'e';
return WriteExponent(kk - 1, &buffer[2]);
}
else {
// 1234e30 -> 1.234e33
memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
buffer[1] = '.';
buffer[length + 1] = 'e';
return WriteExponent(kk - 1, &buffer[0 + length + 2]);
}
}
inline char* dtoa_rapidjson(double value, char* buffer)
static char* dtoa_rapidjson(double value, char* buffer)
{
Double d(value);
@ -449,19 +375,122 @@ inline char* dtoa_rapidjson(double value, char* buffer)
{
u_put_unalignedp32(buffer, U_MULTICHAR_CONSTANT32('-','0','.','0'));
return &buffer[4];
return buffer+4;
}
u_put_unalignedp32(buffer, U_MULTICHAR_CONSTANT32('0','.','0','\0'));
return &buffer[3];
return buffer+3;
}
int length, K;
int length, k;
const DiyFp v(value);
DiyFp w_m, w_p;
Grisu2(value, buffer, &length, &K);
v.NormalizedBoundaries(&w_m, &w_p);
return Prettify(buffer, length, K);
const DiyFp c_mk = GetCachedPower(w_p.e, &k);
const DiyFp W = v.Normalize() * c_mk;
DiyFp Wp = w_p * c_mk;
DiyFp Wm = w_m * c_mk;
Wm.f++;
Wp.f--;
DigitGen(W, Wp, Wp.f - Wm.f, buffer, &length, &k);
int kk = length + k; // 10^(kk-1) <= v < 10^kk
if (0 <= k &&
kk <= 21)
{
// 1234e7 -> 12340000000
memset(buffer+length, '0', k);
buffer += kk;
u_put_unalignedp16(buffer, U_MULTICHAR_CONSTANT16('.','0'));
return buffer+2;
}
if (0 < kk &&
kk <= 21)
{
// 1234e-2 -> 12.34
char* ptr = buffer+kk;
memmove(ptr+1, ptr, static_cast<size_t>(length - kk));
*ptr = '.';
return buffer+length+1;
}
if (-6 < kk &&
kk <= 0)
{
// 1234e-6 -> 0.001234
const int offset = 2 - kk;
memmove(buffer+offset, buffer, static_cast<size_t>(length));
u_put_unalignedp16(buffer, U_MULTICHAR_CONSTANT16('0','.'));
memset(buffer+2, '0', -kk);
return buffer+length+offset;
}
if (length == 1)
{
// 1e30
buffer[1] = 'e';
buffer += 2;
goto exp;
}
// 1234e30 -> 1.234e33
memmove(buffer+2, buffer+1, static_cast<size_t>(length - 1));
buffer[1] = '.';
buffer[length+1] = 'e';
buffer += length+2;
exp:
if (--kk < 0)
{
kk = -kk;
*buffer++ = '-';
}
if (kk >= 100)
{
*buffer++ = '0' + (kk / 100);
kk %= 100;
goto next;
}
if (kk >= 10)
{
next: u_put_unalignedp16(buffer, u_dd(kk * 2));
return buffer + 2;
}
*buffer++ = '0' + kk;
return buffer;
}
#endif

View File

@ -56,9 +56,11 @@ namespace dec_ {
// return reinterpret_cast<uint16_t const*>(digits.data())[u];
}
/*
template<typename T> static constexpr T pow10(size_t x) {
return x ? 10*pow10<T>(x-1) : 1;
}
*/
// Division by a power of 10 is implemented using a multiplicative inverse.
// This strength reduction is also done by optimizing compilers, but

View File

@ -1209,8 +1209,8 @@ mreal:
U_INTERNAL_ASSERT_MINOR(significandDigit, 17)
if (gexponent > 0) val = (double)integerPart * u_pow10[ gexponent];
else val = (double)integerPart / u_pow10[-gexponent];
val = (gexponent > 0 ? (double)integerPart * u_pow10[ gexponent]
: (double)integerPart / u_pow10[-gexponent]);
mreal1:
# ifdef DEBUG

View File

@ -103,9 +103,10 @@ void UOrmDriverMySql::handlerError()
U_ENTRY(CR_AUTH_PLUGIN_CANNOT_LOAD)
};
if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(mysql_error, "%p", (MYSQL*)UOrmDriver::connection);
UOrmDriver::errcode = U_SYSCALL(mysql_errno, "%p", (MYSQL*)UOrmDriver::connection);
UOrmDriver::SQLSTATE = U_SYSCALL(mysql_sqlstate, "%p", (MYSQL*)UOrmDriver::connection);
UOrmDriver::errcode = U_SYSCALL(mysql_errno, "%p", (MYSQL*)UOrmDriver::connection);
UOrmDriver::SQLSTATE = U_SYSCALL(mysql_sqlstate, "%p", (MYSQL*)UOrmDriver::connection);
if (UOrmDriver::errmsg == 0) UOrmDriver::errmsg = U_SYSCALL(mysql_error, "%p", (MYSQL*)UOrmDriver::connection);
if (UOrmDriver::errcode >= CR_ERROR_FIRST) UOrmDriver::errcode -= CR_ERROR_FIRST; // 2000

View File

@ -2256,7 +2256,7 @@ void UHTTP2::handlerResponse()
default: // use literal header field without indexing - indexed name
{
u_put_unalignedp32(ptr+HTTP2_FRAME_HEADER_SIZE, U_MULTICHAR_CONSTANT32(0x08,0x03,0x30+(U_http_info.nResponseCode / 100),'\0'));
U_NUM2STR16(ptr+HTTP2_FRAME_HEADER_SIZE+3, U_http_info.nResponseCode % 100);
u_put_unalignedp16(ptr+HTTP2_FRAME_HEADER_SIZE+3, u_dd(U_http_info.nResponseCode % 100));
sz += 4;
dst += 4;