aboutsummaryrefslogtreecommitdiff
path: root/libk/string.h
diff options
context:
space:
mode:
Diffstat (limited to 'libk/string.h')
-rw-r--r--libk/string.h106
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