Skip to content

Commit d9e606e

Browse files
committed
Distinguish between end of value and end of container
1 parent 5983ed3 commit d9e606e

File tree

1 file changed

+28
-34
lines changed

1 file changed

+28
-34
lines changed

include/boost/decimal/detail/locale_conversion.hpp

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,16 @@ inline int convert_pointer_pair_to_local_locale(char* first, char* last, const s
9898
++start;
9999
}
100100

101+
// Find the actual end of the string
102+
auto string_end {start};
103+
while (string_end < last && *string_end != '\0')
104+
{
105+
++string_end;
106+
}
107+
101108
// Find decimal point position
102109
char* decimal_pos {nullptr};
103-
for (char* p = start; p < last; ++p)
110+
for (char* p = start; p < string_end; ++p)
104111
{
105112
if (*p == '.')
106113
{
@@ -110,25 +117,8 @@ inline int convert_pointer_pair_to_local_locale(char* first, char* last, const s
110117
}
111118
}
112119

113-
// If there is no fractional part we still need to find where the end of the integer is
114-
// We've already inserted a null terminator for ourselves
115-
char* last_digit {start};
116-
if (decimal_pos == nullptr)
117-
{
118-
for (const char* p = start; p < last; ++p)
119-
{
120-
if (*p != '\0')
121-
{
122-
++last_digit;
123-
}
124-
else
125-
{
126-
break;
127-
}
128-
}
129-
}
130-
131-
const auto int_end {decimal_pos != nullptr ? decimal_pos : last_digit};
120+
// Determine the end of the integer part
121+
const auto int_end {decimal_pos != nullptr ? decimal_pos : string_end};
132122
const auto int_digits {static_cast<int>(int_end - start)};
133123

134124
// Calculate how many separators we need
@@ -144,33 +134,43 @@ inline int convert_pointer_pair_to_local_locale(char* first, char* last, const s
144134
// If we need to add separators, shift content and insert them
145135
if (num_separators > 0)
146136
{
147-
const auto original_length {static_cast<int>(last - first)};
137+
const auto original_length {static_cast<int>(string_end - first)};
148138
const auto new_length {original_length + num_separators};
149139

140+
// Check if we have enough space in the buffer
141+
if (first + new_length >= last)
142+
{
143+
// Not enough space, return error indicator
144+
return -1;
145+
}
146+
150147
// Shift everything after the integer part to make room
151148
// Work backwards to avoid overwriting
152-
auto old_pos {last - 1};
153-
auto new_pos {first + new_length - 1};
149+
auto old_pos {string_end};
150+
auto new_pos {first + new_length};
154151

155-
// Copy from end back to the end of integer part
152+
// Copy from end (including null terminator) back to the end of integer part
156153
while (old_pos >= int_end)
157154
{
158155
*new_pos-- = *old_pos--;
159156
}
160157

161-
int digit_count {};
158+
// Now insert the integer digits with separators
159+
// Count digits from right to left (from decimal point backwards)
162160
old_pos = int_end - 1;
161+
int digits_from_right {1};
163162

164163
while (old_pos >= start)
165164
{
166165
*new_pos-- = *old_pos--;
167-
++digit_count;
168166

169-
// Insert separator after every grouping_size digits (but not at the start)
170-
if (digit_count % grouping_size == 0 && old_pos >= start)
167+
// Insert separator after every grouping_size digits from the right
168+
// but not after the leftmost digit
169+
if (old_pos >= start && digits_from_right % grouping_size == 0)
171170
{
172171
*new_pos-- = locale_thousands_sep;
173172
}
173+
++digits_from_right;
174174
}
175175
}
176176

@@ -183,12 +183,6 @@ inline int convert_pointer_pair_to_local_locale(char* first, char* last)
183183
return convert_pointer_pair_to_local_locale(first, last, loc);
184184
}
185185

186-
inline int convert_string_to_local_locale(char* buffer) noexcept
187-
{
188-
const auto loc {std::locale()};
189-
return convert_pointer_pair_to_local_locale(buffer, buffer + std::strlen(buffer), loc);
190-
}
191-
192186
inline int convert_string_to_local_locale(char* buffer, const std::locale& loc) noexcept
193187
{
194188
return convert_pointer_pair_to_local_locale(buffer, buffer + std::strlen(buffer), loc);

0 commit comments

Comments
 (0)