14#include <l4/cxx/minmax>
16#include <l4/sys/cxx/limits>
40 String(
char const *s) noexcept : _start(s), _len(__builtin_strlen(s)) {}
42 String(
char const *s,
unsigned long len) noexcept : _start(s), _len(
len) {}
50 String(
char const *s,
char const *e) noexcept : _start(s), _len(e - s) {}
60 int len()
const {
return _len; }
63 void start(
char const *s) { _start = s; }
67 bool empty()
const {
return !_len; }
91 return String(_start + idx, cxx::min(
len, _len - idx));
99 unsigned long nlen = _start + _len -
start;
101 nlen = cxx::min(nlen,
len);
109 template<
typename F >
126 char const *
find(
char const *c)
const
134 char const *
rfind(
char const *c)
const
139 char const *p =
end();
160 for (i = 0; i < c._len && i < _len; ++i)
161 if (_start[i] != c[i])
163 return i == c._len ?
start() + i : 0;
167 char const *
find(
int c,
char const *s)
const
193 char const *
find(
char const *c,
char const *s)
const
203 for (
char const *x = c; *x; ++x)
212 char const &
operator [] (
unsigned long idx)
const {
return _start[idx]; }
219 bool eof(
char const *s)
const {
return s >= _start + _len || !*s; }
229 template<
typename INT>
237 if (*c >=
'0' && *c <=
'9')
258 template<
typename INT>
267 if (shift >
sizeof(INT) * 8)
270 if (*c >=
'0' && *c <=
'9')
272 else if (*c >=
'A' && *c <=
'F')
274 else if (*c >=
'a' && *c <=
'f')
308 template<
typename INT>
313 typedef unsigned long long Acc;
315 if (base == 1 || base > 36)
319 auto to_digit = [](
char c,
unsigned b) ->
int
322 if (c >=
'0' && c <=
'9')
324 else if (c >=
'a' && c <=
'z')
326 else if (c >=
'A' && c <=
'Z')
331 return d < static_cast<int>(b) ? d : -1;
336 bool have_digits =
false;
339 while (!
eof(i) && (*i ==
' ' || *i ==
'\t'))
343 if (!
eof(i) && (*i ==
'-' || *i ==
'+'))
351 if ((base == 0 || base == 16) && !
eof(i) && *i ==
'0')
356 if ( !
eof(i) && (*i ==
'x' || *i ==
'X')
357 && !
eof(i + 1) && to_digit(i[1], 16) >= 0)
368 constexpr INT Max = L4::Types::numeric_limits<INT>::max();
369 constexpr INT Min = L4::Types::numeric_limits<INT>::min();
373 Acc
const limit =
static_cast<Acc
>(Max) + ((Min != 0 && negate) ? 1U : 0U);
374 Acc
const lim_div = limit / base;
375 Acc
const lim_mod = limit % base;
381 int d = to_digit(*i, base);
385 if (acc > lim_div || (acc == lim_div &&
static_cast<Acc
>(d) > lim_mod))
388 acc = acc * base +
static_cast<Acc
>(d);
397 *v =
static_cast<INT
>(acc);
398 else if (Min != 0 && acc ==
static_cast<Acc
>(Max) + 1U)
401 *v =
static_cast<INT
>(-
static_cast<INT
>(acc));
412 for (
unsigned long i = 0; i < _len; ++i)
413 if (_start[i] != o._start[i])
432L4::BasicOStream &operator << (L4::BasicOStream &s,
cxx::String const &str)
Allocation free string class with explicit length field.
String head(unsigned long end) const
Prefix of length end.
Index start() const
Pointer to first character.
Index end() const
Pointer to first byte behind the string.
char const * find(char const *c, char const *s) const
Find character set at position.
int from_hex(INT *v) const
Convert hex string to integer.
String(char const *s) noexcept
Initialize from a zero-terminated string.
bool operator==(String const &o) const
Equality.
String(char const *s, char const *e) noexcept
Initialize with start and end pointer.
char const * find(int c, char const *s) const
Find character c starting at position s. Return end() if not found.
void len(unsigned long len)
Set length.
bool empty() const
Check if the string has length zero.
bool eof(char const *s) const
Check if pointer s points behind string.
char const * find(char const *c) const
Find character. Return end() if not found.
String(char const *s, unsigned long len) noexcept
Initialize from a pointer to first character and a length.
String substr(unsigned long idx, unsigned long len=~0UL) const
Substring of length len starting at idx.
char const * find_match(F &&match) const
Find matching character. match should be a function such as isspace.
int from_number(INT *v, unsigned base=0) const
Convert a number string to an integer.
char const * find(int c) const
Find character. Return end() if not found.
String head(Index end) const
Return prefix up to index.
char const * Index
Character index type.
int from_dec(INT *v) const
Convert decimal string to integer.
bool operator!=(String const &o) const
Inequality.
void start(char const *s)
Set start.
Index starts_with(cxx::String const &c) const
Check if c is a prefix of string.
char const * rfind(char const *c) const
Find right-most character. Return end() if not found.
char const & operator[](unsigned long idx) const
Get character at idx.
String()
Zero-initialize. Create an invalid string.
String substr(char const *start, unsigned long len=0) const
Substring of length len starting at start.
@ L4_EINVAL
Invalid argument.