Implement integer to string conversion manually
This reduces the amount of non-standard C++ functionality pugixml may be using by avoiding sprintf with %lld; additionally this implementation is significantly faster (4-5x) than sprintf, mostly due to avoiding format string parsing and stream setup that commonly happens in CRT implementations. This comes at the expense of requiring long long division/remainder operations if PUGIXML_USE_LONG_LONG is defined which will surely bite me one day.
This commit is contained in:
parent
234c2f3657
commit
131c1a159c
@ -4540,6 +4540,28 @@ PUGI__NS_BEGIN
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
PUGI__FN char_t* integer_to_string(char_t (&buf)[64], U value, bool negative)
|
||||||
|
{
|
||||||
|
char_t* end = buf + sizeof(buf) / sizeof(buf[0]) - 1;
|
||||||
|
U rest = negative ? 0 - value : value;
|
||||||
|
|
||||||
|
*end-- = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*end-- = static_cast<char_t>('0' + (rest % 10));
|
||||||
|
rest /= 10;
|
||||||
|
}
|
||||||
|
while (rest);
|
||||||
|
|
||||||
|
assert(end >= buf);
|
||||||
|
|
||||||
|
*end = '-';
|
||||||
|
|
||||||
|
return end + !negative;
|
||||||
|
}
|
||||||
|
|
||||||
// set value with conversion functions
|
// set value with conversion functions
|
||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
PUGI__FN bool set_value_buffer(String& dest, Header& header, uintptr_t header_mask, char (&buf)[128])
|
PUGI__FN bool set_value_buffer(String& dest, Header& header, uintptr_t header_mask, char (&buf)[128])
|
||||||
@ -4557,19 +4579,19 @@ PUGI__NS_BEGIN
|
|||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, int value)
|
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, int value)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char_t buf[64];
|
||||||
sprintf(buf, "%d", value);
|
char_t* begin = integer_to_string<unsigned int>(buf, value, value < 0);
|
||||||
|
|
||||||
return set_value_buffer(dest, header, header_mask, buf);
|
return strcpy_insitu(dest, header, header_mask, begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned int value)
|
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned int value)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char_t buf[64];
|
||||||
sprintf(buf, "%u", value);
|
char_t* begin = integer_to_string<unsigned int>(buf, value, false);
|
||||||
|
|
||||||
return set_value_buffer(dest, header, header_mask, buf);
|
return strcpy_insitu(dest, header, header_mask, begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
@ -4600,19 +4622,19 @@ PUGI__NS_BEGIN
|
|||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long long value)
|
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long long value)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char_t buf[64];
|
||||||
sprintf(buf, "%lld", value);
|
char_t* begin = integer_to_string<unsigned long long>(buf, value, value < 0);
|
||||||
|
|
||||||
return set_value_buffer(dest, header, header_mask, buf);
|
return strcpy_insitu(dest, header, header_mask, begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename String, typename Header>
|
template <typename String, typename Header>
|
||||||
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long long value)
|
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long long value)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char_t buf[64];
|
||||||
sprintf(buf, "%llu", value);
|
char_t* begin = integer_to_string<unsigned long long>(buf, value, false);
|
||||||
|
|
||||||
return set_value_buffer(dest, header, header_mask, buf);
|
return strcpy_insitu(dest, header, header_mask, begin);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user