Refactor conversion from integer to string

Unify the implementations by automatically deducing the unsigned type from its
signed counterpart. That allows us to use a templated function instead of
duplicating code.
This commit is contained in:
Arseny Kapoulkine 2016-02-02 10:44:35 -08:00
parent ac4a84df4d
commit 607e46f209

View File

@ -4492,11 +4492,27 @@ PUGI__NS_BEGIN
} }
#endif #endif
template <typename U> template <typename T> struct make_unsigned;
PUGI__FN char_t* integer_to_string(char_t* begin, char_t* end, U value, bool negative)
template <> struct make_unsigned<int> { typedef unsigned int type; };
template <> struct make_unsigned<unsigned int> { typedef unsigned int type; };
template <> struct make_unsigned<long> { typedef unsigned long type; };
template <> struct make_unsigned<unsigned long> { typedef unsigned long type; };
#ifdef PUGIXML_HAS_LONG_LONG
template <> struct make_unsigned<long long> { typedef unsigned long long type; };
template <> struct make_unsigned<unsigned long long> { typedef unsigned long long type; };
#endif
template <typename T>
PUGI__FN char_t* integer_to_string(char_t* begin, char_t* end, T value)
{ {
typedef typename make_unsigned<T>::type U;
bool negative = value < 0;
char_t* result = end - 1; char_t* result = end - 1;
U rest = negative ? 0 - value : value; U rest = negative ? 0 - U(value) : U(value);
do do
{ {
@ -4530,42 +4546,12 @@ PUGI__NS_BEGIN
#endif #endif
} }
template <typename String, typename Header> template <typename String, typename Header, typename Integer>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, int value) PUGI__FN bool set_value_integer(String& dest, Header& header, uintptr_t header_mask, Integer value)
{ {
char_t buf[64]; char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]); char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned int>(buf, end, value, value < 0); char_t* begin = integer_to_string(buf, end, value);
return strcpy_insitu(dest, header, header_mask, begin, end - begin);
}
template <typename String, typename Header>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned int value)
{
char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned int>(buf, end, value, false);
return strcpy_insitu(dest, header, header_mask, begin, end - begin);
}
template <typename String, typename Header>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long value)
{
char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned long>(buf, end, value, value < 0);
return strcpy_insitu(dest, header, header_mask, begin, end - begin);
}
template <typename String, typename Header>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long value)
{
char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned long>(buf, end, value, false);
return strcpy_insitu(dest, header, header_mask, begin, end - begin); return strcpy_insitu(dest, header, header_mask, begin, end - begin);
} }
@ -4594,28 +4580,6 @@ PUGI__NS_BEGIN
return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"), value ? 4 : 5); return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"), value ? 4 : 5);
} }
#ifdef PUGIXML_HAS_LONG_LONG
template <typename String, typename Header>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long long value)
{
char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned long long>(buf, end, value, value < 0);
return strcpy_insitu(dest, header, header_mask, begin, end - begin);
}
template <typename String, typename Header>
PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long long value)
{
char_t buf[64];
char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
char_t* begin = integer_to_string<unsigned long long>(buf, end, value, false);
return strcpy_insitu(dest, header, header_mask, begin, end - begin);
}
#endif
PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer)
{ {
// check input buffer // check input buffer
@ -5236,28 +5200,28 @@ namespace pugi
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
PUGI__FN bool xml_attribute::set_value(unsigned int rhs) PUGI__FN bool xml_attribute::set_value(unsigned int rhs)
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
PUGI__FN bool xml_attribute::set_value(long rhs) PUGI__FN bool xml_attribute::set_value(long rhs)
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
PUGI__FN bool xml_attribute::set_value(unsigned long rhs) PUGI__FN bool xml_attribute::set_value(unsigned long rhs)
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
PUGI__FN bool xml_attribute::set_value(double rhs) PUGI__FN bool xml_attribute::set_value(double rhs)
@ -5286,14 +5250,14 @@ namespace pugi
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) PUGI__FN bool xml_attribute::set_value(unsigned long long rhs)
{ {
if (!_attr) return false; if (!_attr) return false;
return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); return impl::set_value_integer(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
} }
#endif #endif
@ -6391,28 +6355,28 @@ namespace pugi
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
PUGI__FN bool xml_text::set(unsigned int rhs) PUGI__FN bool xml_text::set(unsigned int rhs)
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
PUGI__FN bool xml_text::set(long rhs) PUGI__FN bool xml_text::set(long rhs)
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
PUGI__FN bool xml_text::set(unsigned long rhs) PUGI__FN bool xml_text::set(unsigned long rhs)
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
PUGI__FN bool xml_text::set(float rhs) PUGI__FN bool xml_text::set(float rhs)
@ -6441,14 +6405,14 @@ namespace pugi
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
PUGI__FN bool xml_text::set(unsigned long long rhs) PUGI__FN bool xml_text::set(unsigned long long rhs)
{ {
xml_node_struct* dn = _data_new(); xml_node_struct* dn = _data_new();
return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; return dn ? impl::set_value_integer(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
} }
#endif #endif