From 919ad9d1022edec7fdd97f74ef50de26dde6aebb Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 5 Feb 2021 23:15:37 +0200 Subject: Add IntegerView --- libk/makefile | 7 +++- libk/stdlib.h | 31 ++++++++------ libk/stdlib/console.cc | 8 ++-- libk/string.cc | 22 +++++----- libk/string.h | 106 ++++++++++++++++++++++++++++++++++++----------- libk/type_traits.h | 12 ++++-- libk/type_traits/test.cc | 17 ++++++++ libk/types.h | 1 - 8 files changed, 147 insertions(+), 57 deletions(-) create mode 100644 libk/type_traits/test.cc (limited to 'libk') 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 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 void printk(const T &a) { - if (auto *c = Console::get()) { - if constexpr (is_same()) - c->write(String(a)); - else +template +void printk(const T& a) { + if (auto* c = Console::get()) { + if constexpr (is_same()) { + 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 -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 +#include + +/** + * 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 constexpr void itoa(int n, char s[]) { - int i, sign; - - if ((sign = n) < 0) /* record sign */ - n = -n; /* make n positive */ +template +constexpr size_t itoa(T n, char s[]) { + const bool is_negative = (n < 0); + if constexpr (!is_unsigned()) { + 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 + 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 + IntegerView(HexFormat f) { + buffer[0] = '0'; + buffer[1] = 'x'; + length = itoa(f.n, buffer + 2) + 2; + } + + Iterator begin() const { return Iterator(this); } + +private: + char buffer[128]; + size_t length = 0; +}; + +using hex = IntegerView::HexFormat; +using uhex = IntegerView::HexFormat; + +using hex_addr = IntegerView::HexFormat; // 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 struct integral_constant { +template +struct integral_constant { constexpr T operator()() const { return v; } constexpr operator T() const { return v; } }; -template struct is_same : integral_constant {}; +template +struct is_same : integral_constant {}; -template struct is_same : integral_constant {}; +template +struct is_same : integral_constant {}; + +template +struct is_unsigned : integral_constant(-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 +#include + +// is_same +static_assert(is_same() == true); +static_assert(is_same() == false); + +// is_unsigned +static_assert(is_unsigned() == true); +static_assert(is_unsigned() == true); +static_assert(is_unsigned() == true); +static_assert(is_unsigned() == true); + +static_assert(is_unsigned() == false); +static_assert(is_unsigned() == false); +static_assert(is_unsigned() == false); +static_assert(is_unsigned() == 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); -- cgit v1.2.1