Skip to content

Commit e83abd7

Browse files
authored
[libc] Template StringConverter pop function to avoid duplicate code (#152204)
Addressed TODO to template the StringConverter pop functions to have a single implementation (combine popUTF8 and popUTF32 into a single templated pop function)
1 parent 09dbdf6 commit e83abd7

File tree

6 files changed

+72
-99
lines changed

6 files changed

+72
-99
lines changed

libc/src/__support/wchar/character_converter.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,6 @@ ErrorOr<char32_t> CharacterConverter::pop_utf32() {
132132
return utf32;
133133
}
134134

135-
size_t CharacterConverter::sizeAsUTF32() {
136-
return 1; // a single utf-32 value can fit an entire character
137-
}
138-
139-
size_t CharacterConverter::sizeAsUTF8() { return state->total_bytes; }
140-
141135
ErrorOr<char8_t> CharacterConverter::pop_utf8() {
142136
if (isEmpty())
143137
return Error(-1);

libc/src/__support/wchar/character_converter.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "hdr/types/char32_t.h"
1313
#include "hdr/types/char8_t.h"
1414
#include "hdr/types/size_t.h"
15+
#include "src/__support/CPP/type_traits.h"
1516
#include "src/__support/common.h"
1617
#include "src/__support/error_or.h"
1718
#include "src/__support/wchar/mbstate.h"
@@ -31,14 +32,18 @@ class CharacterConverter {
3132
bool isEmpty();
3233
bool isValidState();
3334

34-
size_t sizeAsUTF32();
35-
size_t sizeAsUTF8();
35+
template <typename CharType> size_t sizeAs();
36+
template <> size_t sizeAs<char8_t>() { return state->total_bytes; }
37+
template <> size_t sizeAs<char32_t>() { return 1; }
3638

3739
int push(char8_t utf8_byte);
3840
int push(char32_t utf32);
3941

4042
ErrorOr<char8_t> pop_utf8();
4143
ErrorOr<char32_t> pop_utf32();
44+
template <typename CharType> ErrorOr<CharType> pop();
45+
template <> ErrorOr<char8_t> pop() { return pop_utf8(); }
46+
template <> ErrorOr<char32_t> pop() { return pop_utf32(); }
4247
};
4348

4449
} // namespace internal

libc/src/__support/wchar/mbsnrtowcs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
3636
StringConverter<char8_t> str_conv(reinterpret_cast<const char8_t *>(*src), ps,
3737
len, nmc);
3838
size_t dst_idx = 0;
39-
ErrorOr<char32_t> converted = str_conv.popUTF32();
39+
ErrorOr<char32_t> converted = str_conv.pop<char32_t>();
4040
while (converted.has_value()) {
4141
if (dst != nullptr)
4242
dst[dst_idx] = converted.value();
@@ -47,7 +47,7 @@ LIBC_INLINE static ErrorOr<size_t> mbsnrtowcs(wchar_t *__restrict dst,
4747
return dst_idx;
4848
}
4949
dst_idx++;
50-
converted = str_conv.popUTF32();
50+
converted = str_conv.pop<char32_t>();
5151
}
5252

5353
if (converted.error() == -1) { // if we hit conversion limit

libc/src/__support/wchar/string_converter.h

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "hdr/types/char32_t.h"
1313
#include "hdr/types/char8_t.h"
1414
#include "hdr/types/size_t.h"
15+
#include "src/__support/CPP/type_traits.h"
1516
#include "src/__support/common.h"
1617
#include "src/__support/error_or.h"
1718
#include "src/__support/wchar/character_converter.h"
@@ -53,9 +54,7 @@ template <typename T> class StringConverter {
5354
size_t srclen = SIZE_MAX)
5455
: cr(ps), src(s), src_len(srclen), src_idx(0), num_to_write(dstlen) {}
5556

56-
// TODO: following functions are almost identical
57-
// look into templating CharacterConverter pop functions
58-
ErrorOr<char32_t> popUTF32() {
57+
template <typename CharType> ErrorOr<CharType> pop() {
5958
if (num_to_write == 0)
6059
return Error(-1);
6160

@@ -64,42 +63,17 @@ template <typename T> class StringConverter {
6463
if (!src_elements_read.has_value())
6564
return Error(src_elements_read.error());
6665

67-
if (cr.sizeAsUTF32() > num_to_write) {
66+
if (cr.sizeAs<CharType>() > num_to_write) {
6867
cr.clear();
6968
return Error(-1);
7069
}
7170

7271
src_idx += src_elements_read.value();
7372
}
7473

75-
auto out = cr.pop_utf32();
76-
if (out.has_value() && out.value() == L'\0')
77-
src_len = src_idx;
78-
79-
num_to_write--;
80-
81-
return out;
82-
}
83-
84-
ErrorOr<char8_t> popUTF8() {
85-
if (num_to_write == 0)
86-
return Error(-1);
87-
88-
if (cr.isEmpty() || src_idx == 0) {
89-
auto src_elements_read = pushFullCharacter();
90-
if (!src_elements_read.has_value())
91-
return Error(src_elements_read.error());
92-
93-
if (cr.sizeAsUTF8() > num_to_write) {
94-
cr.clear();
95-
return Error(-1);
96-
}
97-
98-
src_idx += src_elements_read.value();
99-
}
100-
101-
auto out = cr.pop_utf8();
102-
if (out.has_value() && out.value() == '\0')
74+
ErrorOr<CharType> out = cr.pop<CharType>();
75+
// if out isn't null terminator or an error
76+
if (out.has_value() && out.value() == 0)
10377
src_len = src_idx;
10478

10579
num_to_write--;

libc/src/__support/wchar/wcsnrtombs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
3939
reinterpret_cast<const char32_t *>(*ptr_to_src), ps, dest_len,
4040
num_src_widechars);
4141
size_t dst_idx = 0;
42-
ErrorOr<char8_t> converted = str_conv.popUTF8();
42+
ErrorOr<char8_t> converted = str_conv.pop<char8_t>();
4343
while (converted.has_value()) {
4444
if (dest != nullptr)
4545
dest[dst_idx] = converted.value();
@@ -51,7 +51,7 @@ wcsnrtombs(char *__restrict dest, const wchar_t **__restrict ptr_to_src,
5151
}
5252

5353
dst_idx++;
54-
converted = str_conv.popUTF8();
54+
converted = str_conv.pop<char8_t>();
5555
}
5656

5757
if (dest != nullptr)

0 commit comments

Comments
 (0)