From 13e1e4515746fe65b6c50cfbc42f00e29fd56599 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sat, 6 Feb 2021 17:32:40 +0200 Subject: libk: add some tests - merge types.h and type_traits.h --- libk/makefile | 4 +- libk/stdlib.h | 1 - libk/string.cc | 26 ----------- libk/string.h | 106 +++++++++++++-------------------------------- libk/string/integerview.cc | 40 +++++++++++++++++ libk/string/string.cc | 26 +++++++++++ libk/string/test.cc | 14 ++++++ libk/type_traits.h | 16 ------- libk/type_traits/test.cc | 17 -------- libk/types.h | 35 ++++++++------- libk/types/test.cc | 29 +++++++++++++ makefile | 10 +++-- 12 files changed, 169 insertions(+), 155 deletions(-) delete mode 100644 libk/string.cc create mode 100644 libk/string/integerview.cc create mode 100644 libk/string/string.cc create mode 100644 libk/string/test.cc delete mode 100644 libk/type_traits.h delete mode 100644 libk/type_traits/test.cc create mode 100644 libk/types/test.cc diff --git a/libk/makefile b/libk/makefile index 941d93d..ea684ba 100644 --- a/libk/makefile +++ b/libk/makefile @@ -1,6 +1,6 @@ -CXX_OBJ := string.o stdlib/console.o -CXX_TEST_OBJ := type_traits/test.o +CXX_OBJ := string/string.o string/integerview.o stdlib/console.o +CXX_TEST_OBJ := types/test.o string/test.o libk.a: $(CXX_OBJ) $(AR) rcs $@ $(CXX_OBJ) diff --git a/libk/stdlib.h b/libk/stdlib.h index f031408..e1d3dd2 100644 --- a/libk/stdlib.h +++ b/libk/stdlib.h @@ -1,7 +1,6 @@ #pragma once #include -#include class Console { public: diff --git a/libk/string.cc b/libk/string.cc deleted file mode 100644 index c75feb1..0000000 --- a/libk/string.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "string.h" - -// TODO - -// int strcpy(char *dst, const char *stc); -// void strcat(void *dst, const void *src); -// char* strncpy(char *dest, const char *src, int length); -// 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; -} - -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 0675cea..03c0942 100644 --- a/libk/string.h +++ b/libk/string.h @@ -1,5 +1,4 @@ #pragma once -#include #include /** @@ -8,13 +7,15 @@ */ constexpr size_t strlen(const char* str) { size_t len = 0; - while (str[len]) + while (str[len] != '\0') ++len; return len; } -/* reverse: reverse string s in place */ -constexpr void reverse(char s[], int strlen) { +/** + * Reverse array in place + */ +constexpr void reverse(char s[], size_t strlen) { int i, j; char c; @@ -25,57 +26,29 @@ constexpr void reverse(char s[], int strlen) { } } -/* itoa: convert n to characters in s */ -template -constexpr size_t itoa(T n, char s[]) { - const bool is_negative = (n < 0); - if constexpr (!is_unsigned()) { - if (n < 0) - n = -n; - } - - int i = 0; - do { /* generate digits in reverse order */ - s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ - } while ((n /= base) > 0); /* delete it */ - - if (is_negative) - s[i++] = '-'; - - s[i] = '\0'; - - reverse(s, i); - return i; -} - class ViewIterator { public: - virtual char next() = 0; - virtual operator bool() const = 0; -}; - -class StringView { -public: - class Iterator : public ViewIterator { - friend class StringView; + char next() { return buffer[reverse ? pos-- : pos++]; } + operator bool() const { return reverse ? (pos >= 0) : (pos < length); } - public: - char next() override { return p->buffer[pos++]; } - operator bool() const override { return (pos < p->m_length); } - - private: - Iterator(const StringView* s) : p(s) {} - - size_t pos = 0; - const StringView* p; + explicit ViewIterator(const char* b, size_t l, bool r = false) : buffer(b), length(l), reverse(r) { + if (reverse) + pos = length - 1; }; - friend class Iterator; +private: + ssize_t pos = 0; + const char* const buffer; // const pointer to const char* + const size_t length; + const bool reverse; +}; +class StringView { +public: 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); } + auto begin() const { return ViewIterator(buffer, m_length); } private: const char* const buffer; @@ -84,42 +57,25 @@ private: class IntegerView { public: - template - struct HexFormat { - T n; + struct HexFormat_int32 { + int32_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; + struct HexFormat_uint32 { + uint32_t n; }; - 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; - } + IntegerView(int32_t n); + IntegerView(HexFormat_int32 f); + IntegerView(HexFormat_uint32 f); - Iterator begin() const { return Iterator(this); } + auto begin() const { return ViewIterator(buffer, length, true); } private: - char buffer[128]; + char buffer[32]; size_t length = 0; }; -using hex = IntegerView::HexFormat; -using uhex = IntegerView::HexFormat; +using hex = IntegerView::HexFormat_int32; +using uhex = IntegerView::HexFormat_uint32; -using hex_addr = IntegerView::HexFormat; // TODO causes crash +// using hex_addr = IntegerView::HexFormat; // TODO causes crash diff --git a/libk/string/integerview.cc b/libk/string/integerview.cc new file mode 100644 index 0000000..beeb561 --- /dev/null +++ b/libk/string/integerview.cc @@ -0,0 +1,40 @@ +#include + +/* itoa: convert n to characters in s */ +template +constexpr size_t itoa(T n, char s[]) { + const bool is_negative = (n < 0); + if constexpr (!is_unsigned()) { + if (n < 0) + n = -n; + } + + int i = 0; + do { /* generate digits in reverse order */ + s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ + } while ((n /= base) > 0); /* delete it */ + + if (is_negative) + s[i++] = '-'; + + s[i] = '\0'; + + // reverse(s, i); + return i; +} + +IntegerView::IntegerView(int32_t n) { + length = itoa(n, buffer); +} + +IntegerView::IntegerView(HexFormat_int32 f) { + length = itoa(f.n, buffer); + buffer[length++] = 'x'; + buffer[length++] = '0'; +} + +IntegerView::IntegerView(HexFormat_uint32 f) { + length = itoa(f.n, buffer); + buffer[length++] = 'x'; + buffer[length++] = '0'; +} diff --git a/libk/string/string.cc b/libk/string/string.cc new file mode 100644 index 0000000..c75feb1 --- /dev/null +++ b/libk/string/string.cc @@ -0,0 +1,26 @@ +#include "string.h" + +// TODO + +// int strcpy(char *dst, const char *stc); +// void strcat(void *dst, const void *src); +// char* strncpy(char *dest, const char *src, int length); +// 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; +} + +static_assert(strcmp("one", "one") == 0); +static_assert(strcmp("one", "two") < 0); +static_assert(strcmp("foo", "bar") > 0); diff --git a/libk/string/test.cc b/libk/string/test.cc new file mode 100644 index 0000000..4d7d340 --- /dev/null +++ b/libk/string/test.cc @@ -0,0 +1,14 @@ +#include + +// strlen +static_assert(strlen("") == 0); +static_assert(strlen("0") == 1); +static_assert(strlen("hello") == 5); +static_assert(strlen("world") == 5); + +// reverse +static_assert([]() { + char s[] = "xyz"; + reverse(s, strlen(s)); + return s[0] == 'z' && s[1] == 'y' && s[2] == 'x' && s[3] == '\0'; +}()); diff --git a/libk/type_traits.h b/libk/type_traits.h deleted file mode 100644 index dc70339..0000000 --- a/libk/type_traits.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -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_unsigned : integral_constant(-1))> {}; diff --git a/libk/type_traits/test.cc b/libk/type_traits/test.cc deleted file mode 100644 index 1aa11df..0000000 --- a/libk/type_traits/test.cc +++ /dev/null @@ -1,17 +0,0 @@ -#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 fc20d22..4018ab8 100644 --- a/libk/types.h +++ b/libk/types.h @@ -1,28 +1,33 @@ #pragma once typedef unsigned short size_t; -static_assert(sizeof(size_t) >= 2); +typedef int ssize_t; typedef unsigned char uint8_t; -static_assert(sizeof(uint8_t) == 1); - typedef unsigned short uint16_t; -static_assert(sizeof(uint16_t) == 2); - typedef unsigned int uint32_t; -static_assert(sizeof(uint32_t) == 4); - typedef unsigned long long int uint64_t; -static_assert(sizeof(uint64_t) == 8); typedef char int8_t; -static_assert(sizeof(int8_t) == 1); - typedef short int16_t; -static_assert(sizeof(int16_t) == 2); - typedef int int32_t; -static_assert(sizeof(int32_t) == 4); - typedef long long int int64_t; -static_assert(sizeof(int64_t) == 8); + +// Type Traits + +template +struct integral_constant { + constexpr T operator()() const { return v; } + constexpr operator T() const { return v; } +}; + +/* is_same */ +template +struct is_same : integral_constant {}; + +template +struct is_same : integral_constant {}; + +/* is_unsigned */ +template +struct is_unsigned : integral_constant(-1))> {}; diff --git a/libk/types/test.cc b/libk/types/test.cc new file mode 100644 index 0000000..f93d883 --- /dev/null +++ b/libk/types/test.cc @@ -0,0 +1,29 @@ +#include + +// types +static_assert(sizeof(size_t) >= 2); + +static_assert(sizeof(uint8_t) == 1); +static_assert(sizeof(uint16_t) == 2); +static_assert(sizeof(uint32_t) == 4); +static_assert(sizeof(uint64_t) == 8); + +static_assert(sizeof(int8_t) == 1); +static_assert(sizeof(int16_t) == 2); +static_assert(sizeof(int32_t) == 4); +static_assert(sizeof(int64_t) == 8); + +// 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/makefile b/makefile index f45d65a..1a50a18 100644 --- a/makefile +++ b/makefile @@ -6,8 +6,12 @@ export TARGET := i686-elf export AR := llvm-ar -export AS := clang -export LD := ld.lld + +AS := clang + +LD := ld.lld +LD_FLAGS := -T linker.ld -lk + export CXX := clang export CXX_FLAGS := -std=c++20 -ffreestanding -nostdlib -nostdinc -nostdinc++ \ -fno-exceptions -fno-rtti -Wall -Wextra -O2 @@ -24,7 +28,7 @@ check-grub: glitch.elf grub-file --is-x86-multiboot2 glitch.elf glitch.elf: boot.o $(CXX_OBJ) libk/libk.a - $(LD) -T linker.ld -o glitch.elf boot.o $(CXX_OBJ) -lk + $(LD) $(LD_FLAGS) -o $@ boot.o $(CXX_OBJ) boot.o: boot.s $(AS) -target $(TARGET) -nostdlib -Wall -Wextra -c $^ -o $@ -- cgit v1.2.1