summaryrefslogtreecommitdiff
path: root/boost/convert/strtol.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/convert/strtol.hpp')
-rw-r--r--boost/convert/strtol.hpp32
1 files changed, 16 insertions, 16 deletions
diff --git a/boost/convert/strtol.hpp b/boost/convert/strtol.hpp
index de5aa29a8a..4dd26eef7f 100644
--- a/boost/convert/strtol.hpp
+++ b/boost/convert/strtol.hpp
@@ -76,16 +76,16 @@ boost::cnv::strtol::i_to_str(Type in_value, char_type* buf) const
typedef typename boost::make_unsigned<Type>::type unsigned_type;
- char_type* beg = buf + bufsize_ / 2;
- char_type* end = beg;
- bool const is_negative = in_value < 0;
- unsigned_type value = static_cast<unsigned_type>(is_negative ? -in_value : in_value);
+ char_type* beg = buf + bufsize_ / 2;
+ char_type* end = beg;
+ bool const is_neg = std::is_signed<Type>::value && in_value < 0;
+ unsigned_type value = static_cast<unsigned_type>(is_neg ? -in_value : in_value);
if (base_ == 10) for (; value; *(--beg) = int(value % 10) + '0', value /= 10); //C1
else for (; value; *(--beg) = get_char(value % base_), value /= base_);
- if (beg == end) *(--beg) = '0';
- if (is_negative) *(--beg) = '-';
+ if (beg == end) *(--beg) = '0';
+ if (is_neg) *(--beg) = '-';
return cnv::range<char_type*>(beg, end);
}
@@ -197,20 +197,20 @@ template<typename string_type, typename out_type>
void
boost::cnv::strtol::str_to_d(cnv::range<string_type> range, optional<out_type>& result_out) const
{
- // C2. Simply check if the end-of-string was reached -- *cnv_end == 0
- // instead of traversing once with strlen() to find the end iterator
- // and then comparing to it as in
- // char const* end = str + strlen(str); // Unnecessary traversal!
- // bool const good = ... && cnv_end == end;
+ // C1. Because of strtold() currently only works with 'char'
+ // C2. strtold() does not work with ranges.
+ // Consequently, we have to copy the supplied range into a string for strtold().
+ // C3. Check if the end-of-string was reached -- *cnv_end == 0.
typedef cnv::range<string_type> range_type;
typedef typename range_type::value_type ch_type;
- ch_type const* str = &*range.begin(); // Currently only works with 'char'
- char* cnv_end = 0;
- ldbl_type result = strtold(str, &cnv_end);
- bool good = result != -HUGE_VALL && result != HUGE_VALL && *cnv_end == 0/*C2*/;
- out_type max = (std::numeric_limits<out_type>::max)();
+ size_t const sz = 128;
+ ch_type str[sz] = {0}; std::strncpy(str, &*range.begin(), std::min(sz - 1, range.size()));
+ char* cnv_end = 0;
+ ldbl_type result = strtold(str, &cnv_end);
+ bool good = result != -HUGE_VALL && result != HUGE_VALL && *cnv_end == 0; //C3
+ out_type max = (std::numeric_limits<out_type>::max)();
if (good && -max <= result && result <= max)
result_out = out_type(result);