33#include < cstdint>
44#include < cstring>
55#include < iostream>
6- #include < streambuf >
6+ #include < sstream >
77#include < vector>
88
9- #ifdef __APPLE__
10- # include < locale>
11-
12- // / @brief Custom ctype specialization for uint8_t to work around libc++
13- // / limitation in macOS
14- template <> struct std ::ctype<uint8_t > : public std::ctype_base {
15- using char_type = uint8_t ;
16- static std::locale::id id;
17-
18- ctype () : std::ctype_base() {}
19-
20- ctype ([[maybe_unused]] const std::locale::facet & other) : std::ctype_base() {}
21-
22- ctype & operator =(const ctype & other) {
23- if (this != &other) {
24- std::ctype_base::operator =(other);
25- }
26- return *this ;
27- }
28-
29- // Required public interface methods
30- bool is (mask m, [[maybe_unused]] char_type c) const {
31- return (m & space) != 0 ; // Treat all uint8_t as non-space
32- }
33-
34- const char_type * is (const char_type * low, const char_type * high, mask * vec) const {
35- for (; low != high; ++low, ++vec) {
36- *vec = 0 ; // No special character properties
37- }
38- return high;
39- }
40-
41- const char_type * scan_is (mask m, const char_type * low, const char_type * high) const {
42- for (; low != high; ++low) {
43- if (is (m, *low)) {
44- return low;
45- }
46- }
47- return high;
48- }
49-
50- const char_type * scan_not (mask m, const char_type * low, const char_type * high) const {
51- for (; low != high; ++low) {
52- if (!is (m, *low)) {
53- return low;
54- }
55- }
56- return high;
57- }
58-
59- char_type toupper (char_type c) const {
60- return c; // No case conversion for uint8_t
61- }
62-
63- const char_type * toupper ([[maybe_unused]] char_type * low, const char_type * high) const {
64- return high; // No case conversion for uint8_t
65- }
66-
67- char_type tolower (char_type c) const {
68- return c; // No case conversion for uint8_t
69- }
70-
71- const char_type * tolower ([[maybe_unused]] char_type * low, const char_type * high) const {
72- return high; // No case conversion for uint8_t
73- }
74-
75- char_type widen (char c) const { return static_cast <char_type>(c); }
76-
77- const char * widen (const char * low, const char * high, char_type * dest) const {
78- for (; low != high; ++low, ++dest) {
79- *dest = static_cast <char_type>(*low);
80- }
81- return high;
82- }
83-
84- char narrow (char_type c, [[maybe_unused]] char dfault) const { return static_cast <char >(c); }
85-
86- const char_type * narrow (const char_type * low, const char_type * high, [[maybe_unused]] char dfault,
87- char * dest) const {
88- for (; low != high; ++low, ++dest) {
89- *dest = static_cast <char >(*low);
90- }
91- return high;
92- }
93- };
94- #endif
95-
96- // / @brief Custom traits for uint8_t for usage in std template classes that use char_traits (e.g. std::basic_streambuf)
97- template <> struct std ::char_traits<uint8_t > {
98- using char_type = uint8_t ;
99- using int_type = int ;
100- using off_type = std::streamoff;
101- using pos_type = std::streampos;
102- using state_type = std::mbstate_t ;
103-
104- static void assign (char_type & c1, const char_type & c2) noexcept { c1 = c2; }
105-
106- static constexpr bool eq (char_type a, char_type b) noexcept { return a == b; }
107-
108- static constexpr bool lt (char_type a, char_type b) noexcept { return a < b; }
109-
110- static int compare (const char_type * s1, const char_type * s2, std::size_t n) {
111- for (std::size_t i = 0 ; i < n; ++i) {
112- if (lt (s1[i], s2[i])) {
113- return -1 ;
114- }
115- if (lt (s2[i], s1[i])) {
116- return 1 ;
117- }
118- }
119- return 0 ;
120- }
121-
122- static std::size_t length (const char_type * s) {
123- std::size_t i = 0 ;
124- while (!eq (s[i], char_type ())) {
125- ++i;
126- }
127- return i;
128- }
129-
130- static const char_type * find (const char_type * s, std::size_t n, const char_type & c) {
131- for (std::size_t i = 0 ; i < n; ++i) {
132- if (eq (s[i], c)) {
133- return s + i;
134- }
135- }
136- return nullptr ;
137- }
138-
139- static char_type * move (char_type * s1, const char_type * s2, std::size_t n) {
140- return static_cast <char_type *>(std::memmove (s1, s2, n));
141- }
142-
143- static char_type * copy (char_type * s1, const char_type * s2, std::size_t n) {
144- return static_cast <char_type *>(std::memcpy (s1, s2, n));
145- }
146-
147- static char_type * assign (char_type * s, std::size_t n, char_type c) {
148- for (std::size_t i = 0 ; i < n; ++i) {
149- s[i] = c;
150- }
151- return s;
152- }
153-
154- static constexpr int_type not_eof (int_type c) noexcept { return eq_int_type (c, eof ()) ? 0 : c; }
155-
156- static constexpr char_type to_char_type (int_type c) noexcept {
157- return c >= 0 && c <= 255 ? static_cast <char_type>(c) : char_type ();
158- }
159-
160- static constexpr int_type to_int_type (char_type c) noexcept { return static_cast <int_type>(c); }
161-
162- static constexpr bool eq_int_type (int_type c1, int_type c2) noexcept { return c1 == c2; }
163-
164- static constexpr int_type eof () noexcept { return static_cast <int_type>(-1 ); }
165- };
166-
1679#ifdef GGML_SHARED
16810# if defined(_WIN32) && !defined(__MINGW32__)
16911# ifdef GGML_BUILD
@@ -178,8 +20,10 @@ template <> struct std::char_traits<uint8_t> {
17820# define GGML_CLASS_API
17921#endif
18022
181- // / @brief Custom streambuf for uint8_t
182- class GGML_CLASS_API Uint8BufferStreamBuf : public std::basic_streambuf<uint8_t > {
23+ // / @brief Custom basic_streambuf<char> for uint8_t input data, that owns the underlying data.
24+ // / @note basic_streambuf<char> has more support on different platforms than basic_streambuf<uint8_t>
25+ // / which is missing on some platforms (e.g. MacOS, newer NDKs). C++ 17 provides additional guarantees for char.
26+ class GGML_CLASS_API Uint8BufferStreamBuf : public std::basic_streambuf<char > {
18327 public:
18428 Uint8BufferStreamBuf (std::vector<uint8_t > && _data);
18529
0 commit comments