diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-05 23:15:37 +0200 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2021-02-05 23:15:37 +0200 |
commit | 919ad9d1022edec7fdd97f74ef50de26dde6aebb (patch) | |
tree | 2787aa63255b0ba6c682e4547a2030e591a6a55e /libk | |
parent | Rewrite boot.s to use clang instead of nasm (diff) | |
download | kernel.cpp-919ad9d1022edec7fdd97f74ef50de26dde6aebb.tar.xz |
Add IntegerView
Diffstat (limited to 'libk')
-rw-r--r-- | libk/makefile | 7 | ||||
-rw-r--r-- | libk/stdlib.h | 31 | ||||
-rw-r--r-- | libk/stdlib/console.cc | 8 | ||||
-rw-r--r-- | libk/string.cc | 22 | ||||
-rw-r--r-- | libk/string.h | 106 | ||||
-rw-r--r-- | libk/type_traits.h | 12 | ||||
-rw-r--r-- | libk/type_traits/test.cc | 17 | ||||
-rw-r--r-- | libk/types.h | 1 |
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); |