aboutsummaryrefslogtreecommitdiff
path: root/libk
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-02-05 23:15:37 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-02-05 23:15:37 +0200
commit919ad9d1022edec7fdd97f74ef50de26dde6aebb (patch)
tree2787aa63255b0ba6c682e4547a2030e591a6a55e /libk
parentRewrite boot.s to use clang instead of nasm (diff)
downloadkernel.cpp-919ad9d1022edec7fdd97f74ef50de26dde6aebb.tar.xz
Add IntegerView
Diffstat (limited to 'libk')
-rw-r--r--libk/makefile7
-rw-r--r--libk/stdlib.h31
-rw-r--r--libk/stdlib/console.cc8
-rw-r--r--libk/string.cc22
-rw-r--r--libk/string.h106
-rw-r--r--libk/type_traits.h12
-rw-r--r--libk/type_traits/test.cc17
-rw-r--r--libk/types.h1
8 files changed, 147 insertions, 57 deletions
diff --git a/libk/makefile b/libk/makefile
index faf5b79..941d93d 100644
--- a/libk/makefile
+++ b/libk/makefile
@@ -1,11 +1,14 @@
CXX_OBJ := string.o stdlib/console.o
+CXX_TEST_OBJ := type_traits/test.o
libk.a: $(CXX_OBJ)
$(AR) rcs $@ $(CXX_OBJ)
-$(CXX_OBJ): %.o : %.cc
+test: $(CXX_TEST_OBJ)
+
+$(CXX_OBJ) $(CXX_TEST_OBJ): %.o : %.cc
$(CXX) -target $(TARGET) $(CXX_FLAGS) -I$(CURDIR) -c $^ -o $@
clean:
- rm libk.a $(CXX_OBJ)
+ rm -f libk.a $(CXX_OBJ) $(CXX_TEST_OBJ)
diff --git a/libk/stdlib.h b/libk/stdlib.h
index 44bacf4..f031408 100644
--- a/libk/stdlib.h
+++ b/libk/stdlib.h
@@ -4,27 +4,34 @@
#include <type_traits.h>
class Console {
-public:
+ public:
virtual void write(char c) = 0;
- virtual void write(const String &msg) = 0;
- virtual void write(int n) = 0;
- virtual void write(unsigned int n) = 0;
+ virtual void write(ViewIterator& msg) = 0;
- static void set(Console *ptr);
- static Console *get();
+ static void set(Console* ptr);
+ static Console* get();
};
-template <typename T> void printk(const T &a) {
- if (auto *c = Console::get()) {
- if constexpr (is_same<T, const char *>())
- c->write(String(a));
- else
+template <typename T>
+void printk(const T& a) {
+ if (auto* c = Console::get()) {
+ if constexpr (is_same<T, char>()) {
+ c->write(a);
+ } else if constexpr (requires { StringView(a); }) {
+ StringView v(a);
+ auto iter = v.begin();
+ c->write(iter);
+ } else if constexpr (requires { IntegerView(a); }) {
+ IntegerView v(a);
+ auto iter = v.begin();
+ c->write(iter);
+ } else
c->write(a);
}
}
template <typename T, typename... Args>
-void printk(const T &a, const Args &...x) {
+void printk(const T& a, const Args&... x) {
printk(a);
printk(x...);
}
diff --git a/libk/stdlib/console.cc b/libk/stdlib/console.cc
index dee6a8f..308f055 100644
--- a/libk/stdlib/console.cc
+++ b/libk/stdlib/console.cc
@@ -1,14 +1,16 @@
#include "stdlib.h"
-static Console *global_console = nullptr;
+static Console* global_console = nullptr;
-void Console::set(Console *ptr) {
+void Console::set(Console* ptr) {
if (ptr != nullptr) {
global_console = ptr;
}
}
-Console *Console::get() { return global_console; }
+Console* Console::get() {
+ return global_console;
+}
void abort() {
/*
diff --git a/libk/string.cc b/libk/string.cc
index 5cd4bb2..c75feb1 100644
--- a/libk/string.cc
+++ b/libk/string.cc
@@ -8,19 +8,19 @@
// int strncmp(const char *s1, const char *s2, int c);
/* strcmp - compare two C-strings */
-constexpr int strcmp(const char *s1, const char *s2)
-{
- const auto s1_len = strlen(s1);
- for(size_t i = 0; i < s1_len; ++i) {
- if(s1[i] == s2[i]) continue;
- if(s1[i] > s2[i]) return 1;
- if(s1[i] < s2[i]) return -1;
- }
- return 0;
+constexpr int strcmp(const char* s1, const char* s2) {
+ const auto s1_len = strlen(s1);
+ for (size_t i = 0; i < s1_len; ++i) {
+ if (s1[i] == s2[i])
+ continue;
+ if (s1[i] > s2[i])
+ return 1;
+ if (s1[i] < s2[i])
+ return -1;
+ }
+ return 0;
}
static_assert(strcmp("one", "one") == 0);
static_assert(strcmp("one", "two") < 0);
static_assert(strcmp("foo", "bar") > 0);
-
-
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
diff --git a/libk/type_traits.h b/libk/type_traits.h
index cef30c1..dc70339 100644
--- a/libk/type_traits.h
+++ b/libk/type_traits.h
@@ -1,10 +1,16 @@
#pragma once
-template <class T, T v> struct integral_constant {
+template <class T, T v>
+struct integral_constant {
constexpr T operator()() const { return v; }
constexpr operator T() const { return v; }
};
-template <class T, class U> struct is_same : integral_constant<bool, false> {};
+template <class T, class U>
+struct is_same : integral_constant<bool, false> {};
-template <class T> struct is_same<T, T> : integral_constant<bool, true> {};
+template <class T>
+struct is_same<T, T> : integral_constant<bool, true> {};
+
+template <typename T>
+struct is_unsigned : integral_constant<bool, (T{0} < static_cast<T>(-1))> {};
diff --git a/libk/type_traits/test.cc b/libk/type_traits/test.cc
new file mode 100644
index 0000000..1aa11df
--- /dev/null
+++ b/libk/type_traits/test.cc
@@ -0,0 +1,17 @@
+#include <type_traits.h>
+#include <types.h>
+
+// is_same
+static_assert(is_same<int, int>() == true);
+static_assert(is_same<int, unsigned int>() == false);
+
+// is_unsigned
+static_assert(is_unsigned<uint8_t>() == true);
+static_assert(is_unsigned<uint16_t>() == true);
+static_assert(is_unsigned<uint32_t>() == true);
+static_assert(is_unsigned<uint64_t>() == true);
+
+static_assert(is_unsigned<int8_t>() == false);
+static_assert(is_unsigned<int16_t>() == false);
+static_assert(is_unsigned<int32_t>() == false);
+static_assert(is_unsigned<int64_t>() == false);
diff --git a/libk/types.h b/libk/types.h
index be38cb0..fc20d22 100644
--- a/libk/types.h
+++ b/libk/types.h
@@ -3,7 +3,6 @@
typedef unsigned short size_t;
static_assert(sizeof(size_t) >= 2);
-
typedef unsigned char uint8_t;
static_assert(sizeof(uint8_t) == 1);