diff options
Diffstat (limited to 'libk/string.h')
-rw-r--r-- | libk/string.h | 106 |
1 files changed, 81 insertions, 25 deletions
diff --git a/libk/string.h b/libk/string.h index deb6fde..0675cea 100644 --- a/libk/string.h +++ b/libk/string.h @@ -1,19 +1,24 @@ #pragma once -#include "types.h" - -constexpr size_t strlen(const char *str) { - int len = 0; +#include <type_traits.h> +#include <types.h> + +/** + * Calculate the length of the string (in bytes) pointed to by str, excluding + * the terminating null character. + */ +constexpr size_t strlen(const char* str) { + size_t len = 0; while (str[len]) ++len; return len; } /* reverse: reverse string s in place */ -constexpr void reverse(char s[]) { +constexpr void reverse(char s[], int strlen) { int i, j; char c; - for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { + for (i = 0, j = strlen - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; @@ -21,49 +26,100 @@ constexpr void reverse(char s[]) { } /* itoa: convert n to characters in s */ -template <int base = 10> constexpr void itoa(int n, char s[]) { - int i, sign; - - if ((sign = n) < 0) /* record sign */ - n = -n; /* make n positive */ +template <typename T, int base = 10> +constexpr size_t itoa(T n, char s[]) { + const bool is_negative = (n < 0); + if constexpr (!is_unsigned<T>()) { + if (n < 0) + n = -n; + } - i = 0; - do { /* generate digits in reverse order */ + int i = 0; + do { /* generate digits in reverse order */ s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ } while ((n /= base) > 0); /* delete it */ - if (sign < 0) + if (is_negative) s[i++] = '-'; s[i] = '\0'; - reverse(s); + reverse(s, i); + return i; } -class String { +class ViewIterator { public: - class Iterator { - friend class String; + virtual char next() = 0; + virtual operator bool() const = 0; +}; + +class StringView { +public: + class Iterator : public ViewIterator { + friend class StringView; public: - char next() { return p->buffer[pos++]; } - operator bool() const { return (pos < p->m_length); } + char next() override { return p->buffer[pos++]; } + operator bool() const override { return (pos < p->m_length); } private: - Iterator(const String *s) : p(s) {} + Iterator(const StringView* s) : p(s) {} size_t pos = 0; - const String *p; + const StringView* p; }; friend class Iterator; - String(const char *d) : buffer{d}, m_length{strlen(d)} {} - String(const char *d, size_t l) : buffer{d}, m_length{l} {} + StringView(const char* d) : buffer{d}, m_length{strlen(d)} {} + StringView(const char* d, size_t l) : buffer{d}, m_length{l} {} Iterator begin() const { return Iterator(this); } private: - const char *const buffer; + const char* const buffer; const size_t m_length; }; + +class IntegerView { +public: + template <typename T> + struct HexFormat { + T n; + }; + + class Iterator : public ViewIterator { + friend class IntegerView; + + public: + char next() override { return _p->buffer[pos++]; }; + operator bool() const override { return (pos < _p->length); } + + private: + Iterator(const IntegerView* v) : _p(v) {} + + size_t pos = 0; + const IntegerView* _p; + }; + + IntegerView(int32_t n) { length = itoa(n, buffer); } + + template <typename T> + IntegerView(HexFormat<T> f) { + buffer[0] = '0'; + buffer[1] = 'x'; + length = itoa<T, 16>(f.n, buffer + 2) + 2; + } + + Iterator begin() const { return Iterator(this); } + +private: + char buffer[128]; + size_t length = 0; +}; + +using hex = IntegerView::HexFormat<int32_t>; +using uhex = IntegerView::HexFormat<uint32_t>; + +using hex_addr = IntegerView::HexFormat<uint64_t>; // TODO causes crash |