diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4ab5404 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "banan-os"] + path = banan-os + url = https://git.bananymous.com/Bananymous/banan-os.git diff --git a/0001-linux-window-server-sdl2.patch b/0001-linux-window-server-sdl2.patch new file mode 100644 index 0000000..0f92e51 --- /dev/null +++ b/0001-linux-window-server-sdl2.patch @@ -0,0 +1,812 @@ +From 075f6a11926e247ba64efd25a3acf7a3d3be0bbc Mon Sep 17 00:00:00 2001 +From: Oskari Alaranta +Date: Wed, 15 Apr 2026 16:51:16 +0300 +Subject: [PATCH] linux-window-server-sdl2 + +--- + userspace/libraries/LibGUI/Widget/Widget.cpp | 2 +- + userspace/libraries/LibGUI/Window.cpp | 9 +- + userspace/programs/ProgramLauncher/main.cpp | 2 +- + userspace/programs/Terminal/Terminal.cpp | 4 +- + .../programs/WindowServer/CMakeLists.txt | 3 + + .../programs/WindowServer/Framebuffer.cpp | 52 +-- + userspace/programs/WindowServer/Window.cpp | 29 +- + .../programs/WindowServer/WindowServer.cpp | 47 ++- + .../programs/WindowServer/WindowServer.h | 1 + + userspace/programs/WindowServer/main.cpp | 362 ++++++++++++------ + 10 files changed, 338 insertions(+), 173 deletions(-) + +diff --git a/userspace/libraries/LibGUI/Widget/Widget.cpp b/userspace/libraries/LibGUI/Widget/Widget.cpp +index d6489d87..c532fb04 100644 +--- a/userspace/libraries/LibGUI/Widget/Widget.cpp ++++ b/userspace/libraries/LibGUI/Widget/Widget.cpp +@@ -15,7 +15,7 @@ namespace LibGUI::Widget + const LibFont::Font& Widget::default_font() + { + if (!s_default_font.has_value()) +- MUST(set_default_font("/usr/share/fonts/lat0-16.psfu"_sv)); ++ MUST(set_default_font("./lat0-16.psfu"_sv)); + return s_default_font.value(); + } + +diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp +index b4172f70..3a0e9cca 100644 +--- a/userspace/libraries/LibGUI/Window.cpp ++++ b/userspace/libraries/LibGUI/Window.cpp +@@ -4,9 +4,8 @@ + + #include + #include +-#include + #include +-#include ++#include + #include + #include + #include +@@ -271,7 +270,7 @@ namespace LibGUI + + void Window::cleanup() + { +- munmap(m_framebuffer_smo, m_width * m_height * 4); ++ shmdt(m_framebuffer_smo); + close(m_server_fd); + close(m_epoll_fd); + } +@@ -279,7 +278,7 @@ namespace LibGUI + BAN::ErrorOr Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event) + { + if (m_framebuffer_smo) +- munmap(m_framebuffer_smo, m_width * m_height * 4); ++ shmdt(m_framebuffer_smo); + m_framebuffer_smo = nullptr; + + TRY(m_texture.resize(event.width, event.height)); +@@ -287,7 +286,7 @@ namespace LibGUI + if (m_root_widget) + TRY(m_root_widget->set_fixed_geometry({ 0, 0, event.width, event.height })); + +- void* framebuffer_addr = smo_map(event.smo_key); ++ void* framebuffer_addr = shmat(event.smo_key, nullptr, 0); + if (framebuffer_addr == nullptr) + return BAN::Error::from_errno(errno); + +diff --git a/userspace/programs/ProgramLauncher/main.cpp b/userspace/programs/ProgramLauncher/main.cpp +index c833c582..0e1cc460 100644 +--- a/userspace/programs/ProgramLauncher/main.cpp ++++ b/userspace/programs/ProgramLauncher/main.cpp +@@ -182,7 +182,7 @@ int main() + attributes.alpha_channel = true; + attributes.title_bar = false; + +- auto font = MUST(LibFont::Font::load("/usr/share/fonts/lat0-16.psfu"_sv)); ++ auto font = MUST(LibFont::Font::load("./lat0-16.psfu"_sv)); + + const auto full_program_list = get_program_list(); + +diff --git a/userspace/programs/Terminal/Terminal.cpp b/userspace/programs/Terminal/Terminal.cpp +index e1bd317d..8a6b5bd0 100644 +--- a/userspace/programs/Terminal/Terminal.cpp ++++ b/userspace/programs/Terminal/Terminal.cpp +@@ -92,7 +92,7 @@ void Terminal::start_shell() + close(pts_slave); + close(pts_master); + +- execl("/bin/Shell", "Shell", NULL); ++ execl("/usr/bin/zsh", "zsh", NULL); + exit(1); + } + +@@ -127,7 +127,7 @@ void Terminal::run() + m_window->texture().set_bg_color(m_bg_color); + m_window->invalidate(); + +- m_font = MUST(LibFont::Font::load("/usr/share/fonts/lat0-16.psfu"_sv)); ++ m_font = MUST(LibFont::Font::load("./lat0-16.psfu"_sv)); + + m_window->set_min_size(m_font.width() * 8, m_font.height() * 2); + +diff --git a/userspace/programs/WindowServer/CMakeLists.txt b/userspace/programs/WindowServer/CMakeLists.txt +index 8fdf79f9..fcaf441d 100644 +--- a/userspace/programs/WindowServer/CMakeLists.txt ++++ b/userspace/programs/WindowServer/CMakeLists.txt +@@ -13,4 +13,7 @@ banan_link_library(WindowServer libfont) + banan_link_library(WindowServer libimage) + banan_link_library(WindowServer libinput) + ++find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2) ++target_link_libraries(WindowServer PRIVATE SDL2::SDL2) ++ + install(TARGETS WindowServer OPTIONAL) +diff --git a/userspace/programs/WindowServer/Framebuffer.cpp b/userspace/programs/WindowServer/Framebuffer.cpp +index 0e727e8f..119f1451 100644 +--- a/userspace/programs/WindowServer/Framebuffer.cpp ++++ b/userspace/programs/WindowServer/Framebuffer.cpp +@@ -1,45 +1,53 @@ + #include "Framebuffer.h" + +-#include +-#include +-#include + #include +-#include +-#include ++ ++#include ++ ++static constexpr size_t window_width { 1280 }; ++static constexpr size_t window_height { 800 }; ++static constexpr size_t window_bpp { 32 }; ++ ++SDL_Renderer* g_renderer { nullptr }; ++SDL_Texture* g_texture { nullptr }; ++SDL_Window* g_window { nullptr }; + + Framebuffer open_framebuffer() + { +- int framebuffer_fd = open("/dev/fb0", O_RDWR | O_CLOEXEC); +- if (framebuffer_fd == -1) ++ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == -1) + { +- perror("open"); ++ fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError()); + exit(1); + } + +- framebuffer_info_t framebuffer_info; +- if (pread(framebuffer_fd, &framebuffer_info, sizeof(framebuffer_info), -1) == -1) ++ g_window = SDL_CreateWindow("banan gui", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, SDL_WINDOW_SHOWN); ++ if (g_window == nullptr) + { +- perror("pread"); ++ fprintf(stderr, "Could not create SDL window: %s\n", SDL_GetError()); + exit(1); + } + +- const size_t framebuffer_bytes = framebuffer_info.width * framebuffer_info.height * (BANAN_FB_BPP / 8); ++ g_renderer = SDL_CreateRenderer(g_window, -1, SDL_RENDERER_ACCELERATED); ++ if (g_renderer == nullptr) ++ { ++ fprintf(stderr, "Could not get SDL renderer: %s\n", SDL_GetError()); ++ exit(1); ++ } + +- uint32_t* framebuffer_mmap = (uint32_t*)mmap(NULL, framebuffer_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, framebuffer_fd, 0); +- if (framebuffer_mmap == MAP_FAILED) ++ g_texture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, window_width, window_height); ++ if (g_texture == nullptr) + { +- perror("mmap"); ++ fprintf(stderr, "Could not get SDL texture: %s\n", SDL_GetError()); + exit(1); + } + +- memset(framebuffer_mmap, 0, framebuffer_bytes); +- msync(framebuffer_mmap, framebuffer_bytes, MS_SYNC); ++ uint32_t* pixels = new uint32_t[window_width * window_height]; ++ memset(pixels, 0, window_width * window_height * 4); + + Framebuffer framebuffer; +- framebuffer.fd = framebuffer_fd; +- framebuffer.mmap = framebuffer_mmap; +- framebuffer.width = framebuffer_info.width; +- framebuffer.height = framebuffer_info.height; +- framebuffer.bpp = BANAN_FB_BPP; ++ framebuffer.mmap = pixels; ++ framebuffer.width = window_width; ++ framebuffer.height = window_height; ++ framebuffer.bpp = window_bpp; + return framebuffer; + } +diff --git a/userspace/programs/WindowServer/Window.cpp b/userspace/programs/WindowServer/Window.cpp +index 1e66f522..9759eec9 100644 +--- a/userspace/programs/WindowServer/Window.cpp ++++ b/userspace/programs/WindowServer/Window.cpp +@@ -5,15 +5,14 @@ + + #include + +-#include +-#include ++#include + #include + #include + + Window::~Window() + { +- munmap(m_fb_addr, client_width() * client_height() * 4); +- smo_delete(m_smo_key); ++ shmdt(m_fb_addr); ++ shmctl(m_smo_key, IPC_RMID, nullptr); + + LibGUI::EventPacket::DestroyWindowEvent packet; + +@@ -47,16 +46,16 @@ BAN::ErrorOr Window::resize(uint32_t width, uint32_t height) + { + const size_t fb_bytes = width * height * 4; + +- long smo_key = smo_create(fb_bytes, PROT_READ | PROT_WRITE); +- if (smo_key == -1) ++ int shmid = shmget(rand(), fb_bytes, IPC_CREAT | IPC_EXCL | 0666); ++ if (shmid == -1) + return BAN::Error::from_errno(errno); +- BAN::ScopeGuard smo_deleter([&]() { smo_delete(smo_key); }); ++ BAN::ScopeGuard shmdeleter([&]() { shmctl(shmid, IPC_RMID, nullptr); }); + +- uint32_t* fb_addr = static_cast(smo_map(smo_key)); +- if (fb_addr == nullptr) ++ uint32_t* fb_addr = static_cast(shmat(shmid, nullptr, 0)); ++ if (fb_addr == (void*)-1) + return BAN::Error::from_errno(errno); + memset(fb_addr, 0xFF, fb_bytes); +- BAN::ScopeGuard smo_unmapper([&]() { munmap(fb_addr, fb_bytes); }); ++ BAN::ScopeGuard shmdetacher([&]() { shmdt(fb_addr); }); + + { + const auto old_area = m_client_area; +@@ -70,16 +69,14 @@ BAN::ErrorOr Window::resize(uint32_t width, uint32_t height) + return title_bar_ret.release_error(); + } + +- smo_deleter.disable(); +- smo_unmapper.disable(); ++ shmdetacher.disable(); ++ shmdeleter.disable(); + + if (m_fb_addr) +- munmap(m_fb_addr, client_width() * client_height() * 4); +- if (m_smo_key) +- smo_delete(m_smo_key); ++ shmdt(m_fb_addr); + + m_fb_addr = fb_addr; +- m_smo_key = smo_key; ++ m_smo_key = shmid; + + m_client_area.max_x = m_client_area.min_x + width; + m_client_area.max_y = m_client_area.min_y + height; +diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp +index 2c67d6c0..600704fd 100644 +--- a/userspace/programs/WindowServer/WindowServer.cpp ++++ b/userspace/programs/WindowServer/WindowServer.cpp +@@ -8,19 +8,20 @@ + #include + + #include +-#include +-#include +-#include +-#include + #include + + #include + ++#include ++ ++extern SDL_Renderer* g_renderer; ++extern SDL_Texture* g_texture; ++ + WindowServer::WindowServer(Framebuffer& framebuffer, int32_t corner_radius) + : m_framebuffer(framebuffer) + , m_corner_radius(corner_radius) + , m_cursor({ framebuffer.width / 2, framebuffer.height / 2 }) +- , m_font(MUST(LibFont::Font::load("/usr/share/fonts/lat0-16.psfu"_sv))) ++ , m_font(MUST(LibFont::Font::load("./lat0-16.psfu"_sv))) + { + MUST(m_background_image.resize(m_framebuffer.width * m_framebuffer.height, 0xFF101010)); + +@@ -440,7 +441,7 @@ static void update_volume(const char* new_volume) + + void WindowServer::on_key_event(LibInput::KeyEvent event) + { +- if (event.key == LibInput::Key::Super) ++ if (event.key == LibInput::Key::RightCtrl) + m_is_mod_key_held = event.pressed(); + + if (event.pressed() && event.key == LibInput::Key::VolumeDown) +@@ -461,7 +462,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event) + pid_t pid = fork(); + if (pid == 0) + { +- execl("/usr/bin/Terminal", "Terminal", nullptr); ++ execl("./build/banan-os/userspace/programs/Terminal/Terminal", "Terminal", nullptr); + exit(1); + } + if (pid == -1) +@@ -475,7 +476,7 @@ void WindowServer::on_key_event(LibInput::KeyEvent event) + pid_t pid = fork(); + if (pid == 0) + { +- execl("/usr/bin/ProgramLauncher", "ProgramLauncher", nullptr); ++ execl("./build/banan-os/userspace/programs/ProgramLauncher/ProgramLauncher", "ProgramLauncher", nullptr); + exit(1); + } + if (pid == -1) +@@ -1599,16 +1600,34 @@ void WindowServer::sync() + + for (size_t i = 0; i < m_damaged_area_count; i++) + { +- const fb_msync_region region { +- .min_x = static_cast(m_damaged_areas[i].min_x), +- .min_y = static_cast(m_damaged_areas[i].min_y), +- .max_x = static_cast(m_damaged_areas[i].max_x), +- .max_y = static_cast(m_damaged_areas[i].max_y), ++ const SDL_Rect rect { ++ .x = m_damaged_areas[i].min_x, ++ .y = m_damaged_areas[i].min_y, ++ .w = m_damaged_areas[i].max_x - m_damaged_areas[i].min_x, ++ .h = m_damaged_areas[i].max_y - m_damaged_areas[i].min_y, + }; +- ioctl(m_framebuffer.fd, FB_MSYNC_RECTANGLE, ®ion); ++ ++ void* pixels; ++ int pitch; ++ SDL_LockTexture(g_texture, &rect, &pixels, &pitch); ++ ++ for (int32_t y_off = 0; y_off < rect.h; y_off++) ++ { ++ memcpy( ++ static_cast(pixels) + y_off * pitch, ++ &m_framebuffer.mmap[(rect.y + y_off) * m_framebuffer.width + rect.x], ++ rect.w * sizeof(uint32_t) ++ ); ++ } ++ ++ SDL_UnlockTexture(g_texture); + } + + m_damaged_area_count = 0; ++ ++ SDL_RenderClear(g_renderer); ++ SDL_RenderCopy(g_renderer, g_texture, NULL, NULL); ++ SDL_RenderPresent(g_renderer); + } + + Rectangle WindowServer::cursor_area() const +diff --git a/userspace/programs/WindowServer/WindowServer.h b/userspace/programs/WindowServer/WindowServer.h +index 94fbc774..bcd7a6b9 100644 +--- a/userspace/programs/WindowServer/WindowServer.h ++++ b/userspace/programs/WindowServer/WindowServer.h +@@ -62,6 +62,7 @@ public: + + bool is_damaged() const { return m_damaged_area_count > 0 || m_is_bouncing_window; } + bool is_stopped() const { return m_is_stopped; } ++ void stop() { m_is_stopped = true; } + + private: + void on_mouse_move_impl(int32_t new_x, int32_t new_y); +diff --git a/userspace/programs/WindowServer/main.cpp b/userspace/programs/WindowServer/main.cpp +index 41bd7e8c..cb066bd3 100644 +--- a/userspace/programs/WindowServer/main.cpp ++++ b/userspace/programs/WindowServer/main.cpp +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -150,6 +149,8 @@ int open_server_fd() + + int g_epoll_fd = -1; + ++static void poll_sdl_events(WindowServer&); ++ + int main() + { + srand(time(nullptr)); +@@ -181,14 +182,6 @@ int main() + } + } + +- if (tty_ctrl(STDIN_FILENO, TTY_CMD_UNSET, TTY_FLAG_ENABLE_INPUT) == -1) +- { +- dwarnln("tty_ctrl: {}", strerror(errno)); +- return 1; +- } +- +- atexit([]() { tty_ctrl(STDIN_FILENO, TTY_CMD_SET, TTY_FLAG_ENABLE_INPUT); }); +- + constexpr int non_terminating_signals[] { + SIGCHLD, + SIGCONT, +@@ -196,11 +189,12 @@ int main() + SIGTSTP, + SIGTTIN, + SIGTTOU, ++ SIGWINCH, + }; + constexpr int ignored_signals[] { + SIGPIPE, + }; +- for (int sig = _SIGMIN; sig <= _SIGMAX; sig++) ++ for (int sig = 1; sig < NSIG; sig++) + signal(sig, exit); + for (int sig : non_terminating_signals) + signal(sig, SIG_DFL); +@@ -208,55 +202,10 @@ int main() + signal(sig, SIG_IGN); + + MUST(LibInput::KeyboardLayout::initialize()); +- MUST(LibInput::KeyboardLayout::get().load_from_file("/usr/share/keymaps/us.keymap"_sv)); +- +- int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_CLOEXEC); +- if (keyboard_fd == -1) +- dwarnln("open keyboard: {}", strerror(errno)); +- else +- { +- epoll_event event { +- .events = EPOLLIN, +- .data = { .fd = keyboard_fd }, +- }; +- if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, keyboard_fd, &event) == -1) +- { +- dwarnln("epoll_ctl keyboard: {}", strerror(errno)); +- close(keyboard_fd); +- keyboard_fd = -1; +- } +- } +- +- int mouse_fd = open("/dev/mouse", O_RDONLY | O_CLOEXEC); +- if (mouse_fd == -1) +- dwarnln("open mouse: {}", strerror(errno)); +- else +- { +- epoll_event event { +- .events = EPOLLIN, +- .data = { .fd = mouse_fd }, +- }; +- if (epoll_ctl(g_epoll_fd, EPOLL_CTL_ADD, mouse_fd, &event) == -1) +- { +- dwarnln("epoll_ctl mouse: {}", strerror(errno)); +- close(mouse_fd); +- mouse_fd = -1; +- } +- } ++ MUST(LibInput::KeyboardLayout::get().load_from_file("./us.keymap"_sv)); + + dprintln("Window server started"); + +- if (access("/usr/bin/xbanan", O_EXEC) == 0) +- { +- if (fork() == 0) +- { +- dup2(STDDBG_FILENO, STDOUT_FILENO); +- dup2(STDDBG_FILENO, STDERR_FILENO); +- execl("/usr/bin/xbanan", "xbanan", NULL); +- exit(1); +- } +- } +- + auto config = parse_config(); + + WindowServer window_server(framebuffer, config.corner_radius); +@@ -276,26 +225,23 @@ int main() + uint64_t last_sync_us = get_current_us() - sync_interval_us; + while (!window_server.is_stopped()) + { +- timespec* ptimeout = nullptr; +- + timespec timeout = {}; +- if (window_server.is_damaged()) +- { +- if (const auto current_us = get_current_us(); current_us - last_sync_us > sync_interval_us) +- { +- window_server.sync(); + +- const auto full_intervals = (current_us - last_sync_us) / sync_interval_us; +- last_sync_us += full_intervals * sync_interval_us; +- } ++ if (const auto current_us = get_current_us(); current_us - last_sync_us > sync_interval_us) ++ { ++ window_server.sync(); + +- if (const auto current_us = get_current_us(); current_us - last_sync_us < sync_interval_us) +- timeout.tv_nsec = (sync_interval_us - (current_us - last_sync_us)) * 1000; +- ptimeout = &timeout; ++ const auto full_intervals = (current_us - last_sync_us) / sync_interval_us; ++ last_sync_us += full_intervals * sync_interval_us; + } + ++ if (const auto current_us = get_current_us(); current_us - last_sync_us < sync_interval_us) ++ timeout.tv_nsec = (sync_interval_us - (current_us - last_sync_us)) * 1000; ++ ++ poll_sdl_events(window_server); ++ + epoll_event events[16]; +- int epoll_events = epoll_pwait2(g_epoll_fd, events, 16, ptimeout, nullptr); ++ int epoll_events = epoll_pwait2(g_epoll_fd, events, 16, &timeout, nullptr); + if (epoll_events == -1 && errno != EINTR) + { + dwarnln("epoll_pwait2: {}", strerror(errno)); +@@ -333,48 +279,6 @@ int main() + continue; + } + +- if (events[i].data.fd == keyboard_fd) +- { +- ASSERT(events[i].events & EPOLLIN); +- +- LibInput::RawKeyEvent event; +- if (read(keyboard_fd, &event, sizeof(event)) == -1) +- { +- dwarnln("read keyboard: {}", strerror(errno)); +- continue; +- } +- window_server.on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event)); +- continue; +- } +- +- if (events[i].data.fd == mouse_fd) +- { +- ASSERT(events[i].events & EPOLLIN); +- +- LibInput::MouseEvent event; +- if (read(mouse_fd, &event, sizeof(event)) == -1) +- { +- dwarnln("read mouse: {}", strerror(errno)); +- continue; +- } +- switch (event.type) +- { +- case LibInput::MouseEventType::MouseButtonEvent: +- window_server.on_mouse_button(event.button_event); +- break; +- case LibInput::MouseEventType::MouseMoveEvent: +- window_server.on_mouse_move(event.move_event); +- break; +- case LibInput::MouseEventType::MouseMoveAbsEvent: +- window_server.on_mouse_move_abs(event.move_abs_event); +- break; +- case LibInput::MouseEventType::MouseScrollEvent: +- window_server.on_mouse_scroll(event.scroll_event); +- break; +- } +- continue; +- } +- + const int client_fd = events[i].data.fd; + if (events[i].events & (EPOLLHUP | EPOLLERR)) + { +@@ -500,3 +404,237 @@ int main() + } + } + } ++ ++#include ++ ++extern SDL_Window* g_window; ++struct Keymap ++{ ++ consteval Keymap() ++ { ++ for (auto& scancode : map) ++ scancode = 0; ++ ++ using LibInput::keycode_normal; ++ using LibInput::keycode_function; ++ using LibInput::keycode_numpad; ++ ++ map[SDL_SCANCODE_GRAVE] = keycode_normal(0, 0); ++ map[SDL_SCANCODE_1] = keycode_normal(0, 1); ++ map[SDL_SCANCODE_2] = keycode_normal(0, 2); ++ map[SDL_SCANCODE_3] = keycode_normal(0, 3); ++ map[SDL_SCANCODE_4] = keycode_normal(0, 4); ++ map[SDL_SCANCODE_5] = keycode_normal(0, 5); ++ map[SDL_SCANCODE_6] = keycode_normal(0, 6); ++ map[SDL_SCANCODE_7] = keycode_normal(0, 7); ++ map[SDL_SCANCODE_8] = keycode_normal(0, 8); ++ map[SDL_SCANCODE_9] = keycode_normal(0, 9); ++ map[SDL_SCANCODE_0] = keycode_normal(0, 10); ++ map[SDL_SCANCODE_MINUS] = keycode_normal(0, 11); ++ map[SDL_SCANCODE_EQUALS] = keycode_normal(0, 12); ++ map[SDL_SCANCODE_BACKSPACE] = keycode_normal(0, 13); ++ ++ map[SDL_SCANCODE_TAB] = keycode_normal(1, 0); ++ map[SDL_SCANCODE_Q] = keycode_normal(1, 1); ++ map[SDL_SCANCODE_W] = keycode_normal(1, 2); ++ map[SDL_SCANCODE_E] = keycode_normal(1, 3); ++ map[SDL_SCANCODE_R] = keycode_normal(1, 4); ++ map[SDL_SCANCODE_T] = keycode_normal(1, 5); ++ map[SDL_SCANCODE_Y] = keycode_normal(1, 6); ++ map[SDL_SCANCODE_U] = keycode_normal(1, 7); ++ map[SDL_SCANCODE_I] = keycode_normal(1, 8); ++ map[SDL_SCANCODE_O] = keycode_normal(1, 9); ++ map[SDL_SCANCODE_P] = keycode_normal(1, 10); ++ map[SDL_SCANCODE_LEFTBRACKET] = keycode_normal(1, 11); ++ map[SDL_SCANCODE_RIGHTBRACKET] = keycode_normal(1, 12); ++ ++ map[SDL_SCANCODE_CAPSLOCK] = keycode_normal(2, 0); ++ map[SDL_SCANCODE_A] = keycode_normal(2, 1); ++ map[SDL_SCANCODE_S] = keycode_normal(2, 2); ++ map[SDL_SCANCODE_D] = keycode_normal(2, 3); ++ map[SDL_SCANCODE_F] = keycode_normal(2, 4); ++ map[SDL_SCANCODE_G] = keycode_normal(2, 5); ++ map[SDL_SCANCODE_H] = keycode_normal(2, 6); ++ map[SDL_SCANCODE_J] = keycode_normal(2, 7); ++ map[SDL_SCANCODE_K] = keycode_normal(2, 8); ++ map[SDL_SCANCODE_L] = keycode_normal(2, 9); ++ map[SDL_SCANCODE_SEMICOLON] = keycode_normal(2, 10); ++ map[SDL_SCANCODE_APOSTROPHE] = keycode_normal(2, 11); ++ map[SDL_SCANCODE_BACKSLASH] = keycode_normal(2, 12); ++ map[SDL_SCANCODE_RETURN] = keycode_normal(2, 13); ++ ++ map[SDL_SCANCODE_LSHIFT] = keycode_normal(3, 0); ++ map[SDL_SCANCODE_NONUSBACKSLASH] = keycode_normal(3, 1); ++ map[SDL_SCANCODE_Z] = keycode_normal(3, 2); ++ map[SDL_SCANCODE_X] = keycode_normal(3, 3); ++ map[SDL_SCANCODE_C] = keycode_normal(3, 4); ++ map[SDL_SCANCODE_V] = keycode_normal(3, 5); ++ map[SDL_SCANCODE_B] = keycode_normal(3, 6); ++ map[SDL_SCANCODE_N] = keycode_normal(3, 7); ++ map[SDL_SCANCODE_M] = keycode_normal(3, 8); ++ map[SDL_SCANCODE_COMMA] = keycode_normal(3, 9); ++ map[SDL_SCANCODE_PERIOD] = keycode_normal(3, 10); ++ map[SDL_SCANCODE_SLASH] = keycode_normal(3, 11); ++ map[SDL_SCANCODE_RSHIFT] = keycode_normal(3, 12); ++ ++ map[SDL_SCANCODE_LCTRL] = keycode_normal(4, 0); ++ map[SDL_SCANCODE_LGUI] = keycode_normal(4, 1); ++ map[SDL_SCANCODE_LALT] = keycode_normal(4, 2); ++ map[SDL_SCANCODE_SPACE] = keycode_normal(4, 3); ++ map[SDL_SCANCODE_RALT] = keycode_normal(4, 4); ++ map[SDL_SCANCODE_RCTRL] = keycode_normal(4, 5); ++ ++ map[SDL_SCANCODE_UP] = keycode_normal(5, 0); ++ map[SDL_SCANCODE_LEFT] = keycode_normal(5, 1); ++ map[SDL_SCANCODE_DOWN] = keycode_normal(5, 2); ++ map[SDL_SCANCODE_RIGHT] = keycode_normal(5, 3); ++ ++ map[SDL_SCANCODE_ESCAPE] = keycode_function(0); ++ map[SDL_SCANCODE_F1] = keycode_function(1); ++ map[SDL_SCANCODE_F2] = keycode_function(2); ++ map[SDL_SCANCODE_F3] = keycode_function(3); ++ map[SDL_SCANCODE_F4] = keycode_function(4); ++ map[SDL_SCANCODE_F5] = keycode_function(5); ++ map[SDL_SCANCODE_F6] = keycode_function(6); ++ map[SDL_SCANCODE_F7] = keycode_function(7); ++ map[SDL_SCANCODE_F8] = keycode_function(8); ++ map[SDL_SCANCODE_F9] = keycode_function(9); ++ map[SDL_SCANCODE_F10] = keycode_function(10); ++ map[SDL_SCANCODE_F11] = keycode_function(11); ++ map[SDL_SCANCODE_F12] = keycode_function(12); ++ map[SDL_SCANCODE_INSERT] = keycode_function(13); ++ map[SDL_SCANCODE_PRINTSCREEN] = keycode_function(14); ++ map[SDL_SCANCODE_DELETE] = keycode_function(15); ++ map[SDL_SCANCODE_HOME] = keycode_function(16); ++ map[SDL_SCANCODE_END] = keycode_function(17); ++ map[SDL_SCANCODE_PAGEUP] = keycode_function(18); ++ map[SDL_SCANCODE_PAGEDOWN] = keycode_function(19); ++ map[SDL_SCANCODE_SCROLLLOCK] = keycode_function(20); ++ ++ map[SDL_SCANCODE_NUMLOCKCLEAR] = keycode_numpad(0, 0); ++ map[SDL_SCANCODE_KP_DIVIDE] = keycode_numpad(0, 1); ++ map[SDL_SCANCODE_KP_MULTIPLY] = keycode_numpad(0, 2); ++ map[SDL_SCANCODE_KP_MINUS] = keycode_numpad(0, 3); ++ map[SDL_SCANCODE_KP_7] = keycode_numpad(1, 0); ++ map[SDL_SCANCODE_KP_8] = keycode_numpad(1, 1); ++ map[SDL_SCANCODE_KP_9] = keycode_numpad(1, 2); ++ map[SDL_SCANCODE_KP_PLUS] = keycode_numpad(1, 3); ++ map[SDL_SCANCODE_KP_4] = keycode_numpad(2, 0); ++ map[SDL_SCANCODE_KP_5] = keycode_numpad(2, 1); ++ map[SDL_SCANCODE_KP_6] = keycode_numpad(2, 2); ++ map[SDL_SCANCODE_KP_1] = keycode_numpad(3, 0); ++ map[SDL_SCANCODE_KP_2] = keycode_numpad(3, 1); ++ map[SDL_SCANCODE_KP_3] = keycode_numpad(3, 2); ++ map[SDL_SCANCODE_KP_ENTER] = keycode_numpad(3, 3); ++ map[SDL_SCANCODE_KP_0] = keycode_numpad(4, 0); ++ map[SDL_SCANCODE_KP_COMMA] = keycode_numpad(4, 1); ++ }; ++ ++ uint8_t map[SDL_NUM_SCANCODES]; ++}; ++static Keymap s_sdl_keymap; ++ ++static void poll_sdl_events(WindowServer& window_server) ++{ ++ { ++ static int prev_x { 0 }; ++ static int prev_y { 0 }; ++ ++ int x, y; ++ SDL_GetMouseState(&x, &y); ++ ++ if (prev_x != x || prev_y != y) ++ { ++ int w, h; ++ SDL_GetWindowSize(g_window, &w, &h); ++ ++ window_server.on_mouse_move_abs({ ++ .abs_x = x, ++ .abs_y = y, ++ .min_x = 0, ++ .min_y = 0, ++ .max_x = w, ++ .max_y = h, ++ }); ++ } ++ ++ prev_x = x; ++ prev_y = y; ++ } ++ ++ SDL_Event event; ++ while (SDL_PollEvent(&event)) ++ { ++ switch (event.type) ++ { ++ case SDL_QUIT: ++ window_server.stop(); ++ break; ++ case SDL_WINDOWEVENT: ++ if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) ++ SDL_ShowCursor(SDL_DISABLE); ++ if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) ++ SDL_ShowCursor(SDL_ENABLE); ++ break; ++ case SDL_KEYDOWN: ++ case SDL_KEYUP: ++ { ++ uint16_t modifier = 0; ++ if (event.key.keysym.mod & KMOD_LSHIFT) ++ modifier |= LibInput::KeyEvent::Modifier::LShift; ++ if (event.key.keysym.mod & KMOD_RSHIFT) ++ modifier |= LibInput::KeyEvent::Modifier::RShift; ++ if (event.key.keysym.mod & KMOD_LCTRL) ++ modifier |= LibInput::KeyEvent::Modifier::LCtrl; ++ if (event.key.keysym.mod & KMOD_RCTRL) ++ modifier |= LibInput::KeyEvent::Modifier::RCtrl; ++ if (event.key.keysym.mod & KMOD_LALT) ++ modifier |= LibInput::KeyEvent::Modifier::LAlt; ++ if (event.key.keysym.mod & KMOD_RALT) ++ modifier |= LibInput::KeyEvent::Modifier::RAlt; ++ if (event.key.keysym.mod & KMOD_NUM) ++ modifier |= LibInput::KeyEvent::Modifier::NumLock; ++ if (event.key.keysym.mod & KMOD_SCROLL) ++ modifier |= LibInput::KeyEvent::Modifier::ScrollLock; ++ if (event.key.keysym.mod & KMOD_CAPS) ++ modifier |= LibInput::KeyEvent::Modifier::CapsLock; ++ if (event.key.state == SDL_PRESSED) ++ modifier |= LibInput::KeyEvent::Modifier::Pressed; ++ ++ window_server.on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw({ ++ .modifier = modifier, ++ .keycode = s_sdl_keymap.map[event.key.keysym.scancode], ++ })); ++ ++ break; ++ } ++ case SDL_MOUSEBUTTONDOWN: ++ case SDL_MOUSEBUTTONUP: ++ { ++ LibInput::MouseButton button_map[] { ++ [0] = LibInput::MouseButton::Left, ++ [SDL_BUTTON_LEFT] = LibInput::MouseButton::Left, ++ [SDL_BUTTON_MIDDLE] = LibInput::MouseButton::Middle, ++ [SDL_BUTTON_RIGHT] = LibInput::MouseButton::Right, ++ [SDL_BUTTON_X1] = LibInput::MouseButton::Extra1, ++ [SDL_BUTTON_X2] = LibInput::MouseButton::Extra2, ++ }; ++ ++ window_server.on_mouse_button({ ++ .button = button_map[event.button.button], ++ .pressed = (event.button.state == SDL_PRESSED), ++ }); ++ ++ break; ++ } ++ case SDL_MOUSEWHEEL: ++ { ++ window_server.on_mouse_scroll({ ++ .scroll = event.wheel.y, ++ }); ++ ++ break; ++ } ++ } ++ } ++} +-- +2.53.0 + diff --git a/BAN/BAN/Assert.cpp b/BAN/BAN/Assert.cpp deleted file mode 100644 index 6bc462a..0000000 --- a/BAN/BAN/Assert.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#if __is_kernel - -#include - -[[noreturn]] void __ban_assertion_failed(const char* location, const char* msg) -{ - Kernel::panic_impl(location, msg); -} - -#else - -#include - -[[noreturn]] void __ban_assertion_failed(const char* location, const char* msg) -{ - derrorln("{}: {}", location, msg); - __builtin_trap(); -} - -#endif diff --git a/BAN/BAN/Assert.cpp.o b/BAN/BAN/Assert.cpp.o deleted file mode 100644 index 9b01a13..0000000 Binary files a/BAN/BAN/Assert.cpp.o and /dev/null differ diff --git a/BAN/BAN/New.cpp b/BAN/BAN/New.cpp deleted file mode 100644 index 51d3577..0000000 --- a/BAN/BAN/New.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include - -void* operator new(size_t size) { return BAN::allocator(size); } -void* operator new[](size_t size) { return BAN::allocator(size); } - -void operator delete(void* addr) { BAN::deallocator(addr); } -void operator delete[](void* addr) { BAN::deallocator(addr); } -void operator delete(void* addr, size_t) { BAN::deallocator(addr); } -void operator delete[](void* addr, size_t) { BAN::deallocator(addr); } diff --git a/BAN/BAN/New.cpp.o b/BAN/BAN/New.cpp.o deleted file mode 100644 index 00ca23b..0000000 Binary files a/BAN/BAN/New.cpp.o and /dev/null differ diff --git a/BAN/BAN/StringView.cpp b/BAN/BAN/StringView.cpp deleted file mode 100644 index 5a2eea0..0000000 --- a/BAN/BAN/StringView.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -namespace BAN -{ - - StringView::StringView(const String& other) - : StringView(other.data(), other.size()) - { } - -} diff --git a/BAN/BAN/StringView.cpp.o b/BAN/BAN/StringView.cpp.o deleted file mode 100644 index 149f34f..0000000 Binary files a/BAN/BAN/StringView.cpp.o and /dev/null differ diff --git a/BAN/BAN/Time.cpp b/BAN/BAN/Time.cpp deleted file mode 100644 index 73237a8..0000000 --- a/BAN/BAN/Time.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include - -namespace BAN -{ - - static constexpr bool is_leap_year(uint64_t year) - { - if (year % 400 == 0) - return true; - if (year % 100 == 0) - return false; - if (year % 4 == 0) - return true; - return false; - } - - static constexpr uint64_t leap_days_since_epoch(const BAN::Time& time) - { - uint64_t leap_years = 0; - for (uint32_t year = 1970; year < time.year; year++) - if (is_leap_year(year)) - leap_years++; - if (is_leap_year(time.year) && time.month >= 3) - leap_years++; - return leap_years; - } - - static constexpr uint64_t month_days[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - uint64_t to_unix_time(const BAN::Time& time) - { - uint64_t years = time.year - 1970; - uint64_t days = years * 365 + month_days[time.month - 1] + leap_days_since_epoch(time) + (time.day - 1); - uint64_t hours = days * 24 + time.hour; - uint64_t minutes = hours * 60 + time.minute; - uint64_t seconds = minutes * 60 + time.second; - return seconds; - } - - BAN::Time from_unix_time(uint64_t unix_time) - { - BAN::Time time {}; - - time.second = unix_time % 60; unix_time /= 60; - time.minute = unix_time % 60; unix_time /= 60; - time.hour = unix_time % 24; unix_time /= 24; - - uint64_t total_days = unix_time; - - time.week_day = (total_days + 4) % 7 + 1; - - time.year = 1970; - while (total_days >= 365U + is_leap_year(time.year)) - { - total_days -= 365U + is_leap_year(time.year); - time.year++; - } - - bool is_leap_day = is_leap_year(time.year) && total_days == month_days[2]; - bool had_leap_day = is_leap_year(time.year) && total_days > month_days[2]; - - for (time.month = 1; time.month < 12; time.month++) - if (total_days < month_days[time.month] + (is_leap_day || had_leap_day)) - break; - - time.day = total_days - month_days[time.month - 1] + !had_leap_day; - - return time; - } - -} diff --git a/BAN/BAN/Time.cpp.o b/BAN/BAN/Time.cpp.o deleted file mode 100644 index d477b54..0000000 Binary files a/BAN/BAN/Time.cpp.o and /dev/null differ diff --git a/BAN/CMakeLists.txt b/BAN/CMakeLists.txt deleted file mode 100644 index 1ea6756..0000000 --- a/BAN/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(BAN_SOURCES - BAN/Assert.cpp - BAN/New.cpp - BAN/StringView.cpp - BAN/Time.cpp -) - -add_library(ban ${BAN_SOURCES}) - -set_target_properties(ban PROPERTIES OUTPUT_NAME libban) - -# set SONAME as cmake doesn't set it for some reason?? -set_target_properties(ban PROPERTIES LINK_FLAGS "-Wl,-soname,libban.so") - -banan_install_headers(ban) -install(TARGETS ban OPTIONAL) diff --git a/BAN/include/BAN/Array.h b/BAN/include/BAN/Array.h deleted file mode 100644 index b17d3c9..0000000 --- a/BAN/include/BAN/Array.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace BAN -{ - - template - class Array - { - public: - using size_type = decltype(S); - using value_type = T; - using iterator = IteratorSimple; - using const_iterator = ConstIteratorSimple; - - public: - constexpr Array() = default; - constexpr Array(const T&); - - iterator begin() { return iterator(m_data); } - iterator end() { return iterator(m_data + size()); } - const_iterator begin() const { return const_iterator(m_data); } - const_iterator end() const { return const_iterator(m_data + size()); } - - constexpr const T& operator[](size_type) const; - constexpr T& operator[](size_type); - - constexpr const T& back() const; - constexpr T& back(); - constexpr const T& front() const; - constexpr T& front(); - - Span span() { return Span(m_data, size()); } - Span span() const { return Span(m_data, size()); } - - constexpr size_type size() const; - - constexpr const T* data() const { return m_data; } - constexpr T* data() { return m_data; } - - private: - T m_data[S] {}; - }; - - template - constexpr Array::Array(const T& value) - { - for (size_type i = 0; i < S; i++) - m_data[i] = value; - } - - template - constexpr const T& Array::operator[](size_type index) const - { - ASSERT(index < S); - return m_data[index]; - } - - template - constexpr T& Array::operator[](size_type index) - { - ASSERT(index < S); - return m_data[index]; - } - - template - constexpr const T& Array::back() const - { - ASSERT(S != 0); - return m_data[S - 1]; - } - - template - constexpr T& Array::back() - { - ASSERT(S != 0); - return m_data[S - 1]; - } - - template - constexpr const T& Array::front() const - { - ASSERT(S != 0); - return m_data[0]; - } - - template - constexpr T& Array::front() - { - ASSERT(S != 0); - return m_data[0]; - } - - template - constexpr typename Array::size_type Array::size() const - { - return S; - } - -} diff --git a/BAN/include/BAN/Assert.h b/BAN/include/BAN/Assert.h deleted file mode 100644 index 9877722..0000000 --- a/BAN/include/BAN/Assert.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#define __ban_assert_stringify_helper(s) #s -#define __ban_assert_stringify(s) __ban_assert_stringify_helper(s) - -#define ASSERT(cond) \ - (__builtin_expect(!(cond), 0) \ - ? __ban_assertion_failed(__FILE__ ":" __ban_assert_stringify(__LINE__), "ASSERT(" #cond ") failed") \ - : (void)0) - -#define ASSERT_NOT_REACHED() \ - __ban_assertion_failed(__FILE__ ":" __ban_assert_stringify(__LINE__), "ASSERT_NOT_REACHED() reached") - -[[noreturn]] void __ban_assertion_failed(const char* location, const char* msg); diff --git a/BAN/include/BAN/Atomic.h b/BAN/include/BAN/Atomic.h deleted file mode 100644 index a99376f..0000000 --- a/BAN/include/BAN/Atomic.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include - -namespace BAN -{ - - enum MemoryOrder - { - memory_order_relaxed = __ATOMIC_RELAXED, - memory_order_consume = __ATOMIC_CONSUME, - memory_order_acquire = __ATOMIC_ACQUIRE, - memory_order_release = __ATOMIC_RELEASE, - memory_order_acq_rel = __ATOMIC_ACQ_REL, - memory_order_seq_cst = __ATOMIC_SEQ_CST, - }; - - template concept atomic_c = is_integral_v || is_pointer_v; - template concept atomic_lockfree_c = (is_integral_v || is_pointer_v) && __atomic_always_lock_free(sizeof(T), 0); - - template - inline void atomic_store(T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { __atomic_store_n(&obj, value, mem_order); } - template - inline T atomic_load(T& obj, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_load_n(&obj, mem_order); } - - template - inline T atomic_exchange(T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_exchange_n(&obj, value, mem_order); } - template - inline bool atomic_compare_exchange(T& obj, U& expected, V value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_compare_exchange_n(&obj, &expected, value, false, mem_order, mem_order); } - -#define DECL_ATOMIC_INLINE template inline - DECL_ATOMIC_INLINE T atomic_add_fetch (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_add_fetch (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_sub_fetch (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_sub_fetch (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_and_fetch (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_and_fetch (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_xor_fetch (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_xor_fetch (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_or_fetch (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_or_fetch (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_nand_fetch(T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_nand_fetch(&obj, value, mem_order); } - - DECL_ATOMIC_INLINE T atomic_fetch_add (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_add (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_fetch_sub (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_sub (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_fetch_and (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_and (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_fetch_xor (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_xor (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_fetch_or (T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_or (&obj, value, mem_order); } - DECL_ATOMIC_INLINE T atomic_fetch_nand(T& obj, U value, MemoryOrder mem_order = MemoryOrder::memory_order_seq_cst) { return __atomic_fetch_nand(&obj, value, mem_order); } -#undef DECL_ATOMIC_INLINE - - template - class Atomic - { - Atomic(const Atomic&) = delete; - Atomic(Atomic&&) = delete; - Atomic& operator=(const Atomic&) volatile = delete; - Atomic& operator=(Atomic&&) volatile = delete; - - public: - constexpr Atomic() : m_value(0) {} - constexpr Atomic(T val) : m_value(val) {} - - inline T load(MemoryOrder mem_order = MEM_ORDER) const volatile { return atomic_load(m_value, mem_order); } - inline void store(T val, MemoryOrder mem_order = MEM_ORDER) volatile { atomic_store(m_value, val, mem_order); } - - inline T operator=(T val) volatile { store(val); return val; } - - inline operator T() const volatile { return load(); } - - inline T operator+=(T val) volatile { return atomic_add_fetch(m_value, val, MEM_ORDER); } - inline T operator-=(T val) volatile { return atomic_sub_fetch(m_value, val, MEM_ORDER); } - inline T operator&=(T val) volatile { return atomic_and_fetch(m_value, val, MEM_ORDER); } - inline T operator^=(T val) volatile { return atomic_xor_fetch(m_value, val, MEM_ORDER); } - inline T operator|=(T val) volatile { return atomic_or_fetch(m_value, val, MEM_ORDER); } - - inline T operator--() volatile { return atomic_sub_fetch(m_value, 1, MEM_ORDER); } - inline T operator++() volatile { return atomic_add_fetch(m_value, 1, MEM_ORDER); } - - inline T operator--(int) volatile { return atomic_fetch_sub(m_value, 1, MEM_ORDER); } - inline T operator++(int) volatile { return atomic_fetch_add(m_value, 1, MEM_ORDER); } - - inline bool compare_exchange(T& expected, T desired, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_compare_exchange(m_value, expected, desired, mem_order); } - inline T exchange(T desired, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_exchange(m_value, desired, mem_order); }; - - inline T add_fetch (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_add_fetch (m_value, val, mem_order); } - inline T sub_fetch (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_sub_fetch (m_value, val, mem_order); } - inline T and_fetch (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_and_fetch (m_value, val, mem_order); } - inline T xor_fetch (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_xor_fetch (m_value, val, mem_order); } - inline T or_fetch (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_or_fetch (m_value, val, mem_order); } - inline T nand_fetch(T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_nand_fetch(m_value, val, mem_order); } - - inline T fetch_add (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_add (m_value, val, mem_order); } - inline T fetch_sub (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_sub (m_value, val, mem_order); } - inline T fetch_and (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_and (m_value, val, mem_order); } - inline T fetch_xor (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_xor (m_value, val, mem_order); } - inline T fetch_or (T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_or (m_value, val, mem_order); } - inline T fetch_nand(T val, MemoryOrder mem_order = MEM_ORDER) volatile { return atomic_fetch_nand(m_value, val, mem_order); } - - private: - T m_value; - }; - -} diff --git a/BAN/include/BAN/Bitcast.h b/BAN/include/BAN/Bitcast.h deleted file mode 100644 index e025a91..0000000 --- a/BAN/include/BAN/Bitcast.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace BAN -{ - - template - constexpr To bit_cast(const From& from) - { - return __builtin_bit_cast(To, from); - } - -} diff --git a/BAN/include/BAN/Bitset.h b/BAN/include/BAN/Bitset.h deleted file mode 100644 index 201a80e..0000000 --- a/BAN/include/BAN/Bitset.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - template - class Bitset - { - public: - using internal_type = uint64_t; - - public: - - private: - BAN::Array m_bits; - }; - - void foo() - { - sizeof(Bitset<65>); - }; - -} diff --git a/BAN/include/BAN/ByteSpan.h b/BAN/include/BAN/ByteSpan.h deleted file mode 100644 index faea6fa..0000000 --- a/BAN/include/BAN/ByteSpan.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - template - class ByteSpanGeneral - { - public: - using value_type = maybe_const_t; - using size_type = size_t; - - public: - ByteSpanGeneral() = default; - ByteSpanGeneral(value_type* data, size_type size) - : m_data(data) - , m_size(size) - { } - - template - ByteSpanGeneral(const ByteSpanGeneral& other) requires(CONST || !SRC_CONST) - : m_data(other.data()) - , m_size(other.size()) - { } - template - ByteSpanGeneral(ByteSpanGeneral&& other) requires(CONST || !SRC_CONST) - : m_data(other.data()) - , m_size(other.size()) - { - other.clear(); - } - - template - ByteSpanGeneral(const Span& other) requires(is_same_v || (is_same_v && CONST)) - : m_data(other.data()) - , m_size(other.size()) - { } - template - ByteSpanGeneral(Span&& other) requires(is_same_v || (is_same_v && CONST)) - : m_data(other.data()) - , m_size(other.size()) - { - other.clear(); - } - - template - ByteSpanGeneral& operator=(const ByteSpanGeneral& other) requires(CONST || !SRC_CONST) - { - m_data = other.data(); - m_size = other.size(); - return *this; - } - template - ByteSpanGeneral& operator=(ByteSpanGeneral&& other) requires(CONST || !SRC_CONST) - { - m_data = other.data(); - m_size = other.size(); - other.clear(); - return *this; - } - - template - static ByteSpanGeneral from(S& value) requires(CONST || !is_const_v) - { - return ByteSpanGeneral(reinterpret_cast(&value), sizeof(S)); - } - - template - S& as() const requires(!CONST || is_const_v) - { - ASSERT(m_data); - ASSERT(m_size >= sizeof(S)); - return *reinterpret_cast(m_data); - } - - template - Span as_span() const requires(!CONST || is_const_v) - { - ASSERT(m_data); - return Span(reinterpret_cast(m_data), m_size / sizeof(S)); - } - - [[nodiscard]] ByteSpanGeneral slice(size_type offset, size_type length = size_type(-1)) const - { - ASSERT(m_data); - ASSERT(m_size >= offset); - if (length == size_type(-1)) - length = m_size - offset; - ASSERT(m_size >= offset + length); - return ByteSpanGeneral(m_data + offset, length); - } - - value_type& operator[](size_type offset) const - { - ASSERT(offset < m_size); - return m_data[offset]; - } - - value_type* data() const { return m_data; } - - bool empty() const { return m_size == 0; } - size_type size() const { return m_size; } - - void clear() - { - m_data = nullptr; - m_size = 0; - } - - private: - value_type* m_data { nullptr }; - size_type m_size { 0 }; - - friend class ByteSpanGeneral; - }; - - using ByteSpan = ByteSpanGeneral; - using ConstByteSpan = ByteSpanGeneral; - -} diff --git a/BAN/include/BAN/CircularQueue.h b/BAN/include/BAN/CircularQueue.h deleted file mode 100644 index 9400d81..0000000 --- a/BAN/include/BAN/CircularQueue.h +++ /dev/null @@ -1,158 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -namespace BAN -{ - - template - class CircularQueue - { - public: - using size_type = size_t; - using value_type = T; - - public: - CircularQueue() = default; - ~CircularQueue(); - - void push(const T&); - void push(T&&); - template - void emplace(Args&&... args) requires is_constructible_v; - - void pop(); - - const T& front() const; - T& front(); - - const T& back() const; - T& back(); - - const T& operator[](size_t index) const; - T& operator[](size_t index); - - void clear(); - - size_type size() const { return m_size; } - bool empty() const { return size() == 0; } - bool full() const { return size() == capacity(); } - - static constexpr size_type capacity() { return S; } - - private: - T* element_at(size_type); - const T* element_at(size_type) const; - - private: - alignas(T) uint8_t m_storage[sizeof(T) * capacity()]; - size_type m_first { 0 }; - size_type m_size { 0 }; - }; - - template - CircularQueue::~CircularQueue() - { - clear(); - } - - template - void CircularQueue::push(const T& value) - { - emplace(BAN::move(T(value))); - } - - template - void CircularQueue::push(T&& value) - { - emplace(BAN::move(value)); - } - - template - template - void CircularQueue::emplace(Args&&... args) requires is_constructible_v - { - ASSERT(!full()); - new (element_at(((m_first + m_size) % capacity()))) T(BAN::forward(args)...); - m_size++; - } - - template - void CircularQueue::pop() - { - ASSERT(!empty()); - element_at(m_first)->~T(); - m_first = (m_first + 1) % capacity(); - m_size--; - } - - template - const T& CircularQueue::front() const - { - ASSERT(!empty()); - return *element_at(m_first); - } - - template - T& CircularQueue::front() - { - ASSERT(!empty()); - return *element_at(m_first); - } - - template - const T& CircularQueue::back() const - { - ASSERT(!empty()); - return *element_at((m_first + m_size - 1) % capacity()); - } - - template - T& CircularQueue::back() - { - ASSERT(!empty()); - return *element_at((m_first + m_size - 1) % capacity()); - } - - template - const T& CircularQueue::operator[](size_t index) const - { - ASSERT(index < m_size); - return *element_at((m_first + index) % capacity()); - } - - template - T& CircularQueue::operator[](size_t index) - { - ASSERT(index < m_size); - return *element_at((m_first + index) % capacity()); - } - - template - void CircularQueue::clear() - { - for (size_type i = 0; i < m_size; i++) - element_at((m_first + i) % capacity())->~T(); - m_size = 0; - } - - template - const T* CircularQueue::element_at(size_type index) const - { - ASSERT(index < capacity()); - return (const T*)(m_storage + index * sizeof(T)); - } - - template - T* CircularQueue::element_at(size_type index) - { - ASSERT(index < capacity()); - return (T*)(m_storage + index * sizeof(T)); - } - -} diff --git a/BAN/include/BAN/Debug.h b/BAN/include/BAN/Debug.h deleted file mode 100644 index f7d7ca8..0000000 --- a/BAN/include/BAN/Debug.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#if __is_kernel - -#include - -#else - -#include -#include -#include - -#define __debug_putchar [](int c) { putc_unlocked(c, stddbg); } - -inline uint64_t _ban_init_start_ms() -{ - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; -} - -inline uint64_t _ban_start_ms = _ban_init_start_ms(); - -#define __print_timestamp() \ - do { \ - timespec ts; \ - clock_gettime(CLOCK_MONOTONIC, &ts); \ - const auto ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000 - _ban_start_ms; \ - BAN::Formatter::print(__debug_putchar, "[{}.{03}] ", ms / 1000, ms % 1000); \ - } while (false) - -#define dprintln(...) \ - do { \ - flockfile(stddbg); \ - __print_timestamp(); \ - BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ - BAN::Formatter::print(__debug_putchar,"\n"); \ - fflush(stddbg); \ - funlockfile(stddbg); \ - } while (false) - -#define dwarnln(...) \ - do { \ - flockfile(stddbg); \ - BAN::Formatter::print(__debug_putchar, "\e[33m"); \ - __print_timestamp(); \ - BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ - BAN::Formatter::print(__debug_putchar, "\e[m\n"); \ - fflush(stddbg); \ - funlockfile(stddbg); \ - } while(false) - -#define derrorln(...) \ - do { \ - flockfile(stddbg); \ - BAN::Formatter::print(__debug_putchar, "\e[31m"); \ - __print_timestamp(); \ - BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ - BAN::Formatter::print(__debug_putchar, "\e[m\n"); \ - fflush(stddbg); \ - funlockfile(stddbg); \ - } while(false) - -#define dprintln_if(cond, ...) \ - do { \ - if constexpr(cond) \ - dprintln(__VA_ARGS__); \ - } while(false) - -#define dwarnln_if(cond, ...) \ - do { \ - if constexpr(cond) \ - dwarnln(__VA_ARGS__); \ - } while(false) - -#define derrorln_if(cond, ...) \ - do { \ - if constexpr(cond) \ - derrorln(__VA_ARGS__); \ - } while(false) - -#endif diff --git a/BAN/include/BAN/Endianness.h b/BAN/include/BAN/Endianness.h deleted file mode 100644 index e1ccc09..0000000 --- a/BAN/include/BAN/Endianness.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - template - constexpr T swap_endianness(T value) - { - if constexpr(sizeof(T) == 1) - return value; - if constexpr(sizeof(T) == 2) - return (((value >> 8) & 0xFF) << 0) - | (((value >> 0) & 0xFF) << 8); - if constexpr(sizeof(T) == 4) - return (((value >> 24) & 0xFF) << 0) - | (((value >> 16) & 0xFF) << 8) - | (((value >> 8) & 0xFF) << 16) - | (((value >> 0) & 0xFF) << 24); - if constexpr(sizeof(T) == 8) - return (((value >> 56) & 0xFF) << 0) - | (((value >> 48) & 0xFF) << 8) - | (((value >> 40) & 0xFF) << 16) - | (((value >> 32) & 0xFF) << 24) - | (((value >> 24) & 0xFF) << 32) - | (((value >> 16) & 0xFF) << 40) - | (((value >> 8) & 0xFF) << 48) - | (((value >> 0) & 0xFF) << 56); - T result { 0 }; - for (size_t i = 0; i < sizeof(T); i++) - result |= ((value >> (i * 8)) & 0xFF) << ((sizeof(T) - i - 1) * 8); - return result; - } - - template - constexpr T host_to_little_endian(T value) - { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ - return value; -#else - return swap_endianness(value); -#endif - } - - template - constexpr T little_endian_to_host(T value) - { - return host_to_little_endian(value); - } - - template - constexpr T host_to_big_endian(T value) - { -#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - return value; -#else - return swap_endianness(value); -#endif - } - - template - constexpr T big_endian_to_host(T value) - { - return host_to_big_endian(value); - } - - template - struct LittleEndian - { - constexpr LittleEndian() - : raw(0) - { } - - constexpr LittleEndian(T value) - : raw(host_to_little_endian(value)) - { } - - constexpr operator T() const - { - return host_to_little_endian(raw); - } - - private: - T raw; - }; - - template - struct BigEndian - { - constexpr BigEndian() - : raw(0) - { } - - constexpr BigEndian(T value) - : raw(host_to_big_endian(value)) - { } - - constexpr operator T() const - { - return host_to_big_endian(raw); - } - - private: - T raw; - }; - - template - using NetworkEndian = BigEndian; - - template - constexpr T host_to_network_endian(T value) - { - return host_to_big_endian(value); - } - - template - constexpr T network_endian_to_host(T value) - { - return big_endian_to_host(value); - } - -} diff --git a/BAN/include/BAN/Errors.h b/BAN/include/BAN/Errors.h deleted file mode 100644 index dc9e9fe..0000000 --- a/BAN/include/BAN/Errors.h +++ /dev/null @@ -1,194 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -#ifdef __is_kernel - #include - #include - #define MUST(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) Kernel::panic("{}", e.error()); e.release_value(); }) - #define MUST_REF(...) *({ auto&& e = (__VA_ARGS__); if (e.is_error()) Kernel::panic("{}", e.error()); &e.release_value(); }) -#else - #include - #define MUST(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) { derrorln("MUST(" #__VA_ARGS__ "): {}", e.error()); __builtin_trap(); } e.release_value(); }) - #define MUST_REF(...) *({ auto&& e = (__VA_ARGS__); if (e.is_error()) { derrorln("MUST(" #__VA_ARGS__ "): {}", e.error()); __builtin_trap(); } &e.release_value(); }) -#endif - -#define TRY(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) return e.release_error(); e.release_value(); }) -#define TRY_REF(...) *({ auto&& e = (__VA_ARGS__); if (e.is_error()) return e.release_error(); &e.release_value(); }) - -namespace BAN -{ - - class Error - { -#ifdef __is_kernel - private: - static constexpr uint64_t kernel_error_mask = uint64_t(1) << 63; -#endif - - public: -#ifdef __is_kernel - static Error from_error_code(Kernel::ErrorCode error) - { - return Error((uint64_t)error | kernel_error_mask); - } -#else - template - consteval static Error from_literal(const char (&message)[N]) - { - return Error(message); - } -#endif - - static Error from_errno(int error) - { - return Error(error); - } - -#ifdef __is_kernel - Kernel::ErrorCode kernel_error() const - { - return (Kernel::ErrorCode)(m_error_code & ~kernel_error_mask); - } - - bool is_kernel_error() const - { - return m_error_code & kernel_error_mask; - } -#endif - - constexpr uint64_t get_error_code() const { return m_error_code; } - const char* get_message() const - { -#ifdef __is_kernel - if (m_error_code & kernel_error_mask) - return Kernel::error_string(kernel_error()); -#else - if (m_message) - return m_message; -#endif - if (auto* desc = strerrordesc_np(m_error_code)) - return desc; - return "Unknown error"; - } - - private: - constexpr Error(uint64_t error) - : m_error_code(error) - {} - -#ifndef __is_kernel - constexpr Error(const char* message) - : m_message(message) - {} -#endif - - uint64_t m_error_code { 0 }; - -#ifndef __is_kernel - const char* m_message { nullptr }; -#endif - }; - - template - class [[nodiscard]] ErrorOr - { - BAN_NON_COPYABLE(ErrorOr); - public: - ErrorOr(const T& value) - : m_data(value) - {} - ErrorOr(T&& value) - : m_data(move(value)) - {} - ErrorOr(const Error& error) - : m_data(error) - {} - ErrorOr(Error&& error) - : m_data(move(error)) - {} - ErrorOr(ErrorOr&& other) - : m_data(move(other.m_data)) - {} - ErrorOr& operator=(ErrorOr&& other) - { - m_data = move(other.m_data); - return *this; - } - - bool is_error() const { return m_data.template has(); } - const Error& error() const { return m_data.template get(); } - Error& error() { return m_data.template get(); } - const T& value() const { return m_data.template get(); } - T& value() { return m_data.template get(); } - - Error release_error() { return move(error()); m_data.clear(); } - T release_value() { return move(value()); m_data.clear(); } - - private: - Variant m_data; - }; - - template - class [[nodiscard]] ErrorOr - { - public: - ErrorOr(T value) - { - m_data.template set(value); - } - ErrorOr(Error&& error) - : m_data(move(error)) - { } - ErrorOr(const Error& error) - : m_data(error) - { } - - bool is_error() const { return m_data.template has(); } - Error& error() { return m_data.template get(); } - const Error& error() const { return m_data.template get(); } - T value() { return m_data.template get(); } - - Error release_error() { return move(error()); m_data.clear(); } - T release_value() { return value(); m_data.clear(); } - - private: - Variant m_data; - }; - - template<> - class [[nodiscard]] ErrorOr - { - public: - ErrorOr() {} - ErrorOr(const Error& error) : m_data(error), m_has_error(true) {} - ErrorOr(Error&& error) : m_data(move(error)), m_has_error(true) {} - - bool is_error() const { return m_has_error; } - Error& error() { return m_data; } - const Error& error() const { return m_data; } - void value() { } - - Error release_error() { return move(m_data); } - void release_value() { } - - private: - Error m_data { Error::from_errno(0) }; - bool m_has_error { false }; - }; - -} - -namespace BAN::Formatter -{ - template - void print_argument(F putc, const Error& error, const ValueFormat& format) - { - print_argument(putc, error.get_message(), format); - } -} diff --git a/BAN/include/BAN/Formatter.h b/BAN/include/BAN/Formatter.h deleted file mode 100644 index 4f36fa2..0000000 --- a/BAN/include/BAN/Formatter.h +++ /dev/null @@ -1,257 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace BAN::Formatter -{ - - struct ValueFormat; - - template - concept PrintableArguments = requires(F putc, Args&&... args, const ValueFormat& format) - { - (print_argument(putc, BAN::forward(args), format), ...); - }; - - template - inline void print_argument(F putc, T value, const ValueFormat& format); - - namespace detail - { - template - inline size_t parse_format_and_print_argument(F putc, const char* format, T&& arg); - } - - /* - - IMPLEMENTATION - - */ - - struct ValueFormat - { - int base = 10; - int percision = 3; - int fill = 0; - char fill_char = '0'; - bool upper = false; - }; - - template - inline void print(F putc, const char* format) - { - while (*format) - { - putc(*format); - format++; - } - } - - template requires PrintableArguments - inline void print(F putc, const char* format, Arg&& arg, Args&&... args) - { - while (*format && *format != '{') - { - putc(*format); - format++; - } - - if (*format == '{') - { - size_t arg_len = detail::parse_format_and_print_argument(putc, format, forward(arg)); - if (arg_len == size_t(-1)) - return print(putc, format); - print(putc, format + arg_len, forward(args)...); - } - } - - template - inline void println(F putc, const char* format, Args&&... args) - { - print(putc, format, args...); - putc('\n'); - } - - namespace detail - { - - template - inline size_t parse_format_and_print_argument(F putc, const char* format, Arg&& argument) - { - ValueFormat value_format; - - if (format[0] != '{') - return size_t(-1); - - size_t i = 1; - do - { - if (!format[i] || format[i] == '}') - break; - - if (format[i] == ' ') - { - value_format.fill_char = ' '; - i++; - } - - if ('0' <= format[i] && format[i] <= '9') - { - int fill = 0; - while ('0' <= format[i] && format[i] <= '9') - { - fill = (fill * 10) + (format[i] - '0'); - i++; - } - value_format.fill = fill; - } - - switch (format[i]) - { - case 'b': value_format.base = 2; value_format.upper = false; i++; break; - case 'B': value_format.base = 2; value_format.upper = true; i++; break; - case 'o': value_format.base = 8; value_format.upper = false; i++; break; - case 'O': value_format.base = 8; value_format.upper = true; i++; break; - case 'd': value_format.base = 10; value_format.upper = false; i++; break; - case 'D': value_format.base = 10; value_format.upper = true; i++; break; - case 'h': value_format.base = 16; value_format.upper = false; i++; break; - case 'H': value_format.base = 16; value_format.upper = true; i++; break; - default: break; - } - - if (!format[i] || format[i] == '}') - break; - - if (format[i] == '.') - { - i++; - int percision = 0; - while ('0' <= format[i] && format[i] <= '9') - { - percision = (percision * 10) + (format[i] - '0'); - i++; - } - value_format.percision = percision; - } - - } while(false); - - if (format[i] != '}') - return size_t(-1); - - print_argument(putc, forward(argument), value_format); - - return i + 1; - } - - inline char value_to_base_char(uint8_t value, int base, bool upper) - { - if (base <= 10) - return value + '0'; - if (base <= 36) - { - if (value < 10) - return value + '0'; - return value + (upper ? 'A' : 'a') - 10; - } - return '?'; - } - - template - inline void print_integer(F putc, T value, const ValueFormat& format) - { - if (value == 0) - { - for (int i = 0; i < format.fill - 1; i++) - putc(format.fill_char); - putc('0'); - return; - } - - bool sign = false; - - // Fits signed 64-bit binary number and null - char buffer[66]; - char* ptr = buffer + sizeof(buffer); - *(--ptr) = '\0'; - - if (value < 0) - { - sign = true; - T digit = (format.base - (value % format.base)) % format.base; - *(--ptr) = value_to_base_char(digit, format.base, format.upper); - value = -(value / format.base); - } - - while (value) - { - *(--ptr) = value_to_base_char(value % format.base, format.base, format.upper); - value /= format.base; - } - - while (ptr >= buffer + sizeof(buffer) - format.fill) - *(--ptr) = format.fill_char; - - if (sign) - *(--ptr) = '-'; - - print(putc, ptr); - } - - template - inline void print_floating(F putc, T value, const ValueFormat& format) - { - if (value < 0) - { - putc('-'); - return print_floating(putc, -value, format); - } - - int64_t int_part = (int64_t)value; - T frac_part = value - (T)int_part; - - print_integer(putc, int_part, format); - - if (format.percision > 0) - putc('.'); - - for (int i = 0; i < format.percision; i++) - { - frac_part *= format.base; - if (i == format.percision - 1) - frac_part += 0.5; - - putc(value_to_base_char((uint8_t)frac_part % format.base, format.base, format.upper)); - } - } - - template - inline void print_pointer(F putc, void* ptr, const ValueFormat& format) - { - uintptr_t value = (uintptr_t)ptr; - print(putc, "0x"); - for (int i = sizeof(void*) * 8 - 4; i >= 0; i -= 4) - putc(value_to_base_char((value >> i) & 0xF, 16, format.upper)); - } - - } - - /* - - TEMPLATE SPECIALIZATIONS - - */ - - template inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_integer(putc, value, format); } - template inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_floating(putc, value, format); } - template inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_pointer(putc, (void*)value, format); } - - template inline void print_argument(F putc, char value, const ValueFormat&) { putc(value); } - template inline void print_argument(F putc, bool value, const ValueFormat&) { print(putc, value ? "true" : "false"); } - template inline void print_argument(F putc, const char* value, const ValueFormat&) { print(putc, value); } - template inline void print_argument(F putc, char* value, const ValueFormat&) { print(putc, value); } - -} diff --git a/BAN/include/BAN/ForwardList.h b/BAN/include/BAN/ForwardList.h deleted file mode 100644 index 6d1f0d5..0000000 --- a/BAN/include/BAN/ForwardList.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -namespace BAN -{ - - - template class Array; - template class ErrorOr; - template class Function; - template class Queue; - class String; - class StringView; - template class Vector; - template class LinkedList; - template requires (!is_const_v && ...) class Variant; - -} diff --git a/BAN/include/BAN/Function.h b/BAN/include/BAN/Function.h deleted file mode 100644 index 9406872..0000000 --- a/BAN/include/BAN/Function.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace BAN -{ - - template - class Function; - template - class Function - { - public: - Function() = default; - Function(Ret(*function)(Args...)) - { - static_assert(sizeof(CallablePointer) <= m_size); - new (m_storage) CallablePointer(function); - } - template - Function(Ret(Own::*function)(Args...), Own& owner) - { - static_assert(sizeof(CallableMember) <= m_size); - new (m_storage) CallableMember(function, owner); - } - template - Function(Ret(Own::*function)(Args...) const, const Own& owner) - { - static_assert(sizeof(CallableMemberConst) <= m_size); - new (m_storage) CallableMemberConst(function, owner); - } - template - Function(Lambda lambda) requires requires(Lambda lamda, Args&&... args) { { lambda(forward(args)...) } -> BAN::same_as; } - { - static_assert(sizeof(CallableLambda) <= m_size); - new (m_storage) CallableLambda(lambda); - } - - ~Function() - { - clear(); - } - - Ret operator()(Args... args) const - { - ASSERT(*this); - return reinterpret_cast(m_storage)->call(forward(args)...); - } - - operator bool() const - { - for (size_t i = 0; i < m_size; i++) - if (m_storage[i]) - return true; - return false; - } - - void clear() - { - if (*this) - reinterpret_cast(m_storage)->~CallableBase(); - memset(m_storage, 0, m_size); - } - - static constexpr size_t size() { return m_size; } - - private: - struct CallableBase - { - virtual ~CallableBase() {} - virtual Ret call(Args...) const = 0; - }; - - struct CallablePointer : public CallableBase - { - CallablePointer(Ret(*function)(Args...)) - : m_function(function) - { } - - virtual Ret call(Args... args) const override - { - return m_function(forward(args)...); - } - - private: - Ret(*m_function)(Args...) = nullptr; - }; - - template - struct CallableMember : public CallableBase - { - CallableMember(Ret(Own::*function)(Args...), Own& owner) - : m_owner(owner) - , m_function(function) - { } - - virtual Ret call(Args... args) const override - { - return (m_owner.*m_function)(forward(args)...); - } - - private: - Own& m_owner; - Ret(Own::*m_function)(Args...) = nullptr; - }; - - template - struct CallableMemberConst : public CallableBase - { - CallableMemberConst(Ret(Own::*function)(Args...) const, const Own& owner) - : m_owner(owner) - , m_function(function) - { } - - virtual Ret call(Args... args) const override - { - return (m_owner.*m_function)(forward(args)...); - } - - private: - const Own& m_owner; - Ret(Own::*m_function)(Args...) const = nullptr; - }; - - template - struct CallableLambda : public CallableBase - { - CallableLambda(Lambda lambda) - : m_lambda(lambda) - { } - - virtual Ret call(Args... args) const override - { - return m_lambda(forward(args)...); - } - - private: - Lambda m_lambda; - }; - - private: - static constexpr size_t m_size = sizeof(void*) * 8; - alignas(CallableBase) uint8_t m_storage[m_size] { 0 }; - }; - -} diff --git a/BAN/include/BAN/GUID.h b/BAN/include/BAN/GUID.h deleted file mode 100644 index 2336ee7..0000000 --- a/BAN/include/BAN/GUID.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace BAN -{ - - struct GUID - { - uint32_t component1 { 0 }; - uint16_t component2 { 0 }; - uint16_t component3 { 0 }; - uint8_t component45[8] { }; - - bool operator==(const GUID& other) const - { - return memcmp(this, &other, sizeof(GUID)) == 0; - } - - BAN::ErrorOr to_string() const - { - char buffer[37]; - char* ptr = buffer; - - const auto append_hex_nibble = - [&ptr](uint8_t nibble) - { - if (nibble < 10) - *ptr++ = '0' + nibble; - else - *ptr++ = 'A' + nibble - 10; - }; - - const auto append_hex_byte = - [&append_hex_nibble](uint8_t byte) - { - append_hex_nibble(byte >> 4); - append_hex_nibble(byte & 0xF); - }; - - append_hex_byte((component1 >> 24) & 0xFF); - append_hex_byte((component1 >> 16) & 0xFF); - append_hex_byte((component1 >> 8) & 0xFF); - append_hex_byte((component1 >> 0) & 0xFF); - *ptr++ = '-'; - append_hex_byte((component2 >> 8) & 0xFF); - append_hex_byte((component2 >> 0) & 0xFF); - *ptr++ = '-'; - append_hex_byte((component3 >> 8) & 0xFF); - append_hex_byte((component3 >> 0) & 0xFF); - *ptr++ = '-'; - append_hex_byte(component45[0]); - append_hex_byte(component45[1]); - *ptr++ = '-'; - append_hex_byte(component45[2]); - append_hex_byte(component45[3]); - append_hex_byte(component45[4]); - append_hex_byte(component45[5]); - append_hex_byte(component45[6]); - append_hex_byte(component45[7]); - *ptr = '\0'; - - BAN::String guid; - TRY(guid.append(buffer)); - return BAN::move(guid); - } - }; - static_assert(sizeof(GUID) == 16); - -} diff --git a/BAN/include/BAN/Hash.h b/BAN/include/BAN/Hash.h deleted file mode 100644 index 035e3be..0000000 --- a/BAN/include/BAN/Hash.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace BAN -{ - - template - struct hash; - - using hash_t = uint32_t; - - inline constexpr hash_t u32_hash(uint32_t val) - { - val = ((val >> 16) ^ val) * 0x119de1f3; - val = ((val >> 16) ^ val) * 0x119de1f3; - val = ((val >> 16) ^ val); - return val; - } - - inline constexpr hash_t u64_hash(uint64_t val) - { - hash_t low = u32_hash(val); - hash_t high = u32_hash(val >> 32); - return low ^ high; - } - - template - struct hash - { - constexpr hash_t operator()(T val) const - { - if constexpr(sizeof(val) <= sizeof(uint32_t)) - return u32_hash(val); - return u64_hash(val); - } - }; - - template - struct hash - { - constexpr hash_t operator()(T val) const - { - return hash()((uintptr_t)val); - } - }; - -} diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h deleted file mode 100644 index ef2489d..0000000 --- a/BAN/include/BAN/HashMap.h +++ /dev/null @@ -1,319 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace BAN -{ - - template> - class HashMap - { - public: - struct Entry - { - template - Entry(const Key& key, Args&&... args) requires is_constructible_v - : key(key) - , value(forward(args)...) - {} - - template - Entry(Key&& key, Args&&... args) requires is_constructible_v - : key(BAN::move(key)) - , value(forward(args)...) - {} - - Key key; - T value; - }; - - public: - using size_type = size_t; - using key_type = Key; - using value_type = T; - using iterator = IteratorDouble; - using const_iterator = ConstIteratorDouble; - - public: - HashMap() = default; - HashMap(const HashMap&); - HashMap(HashMap&&); - ~HashMap(); - - HashMap& operator=(const HashMap&); - HashMap& operator=(HashMap&&); - - ErrorOr insert(const Key& key, const T& value) { return emplace(key, value); } - ErrorOr insert(const Key& key, T&& value) { return emplace(key, move(value)); } - ErrorOr insert(Key&& key, const T& value) { return emplace(move(key), value); } - ErrorOr insert(Key&& key, T&& value) { return emplace(move(key), move(value)); } - - ErrorOr insert_or_assign(const Key& key, const T& value) { return emplace_or_assign(key, value); } - ErrorOr insert_or_assign(const Key& key, T&& value) { return emplace_or_assign(key, move(value)); } - ErrorOr insert_or_assign(Key&& key, const T& value) { return emplace_or_assign(move(key), value); } - ErrorOr insert_or_assign(Key&& key, T&& value) { return emplace_or_assign(move(key), move(value)); } - - template - ErrorOr emplace(const Key& key, Args&&... args) requires is_constructible_v - { return emplace(Key(key), forward(args)...); } - template - ErrorOr emplace(Key&&, Args&&...) requires is_constructible_v; - - template - ErrorOr emplace_or_assign(const Key& key, Args&&... args) requires is_constructible_v - { return emplace_or_assign(Key(key), forward(args)...); } - template - ErrorOr emplace_or_assign(Key&&, Args&&...) requires is_constructible_v; - - iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); } - iterator end() { return iterator(m_buckets.end(), m_buckets.end()); } - const_iterator begin() const { return const_iterator(m_buckets.end(), m_buckets.begin()); } - const_iterator end() const { return const_iterator(m_buckets.end(), m_buckets.end()); } - - ErrorOr reserve(size_type); - - void remove(const Key&); - void remove(iterator it); - void clear(); - - T& operator[](const Key&); - const T& operator[](const Key&) const; - - iterator find(const Key& key); - const_iterator find(const Key& key) const; - bool contains(const Key&) const; - - bool empty() const; - size_type size() const; - - private: - ErrorOr rebucket(size_type); - LinkedList& get_bucket(const Key&); - const LinkedList& get_bucket(const Key&) const; - Vector>::iterator get_bucket_iterator(const Key&); - Vector>::const_iterator get_bucket_iterator(const Key&) const; - - private: - Vector> m_buckets; - size_type m_size = 0; - - friend iterator; - }; - - template - HashMap::HashMap(const HashMap& other) - { - *this = other; - } - - template - HashMap::HashMap(HashMap&& other) - { - *this = move(other); - } - - template - HashMap::~HashMap() - { - clear(); - } - - template - HashMap& HashMap::operator=(const HashMap& other) - { - clear(); - m_buckets = other.m_buckets; - m_size = other.m_size; - return *this; - } - - template - HashMap& HashMap::operator=(HashMap&& other) - { - clear(); - m_buckets = move(other.m_buckets); - m_size = other.m_size; - other.m_size = 0; - return *this; - } - - template - template - ErrorOr::iterator> HashMap::emplace(Key&& key, Args&&... args) requires is_constructible_v - { - ASSERT(!contains(key)); - TRY(rebucket(m_size + 1)); - - auto bucket_it = get_bucket_iterator(key); - TRY(bucket_it->emplace_back(move(key), forward(args)...)); - m_size++; - - return iterator(m_buckets.end(), bucket_it, prev(bucket_it->end(), 1)); - } - - template - template - ErrorOr::iterator> HashMap::emplace_or_assign(Key&& key, Args&&... args) requires is_constructible_v - { - if (empty()) - return emplace(move(key), forward(args)...); - - auto bucket_it = get_bucket_iterator(key); - for (auto entry_it = bucket_it->begin(); entry_it != bucket_it->end(); entry_it++) - { - if (entry_it->key != key) - continue; - entry_it->value = T(forward(args)...); - return iterator(m_buckets.end(), bucket_it, entry_it); - } - - return emplace(move(key), forward(args)...); - } - - template - ErrorOr HashMap::reserve(size_type size) - { - TRY(rebucket(size)); - return {}; - } - - template - void HashMap::remove(const Key& key) - { - auto it = find(key); - if (it != end()) - remove(it); - } - - template - void HashMap::remove(iterator it) - { - it.outer_current()->remove(it.inner_current()); - m_size--; - } - - template - void HashMap::clear() - { - m_buckets.clear(); - m_size = 0; - } - - template - T& HashMap::operator[](const Key& key) - { - ASSERT(!empty()); - auto& bucket = get_bucket(key); - for (Entry& entry : bucket) - if (entry.key == key) - return entry.value; - ASSERT_NOT_REACHED(); - } - - template - const T& HashMap::operator[](const Key& key) const - { - ASSERT(!empty()); - const auto& bucket = get_bucket(key); - for (const Entry& entry : bucket) - if (entry.key == key) - return entry.value; - ASSERT_NOT_REACHED(); - } - - template - typename HashMap::iterator HashMap::find(const Key& key) - { - if (empty()) - return end(); - auto bucket_it = get_bucket_iterator(key); - for (auto it = bucket_it->begin(); it != bucket_it->end(); it++) - if (it->key == key) - return iterator(m_buckets.end(), bucket_it, it); - return end(); - } - - template - typename HashMap::const_iterator HashMap::find(const Key& key) const - { - if (empty()) - return end(); - auto bucket_it = get_bucket_iterator(key); - for (auto it = bucket_it->begin(); it != bucket_it->end(); it++) - if (it->key == key) - return const_iterator(m_buckets.end(), bucket_it, it); - return end(); - } - - template - bool HashMap::contains(const Key& key) const - { - return find(key) != end(); - } - - template - bool HashMap::empty() const - { - return m_size == 0; - } - - template - typename HashMap::size_type HashMap::size() const - { - return m_size; - } - - template - ErrorOr HashMap::rebucket(size_type bucket_count) - { - if (m_buckets.size() >= bucket_count) - return {}; - - size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 2); - Vector> new_buckets; - TRY(new_buckets.resize(new_bucket_count)); - - for (auto& bucket : m_buckets) - { - for (auto it = bucket.begin(); it != bucket.end();) - { - size_type new_bucket_index = HASH()(it->key) % new_buckets.size(); - it = bucket.move_element_to_other_linked_list(new_buckets[new_bucket_index], new_buckets[new_bucket_index].end(), it); - } - } - - m_buckets = move(new_buckets); - return {}; - } - - template - LinkedList::Entry>& HashMap::get_bucket(const Key& key) - { - return *get_bucket_iterator(key); - } - - template - const LinkedList::Entry>& HashMap::get_bucket(const Key& key) const - { - return *get_bucket_iterator(key); - } - - template - Vector::Entry>>::iterator HashMap::get_bucket_iterator(const Key& key) - { - ASSERT(!m_buckets.empty()); - auto index = HASH()(key) % m_buckets.size(); - return next(m_buckets.begin(), index); - } - - template - Vector::Entry>>::const_iterator HashMap::get_bucket_iterator(const Key& key) const - { - ASSERT(!m_buckets.empty()); - auto index = HASH()(key) % m_buckets.size(); - return next(m_buckets.begin(), index); - } - -} diff --git a/BAN/include/BAN/HashSet.h b/BAN/include/BAN/HashSet.h deleted file mode 100644 index d8a5305..0000000 --- a/BAN/include/BAN/HashSet.h +++ /dev/null @@ -1,199 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace BAN -{ - - template> - class HashSet - { - public: - using value_type = T; - using size_type = size_t; - using iterator = IteratorDouble; - using const_iterator = ConstIteratorDouble; - - public: - HashSet() = default; - HashSet(const HashSet&); - HashSet(HashSet&&); - - HashSet& operator=(const HashSet&); - HashSet& operator=(HashSet&&); - - ErrorOr insert(const T&); - ErrorOr insert(T&&); - void remove(const T&); - void clear(); - - ErrorOr reserve(size_type); - - iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); } - iterator end() { return iterator(m_buckets.end(), m_buckets.end()); } - const_iterator begin() const { return const_iterator(m_buckets.end(), m_buckets.begin()); } - const_iterator end() const { return const_iterator(m_buckets.end(), m_buckets.end()); } - - bool contains(const T&) const; - - size_type size() const; - bool empty() const; - - private: - ErrorOr rebucket(size_type); - LinkedList& get_bucket(const T&); - const LinkedList& get_bucket(const T&) const; - - private: - Vector> m_buckets; - size_type m_size = 0; - }; - - template - HashSet::HashSet(const HashSet& other) - : m_buckets(other.m_buckets) - , m_size(other.m_size) - { - } - - template - HashSet::HashSet(HashSet&& other) - : m_buckets(move(other.m_buckets)) - , m_size(other.m_size) - { - other.clear(); - } - - template - HashSet& HashSet::operator=(const HashSet& other) - { - clear(); - m_buckets = other.m_buckets; - m_size = other.m_size; - return *this; - } - - template - HashSet& HashSet::operator=(HashSet&& other) - { - clear(); - m_buckets = move(other.m_buckets); - m_size = other.m_size; - other.clear(); - return *this; - } - - template - ErrorOr HashSet::insert(const T& key) - { - return insert(move(T(key))); - } - - template - ErrorOr HashSet::insert(T&& key) - { - if (!empty() && get_bucket(key).contains(key)) - return {}; - - TRY(rebucket(m_size + 1)); - TRY(get_bucket(key).push_back(move(key))); - m_size++; - return {}; - } - - template - void HashSet::remove(const T& key) - { - if (empty()) return; - auto& bucket = get_bucket(key); - for (auto it = bucket.begin(); it != bucket.end(); it++) - { - if (*it == key) - { - bucket.remove(it); - m_size--; - break; - } - } - } - - template - void HashSet::clear() - { - m_buckets.clear(); - m_size = 0; - } - - template - ErrorOr HashSet::reserve(size_type size) - { - TRY(rebucket(size)); - return {}; - } - - template - bool HashSet::contains(const T& key) const - { - if (empty()) return false; - return get_bucket(key).contains(key); - } - - template - typename HashSet::size_type HashSet::size() const - { - return m_size; - } - - template - bool HashSet::empty() const - { - return m_size == 0; - } - - template - ErrorOr HashSet::rebucket(size_type bucket_count) - { - if (m_buckets.size() >= bucket_count) - return {}; - - size_type new_bucket_count = Math::max(bucket_count, m_buckets.size() * 2); - Vector> new_buckets; - if (new_buckets.resize(new_bucket_count).is_error()) - return Error::from_errno(ENOMEM); - - for (auto& bucket : m_buckets) - { - for (auto it = bucket.begin(); it != bucket.end();) - { - size_type new_bucket_index = HASH()(*it) % new_buckets.size(); - it = bucket.move_element_to_other_linked_list(new_buckets[new_bucket_index], new_buckets[new_bucket_index].end(), it); - } - } - - m_buckets = move(new_buckets); - return {}; - } - - template - LinkedList& HashSet::get_bucket(const T& key) - { - ASSERT(!m_buckets.empty()); - size_type index = HASH()(key) % m_buckets.size(); - return m_buckets[index]; - } - - template - const LinkedList& HashSet::get_bucket(const T& key) const - { - ASSERT(!m_buckets.empty()); - size_type index = HASH()(key) % m_buckets.size(); - return m_buckets[index]; - } - -} diff --git a/BAN/include/BAN/Heap.h b/BAN/include/BAN/Heap.h deleted file mode 100644 index 28f6fb8..0000000 --- a/BAN/include/BAN/Heap.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace BAN -{ - - namespace detail - { - - template - void heapify_up(It begin, size_t index, Comp comp) - { - size_t parent = (index - 1) / 2; - while (parent < index) - { - if (comp(*(begin + index), *(begin + parent))) - break; - swap(*(begin + parent), *(begin + index)); - index = parent; - parent = (index - 1) / 2; - } - } - - template - void heapify_down(It begin, size_t index, size_t len, Comp comp) - { - for (;;) - { - const size_t lchild = 2 * index + 1; - const size_t rchild = 2 * index + 2; - - size_t child = 0; - if (lchild < len && !comp(*(begin + lchild), *(begin + index))) - { - if (rchild < len && !comp(*(begin + rchild), *(begin + lchild))) - child = rchild; - else - child = lchild; - } - else if (rchild < len && !comp(*(begin + rchild), *(begin + index))) - child = rchild; - else - break; - - swap(*(begin + child), *(begin + index)); - index = child; - } - } - - } - - template>> - void make_heap(It begin, It end, Comp comp = {}) - { - const size_t len = distance(begin, end); - if (len <= 1) - return; - - size_t index = (len - 2) / 2; - while (index < len) - detail::heapify_down(begin, index--, len, comp); - } - - template>> - void push_heap(It begin, It end, Comp comp = {}) - { - const size_t len = distance(begin, end); - detail::heapify_up(begin, len - 1, comp); - } - - template>> - void pop_heap(It begin, It end, Comp comp = {}) - { - const size_t len = distance(begin, end); - swap(*begin, *(begin + len - 1)); - detail::heapify_down(begin, 0, len - 1, comp); - } - - template>> - void sort_heap(It begin, It end, Comp comp = {}) - { - while (begin != end) - pop_heap(begin, end--, comp); - } - -} diff --git a/BAN/include/BAN/IPv4.h b/BAN/include/BAN/IPv4.h deleted file mode 100644 index 325f0c4..0000000 --- a/BAN/include/BAN/IPv4.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace BAN -{ - - struct IPv4Address - { - constexpr IPv4Address(uint32_t u32_address) - { - raw = u32_address; - } - - constexpr IPv4Address(uint8_t oct1, uint8_t oct2, uint8_t oct3, uint8_t oct4) - { - octets[0] = oct1; - octets[1] = oct2; - octets[2] = oct3; - octets[3] = oct4; - } - - constexpr bool operator==(const IPv4Address& other) const - { - return raw == other.raw; - } - - constexpr IPv4Address mask(const IPv4Address& other) const - { - return IPv4Address(raw & other.raw); - } - - union - { - uint8_t octets[4]; - uint32_t raw; - } __attribute__((packed)); - }; - static_assert(sizeof(IPv4Address) == 4); - - template<> - struct hash - { - constexpr hash_t operator()(IPv4Address ipv4) const - { - return hash()(ipv4.raw); - } - }; - -} - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const IPv4Address& ipv4, const ValueFormat&) - { - ValueFormat format { - .base = 10, - .percision = 0, - .fill = 0, - .upper = false, - }; - - print_argument(putc, ipv4.octets[0], format); - for (size_t i = 1; i < 4; i++) - { - putc('.'); - print_argument(putc, ipv4.octets[i], format); - } - } - -} diff --git a/BAN/include/BAN/Iteration.h b/BAN/include/BAN/Iteration.h deleted file mode 100644 index f90385a..0000000 --- a/BAN/include/BAN/Iteration.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -namespace BAN -{ - - enum class Iteration - { - Continue, - Break - }; - -} diff --git a/BAN/include/BAN/Iterators.h b/BAN/include/BAN/Iterators.h deleted file mode 100644 index 782b59e..0000000 --- a/BAN/include/BAN/Iterators.h +++ /dev/null @@ -1,330 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace BAN -{ - - template - constexpr It next(It it, size_t count) - { - for (size_t i = 0; i < count; i++) - ++it; - return it; - } - - template - requires requires(It it, size_t n) { requires is_same_v; } - constexpr It next(It it, size_t count) - { - return it + count; - } - - template - constexpr It prev(It it, size_t count) - { - for (size_t i = 0; i < count; i++) - --it; - return it; - } - - template - requires requires(It it, size_t n) { requires is_same_v; } - constexpr It prev(It it, size_t count) - { - return it - count; - } - - template - constexpr size_t distance(It it1, It it2) - { - size_t dist = 0; - while (it1 != it2) - { - ++it1; - ++dist; - } - return dist; - } - - template - requires requires(It it1, It it2) { requires is_integral_v; } - constexpr size_t distance(It it1, It it2) - { - return it2 - it1; - } - - template - class IteratorSimpleGeneral - { - public: - using value_type = T; - - public: - constexpr IteratorSimpleGeneral() = default; - template> - constexpr IteratorSimpleGeneral(const IteratorSimpleGeneral& other) - : m_pointer(other.m_pointer) - , m_valid(other.m_valid) - { - } - - constexpr const T& operator*() const - { - ASSERT(m_pointer); - return *m_pointer; - } - template - constexpr enable_if_t operator*() - { - ASSERT(*this); - ASSERT(m_pointer); - return *m_pointer; - } - - constexpr const T* operator->() const - { - ASSERT(*this); - ASSERT(m_pointer); - return m_pointer; - } - template - constexpr enable_if_t operator->() - { - ASSERT(*this); - ASSERT(m_pointer); - return m_pointer; - } - - constexpr IteratorSimpleGeneral& operator++() - { - ASSERT(*this); - ASSERT(m_pointer); - ++m_pointer; - return *this; - } - constexpr IteratorSimpleGeneral operator++(int) - { - auto temp = *this; - ++(*this); - return temp; - } - - constexpr IteratorSimpleGeneral& operator--() - { - ASSERT(*this); - ASSERT(m_pointer); - --m_pointer; - return *this; - } - constexpr IteratorSimpleGeneral operator--(int) - { - auto temp = *this; - --(*this); - return temp; - } - - constexpr size_t operator-(const IteratorSimpleGeneral& other) const - { - ASSERT(*this && other); - return m_pointer - other.m_pointer; - } - - constexpr IteratorSimpleGeneral operator+(size_t offset) const - { - return IteratorSimpleGeneral(m_pointer + offset); - } - - constexpr IteratorSimpleGeneral operator-(size_t offset) const - { - return IteratorSimpleGeneral(m_pointer - offset); - } - - constexpr bool operator<(const IteratorSimpleGeneral& other) const - { - ASSERT(*this); - return m_pointer < other.m_pointer; - } - - constexpr bool operator==(const IteratorSimpleGeneral& other) const - { - ASSERT(*this); - return m_pointer == other.m_pointer; - } - constexpr bool operator!=(const IteratorSimpleGeneral& other) const - { - ASSERT(*this); - return !(*this == other); - } - - constexpr explicit operator bool() const - { - return m_valid; - } - - private: - constexpr IteratorSimpleGeneral(maybe_const_t* pointer) - : m_pointer(pointer) - , m_valid(true) - { - } - - private: - maybe_const_t* m_pointer = nullptr; - bool m_valid = false; - - friend IteratorSimpleGeneral; - friend Container; - }; - - template typename OuterContainer, template typename InnerContainer, typename Container, bool CONST> - class IteratorDoubleGeneral - { - public: - using Inner = InnerContainer; - using Outer = OuterContainer; - - using InnerIterator = either_or_t; - using OuterIterator = either_or_t; - - using value_type = T; - - public: - constexpr IteratorDoubleGeneral() = default; - template> - constexpr IteratorDoubleGeneral(const IteratorDoubleGeneral& other) - : m_outer_end(other.m_outer_end) - , m_outer_current(other.m_outer_current) - , m_inner_current(other.m_inner_current) - { - } - - constexpr const T& operator*() const - { - ASSERT(*this); - ASSERT(m_outer_current != m_outer_end); - ASSERT(m_inner_current); - return m_inner_current.operator*(); - } - template - constexpr enable_if_t operator*() - { - ASSERT(*this); - ASSERT(m_outer_current != m_outer_end); - ASSERT(m_inner_current); - return m_inner_current.operator*(); - } - - constexpr const T* operator->() const - { - ASSERT(*this); - ASSERT(m_outer_current != m_outer_end); - ASSERT(m_inner_current); - return m_inner_current.operator->(); - } - template - constexpr enable_if_t operator->() - { - ASSERT(*this); - ASSERT(m_outer_current != m_outer_end); - ASSERT(m_inner_current); - return m_inner_current.operator->(); - } - - constexpr IteratorDoubleGeneral& operator++() - { - ASSERT(*this); - ASSERT(m_outer_current != m_outer_end); - ASSERT(m_inner_current); - m_inner_current++; - find_valid_or_end(); - return *this; - } - constexpr IteratorDoubleGeneral operator++(int) - { - auto temp = *this; - ++(*this); - return temp; - } - - constexpr bool operator==(const IteratorDoubleGeneral& other) const - { - ASSERT(*this && other); - if (m_outer_end != other.m_outer_end) - return false; - if (m_outer_current != other.m_outer_current) - return false; - if (m_outer_current == m_outer_end) - return true; - ASSERT(m_inner_current && other.m_inner_current); - return m_inner_current == other.m_inner_current; - } - constexpr bool operator!=(const IteratorDoubleGeneral& other) const - { - return !(*this == other); - } - - constexpr explicit operator bool() const - { - return !!m_outer_current; - } - - private: - constexpr IteratorDoubleGeneral(const OuterIterator& outer_end, const OuterIterator& outer_current) - : m_outer_end(outer_end) - , m_outer_current(outer_current) - { - if (outer_current != outer_end) - { - m_inner_current = m_outer_current->begin(); - find_valid_or_end(); - } - } - - constexpr IteratorDoubleGeneral(const OuterIterator& outer_end, const OuterIterator& outer_current, const InnerIterator& inner_current) - : m_outer_end(outer_end) - , m_outer_current(outer_current) - , m_inner_current(inner_current) - { - find_valid_or_end(); - } - - constexpr void find_valid_or_end() - { - while (m_inner_current == m_outer_current->end()) - { - m_outer_current++; - if (m_outer_current == m_outer_end) - break; - m_inner_current = m_outer_current->begin(); - } - } - - constexpr OuterIterator outer_current() { return m_outer_current; } - constexpr InnerIterator inner_current() { return m_inner_current; } - - private: - OuterIterator m_outer_end; - OuterIterator m_outer_current; - InnerIterator m_inner_current; - - friend class IteratorDoubleGeneral; - friend Container; - }; - - template - using IteratorSimple = IteratorSimpleGeneral; - - template - using ConstIteratorSimple = IteratorSimpleGeneral; - - template typename OuterContainer, template typename InnerContainer, typename Container> - using IteratorDouble = IteratorDoubleGeneral; - - template typename OuterContainer, template typename InnerContainer, typename Container> - using ConstIteratorDouble = IteratorDoubleGeneral; - -} diff --git a/BAN/include/BAN/Limits.h b/BAN/include/BAN/Limits.h deleted file mode 100644 index 5efc694..0000000 --- a/BAN/include/BAN/Limits.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - template - class numeric_limits - { - public: - numeric_limits() = delete; - - static inline constexpr T max() - { - if constexpr(is_same_v) - return __SCHAR_MAX__; - if constexpr(is_same_v) - return __SCHAR_MAX__; - if constexpr(is_same_v) - return (T)__SCHAR_MAX__ * 2 + 1; - - if constexpr(is_same_v) - return __SHRT_MAX__; - if constexpr(is_same_v) - return __INT_MAX__; - if constexpr(is_same_v) - return __LONG_MAX__; - if constexpr(is_same_v) - return __LONG_LONG_MAX__; - - if constexpr(is_same_v) - return (T)__SHRT_MAX__ * 2 + 1; - if constexpr(is_same_v) - return (T)__INT_MAX__ * 2 + 1; - if constexpr(is_same_v) - return (T)__LONG_MAX__ * 2 + 1; - if constexpr(is_same_v) - return (T)__LONG_LONG_MAX__ * 2 + 1; - - if constexpr(is_same_v) - return __FLT_MAX__; - if constexpr(is_same_v) - return __DBL_MAX__; - if constexpr(is_same_v) - return __LDBL_MAX__; - } - - static inline constexpr T min() - { - if constexpr(is_signed_v && is_integral_v) - return -max() - 1; - - if constexpr(is_unsigned_v && is_integral_v) - return 0; - - if constexpr(is_same_v) - return __FLT_MIN__; - if constexpr(is_same_v) - return __DBL_MIN__; - if constexpr(is_same_v) - return __LDBL_MIN__; - } - - static inline constexpr bool has_infinity() - { - if constexpr(is_same_v) - return __FLT_HAS_INFINITY__; - if constexpr(is_same_v) - return __DBL_HAS_INFINITY__; - if constexpr(is_same_v) - return __LDBL_HAS_INFINITY__; - return false; - } - - static inline constexpr T infinity() requires(has_infinity()) - { - if constexpr(is_same_v) - return __builtin_inff(); - if constexpr(is_same_v) - return __builtin_inf(); - if constexpr(is_same_v) - return __builtin_infl(); - } - - static inline constexpr bool has_quiet_NaN() - { - if constexpr(is_same_v) - return __FLT_HAS_QUIET_NAN__; - if constexpr(is_same_v) - return __DBL_HAS_QUIET_NAN__; - if constexpr(is_same_v) - return __LDBL_HAS_QUIET_NAN__; - return false; - } - - static inline constexpr T quiet_NaN() requires(has_quiet_NaN()) - { - if constexpr(is_same_v) - return __builtin_nanf(""); - if constexpr(is_same_v) - return __builtin_nan(""); - if constexpr(is_same_v) - return __builtin_nanl(""); - } - - static inline constexpr int max_exponent2() - { - static_assert(__FLT_RADIX__ == 2); - if constexpr(is_same_v) - return __FLT_MAX_EXP__; - if constexpr(is_same_v) - return __DBL_MAX_EXP__; - if constexpr(is_same_v) - return __LDBL_MAX_EXP__; - return 0; - } - - static inline constexpr int max_exponent10() - { - if constexpr(is_same_v) - return __FLT_MAX_10_EXP__; - if constexpr(is_same_v) - return __DBL_MAX_10_EXP__; - if constexpr(is_same_v) - return __LDBL_MAX_10_EXP__; - return 0; - } - - static inline constexpr int min_exponent2() - { - static_assert(__FLT_RADIX__ == 2); - if constexpr(is_same_v) - return __FLT_MIN_EXP__; - if constexpr(is_same_v) - return __DBL_MIN_EXP__; - if constexpr(is_same_v) - return __LDBL_MIN_EXP__; - return 0; - } - - static inline constexpr int min_exponent10() - { - if constexpr(is_same_v) - return __FLT_MIN_10_EXP__; - if constexpr(is_same_v) - return __DBL_MIN_10_EXP__; - if constexpr(is_same_v) - return __LDBL_MIN_10_EXP__; - return 0; - } - }; - -} diff --git a/BAN/include/BAN/LinkedList.h b/BAN/include/BAN/LinkedList.h deleted file mode 100644 index a7b5f3a..0000000 --- a/BAN/include/BAN/LinkedList.h +++ /dev/null @@ -1,426 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace BAN -{ - - template - class LinkedListIterator; - - template - class LinkedList - { - public: - using size_type = size_t; - using value_type = T; - using iterator = LinkedListIterator; - using const_iterator = LinkedListIterator; - - public: - LinkedList() = default; - LinkedList(const LinkedList& other) requires is_copy_constructible_v { *this = other; } - LinkedList(LinkedList&& other) { *this = move(other); } - ~LinkedList() { clear(); } - - LinkedList& operator=(const LinkedList&) requires is_copy_constructible_v; - LinkedList& operator=(LinkedList&&); - - ErrorOr push_back(const T&); - ErrorOr push_back(T&&); - ErrorOr insert(iterator, const T&); - ErrorOr insert(iterator, T&&); - template - ErrorOr emplace_back(Args&&...) requires is_constructible_v; - template - ErrorOr emplace(iterator, Args&&...) requires is_constructible_v; - - void pop_back(); - iterator remove(iterator); - void clear(); - - iterator move_element_to_other_linked_list(LinkedList& dest_list, iterator dest_iter, iterator src_iter); - - iterator begin() { return iterator(m_data, empty()); } - const_iterator begin() const { return const_iterator(m_data, empty()); } - iterator end() { return iterator(m_last, true); } - const_iterator end() const { return const_iterator(m_last, true); } - - const T& back() const; - T& back(); - const T& front() const; - T& front(); - - bool contains(const T&) const; - - size_type size() const; - bool empty() const; - - private: - struct Node - { - T value; - Node* next; - Node* prev; - }; - - template - ErrorOr allocate_node(Args&&...) const; - - Node* remove_node(iterator); - void insert_node(iterator, Node*); - - Node* m_data = nullptr; - Node* m_last = nullptr; - size_type m_size = 0; - - friend class LinkedListIterator; - friend class LinkedListIterator; - }; - - template - class LinkedListIterator - { - public: - using value_type = T; - using data_type = maybe_const_t::Node>; - - public: - LinkedListIterator() = default; - template - LinkedListIterator(const LinkedListIterator&, enable_if_t* = 0); - - LinkedListIterator& operator++(); - LinkedListIterator& operator--(); - LinkedListIterator operator++(int); - LinkedListIterator operator--(int); - - template - enable_if_t operator*(); - const T& operator*() const; - - template - enable_if_t operator->(); - const T* operator->() const; - - bool operator==(const LinkedListIterator&) const; - bool operator!=(const LinkedListIterator&) const; - operator bool() const; - - private: - LinkedListIterator(data_type*, bool); - - private: - data_type* m_current = nullptr; - bool m_past_end = false; - - friend class LinkedList; - friend class LinkedListIterator; - }; - - template - LinkedList& LinkedList::operator=(const LinkedList& other) requires is_copy_constructible_v - { - clear(); - for (const T& elem : other) - MUST(push_back(elem)); - return *this; - } - - template - LinkedList& LinkedList::operator=(LinkedList&& other) - { - clear(); - m_data = other.m_data; - m_last = other.m_last; - m_size = other.m_size; - other.m_data = nullptr; - other.m_last = nullptr; - other.m_size = 0; - return *this; - } - - template - LinkedList::Node* LinkedList::remove_node(iterator iter) - { - ASSERT(!empty() && iter); - Node* node = iter.m_current; - Node* prev = node->prev; - Node* next = node->next; - (prev ? prev->next : m_data) = next; - (next ? next->prev : m_last) = prev; - m_size--; - return node; - } - - template - void LinkedList::insert_node(iterator iter, Node* node) - { - Node* next = iter.m_past_end ? nullptr : iter.m_current; - Node* prev = next ? next->prev : m_last; - node->next = next; - node->prev = prev; - (prev ? prev->next : m_data) = node; - (next ? next->prev : m_last) = node; - m_size++; - } - - template - ErrorOr LinkedList::push_back(const T& value) - { - return push_back(move(T(value))); - } - - template - ErrorOr LinkedList::push_back(T&& value) - { - return insert(end(), move(value)); - } - - template - ErrorOr LinkedList::insert(iterator iter, const T& value) - { - return insert(iter, move(T(value))); - } - - template - ErrorOr LinkedList::insert(iterator iter, T&& value) - { - Node* new_node = TRY(allocate_node(move(value))); - insert_node(iter, new_node); - return {}; - } - - template - template - ErrorOr LinkedList::emplace_back(Args&&... args) requires is_constructible_v - { - return emplace(end(), forward(args)...); - } - - template - template - ErrorOr LinkedList::emplace(iterator iter, Args&&... args) requires is_constructible_v - { - Node* new_node = TRY(allocate_node(forward(args)...)); - insert_node(iter, new_node); - return {}; - } - - template - void LinkedList::pop_back() - { - ASSERT(!empty()); - remove(iterator(m_last, false)); - } - - template - LinkedList::iterator LinkedList::remove(iterator iter) - { - ASSERT(!empty() && iter); - Node* node = remove_node(iter); - Node* next = node->next; - node->value.~T(); - BAN::deallocator(node); - return next ? iterator(next, false) : iterator(m_last, true); - } - - template - void LinkedList::clear() - { - Node* ptr = m_data; - while (ptr) - { - Node* next = ptr->next; - ptr->value.~T(); - BAN::deallocator(ptr); - ptr = next; - } - m_data = nullptr; - m_last = nullptr; - m_size = 0; - } - - template - LinkedList::iterator LinkedList::move_element_to_other_linked_list(LinkedList& dest_list, iterator dest_iter, iterator src_iter) - { - ASSERT(!empty() && src_iter); - Node* node = remove_node(src_iter); - iterator ret = node->next ? iterator(node->next, false) : iterator(m_last, true); - dest_list.insert_node(dest_iter, node); - return ret; - } - - template - const T& LinkedList::back() const - { - ASSERT(!empty()); - return *const_iterator(m_last, false); - } - - template - T& LinkedList::back() - { - ASSERT(!empty()); - return *iterator(m_last, false); - } - - template - const T& LinkedList::front() const - { - ASSERT(!empty()); - return *const_iterator(m_data, false); - } - - template - T& LinkedList::front() - { - ASSERT(!empty()); - return *iterator(m_data, false); - } - - template - bool LinkedList::contains(const T& value) const - { - if (empty()) return false; - for (Node* node = m_data;; node = node->next) - { - if (node->value == value) - return true; - if (node == m_last) - return false; - } - } - - template - typename LinkedList::size_type LinkedList::size() const - { - return m_size; - } - - template - bool LinkedList::empty() const - { - return m_size == 0; - } - - template - template - ErrorOr::Node*> LinkedList::allocate_node(Args&&... args) const - { - Node* node = (Node*)BAN::allocator(sizeof(Node)); - if (node == nullptr) - return Error::from_errno(ENOMEM); - new (&node->value) T(forward(args)...); - return node; - } - - template - template - LinkedListIterator::LinkedListIterator(const LinkedListIterator& other, enable_if_t*) - : m_current(other.m_current) - , m_past_end(other.m_past_end) - { - } - - template - LinkedListIterator::LinkedListIterator(data_type* node, bool past_end) - : m_current(node) - , m_past_end(past_end) - { - } - - template - LinkedListIterator& LinkedListIterator::operator++() - { - ASSERT(m_current); - ASSERT(m_current->next || !m_past_end); - if (m_current->next) - m_current = m_current->next; - else - m_past_end = true; - return *this; - } - - template - LinkedListIterator& LinkedListIterator::operator--() - { - ASSERT(m_current); - ASSERT(m_current->prev || m_past_end); - if (m_past_end) - m_past_end = false; - else - m_current = m_current->prev; - return *this; - } - - template - LinkedListIterator LinkedListIterator::operator++(int) - { - auto temp = *this; - ++(*this); - return temp; - } - - template - LinkedListIterator LinkedListIterator::operator--(int) - { - auto temp = *this; - --(*this); - return temp; - } - - template - template - enable_if_t LinkedListIterator::operator*() - { - ASSERT(m_current); - return m_current->value; - } - - template - const T& LinkedListIterator::operator*() const - { - ASSERT(m_current); - return m_current->value; - } - - template - template - enable_if_t LinkedListIterator::operator->() - { - ASSERT(m_current); - return &m_current->value; - } - - template - const T* LinkedListIterator::operator->() const - { - ASSERT(m_current); - return &m_current->value; - } - - template - bool LinkedListIterator::operator==(const LinkedListIterator& other) const - { - if (m_current != other.m_current) - return false; - return m_past_end == other.m_past_end; - } - - template - bool LinkedListIterator::operator!=(const LinkedListIterator& other) const - { - return !(*this == other); - } - - template - LinkedListIterator::operator bool() const - { - return m_current; - } - -} diff --git a/BAN/include/BAN/MAC.h b/BAN/include/BAN/MAC.h deleted file mode 100644 index cd4e408..0000000 --- a/BAN/include/BAN/MAC.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include - -namespace BAN -{ - - struct MACAddress - { - uint8_t address[6]; - - constexpr bool operator==(const MACAddress& other) const - { - return - address[0] == other.address[0] && - address[1] == other.address[1] && - address[2] == other.address[2] && - address[3] == other.address[3] && - address[4] == other.address[4] && - address[5] == other.address[5]; - } - }; - -} - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const MACAddress& mac, const ValueFormat&) - { - ValueFormat format { - .base = 16, - .percision = 0, - .fill = 2, - .upper = true, - }; - - print_argument(putc, mac.address[0], format); - for (size_t i = 1; i < 6; i++) - { - putc(':'); - print_argument(putc, mac.address[i], format); - } - } - -} diff --git a/BAN/include/BAN/Math.h b/BAN/include/BAN/Math.h deleted file mode 100644 index 0a66347..0000000 --- a/BAN/include/BAN/Math.h +++ /dev/null @@ -1,443 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace BAN::Math -{ - - template - inline constexpr T abs(T x) - { - return x < 0 ? -x : x; - } - - template - inline constexpr T min(T a, T b) - { - return a < b ? a : b; - } - - template - inline constexpr T max(T a, T b) - { - return a > b ? a : b; - } - - template - inline constexpr T clamp(T x, T min, T max) - { - return x < min ? min : x > max ? max : x; - } - - template - inline constexpr T gcd(T a, T b) - { - T t; - while (b) - { - t = b; - b = a % b; - a = t; - } - return a; - } - - template - inline constexpr T lcm(T a, T b) - { - return a / gcd(a, b) * b; - } - - template - inline constexpr T div_round_up(T a, T b) - { - return (a + b - 1) / b; - } - - template - inline constexpr bool is_power_of_two(T x) - { - if (x == 0) - return false; - return (x & (x - 1)) == 0; - } - - template - static constexpr bool will_multiplication_overflow(T a, T b) - { - if (a == 0 || b == 0) - return false; - if ((a > 0) == (b > 0)) - return a > BAN::numeric_limits::max() / b; - else - return a < BAN::numeric_limits::min() / b; - } - - template - static constexpr bool will_addition_overflow(T a, T b) - { - if (a > 0 && b > 0) - return a > BAN::numeric_limits::max() - b; - if (a < 0 && b < 0) - return a < BAN::numeric_limits::min() - b; - return false; - } - - template - requires is_same_v || is_same_v || is_same_v - inline constexpr T ilog2(T x) - { - if constexpr(is_same_v) - return sizeof(T) * 8 - __builtin_clz(x) - 1; - if constexpr(is_same_v) - return sizeof(T) * 8 - __builtin_clzl(x) - 1; - return sizeof(T) * 8 - __builtin_clzll(x) - 1; - } - - template - inline constexpr T floor(T x) - { - if constexpr(is_same_v) - return __builtin_floorf(x); - if constexpr(is_same_v) - return __builtin_floor(x); - if constexpr(is_same_v) - return __builtin_floorl(x); - } - - template - inline constexpr T ceil(T x) - { - if constexpr(is_same_v) - return __builtin_ceilf(x); - if constexpr(is_same_v) - return __builtin_ceil(x); - if constexpr(is_same_v) - return __builtin_ceill(x); - } - - template - inline constexpr T round(T x) - { - if (x == (T)0.0) - return x; - if (x > (T)0.0) - return floor(x + (T)0.5); - return ceil(x - (T)0.5); - } - - template - inline constexpr T trunc(T x) - { - if constexpr(is_same_v) - return __builtin_truncf(x); - if constexpr(is_same_v) - return __builtin_trunc(x); - if constexpr(is_same_v) - return __builtin_truncl(x); - } - - template - inline constexpr T rint(T x) - { - asm("frndint" : "+t"(x)); - return x; - } - - template - inline constexpr T fmod(T a, T b) - { - asm( - "1:" - "fprem;" - "fnstsw %%ax;" - "testb $4, %%ah;" - "jne 1b;" - : "+t"(a) - : "u"(b) - : "ax" - ); - return a; - } - - template - static T modf(T x, T* iptr) - { - const T frac = BAN::Math::fmod(x, 1); - *iptr = x - frac; - return frac; - } - - template - inline constexpr T frexp(T num, int* exp) - { - if (num == 0.0) - { - *exp = 0; - return 0.0; - } - - T _exp; - asm("fxtract" : "+t"(num), "=u"(_exp)); - *exp = (int)_exp + 1; - return num / (T)2.0; - } - - template - inline constexpr T copysign(T x, T y) - { - if ((x < (T)0.0) != (y < (T)0.0)) - x = -x; - return x; - } - - namespace detail - { - - template - inline constexpr T fyl2x(T x, T y) - { - asm("fyl2x" : "+t"(x) : "u"(y) : "st(1)"); - return x; - } - - } - - template - inline constexpr T log(T x) - { - return detail::fyl2x(x, numbers::ln2_v); - } - - template - inline constexpr T log2(T x) - { - return detail::fyl2x(x, 1.0); - } - - template - inline constexpr T log10(T x) - { - return detail::fyl2x(x, numbers::lg2_v); - } - - template - inline constexpr T logb(T x) - { - static_assert(FLT_RADIX == 2); - return log2(x); - } - - template - inline constexpr T exp2(T x) - { - if (abs(x) <= (T)1.0) - { - asm("f2xm1" : "+t"(x)); - return x + (T)1.0; - } - - asm( - "fld1;" - "fld %%st(1);" - "fprem;" - "f2xm1;" - "faddp;" - "fscale;" - "fstp %%st(1);" - : "+t"(x) - ); - return x; - } - - template - inline constexpr T exp(T x) - { - return exp2(x * numbers::log2e_v); - } - - template - inline constexpr T pow(T x, T y) - { - asm( - "fyl2x;" - "fld1;" - "fld %%st(1);" - "fprem;" - "f2xm1;" - "faddp;" - "fscale;" - : "+t"(x), "+u"(y) - ); - - return x; - } - - template - inline constexpr T scalbn(T x, int n) - { - asm("fscale" : "+t"(x) : "u"(static_cast(n))); - return x; - } - - template - inline constexpr T ldexp(T x, int y) - { - const bool exp_sign = y < 0; - if (exp_sign) - y = -y; - - T exp = (T)1.0; - T mult = (T)2.0; - while (y) - { - if (y & 1) - exp *= mult; - mult *= mult; - y >>= 1; - } - - if (exp_sign) - exp = (T)1.0 / exp; - - return x * exp; - } - - template - inline constexpr T sqrt(T x) - { - asm("fsqrt" : "+t"(x)); - return x; - } - - template - inline constexpr T cbrt(T value) - { - if (value == 0.0) - return 0.0; - return pow(value, 1.0 / 3.0); - } - - template - inline constexpr T sin(T x) - { - asm("fsin" : "+t"(x)); - return x; - } - - template - inline constexpr T cos(T x) - { - asm("fcos" : "+t"(x)); - return x; - } - - template - inline constexpr void sincos(T x, T& sin, T& cos) - { - asm("fsincos" : "=t"(cos), "=u"(sin) : "0"(x)); - } - - template - inline constexpr T tan(T x) - { - T one, ret; - asm( - "fptan" - : "=t"(one), "=u"(ret) - : "0"(x) - ); - return ret; - } - - template - inline constexpr T atan2(T y, T x) - { - asm( - "fpatan" - : "+t"(x) - : "u"(y) - : "st(1)" - ); - return x; - } - - template - inline constexpr T atan(T x) - { - return atan2(x, 1.0); - } - - template - inline constexpr T asin(T x) - { - if (x == (T)0.0) - return (T)0.0; - if (x == (T)1.0) - return numbers::pi_v / (T)2.0; - if (x == (T)-1.0) - return -numbers::pi_v / (T)2.0; - return (T)2.0 * atan(x / (T(1.0) + sqrt((T)1.0 - x * x))); - } - - template - inline constexpr T acos(T x) - { - if (x == (T)0.0) - return numbers::pi_v / (T)2.0; - if (x == (T)1.0) - return (T)0.0; - if (x == (T)-1.0) - return numbers::pi_v; - return (T)2.0 * atan(sqrt((T)1.0 - x * x) / ((T)1.0 + x)); - } - - template - inline constexpr T sinh(T x) - { - return (exp(x) - exp(-x)) / (T)2.0; - } - - template - inline constexpr T cosh(T x) - { - return (exp(x) + exp(-x)) / (T)2.0; - } - - template - inline constexpr T tanh(T x) - { - const T exp_px = exp(x); - const T exp_nx = exp(-x); - return (exp_px - exp_nx) / (exp_px + exp_nx); - } - - template - inline constexpr T asinh(T x) - { - return log(x + sqrt(x * x + (T)1.0)); - } - - template - inline constexpr T acosh(T x) - { - return log(x + sqrt(x * x - (T)1.0)); - } - - template - inline constexpr T atanh(T x) - { - return (T)0.5 * log(((T)1.0 + x) / ((T)1.0 - x)); - } - - template - inline constexpr T hypot(T x, T y) - { - return sqrt(x * x + y * y); - } - -} diff --git a/BAN/include/BAN/Move.h b/BAN/include/BAN/Move.h deleted file mode 100644 index 8652b2b..0000000 --- a/BAN/include/BAN/Move.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - template - constexpr remove_reference_t&& move(T&& arg) - { - return static_cast&&>(arg); - } - - template - constexpr T&& forward(remove_reference_t& arg) - { - return static_cast(arg); - } - - template - constexpr T&& forward(remove_reference_t&& arg) - { - static_assert(!is_lvalue_reference_v); - return static_cast(arg); - } - -} diff --git a/BAN/include/BAN/New.h b/BAN/include/BAN/New.h deleted file mode 100644 index 5773bf3..0000000 --- a/BAN/include/BAN/New.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#if defined(__is_kernel) - #include -#else - #include -#endif - -namespace BAN -{ - #if defined(__is_kernel) - static constexpr void*(&allocator)(size_t) = kmalloc; - static constexpr void*(&reallocator)(void*, size_t) = nullptr; - static constexpr void(&deallocator)(void*) = kfree; - #else - static constexpr void*(&allocator)(size_t) = malloc; - static constexpr void*(&reallocator)(void*, size_t) = realloc; - static constexpr void(&deallocator)(void*) = free; - #endif -} diff --git a/BAN/include/BAN/NoCopyMove.h b/BAN/include/BAN/NoCopyMove.h deleted file mode 100644 index a60c56e..0000000 --- a/BAN/include/BAN/NoCopyMove.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#define BAN_NON_COPYABLE(class) \ - private: \ - class(const class&) = delete; \ - class& operator=(const class&) = delete - -#define BAN_NON_MOVABLE(class) \ - private: \ - class(class&&) = delete; \ - class& operator=(class&&) = delete diff --git a/BAN/include/BAN/Numbers.h b/BAN/include/BAN/Numbers.h deleted file mode 100644 index 9389e54..0000000 --- a/BAN/include/BAN/Numbers.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include - -namespace BAN::numbers -{ - - template inline constexpr T e_v = 2.71828182845904523536; - template inline constexpr T log2e_v = 1.44269504088896340736; - template inline constexpr T lge_v = 0.43429448190325182765; - template inline constexpr T lg2_v = 0.30102999566398119521; - template inline constexpr T ln2_v = 0.69314718055994530942; - template inline constexpr T ln10_v = 2.30258509299404568402; - template inline constexpr T pi_v = 3.14159265358979323846; - template inline constexpr T sqrt2_v = 1.41421356237309504880; - template inline constexpr T sqrt3_v = 1.73205080756887729353; - - inline constexpr double e = e_v; - inline constexpr double log2e = log2e_v; - inline constexpr double lge = lge_v; - inline constexpr double lg2 = lge_v; - inline constexpr double ln2 = ln2_v; - inline constexpr double ln10 = ln10_v; - inline constexpr double pi = pi_v; - inline constexpr double sqrt2 = sqrt2_v; - inline constexpr double sqrt3 = sqrt3_v; - -} diff --git a/BAN/include/BAN/Optional.h b/BAN/include/BAN/Optional.h deleted file mode 100644 index c593247..0000000 --- a/BAN/include/BAN/Optional.h +++ /dev/null @@ -1,204 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace BAN -{ - - template - class Optional - { - public: - constexpr Optional(); - constexpr Optional(Optional&&); - constexpr Optional(const Optional&); - constexpr Optional(const T&); - constexpr Optional(T&&); - - ~Optional(); - - constexpr Optional& operator=(Optional&&); - constexpr Optional& operator=(const Optional&); - - template - constexpr Optional& emplace(Args&&...) requires is_constructible_v; - - constexpr T* operator->(); - constexpr const T* operator->() const; - - constexpr T& operator*(); - constexpr const T& operator*() const; - - constexpr bool has_value() const; - - constexpr T release_value(); - constexpr T& value(); - constexpr const T& value() const; - constexpr T& value_or(T&); - constexpr const T& value_or(const T&) const; - - constexpr void clear(); - - private: - alignas(T) uint8_t m_storage[sizeof(T)] {}; - bool m_has_value { false }; - }; - - template - constexpr Optional::Optional() - : m_has_value(false) - {} - - template - constexpr Optional::Optional(Optional&& other) - : m_has_value(other.has_value()) - { - if (other.has_value()) - new (m_storage) T(move(other.release_value())); - } - - template - constexpr Optional::Optional(const Optional& other) - : m_has_value(other.has_value()) - { - if (other.has_value()) - new (m_storage) T(other.value()); - } - - template - constexpr Optional::Optional(const T& value) - : m_has_value(true) - { - new (m_storage) T(value); - } - - template - constexpr Optional::Optional(T&& value) - : m_has_value(true) - { - new (m_storage) T(move(value)); - } - - template - Optional::~Optional() - { - clear(); - } - - template - constexpr Optional& Optional::operator=(Optional&& other) - { - clear(); - m_has_value = other.has_value(); - if (other.has_value()) - new (m_storage) T(move(other.release_value())); - return *this; - } - - template - constexpr Optional& Optional::operator=(const Optional& other) - { - clear(); - m_has_value = other.has_value(); - if (other.has_value()) - new (m_storage) T(other.value()); - return *this; - } - - template - template - constexpr Optional& Optional::emplace(Args&&... args) requires is_constructible_v - { - clear(); - m_has_value = true; - new (m_storage) T(forward(args)...); - return *this; - } - - template - constexpr T* Optional::operator->() - { - ASSERT(has_value()); - return &value(); - } - - template - constexpr const T* Optional::operator->() const - { - ASSERT(has_value()); - return &value(); - } - - template - constexpr T& Optional::operator*() - { - ASSERT(has_value()); - return value(); - } - - template - constexpr const T& Optional::operator*() const - { - ASSERT(has_value()); - return value(); - } - - template - constexpr bool Optional::has_value() const - { - return m_has_value; - } - - template - constexpr T Optional::release_value() - { - ASSERT(has_value()); - T released_value = move(value()); - value().~T(); - m_has_value = false; - return move(released_value); - } - - template - constexpr T& Optional::value() - { - ASSERT(has_value()); - return *reinterpret_cast(&m_storage); - } - - template - constexpr const T& Optional::value() const - { - ASSERT(has_value()); - return *reinterpret_cast(&m_storage); - } - - template - constexpr T& Optional::value_or(T& empty) - { - if (!has_value()) - return empty; - return value(); - } - - template - constexpr const T& Optional::value_or(const T& empty) const - { - if (!has_value()) - return empty; - return value(); - } - - template - constexpr void Optional::clear() - { - if (m_has_value) - value().~T(); - m_has_value = false; - } - -} diff --git a/BAN/include/BAN/PlacementNew.h b/BAN/include/BAN/PlacementNew.h deleted file mode 100644 index 828a8e5..0000000 --- a/BAN/include/BAN/PlacementNew.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#if __has_include() - #include -#else - #include - - inline void* operator new(size_t, void* addr) { return addr; } - inline void* operator new[](size_t, void* addr) { return addr; } -#endif diff --git a/BAN/include/BAN/PriorityQueue.h b/BAN/include/BAN/PriorityQueue.h deleted file mode 100644 index bee03eb..0000000 --- a/BAN/include/BAN/PriorityQueue.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "BAN/Errors.h" -#include -#include - -namespace BAN -{ - - template> - class PriorityQueue - { - public: - PriorityQueue() = default; - PriorityQueue(Comp comp) - : m_comp(comp) - { } - - ErrorOr push(const T& value) - { - TRY(m_data.push_back(value)); - push_heap(m_data.begin(), m_data.end()); - return {}; - } - - ErrorOr push(T&& value) - { - TRY(m_data.push_back(move(value))); - push_heap(m_data.begin(), m_data.end()); - return {}; - } - - template - ErrorOr emplace(Args&&... args) requires is_constructible_v - { - TRY(m_data.emplace_back(forward(args)...)); - push_heap(m_data.begin(), m_data.end()); - return {}; - } - - void pop() - { - pop_heap(m_data.begin(), m_data.end()); - m_data.pop_back(); - } - - BAN::ErrorOr reserve(Vector::size_type size) - { - return m_data.reserve(size); - } - - T& top() { return m_data.front(); } - const T& top() const { return m_data.front(); } - - bool empty() const { return m_data.empty(); } - Vector::size_type size() const { return m_data.size(); } - Vector::size_type capacity() const { return m_data.capacity(); } - - private: - Comp m_comp; - Vector m_data; - }; - -} diff --git a/BAN/include/BAN/Queue.h b/BAN/include/BAN/Queue.h deleted file mode 100644 index 88d472e..0000000 --- a/BAN/include/BAN/Queue.h +++ /dev/null @@ -1,236 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace BAN -{ - - template - class Queue - { - public: - using size_type = size_t; - using value_type = T; - using iterator = IteratorSimple; - using const_iterator = ConstIteratorSimple; - - public: - Queue() = default; - Queue(Queue&&); - Queue(const Queue&); - ~Queue(); - - Queue& operator=(Queue&&); - Queue& operator=(const Queue&); - - ErrorOr push(T&&); - ErrorOr push(const T&); - template - ErrorOr emplace(Args&&...) requires is_constructible_v; - - ErrorOr reserve(size_type); - ErrorOr shrink_to_fit(); - - iterator begin() { return iterator(m_data); } - iterator end() { return iterator(m_data + m_size); } - const_iterator begin() const { return const_iterator(m_data); } - const_iterator end() const { return const_iterator(m_data + m_size); } - - void pop(); - void clear(); - - bool empty() const; - size_type capacity() const; - size_type size() const; - - const T& front() const; - T& front(); - - private: - ErrorOr ensure_capacity(size_type size); - - private: - T* m_data = nullptr; - size_type m_capacity = 0; - size_type m_size = 0; - }; - - template - Queue::Queue(Queue&& other) - { - m_data = other.m_data; - m_capacity = other.m_capacity; - m_size = other.m_size; - - other.m_data = nullptr; - other.m_capacity = 0; - other.m_size = 0; - } - - template - Queue::Queue(const Queue& other) - { - MUST(ensure_capacity(other.size())); - for (size_type i = 0; i < other.size(); i++) - new (m_data + i) T(other.m_data[i]); - m_size = other.m_size; - } - - template - Queue::~Queue() - { - clear(); - } - - template - Queue& Queue::operator=(Queue&& other) - { - clear(); - - m_data = other.m_data; - m_capacity = other.m_capacity; - m_size = other.m_size; - - other.m_data = nullptr; - other.m_capacity = 0; - other.m_size = 0; - - return *this; - } - - template - Queue& Queue::operator=(const Queue& other) - { - clear(); - MUST(ensure_capacity(other.size())); - for (size_type i = 0; i < other.size(); i++) - new (m_data + i) T(other.m_data[i]); - m_size = other.m_size; - return *this; - } - - template - ErrorOr Queue::push(T&& value) - { - TRY(ensure_capacity(m_size + 1)); - new (m_data + m_size) T(move(value)); - m_size++; - return {}; - } - - template - ErrorOr Queue::push(const T& value) - { - return push(move(T(value))); - } - - template - template - ErrorOr Queue::emplace(Args&&... args) requires is_constructible_v - { - TRY(ensure_capacity(m_size + 1)); - new (m_data + m_size) T(forward(args)...); - m_size++; - return {}; - } - - template - ErrorOr Queue::reserve(size_type size) - { - TRY(ensure_capacity(size)); - return {}; - } - - template - ErrorOr Queue::shrink_to_fit() - { - size_type temp = m_capacity; - m_capacity = 0; - auto error_or = ensure_capacity(m_size); - if (error_or.is_error()) - { - m_capacity = temp; - return error_or; - } - return {}; - } - - template - void Queue::pop() - { - ASSERT(m_size > 0); - for (size_type i = 0; i < m_size - 1; i++) - m_data[i] = move(m_data[i + 1]); - m_data[m_size - 1].~T(); - m_size--; - } - - template - void Queue::clear() - { - for (size_type i = 0; i < m_size; i++) - m_data[i].~T(); - BAN::deallocator(m_data); - m_data = nullptr; - m_capacity = 0; - m_size = 0; - } - - template - bool Queue::empty() const - { - return m_size == 0; - } - - template - typename Queue::size_type Queue::capacity() const - { - return m_capacity; - } - - template - typename Queue::size_type Queue::size() const - { - return m_size; - } - - template - const T& Queue::front() const - { - ASSERT(m_size > 0); - return m_data[0]; - } - - template - T& Queue::front() - { - ASSERT(m_size > 0); - return m_data[0]; - } - - template - ErrorOr Queue::ensure_capacity(size_type size) - { - if (m_capacity > size) - return {}; - size_type new_cap = BAN::Math::max(size, m_capacity * 2); - T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - for (size_type i = 0; i < m_size; i++) - { - new (new_data + i) T(move(m_data[i])); - m_data[i].~T(); - } - BAN::deallocator(m_data); - m_data = new_data; - m_capacity = new_cap; - return {}; - } - -} diff --git a/BAN/include/BAN/RefPtr.h b/BAN/include/BAN/RefPtr.h deleted file mode 100644 index 9f83ceb..0000000 --- a/BAN/include/BAN/RefPtr.h +++ /dev/null @@ -1,161 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace BAN -{ - - template - class RefCounted - { - BAN_NON_COPYABLE(RefCounted); - BAN_NON_MOVABLE(RefCounted); - - public: - uint32_t ref_count() const - { - return m_ref_count; - } - - void ref() const - { - uint32_t old = m_ref_count.fetch_add(1, MemoryOrder::memory_order_relaxed); - ASSERT(old > 0); - } - - bool try_ref() const - { - uint32_t expected = m_ref_count.load(MemoryOrder::memory_order_relaxed); - for (;;) - { - if (expected == 0) - return false; - if (m_ref_count.compare_exchange(expected, expected + 1, MemoryOrder::memory_order_acquire)) - return true; - } - } - - void unref() const - { - uint32_t old = m_ref_count.fetch_sub(1); - ASSERT(old > 0); - if (old == 1) - delete static_cast(this); - } - - protected: - RefCounted() = default; - virtual ~RefCounted() { ASSERT(m_ref_count == 0); } - - private: - mutable Atomic m_ref_count = 1; - }; - - template - class RefPtr - { - public: - RefPtr() = default; - RefPtr(T* pointer) - { - m_pointer = pointer; - if (m_pointer) - m_pointer->ref(); - } - ~RefPtr() { clear(); } - - template - static RefPtr adopt(U* pointer) - { - RefPtr ptr; - ptr.m_pointer = pointer; - return ptr; - } - - // NOTE: don't use is_constructible_v as RefPtr is allowed with friends - template - static ErrorOr create(Args&&... args) requires requires(Args&&... args) { T(forward(args)...); } - { - T* pointer = new T(forward(args)...); - if (pointer == nullptr) - return Error::from_errno(ENOMEM); - return adopt(pointer); - } - - RefPtr(const RefPtr& other) { *this = other; } - RefPtr(RefPtr&& other) { *this = move(other); } - template - RefPtr(const RefPtr& other) { *this = other; } - template - RefPtr(RefPtr&& other) { *this = move(other); } - - RefPtr& operator=(const RefPtr& other) - { - clear(); - m_pointer = other.m_pointer; - if (m_pointer) - m_pointer->ref(); - return *this; - } - - RefPtr& operator=(RefPtr&& other) - { - clear(); - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - return *this; - } - - template - RefPtr& operator=(const RefPtr& other) - { - clear(); - m_pointer = other.m_pointer; - if (m_pointer) - m_pointer->ref(); - return *this; - } - - template - RefPtr& operator=(RefPtr&& other) - { - clear(); - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - return *this; - } - - T* ptr() { ASSERT(!empty()); return m_pointer; } - const T* ptr() const { ASSERT(!empty()); return m_pointer; } - - T& operator*() { return *ptr(); } - const T& operator*() const { return *ptr(); } - - T* operator->() { return ptr(); } - const T* operator->() const { return ptr(); } - - bool operator==(RefPtr other) const { return m_pointer == other.m_pointer; } - bool operator!=(RefPtr other) const { return m_pointer != other.m_pointer; } - - bool empty() const { return m_pointer == nullptr; } - explicit operator bool() const { return m_pointer; } - - void clear() - { - if (m_pointer) - m_pointer->unref(); - m_pointer = nullptr; - } - - private: - T* m_pointer = nullptr; - - template - friend class RefPtr; - }; - -} diff --git a/BAN/include/BAN/ScopeGuard.h b/BAN/include/BAN/ScopeGuard.h deleted file mode 100644 index d514d0e..0000000 --- a/BAN/include/BAN/ScopeGuard.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include - -namespace BAN -{ - - class ScopeGuard - { - public: - ScopeGuard(const BAN::Function& func) - : m_func(func) - { } - ~ScopeGuard() - { - if (m_enabled) - m_func(); - } - void disable() - { - m_enabled = false; - } - private: - BAN::Function m_func; - bool m_enabled { true }; - }; - -} diff --git a/BAN/include/BAN/Sort.h b/BAN/include/BAN/Sort.h deleted file mode 100644 index 4f3a3d7..0000000 --- a/BAN/include/BAN/Sort.h +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace BAN::sort -{ - - template>> - void exchange_sort(It begin, It end, Comp comp = {}) - { - for (It lhs = begin; lhs != end; ++lhs) - for (It rhs = next(lhs, 1); rhs != end; ++rhs) - if (!comp(*lhs, *rhs)) - swap(*lhs, *rhs); - } - - namespace detail - { - - template - It partition(It begin, It end, Comp comp) - { - It pivot = prev(end, 1); - - It it1 = begin; - for (It it2 = begin; it2 != pivot; ++it2) - { - if (comp(*it2, *pivot)) - { - swap(*it1, *it2); - ++it1; - } - } - - swap(*it1, *pivot); - - return it1; - } - - } - - template>> - void quick_sort(It begin, It end, Comp comp = {}) - { - if (distance(begin, end) <= 1) - return; - It mid = detail::partition(begin, end, comp); - quick_sort(begin, mid, comp); - quick_sort(++mid, end, comp); - } - - template>> - void insertion_sort(It begin, It end, Comp comp = {}) - { - if (distance(begin, end) <= 1) - return; - for (It it1 = next(begin, 1); it1 != end; ++it1) - { - auto x = move(*it1); - It it2 = it1; - for (; it2 != begin && comp(x, *prev(it2, 1)); --it2) - *it2 = move(*prev(it2, 1)); - *it2 = move(x); - } - } - - template>> - void heap_sort(It begin, It end, Comp comp = {}) - { - make_heap(begin, end, comp); - sort_heap(begin, end, comp); - } - - namespace detail - { - - template - void intro_sort_impl(It begin, It end, size_t max_depth, Comp comp) - { - if (distance(begin, end) <= 16) - return insertion_sort(begin, end, comp); - if (max_depth == 0) - return heap_sort(begin, end, comp); - It mid = detail::partition(begin, end, comp); - intro_sort_impl(begin, mid, max_depth - 1, comp); - intro_sort_impl(++mid, end, max_depth - 1, comp); - } - - } - - template>> - void intro_sort(It begin, It end, Comp comp = {}) - { - const size_t len = distance(begin, end); - if (len <= 1) - return; - detail::intro_sort_impl(begin, end, 2 * Math::ilog2(len), comp); - } - - namespace detail - { - - template - consteval T lsb_index(T value) - { - for (T result = 0;; result++) - if (value & (1 << result)) - return result; - } - - } - - template - requires is_unsigned_v> && (radix > 0 && (radix & (radix - 1)) == 0) - BAN::ErrorOr radix_sort(It begin, It end) - { - using value_type = it_value_type_t; - - const size_t len = distance(begin, end); - if (len <= 1) - return {}; - - Vector temp; - TRY(temp.resize(len)); - - Vector counts; - TRY(counts.resize(radix)); - - constexpr size_t mask = radix - 1; - constexpr size_t shift = detail::lsb_index(radix); - - for (size_t s = 0; s < sizeof(value_type) * 8; s += shift) - { - for (auto& cnt : counts) - cnt = 0; - for (It it = begin; it != end; ++it) - counts[(*it >> s) & mask]++; - - for (size_t i = 0; i < radix - 1; i++) - counts[i + 1] += counts[i]; - - for (It it = end; it != begin;) - { - --it; - temp[--counts[(*it >> s) & mask]] = *it; - } - - for (size_t j = 0; j < temp.size(); j++) - *next(begin, j) = temp[j]; - } - - return {}; - } - - template>> - void sort(It begin, It end, Comp comp = {}) - { - return intro_sort(begin, end, comp); - } - -} diff --git a/BAN/include/BAN/Span.h b/BAN/include/BAN/Span.h deleted file mode 100644 index 30e1a87..0000000 --- a/BAN/include/BAN/Span.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace BAN -{ - - template - class Span - { - public: - using value_type = T; - using size_type = size_t; - using iterator = IteratorSimple; - using const_iterator = ConstIteratorSimple; - - private: - template - static inline constexpr bool can_init_from_v = is_same_v || is_same_v; - - public: - Span() = default; - Span(value_type* data, size_type size) - : m_data(data) - , m_size(size) - { } - - template - Span(const Span& other) requires can_init_from_v - : m_data(other.m_data) - , m_size(other.m_size) - { } - template - Span(Span&& other) requires can_init_from_v - : m_data(other.m_data) - , m_size(other.m_size) - { - other.clear(); - } - - template - Span& operator=(const Span& other) requires can_init_from_v - { - m_data = other.m_data; - m_size = other.m_size; - return *this; - } - template - Span& operator=(Span&& other) requires can_init_from_v - { - m_data = other.m_data; - m_size = other.m_size; - return *this; - } - - iterator begin() { return iterator(m_data); } - iterator end() { return iterator(m_data + m_size); } - const_iterator begin() const { return const_iterator(m_data); } - const_iterator end() const { return const_iterator(m_data + m_size); } - - value_type& operator[](size_type index) const - { - ASSERT(index < m_size); - return m_data[index]; - } - - value_type* data() const - { - return m_data; - } - - bool empty() const { return m_size == 0; } - size_type size() const { return m_size; } - - void clear() - { - m_data = nullptr; - m_size = 0; - } - - Span slice(size_type start, size_type length = ~size_type(0)) const - { - ASSERT(start <= m_size); - if (length == ~size_type(0)) - length = m_size - start; - ASSERT(m_size - start >= length); - return Span(m_data + start, length); - } - - Span as_const() const { return *this; } - - private: - value_type* m_data = nullptr; - size_type m_size = 0; - - friend class Span; - }; - -} diff --git a/BAN/include/BAN/String.h b/BAN/include/BAN/String.h deleted file mode 100644 index 82da541..0000000 --- a/BAN/include/BAN/String.h +++ /dev/null @@ -1,362 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace BAN -{ - - class String - { - public: - using size_type = size_t; - using value_type = char; - using iterator = IteratorSimple; - using const_iterator = ConstIteratorSimple; - static constexpr size_type sso_capacity = 15; - - public: - String() {} - String(const String& other) { *this = other; } - String(String&& other) { *this = move(other); } - String(StringView other) { *this = other; } - ~String() { clear(); } - - template - static BAN::ErrorOr formatted(const char* format, Args&&... args) - { - size_type length = 0; - BAN::Formatter::print([&](char) { length++; }, format, BAN::forward(args)...); - - String result; - TRY(result.reserve(length)); - BAN::Formatter::print([&](char c){ MUST(result.push_back(c)); }, format, BAN::forward(args)...); - - return result; - } - - String& operator=(const String& other) - { - clear(); - MUST(ensure_capacity(other.size())); - memcpy(data(), other.data(), other.size() + 1); - m_size = other.size(); - return *this; - } - - String& operator=(String&& other) - { - clear(); - - if (other.has_sso()) - memcpy(data(), other.data(), other.size() + 1); - else - { - m_storage.general_storage = other.m_storage.general_storage; - m_has_sso = false; - } - m_size = other.m_size; - - other.m_size = 0; - other.m_storage.sso_storage = SSOStorage(); - other.m_has_sso = true; - - return *this; - } - - String& operator=(StringView other) - { - clear(); - MUST(ensure_capacity(other.size())); - memcpy(data(), other.data(), other.size()); - m_size = other.size(); - data()[m_size] = '\0'; - return *this; - } - - ErrorOr push_back(char c) - { - TRY(ensure_capacity(m_size + 1)); - data()[m_size] = c; - m_size++; - data()[m_size] = '\0'; - return {}; - } - - ErrorOr insert(char c, size_type index) - { - ASSERT(index <= m_size); - TRY(ensure_capacity(m_size + 1)); - memmove(data() + index + 1, data() + index, m_size - index); - data()[index] = c; - m_size++; - data()[m_size] = '\0'; - return {}; - } - - ErrorOr insert(StringView str, size_type index) - { - ASSERT(index <= m_size); - TRY(ensure_capacity(m_size + str.size())); - memmove(data() + index + str.size(), data() + index, m_size - index); - memcpy(data() + index, str.data(), str.size()); - m_size += str.size(); - data()[m_size] = '\0'; - return {}; - } - - ErrorOr append(StringView str) - { - TRY(ensure_capacity(m_size + str.size())); - memcpy(data() + m_size, str.data(), str.size()); - m_size += str.size(); - data()[m_size] = '\0'; - return {}; - } - - void pop_back() - { - ASSERT(m_size > 0); - m_size--; - data()[m_size] = '\0'; - } - - void remove(size_type index) - { - ASSERT(index < m_size); - memmove(data() + index, data() + index + 1, m_size - index); - m_size--; - data()[m_size] = '\0'; - } - - void clear() - { - if (!has_sso()) - { - deallocator(m_storage.general_storage.data); - m_storage.sso_storage = SSOStorage(); - m_has_sso = true; - } - m_size = 0; - data()[m_size] = '\0'; - } - - const_iterator begin() const { return const_iterator(data()); } - iterator begin() { return iterator(data()); } - const_iterator end() const { return const_iterator(data() + size()); } - iterator end() { return iterator(data() + size()); } - - char front() const { ASSERT(m_size > 0); return data()[0]; } - char& front() { ASSERT(m_size > 0); return data()[0]; } - - char back() const { ASSERT(m_size > 0); return data()[m_size - 1]; } - char& back() { ASSERT(m_size > 0); return data()[m_size - 1]; } - - char operator[](size_type index) const { ASSERT(index < m_size); return data()[index]; } - char& operator[](size_type index) { ASSERT(index < m_size); return data()[index]; } - - bool operator==(const String& str) const - { - if (size() != str.size()) - return false; - for (size_type i = 0; i < m_size; i++) - if (data()[i] != str.data()[i]) - return false; - return true; - } - - bool operator==(StringView str) const - { - if (size() != str.size()) - return false; - for (size_type i = 0; i < m_size; i++) - if (data()[i] != str.data()[i]) - return false; - return true; - } - - bool operator==(const char* cstr) const - { - for (size_type i = 0; i < m_size; i++) - if (data()[i] != cstr[i]) - return false; - if (cstr[size()] != '\0') - return false; - return true; - } - - ErrorOr resize(size_type new_size, char init_c = '\0') - { - if (m_size == new_size) - return {}; - - // expanding - if (m_size < new_size) - { - TRY(ensure_capacity(new_size)); - memset(data() + m_size, init_c, new_size - m_size); - m_size = new_size; - data()[m_size] = '\0'; - return {}; - } - - m_size = new_size; - data()[m_size] = '\0'; - return {}; - } - - ErrorOr reserve(size_type new_size) - { - TRY(ensure_capacity(new_size)); - return {}; - } - - ErrorOr shrink_to_fit() - { - if (has_sso()) - return {}; - - if (fits_in_sso()) - { - char* data = m_storage.general_storage.data; - m_storage.sso_storage = SSOStorage(); - m_has_sso = true; - memcpy(this->data(), data, m_size + 1); - deallocator(data); - return {}; - } - - GeneralStorage& storage = m_storage.general_storage; - if (storage.capacity == m_size) - return {}; - - char* new_data = (char*)allocator(m_size + 1); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - - memcpy(new_data, storage.data, m_size); - deallocator(storage.data); - - storage.capacity = m_size; - storage.data = new_data; - - return {}; - } - - StringView sv() const { return StringView(data(), size()); } - - bool empty() const { return m_size == 0; } - size_type size() const { return m_size; } - - size_type capacity() const - { - if (has_sso()) - return sso_capacity; - return m_storage.general_storage.capacity; - } - - char* data() - { - if (has_sso()) - return m_storage.sso_storage.data; - return m_storage.general_storage.data; - } - - const char* data() const - { - if (has_sso()) - return m_storage.sso_storage.data; - return m_storage.general_storage.data; - } - - private: - ErrorOr ensure_capacity(size_type new_size) - { - if (m_size >= new_size) - return {}; - if (has_sso() && fits_in_sso(new_size)) - return {}; - - char* new_data = (char*)allocator(new_size + 1); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - - if (m_size) - memcpy(new_data, data(), m_size + 1); - - if (has_sso()) - { - m_storage.general_storage = GeneralStorage(); - m_has_sso = false; - } - else - deallocator(m_storage.general_storage.data); - - auto& storage = m_storage.general_storage; - storage.capacity = new_size; - storage.data = new_data; - - return {}; - } - - bool has_sso() const { return m_has_sso; } - - bool fits_in_sso() const { return fits_in_sso(m_size); } - static bool fits_in_sso(size_type size) { return size < sso_capacity; } - - private: - struct SSOStorage - { - char data[sso_capacity + 1] {}; - }; - struct GeneralStorage - { - size_type capacity { 0 }; - char* data { nullptr }; - }; - - private: - union { - SSOStorage sso_storage; - GeneralStorage general_storage; - } m_storage { .sso_storage = SSOStorage() }; - size_type m_size : sizeof(size_type) * 8 - 1 { 0 }; - size_type m_has_sso : 1 { true }; - }; - - template<> - struct hash - { - hash_t operator()(const String& string) const - { - constexpr hash_t FNV_offset_basis = 0x811c9dc5; - constexpr hash_t FNV_prime = 0x01000193; - - hash_t hash = FNV_offset_basis; - for (String::size_type i = 0; i < string.size(); i++) - { - hash *= FNV_prime; - hash ^= (uint8_t)string[i]; - } - - return hash; - } - }; - -} - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const String& string, const ValueFormat&) - { - for (String::size_type i = 0; i < string.size(); i++) - putc(string[i]); - } - -} diff --git a/BAN/include/BAN/StringView.h b/BAN/include/BAN/StringView.h deleted file mode 100644 index eb35de4..0000000 --- a/BAN/include/BAN/StringView.h +++ /dev/null @@ -1,256 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace BAN -{ - - class StringView - { - public: - using size_type = size_t; - using value_type = char; - using const_iterator = ConstIteratorSimple; - - public: - constexpr StringView() {} - constexpr StringView(const char* string, size_type len = -1) - { - if (len == size_type(-1)) - for (len = 0; string[len];) - len++; - m_data = string; - m_size = len; - } - StringView(const String&); - - constexpr const_iterator begin() const { return const_iterator(m_data); } - constexpr const_iterator end() const { return const_iterator(m_data + m_size); } - - constexpr char operator[](size_type index) const - { - ASSERT(index < m_size); - return m_data[index]; - } - - constexpr bool operator==(StringView other) const - { - if (m_size != other.m_size) - return false; - for (size_type i = 0; i < m_size; i++) - if (m_data[i] != other.m_data[i]) - return false; - return true; - } - - constexpr bool operator==(const char* other) const - { - for (size_type i = 0; i < m_size; i++) - if (m_data[i] != other[i]) - return false; - return other[m_size] == '\0'; - } - - constexpr StringView substring(size_type index, size_type len = -1) const - { - ASSERT(index <= m_size); - if (len == size_type(-1)) - len = m_size - index; - ASSERT(len <= m_size - index); // weird order to avoid overflow - StringView result; - result.m_data = m_data + index; - result.m_size = len; - return result; - } - - ErrorOr> split(char delim, bool allow_empties = false) const - { - size_type count = 0; - { - size_type start = 0; - for (size_type i = 0; i < m_size; i++) - { - if (m_data[i] == delim) - { - if (allow_empties || start != i) - count++; - start = i + 1; - } - } - if (start != m_size) - count++; - } - - Vector result; - TRY(result.reserve(count)); - - size_type start = 0; - for (size_type i = 0; i < m_size; i++) - { - if (m_data[i] == delim) - { - if (allow_empties || start != i) - TRY(result.push_back(this->substring(start, i - start))); - start = i + 1; - } - } - if (start < m_size || (start == m_size && allow_empties)) - TRY(result.push_back(this->substring(start))); - return result; - } - - ErrorOr> split(bool(*comp)(char), bool allow_empties = false) const - { - size_type count = 0; - { - size_type start = 0; - for (size_type i = 0; i < m_size; i++) - { - if (comp(m_data[i])) - { - if (allow_empties || start != i) - count++; - start = i + 1; - } - } - if (start != m_size) - count++; - } - - Vector result; - TRY(result.reserve(count)); - - size_type start = 0; - for (size_type i = 0; i < m_size; i++) - { - if (comp(m_data[i])) - { - if (allow_empties || start != i) - TRY(result.push_back(this->substring(start, i - start))); - start = i + 1; - } - } - if (start < m_size || (start == m_size && allow_empties)) - TRY(result.push_back(this->substring(start))); - return result; - } - - constexpr char back() const - { - ASSERT(m_size > 0); - return m_data[m_size - 1]; - } - - constexpr char front() const - { - ASSERT(m_size > 0); - return m_data[0]; - } - - BAN::Optional find(char ch) const - { - for (size_type i = 0; i < m_size; i++) - if (m_data[i] == ch) - return i; - return {}; - } - - BAN::Optional find(bool(*comp)(char)) const - { - for (size_type i = 0; i < m_size; i++) - if (comp(m_data[i])) - return i; - return {}; - } - - BAN::Optional rfind(char ch) const - { - for (size_type i = m_size; i > 0; i--) - if (m_data[i - 1] == ch) - return i - 1; - return {}; - } - - BAN::Optional rfind(bool(*comp)(char)) const - { - for (size_type i = m_size; i > 0; i--) - if (comp(m_data[i - 1])) - return i - 1; - return {}; - } - - constexpr bool starts_with(BAN::StringView target) const - { - if (target.size() > m_size) - return false; - for (size_type i = 0; i < target.size(); i++) - if (m_data[i] != target[i]) - return false; - return true; - } - - constexpr bool contains(char ch) const - { - for (size_type i = 0; i < m_size; i++) - if (m_data[i] == ch) - return true; - return false; - } - - constexpr size_type count(char ch) const - { - size_type result = 0; - for (size_type i = 0; i < m_size; i++) - if (m_data[i] == ch) - result++; - return result; - } - - constexpr bool empty() const { return m_size == 0; } - constexpr size_type size() const { return m_size; } - constexpr const char* data() const { return m_data; } - - private: - const char* m_data = nullptr; - size_type m_size = 0; - }; - - template<> - struct hash - { - hash_t operator()(StringView string) const - { - constexpr hash_t FNV_offset_basis = 0x811c9dc5; - constexpr hash_t FNV_prime = 0x01000193; - - hash_t hash = FNV_offset_basis; - for (StringView::size_type i = 0; i < string.size(); i++) - { - hash *= FNV_prime; - hash ^= (uint8_t)string[i]; - } - - return hash; - } - }; - -} - -inline constexpr BAN::StringView operator""_sv(const char* str, BAN::StringView::size_type len) { return BAN::StringView(str, len); } - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const StringView& sv, const ValueFormat&) - { - for (StringView::size_type i = 0; i < sv.size(); i++) - putc(sv[i]); - } - -} diff --git a/BAN/include/BAN/Swap.h b/BAN/include/BAN/Swap.h deleted file mode 100644 index 8952eb0..0000000 --- a/BAN/include/BAN/Swap.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -namespace BAN -{ - - template - void swap(T& lhs, T& rhs) - { - T tmp = move(lhs); - lhs = move(rhs); - rhs = move(tmp); - } - -} diff --git a/BAN/include/BAN/Time.h b/BAN/include/BAN/Time.h deleted file mode 100644 index b3c420c..0000000 --- a/BAN/include/BAN/Time.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include - -#include - -namespace BAN -{ - - struct Time - { - uint32_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t minute; - uint8_t second; - uint8_t week_day; - }; - - uint64_t to_unix_time(const BAN::Time&); - BAN::Time from_unix_time(uint64_t); - -} - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const Time& time, const ValueFormat&) - { - constexpr const char* week_days[] { "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - constexpr const char* months[] { "", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - print(putc, "{} {} {} {2}:{2}:{2} GMT+0 {4}", week_days[time.week_day], months[time.month], time.day, time.hour, time.minute, time.second, time.year); - } - -} diff --git a/BAN/include/BAN/Traits.h b/BAN/include/BAN/Traits.h deleted file mode 100644 index 8b9639a..0000000 --- a/BAN/include/BAN/Traits.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once - -namespace BAN -{ - - template struct remove_reference { using type = T; }; - template struct remove_reference { using type = T; }; - template struct remove_reference { using type = T; }; - template using remove_reference_t = typename remove_reference::type; - - template struct remove_const { using type = T; }; - template struct remove_const { using type = T; }; - template using remove_const_t = typename remove_const::type; - - template struct remove_volatile { using type = T; }; - template struct remove_volatile { using type = T; }; - template using remove_volatile_t = typename remove_volatile::type; - - template struct remove_cv { using type = remove_volatile_t>; }; - template using remove_cv_t = typename remove_cv::type; - - template struct remove_const_and_reference { using type = remove_const_t>; }; - template using remove_const_and_reference_t = typename remove_const_and_reference::type; - - template struct enable_if {}; - template struct enable_if { using type = T; }; - template using enable_if_t = typename enable_if::type; - - template struct maybe_const { using type = T; }; - template struct maybe_const { using type = const T; }; - template using maybe_const_t = typename maybe_const::type; - - template struct either_or { using type = T2; }; - template struct either_or { using type = T1; }; - template using either_or_t = typename either_or::type; - - template struct integral_constant { static constexpr T value = V; }; - template inline constexpr T integral_constant_v = integral_constant::value; - using true_type = integral_constant; - using false_type = integral_constant; - - template struct is_same : false_type {}; - template struct is_same : true_type {}; - template inline constexpr bool is_same_v = is_same::value; - template concept same_as = BAN::is_same_v; - - template struct is_lvalue_reference : false_type {}; - template struct is_lvalue_reference : true_type {}; - template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; - template concept lvalue_reference = is_lvalue_reference_v; - - template struct is_constructible { static constexpr bool value = __is_constructible(T, Args...); }; - template inline constexpr bool is_constructible_v = is_constructible::value; - - template struct is_default_constructible { static constexpr bool value = is_constructible_v; }; - template inline constexpr bool is_default_constructible_v = is_default_constructible::value; - - template struct is_copy_constructible { static constexpr bool value = is_constructible_v; }; - template inline constexpr bool is_copy_constructible_v = is_copy_constructible::value; - - template struct is_move_constructible { static constexpr bool value = is_constructible_v; }; - template inline constexpr bool is_move_constructible_v = is_move_constructible::value; - - template struct is_trivially_copyable { static constexpr bool value = __is_trivially_copyable(T); }; - template inline constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; - - template struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast(t); f(0); p + t; }; }; - template inline constexpr bool is_integral_v = is_integral::value; - template concept integral = is_integral_v; - - template struct is_floating_point : false_type {}; - template<> struct is_floating_point : true_type {}; - template<> struct is_floating_point : true_type {}; - template<> struct is_floating_point : true_type {}; - template inline constexpr bool is_floating_point_v = is_floating_point::value; - template concept floating_point = is_floating_point_v; - - template struct is_pointer : false_type {}; - template struct is_pointer : true_type {}; - template struct is_pointer : true_type {}; - template struct is_pointer : true_type {}; - template struct is_pointer : true_type {}; - template inline constexpr bool is_pointer_v = is_pointer::value; - template concept pointer = is_pointer_v; - - template struct is_const : false_type {}; - template struct is_const : true_type {}; - template inline constexpr bool is_const_v = is_const::value; - - template struct is_arithmetic { static constexpr bool value = is_integral_v || is_floating_point_v; }; - template inline constexpr bool is_arithmetic_v = is_arithmetic::value; - - template struct is_base_of { static constexpr bool value = __is_base_of(Base, Derived); }; - template inline constexpr bool is_base_of_v = is_base_of::value; - - template struct is_pod { static constexpr bool value = __is_pod(T); }; - template inline constexpr bool is_pod_v = is_pod::value; - - namespace detail - { - template> struct is_signed { static constexpr bool value = T(-1) < T(0); }; - template struct is_signed : false_type {}; - - template> struct is_unsigned { static constexpr bool value = T(0) < T(-1); }; - template struct is_unsigned : false_type {}; - } - template struct is_signed : detail::is_signed {}; - template inline constexpr bool is_signed_v = is_signed::value; - template concept signed_integral = is_signed_v && is_integral_v; - - template struct is_unsigned : detail::is_unsigned {}; - template inline constexpr bool is_unsigned_v = is_unsigned::value; - template concept unsigned_integral = is_unsigned_v && is_integral_v; - -#define __BAN_TRAITS_MAKE_UNSIGNED_CV(__type) \ - template<> struct make_unsigned<__type> { using type = unsigned __type; }; \ - template<> struct make_unsigned { using type = unsigned const __type; }; \ - template<> struct make_unsigned { using type = unsigned volatile __type; }; \ - template<> struct make_unsigned { using type = unsigned const volatile __type; }; - - template requires is_arithmetic_v struct make_unsigned { using type = T; }; - __BAN_TRAITS_MAKE_UNSIGNED_CV(char) - __BAN_TRAITS_MAKE_UNSIGNED_CV(short) - __BAN_TRAITS_MAKE_UNSIGNED_CV(int) - __BAN_TRAITS_MAKE_UNSIGNED_CV(long) - __BAN_TRAITS_MAKE_UNSIGNED_CV(long long) - template using make_unsigned_t = typename make_unsigned::type; -#undef __BAN_TRAITS_MAKE_UNSIGNED_CV - -#define __BAN_TRAITS_MAKE_SIGNED_CV(__type) \ - template<> struct make_signed { using type = __type; }; \ - template<> struct make_signed { using type = const __type; }; \ - template<> struct make_signed { using type = volatile __type; }; \ - template<> struct make_signed { using type = const volatile __type; }; - - template requires is_arithmetic_v struct make_signed { using type = T; }; - __BAN_TRAITS_MAKE_SIGNED_CV(char) - __BAN_TRAITS_MAKE_SIGNED_CV(short) - __BAN_TRAITS_MAKE_SIGNED_CV(int) - __BAN_TRAITS_MAKE_SIGNED_CV(long) - __BAN_TRAITS_MAKE_SIGNED_CV(long long) - template using make_signed_t = typename make_signed::type; -#undef __BAN_TRAITS_MAKE_SIGNED_CV - - template struct it_value_type { using value_type = T::value_type; }; - template struct it_value_type { using value_type = T; }; - template using it_value_type_t = typename it_value_type::value_type; - - template struct less { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; - template struct equal { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; - template struct greater { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs > rhs; } }; - -} diff --git a/BAN/include/BAN/UTF8.h b/BAN/include/BAN/UTF8.h deleted file mode 100644 index 1976172..0000000 --- a/BAN/include/BAN/UTF8.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include -#include - -namespace BAN::UTF8 -{ - - static constexpr uint32_t invalid = 0xFFFFFFFF; - - constexpr uint32_t byte_length(uint8_t first_byte) - { - if ((first_byte & 0x80) == 0x00) - return 1; - if ((first_byte & 0xE0) == 0xC0) - return 2; - if ((first_byte & 0xF0) == 0xE0) - return 3; - if ((first_byte & 0xF8) == 0xF0) - return 4; - return UTF8::invalid; - } - - template requires (sizeof(T) == 1) - constexpr uint32_t to_codepoint(const T* bytes) - { - uint32_t length = byte_length(bytes[0]); - - for (uint32_t i = 1; i < length; i++) - if (((uint8_t)bytes[i] & 0xC0) != 0x80) - return UTF8::invalid; - - switch (length) - { - case 1: return (((uint8_t)bytes[0] & 0x80) != 0x00) ? UTF8::invalid : (uint8_t)bytes[0]; - case 2: return (((uint8_t)bytes[0] & 0xE0) != 0xC0) ? UTF8::invalid : (((uint8_t)bytes[0] & 0x1F) << 6) | ((uint8_t)bytes[1] & 0x3F); - case 3: return (((uint8_t)bytes[0] & 0xF0) != 0xE0) ? UTF8::invalid : (((uint8_t)bytes[0] & 0x0F) << 12) | (((uint8_t)bytes[1] & 0x3F) << 6) | ((uint8_t)bytes[2] & 0x3F); - case 4: return (((uint8_t)bytes[0] & 0xF8) != 0xF0) ? UTF8::invalid : (((uint8_t)bytes[0] & 0x07) << 18) | (((uint8_t)bytes[1] & 0x3F) << 12) | (((uint8_t)bytes[2] & 0x3F) << 6) | ((uint8_t)bytes[3] & 0x3F); - } - - return UTF8::invalid; - } - - template - constexpr bool from_codepoints(const T* codepoints, size_t count, char* out) - { - uint8_t* ptr = (uint8_t*)out; - - for (size_t i = 0; i < count; i++) - { - if (codepoints[i] < 0x80) - { - *ptr++ = codepoints[i]; - } - else if (codepoints[i] < 0x800) - { - *ptr++ = 0xC0 | ((codepoints[i] >> 6) & 0x1F); - *ptr++ = 0x80 | ((codepoints[i] >> 0) & 0x3F); - } - else if (codepoints[i] < 0x10000) - { - *ptr++ = 0xE0 | ((codepoints[i] >> 12) & 0x0F); - *ptr++ = 0x80 | ((codepoints[i] >> 6) & 0x3F); - *ptr++ = 0x80 | ((codepoints[i] >> 0) & 0x3F); - } - else if (codepoints[i] < 0x110000) - { - *ptr++ = 0xF0 | ((codepoints[i] >> 18) & 0x07); - *ptr++ = 0x80 | ((codepoints[i] >> 12) & 0x3F); - *ptr++ = 0x80 | ((codepoints[i] >> 6) & 0x3F); - *ptr++ = 0x80 | ((codepoints[i] >> 0) & 0x3F); - } - else - { - return false; - } - } - - *ptr = '\0'; - - return true; - } - -} diff --git a/BAN/include/BAN/UniqPtr.h b/BAN/include/BAN/UniqPtr.h deleted file mode 100644 index 7d21467..0000000 --- a/BAN/include/BAN/UniqPtr.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include -#include - -namespace BAN -{ - - template - class UniqPtr - { - BAN_NON_COPYABLE(UniqPtr); - - public: - UniqPtr() = default; - - template - UniqPtr(UniqPtr&& other) - { - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - } - - ~UniqPtr() - { - clear(); - } - - static UniqPtr adopt(T* pointer) - { - UniqPtr uniq; - uniq.m_pointer = pointer; - return uniq; - } - - // NOTE: don't use is_constructible_v as UniqPtr is allowed with friends - template - static BAN::ErrorOr create(Args&&... args) requires requires(Args&&... args) { T(forward(args)...); } - { - UniqPtr uniq; - uniq.m_pointer = new T(BAN::forward(args)...); - if (uniq.m_pointer == nullptr) - return BAN::Error::from_errno(ENOMEM); - return uniq; - } - - template - UniqPtr& operator=(UniqPtr&& other) - { - clear(); - m_pointer = other.m_pointer; - other.m_pointer = nullptr; - return *this; - } - - T& operator*() - { - ASSERT(m_pointer); - return *m_pointer; - } - - const T& operator*() const - { - ASSERT(m_pointer); - return *m_pointer; - } - - T* operator->() - { - ASSERT(m_pointer); - return m_pointer; - } - - const T* operator->() const - { - ASSERT(m_pointer); - return m_pointer; - } - - T* ptr() { return m_pointer; } - const T* ptr() const { return m_pointer; } - - void clear() - { - if (m_pointer) - delete m_pointer; - m_pointer = nullptr; - } - - operator bool() const { return m_pointer != nullptr; } - - private: - T* m_pointer = nullptr; - - template - friend class UniqPtr; - }; - -} diff --git a/BAN/include/BAN/Variant.h b/BAN/include/BAN/Variant.h deleted file mode 100644 index 0ce615c..0000000 --- a/BAN/include/BAN/Variant.h +++ /dev/null @@ -1,317 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -namespace BAN -{ - - namespace detail - { - - template - constexpr size_t size_ref_as_ptr() { return is_lvalue_reference_v ? sizeof(remove_reference_t*) : sizeof(T); } - template - constexpr size_t align_ref_as_ptr() { return is_lvalue_reference_v ? alignof(remove_reference_t*) : alignof(T); } - - template - constexpr size_t max_size_ref_as_ptr() { return size_ref_as_ptr(); } - template - constexpr size_t max_size_ref_as_ptr() { return size_ref_as_ptr() > size_ref_as_ptr() ? max_size_ref_as_ptr() : max_size_ref_as_ptr(); } - - template - constexpr size_t max_align_ref_as_ptr() { return align_ref_as_ptr(); } - template - constexpr size_t max_align_ref_as_ptr() { return align_ref_as_ptr() > align_ref_as_ptr() ? max_align_ref_as_ptr() : max_align_ref_as_ptr(); } - - template - constexpr size_t index() - { - if constexpr(is_same_v) - return 0; - else if constexpr(sizeof...(Ts) == 0) - return 1; - else - return index() + 1; - } - - template - void destruct(size_t index, uint8_t* data) - { - if (index == 0) - { - if constexpr(!is_lvalue_reference_v) - reinterpret_cast(data)->~T(); - } - else if constexpr(sizeof...(Ts) > 0) - destruct(index - 1, data); - else - ASSERT_NOT_REACHED(); - } - - template - void move_construct(size_t index, uint8_t* source, uint8_t* target) - { - if (index == 0) - if constexpr(!is_lvalue_reference_v) - new (target) T(move(*reinterpret_cast(source))); - else - memcpy(target, source, sizeof(remove_reference_t*)); - else if constexpr(sizeof...(Ts) > 0) - move_construct(index - 1, source, target); - else - ASSERT_NOT_REACHED(); - } - - template - void copy_construct(size_t index, const uint8_t* source, uint8_t* target) - { - if (index == 0) - if constexpr(!is_lvalue_reference_v) - new (target) T(*reinterpret_cast(source)); - else - memcpy(target, source, sizeof(remove_reference_t*)); - else if constexpr(sizeof...(Ts) > 0) - copy_construct(index - 1, source, target); - else - ASSERT_NOT_REACHED(); - } - - template - void move_assign(size_t index, uint8_t* source, uint8_t* target) - { - if (index == 0) - if constexpr(!is_lvalue_reference_v) - *reinterpret_cast(target) = move(*reinterpret_cast(source)); - else - memcpy(target, source, sizeof(remove_reference_t*)); - else if constexpr(sizeof...(Ts) > 0) - move_assign(index - 1, source, target); - else - ASSERT_NOT_REACHED(); - } - - template - void copy_assign(size_t index, const uint8_t* source, uint8_t* target) - { - if (index == 0) - if constexpr(!is_lvalue_reference_v) - *reinterpret_cast(target) = *reinterpret_cast(source); - else - memcpy(target, source, sizeof(remove_reference_t*)); - else if constexpr(sizeof...(Ts) > 0) - copy_assign(index - 1, source, target); - else - ASSERT_NOT_REACHED(); - } - - } - - template - requires (!is_const_v && ...) - class Variant - { - private: - template - static constexpr bool can_have() { return detail::index() != invalid_index(); } - static constexpr size_t invalid_index() { return sizeof...(Ts); } - - public: - Variant() = default; - - Variant(Variant&& other) - : m_index(other.m_index) - { - if (!other.has_value()) - return; - detail::move_construct(other.m_index, other.m_storage, m_storage); - other.clear(); - } - - Variant(const Variant& other) - : m_index(other.m_index) - { - if (!other.has_value()) - return; - detail::copy_construct(other.m_index, other.m_storage, m_storage); - } - - template - Variant(T&& value) requires (can_have() && !is_lvalue_reference_v) - : m_index(detail::index()) - { - new (m_storage) T(move(value)); - } - - template - Variant(const T& value) requires (can_have() && !is_lvalue_reference_v) - : m_index(detail::index()) - { - new (m_storage) T(value); - } - - ~Variant() - { - clear(); - } - - Variant& operator=(Variant&& other) - { - if (m_index == other.m_index) - detail::move_assign(m_index, other.m_storage, m_storage); - else - { - clear(); - detail::move_construct(other.m_index, other.m_storage, m_storage); - m_index = other.m_index; - } - other.clear(); - return *this; - } - - Variant& operator=(const Variant& other) - { - if (m_index == other.m_index) - detail::copy_assign(m_index, other.m_storage, m_storage); - else - { - clear(); - detail::copy_construct(other.m_index, other.m_storage, m_storage); - m_index = other.m_index; - } - return *this; - } - - template - Variant& operator=(T&& value) requires (can_have() && !is_lvalue_reference_v) - { - if (size_t index = detail::index(); index == m_index) - get() = move(value); - else - { - clear(); - new (m_storage) T(move(value)); - m_index = index; - } - return *this; - } - - template - Variant& operator=(const T& value) requires (can_have() && !is_lvalue_reference_v) - { - if (size_t index = detail::index(); index == m_index) - get() = value; - else - { - clear(); - new (m_storage) T(value); - m_index = index; - } - return *this; - } - - template - bool has() const requires (can_have()) - { - return m_index == detail::index(); - } - - template - void emplace(Args&&... args) requires (can_have() && is_constructible_v) - { - clear(); - m_index = detail::index(); - new (m_storage) T(BAN::forward(args)...); - } - - template - void set(T&& value) requires (can_have() && !is_lvalue_reference_v) - { - if (has()) - get() = move(value); - else - { - clear(); - m_index = detail::index(); - new (m_storage) T(move(value)); - } - } - - template - void set(const T& value) requires (can_have() && !is_lvalue_reference_v) - { - if (has()) - get() = value; - else - { - clear(); - m_index = detail::index(); - new (m_storage) T(value); - } - } - - template - void set(T value) requires (can_have() && is_lvalue_reference_v) - { - clear(); - m_index = detail::index(); - *reinterpret_cast**>(m_storage) = &value; - } - - template - T& get() requires (can_have() && !is_lvalue_reference_v) - { - ASSERT(has()); - return *reinterpret_cast(m_storage); - } - - template - const T& get() const requires (can_have() && !is_lvalue_reference_v) - { - ASSERT(has()); - return *reinterpret_cast(m_storage); - } - - template - T get() requires (can_have() && is_lvalue_reference_v) - { - ASSERT(has()); - return **reinterpret_cast**>(m_storage); - } - - template - const T get() const requires (can_have() && is_lvalue_reference_v) - { - ASSERT(has()); - return **reinterpret_cast**>(m_storage); - } - - bool has_value() const - { - return m_index != invalid_index(); - } - - explicit operator bool() const - { - return has_value(); - } - - void clear() - { - if (m_index != invalid_index()) - { - detail::destruct(m_index, m_storage); - m_index = invalid_index(); - } - } - - private: - alignas(detail::max_align_ref_as_ptr()) uint8_t m_storage[detail::max_size_ref_as_ptr()] {}; - size_t m_index { invalid_index() }; - }; - -} diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h deleted file mode 100644 index 18f0b77..0000000 --- a/BAN/include/BAN/Vector.h +++ /dev/null @@ -1,445 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace BAN -{ - - // T must be move assignable, move constructable (and copy constructable for some functions) - template - class Vector - { - public: - using size_type = size_t; - using value_type = T; - using iterator = IteratorSimple; - using const_iterator = ConstIteratorSimple; - - public: - Vector() = default; - Vector(Vector&&); - Vector(const Vector&); - Vector(size_type, const T& = T()); - ~Vector(); - - Vector& operator=(Vector&&); - Vector& operator=(const Vector&); - - ErrorOr push_back(T&&); - ErrorOr push_back(const T&); - template - ErrorOr emplace_back(Args&&...) requires is_constructible_v; - template - ErrorOr emplace(size_type, Args&&...) requires is_constructible_v; - ErrorOr insert(size_type, T&&); - ErrorOr insert(size_type, const T&); - - iterator begin() { return iterator(m_data); } - iterator end() { return iterator(m_data + m_size); } - const_iterator begin() const { return const_iterator(m_data); } - const_iterator end() const { return const_iterator(m_data + m_size); } - - void pop_back(); - void remove(size_type); - void clear(); - - T* data() { return m_data; } - const T* data() const { return m_data; } - - bool contains(const T&) const; - - Span span() { return Span(m_data, m_size); } - Span span() const { return Span(m_data, m_size); } - - const T& operator[](size_type) const; - T& operator[](size_type); - - const T& back() const; - T& back(); - const T& front() const; - T& front(); - - void reverse(); - - ErrorOr resize(size_type) requires is_default_constructible_v; - ErrorOr resize(size_type, const T&) requires is_copy_constructible_v; - ErrorOr reserve(size_type); - ErrorOr shrink_to_fit(); - - bool empty() const; - size_type size() const; - size_type capacity() const; - - private: - ErrorOr ensure_capacity(size_type); - - private: - T* m_data = nullptr; - size_type m_capacity = 0; - size_type m_size = 0; - }; - - template - Vector::Vector(Vector&& other) - { - m_data = other.m_data; - m_capacity = other.m_capacity; - m_size = other.m_size; - - other.m_data = nullptr; - other.m_capacity = 0; - other.m_size = 0; - } - - template - Vector::Vector(const Vector& other) - { - MUST(ensure_capacity(other.m_size)); - for (size_type i = 0; i < other.m_size; i++) - new (m_data + i) T(other.m_data[i]); - m_size = other.m_size; - } - - template - Vector::Vector(size_type size, const T& value) - { - MUST(ensure_capacity(size)); - for (size_type i = 0; i < size; i++) - new (m_data + i) T(value); - m_size = size; - } - - template - Vector::~Vector() - { - clear(); - } - - template - Vector& Vector::operator=(Vector&& other) - { - clear(); - - m_data = other.m_data; - m_capacity = other.m_capacity; - m_size = other.m_size; - - other.m_data = nullptr; - other.m_capacity = 0; - other.m_size = 0; - - return *this; - } - - template - Vector& Vector::operator=(const Vector& other) - { - MUST(ensure_capacity(other.size())); - for (size_type i = 0; i < BAN::Math::min(size(), other.size()); i++) - m_data[i] = other.m_data[i]; - for (size_type i = size(); i < other.size(); i++) - new (m_data + i) T(other[i]); - for (size_type i = other.size(); i < size(); i++) - m_data[i].~T(); - m_size = other.m_size; - return *this; - } - - template - ErrorOr Vector::push_back(T&& value) - { - TRY(ensure_capacity(m_size + 1)); - new (m_data + m_size) T(move(value)); - m_size++; - return {}; - } - - template - ErrorOr Vector::push_back(const T& value) - { - return push_back(move(T(value))); - } - - template - template - ErrorOr Vector::emplace_back(Args&&... args) requires is_constructible_v - { - TRY(ensure_capacity(m_size + 1)); - new (m_data + m_size) T(forward(args)...); - m_size++; - return {}; - } - - template - template - ErrorOr Vector::emplace(size_type index, Args&&... args) requires is_constructible_v - { - ASSERT(index <= m_size); - TRY(ensure_capacity(m_size + 1)); - if (index < m_size) - { - new (m_data + m_size) T(move(m_data[m_size - 1])); - for (size_type i = m_size - 1; i > index; i--) - m_data[i] = move(m_data[i - 1]); - m_data[index] = move(T(forward(args)...)); - } - else - { - new (m_data + m_size) T(forward(args)...); - } - m_size++; - return {}; - } - - template - ErrorOr Vector::insert(size_type index, T&& value) - { - ASSERT(index <= m_size); - TRY(ensure_capacity(m_size + 1)); - if (index < m_size) - { - new (m_data + m_size) T(move(m_data[m_size - 1])); - for (size_type i = m_size - 1; i > index; i--) - m_data[i] = move(m_data[i - 1]); - m_data[index] = move(value); - } - else - { - new (m_data + m_size) T(move(value)); - } - m_size++; - return {}; - } - - template - ErrorOr Vector::insert(size_type index, const T& value) - { - return insert(index, move(T(value))); - } - - template - void Vector::pop_back() - { - ASSERT(m_size > 0); - m_data[m_size - 1].~T(); - m_size--; - } - - template - void Vector::remove(size_type index) - { - ASSERT(index < m_size); - for (size_type i = index; i < m_size - 1; i++) - m_data[i] = move(m_data[i + 1]); - m_data[m_size - 1].~T(); - m_size--; - } - - template - void Vector::clear() - { - for (size_type i = 0; i < m_size; i++) - m_data[i].~T(); - BAN::deallocator(m_data); - m_data = nullptr; - m_capacity = 0; - m_size = 0; - } - - template - bool Vector::contains(const T& other) const - { - for (size_type i = 0; i < m_size; i++) - if (m_data[i] == other) - return true; - return false; - } - - template - const T& Vector::operator[](size_type index) const - { - ASSERT(index < m_size); - return m_data[index]; - } - - template - T& Vector::operator[](size_type index) - { - ASSERT(index < m_size); - return m_data[index]; - } - - template - const T& Vector::back() const - { - ASSERT(m_size > 0); - return m_data[m_size - 1]; - } - - template - T& Vector::back() - { - ASSERT(m_size > 0); - return m_data[m_size - 1]; - } - - template - const T& Vector::front() const - { - ASSERT(m_size > 0); - return m_data[0]; - } - - template - T& Vector::front() - { - ASSERT(m_size > 0); - return m_data[0]; - } - - template - void Vector::reverse() - { - for (size_type i = 0; i < m_size / 2; i++) - BAN::swap(m_data[i], m_data[m_size - i - 1]); - } - - template - ErrorOr Vector::resize(size_type size) requires is_default_constructible_v - { - TRY(ensure_capacity(size)); - if (size < m_size) - for (size_type i = size; i < m_size; i++) - m_data[i].~T(); - if (size > m_size) - for (size_type i = m_size; i < size; i++) - new (m_data + i) T(); - m_size = size; - return {}; - } - - template - ErrorOr Vector::resize(size_type size, const T& value) requires is_copy_constructible_v - { - TRY(ensure_capacity(size)); - if (size < m_size) - for (size_type i = size; i < m_size; i++) - m_data[i].~T(); - if (size > m_size) - for (size_type i = m_size; i < size; i++) - new (m_data + i) T(value); - m_size = size; - return {}; - } - - template - ErrorOr Vector::reserve(size_type size) - { - TRY(ensure_capacity(size)); - return {}; - } - - template - ErrorOr Vector::shrink_to_fit() - { - size_type temp = m_capacity; - m_capacity = 0; - auto error_or = ensure_capacity(m_size); - if (error_or.is_error()) - { - m_capacity = temp; - return error_or; - } - return {}; - } - - template - bool Vector::empty() const - { - return m_size == 0; - } - - template - typename Vector::size_type Vector::size() const - { - return m_size; - } - - template - typename Vector::size_type Vector::capacity() const - { - return m_capacity; - } - - template - ErrorOr Vector::ensure_capacity(size_type size) - { - static_assert(alignof(T) <= alignof(max_align_t), "over aligned types not supported"); - - if (m_capacity >= size) - return {}; - - const size_type new_cap = BAN::Math::max(size, m_capacity * 2); - - if constexpr (BAN::is_trivially_copyable_v) - { - if constexpr (BAN::reallocator) - { - auto* new_data = static_cast(BAN::reallocator(m_data, new_cap * sizeof(T))); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - m_data = new_data; - } - else - { - auto* new_data = static_cast(BAN::allocator(new_cap * sizeof(T))); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - memcpy(new_data, m_data, m_size * sizeof(T)); - BAN::deallocator(m_data); - m_data = new_data; - } - } - else - { - auto* new_data = static_cast(BAN::allocator(new_cap * sizeof(T))); - if (new_data == nullptr) - return Error::from_errno(ENOMEM); - for (size_type i = 0; i < m_size; i++) - { - new (new_data + i) T(move(m_data[i])); - m_data[i].~T(); - } - BAN::deallocator(m_data); - m_data = new_data; - } - - m_capacity = new_cap; - return {}; - } - -} - -namespace BAN::Formatter -{ - - template - void print_argument(F putc, const Vector& vector, const ValueFormat& format) - { - putc('['); - for (typename Vector::size_type i = 0; i < vector.size(); i++) - { - if (i != 0) putc(','); - print_argument(putc, vector[i], format); - } - putc(']'); - } - -} diff --git a/BAN/include/BAN/WeakPtr.h b/BAN/include/BAN/WeakPtr.h deleted file mode 100644 index b5d0041..0000000 --- a/BAN/include/BAN/WeakPtr.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once - -#include - -#if __is_kernel -#include -#endif - -namespace BAN -{ - - template - class Weakable; - - template - class WeakPtr; - - // FIXME: Write this without using locks... - template - class WeakLink : public RefCounted> - { - public: - RefPtr try_lock() const - { -#if __is_kernel - Kernel::SpinLockGuard _(m_weak_lock); -#endif - if (m_ptr && m_ptr->try_ref()) - return RefPtr::adopt(m_ptr); - return nullptr; - } - bool valid() const { return m_ptr; } - void invalidate() - { -#if __is_kernel - Kernel::SpinLockGuard _(m_weak_lock); -#endif - m_ptr = nullptr; - } - - private: - WeakLink(T* ptr) : m_ptr(ptr) {} - - private: - T* m_ptr; -#if __is_kernel - mutable Kernel::SpinLock m_weak_lock; -#endif - friend class RefPtr>; - }; - - template - class Weakable - { - public: - virtual ~Weakable() - { - if (m_link) - m_link->invalidate(); - } - - ErrorOr> get_weak_ptr() const - { - if (!m_link) - m_link = TRY(RefPtr>::create((T*)this)); - return WeakPtr(m_link); - } - - private: - mutable RefPtr> m_link; - }; - - template - class WeakPtr - { - public: - WeakPtr() = default; - WeakPtr(WeakPtr&& other) { *this = move(other); } - WeakPtr(const WeakPtr& other) { *this = other; } - WeakPtr(const RefPtr& other) { *this = other; } - - WeakPtr& operator=(WeakPtr&& other) - { - clear(); - m_link = move(other.m_link); - return *this; - } - WeakPtr& operator=(const WeakPtr& other) - { - clear(); - m_link = other.m_link; - return *this; - } - WeakPtr& operator=(const RefPtr& other) - { - clear(); - if (other) - m_link = MUST(other->get_weak_ptr()).move_link(); - return *this; - } - - RefPtr lock() const - { - if (m_link) - return m_link->try_lock(); - return nullptr; - } - - void clear() { m_link.clear(); } - - bool valid() const { return m_link && m_link->valid(); } - - explicit operator bool() const { return valid(); } - - private: - WeakPtr(const RefPtr>& link) - : m_link(link) - { } - - RefPtr>&& move_link() { return move(m_link); } - - private: - RefPtr> m_link; - - friend class Weakable; - }; - -} diff --git a/CMakeLists.txt b/CMakeLists.txt index e97aa32..42d183e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,16 +43,21 @@ if(BANAN_OS) add_library(libdeflate SHARED IMPORTED) set_target_properties(libdeflate PROPERTIES IMPORTED_LOCATION "${LIBDEFLATE}") else() - add_subdirectory(BAN) - add_subdirectory(LibClipboard) - add_subdirectory(LibDEFLATE) - add_subdirectory(LibFont) - add_subdirectory(LibGUI) - add_subdirectory(LibImage) - add_subdirectory(LibInput) - add_subdirectory(Terminal) - add_subdirectory(ProgramLauncher) - add_subdirectory(WindowServer) + find_library(LIBC c REQUIRED) + add_library(libc SHARED IMPORTED) + set_target_properties(libc PROPERTIES IMPORTED_LOCATION "${LIBC}") + + add_subdirectory(banan-os/BAN) + add_subdirectory(banan-os/userspace/libraries/LibClipboard) + add_subdirectory(banan-os/userspace/libraries/LibDEFLATE) + add_subdirectory(banan-os/userspace/libraries/LibFont) + add_subdirectory(banan-os/userspace/libraries/LibGUI) + add_subdirectory(banan-os/userspace/libraries/LibImage) + add_subdirectory(banan-os/userspace/libraries/LibInput) + + add_subdirectory(banan-os/userspace/programs/ProgramLauncher) + add_subdirectory(banan-os/userspace/programs/Terminal) + add_subdirectory(banan-os/userspace/programs/WindowServer) endif() add_subdirectory(xbanan) diff --git a/LibClipboard/CMakeLists.txt b/LibClipboard/CMakeLists.txt deleted file mode 100644 index 69c1de4..0000000 --- a/LibClipboard/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(LIBCLIPBOARD_SOURCES - Clipboard.cpp -) - -add_library(libclipboard ${LIBCLIPBOARD_SOURCES}) -banan_link_library(libclipboard ban) - -banan_install_headers(libclipboard) -install(TARGETS libclipboard OPTIONAL) diff --git a/LibClipboard/Clipboard.cpp b/LibClipboard/Clipboard.cpp deleted file mode 100644 index b65377a..0000000 --- a/LibClipboard/Clipboard.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include - -#include -#include -#include -#include - -namespace LibClipboard -{ - - static int s_server_fd = -1; - - static BAN::ErrorOr send_credentials(int fd) - { - char dummy = '\0'; - iovec iovec { - .iov_base = &dummy, - .iov_len = 1, - }; - - constexpr size_t control_size = CMSG_LEN(sizeof(ucred)); - uint8_t control_buffer[control_size]; - - cmsghdr* control = reinterpret_cast(control_buffer); - - *control = { - .cmsg_len = control_size, - .cmsg_level = SOL_SOCKET, - .cmsg_type = SCM_CREDENTIALS, - }; - - *reinterpret_cast(CMSG_DATA(control)) = { - .pid = getpid(), - .uid = getuid(), - .gid = getgid(), - }; - - const msghdr message { - .msg_name = nullptr, - .msg_namelen = 0, - .msg_iov = &iovec, - .msg_iovlen = 1, - .msg_control = control, - .msg_controllen = control_size, - .msg_flags = 0, - }; - - if (sendmsg(fd, &message, 0) < 0) - return BAN::Error::from_errno(errno); - - return {}; - } - - static BAN::ErrorOr ensure_connected() - { - if (s_server_fd != -1) - return {}; - - const int sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) - return BAN::Error::from_errno(errno); - - sockaddr_un server_addr; - server_addr.sun_family = AF_UNIX; - strcpy(server_addr.sun_path, s_clipboard_server_socket.data()); - - if (connect(sock, reinterpret_cast(&server_addr), sizeof(server_addr)) == -1) - { - close(sock); - return BAN::Error::from_errno(errno); - } - - if (auto ret = send_credentials(sock); ret.is_error()) - { - close(sock); - return ret; - } - - s_server_fd = sock; - return {}; - } - - static BAN::ErrorOr recv_sized(void* data, size_t size) - { - ASSERT(s_server_fd != -1); - - uint8_t* u8_data = static_cast(data); - - size_t total_recv = 0; - while (total_recv < size) - { - const ssize_t nrecv = recv(s_server_fd, u8_data + total_recv, size - total_recv, 0); - if (nrecv <= 0) - { - const int error = nrecv ? errno : ECONNRESET; - close(s_server_fd); - s_server_fd = -1; - return BAN::Error::from_errno(error); - } - total_recv += nrecv; - } - - return {}; - } - - static BAN::ErrorOr send_sized(const void* data, size_t size) - { - ASSERT(s_server_fd != -1); - - const uint8_t* u8_data = static_cast(data); - - size_t total_sent = 0; - while (total_sent < size) - { - const ssize_t nsend = send(s_server_fd, u8_data + total_sent, size - total_sent, 0); - if (nsend <= 0) - { - const int error = nsend ? errno : ECONNRESET; - close(s_server_fd); - s_server_fd = -1; - return BAN::Error::from_errno(error); - } - total_sent += nsend; - } - - return {}; - } - - BAN::ErrorOr Clipboard::get_clipboard() - { - TRY(ensure_connected()); - - { - DataType type = DataType::__get; - TRY(send_sized(&type, sizeof(type))); - } - - Info info; - TRY(recv_sized(&info.type, sizeof(info.type))); - - switch (info.type) - { - case DataType::__get: - ASSERT_NOT_REACHED(); - case DataType::None: - break; - case DataType::Text: - size_t data_size; - TRY(recv_sized(&data_size, sizeof(data_size))); - - TRY(info.data.resize(data_size)); - TRY(recv_sized(info.data.data(), data_size)); - break; - } - - return info; - } - - BAN::ErrorOr Clipboard::set_clipboard(DataType type, BAN::Span data) - { - ASSERT(type != DataType::__get); - - TRY(ensure_connected()); - - TRY(send_sized(&type, sizeof(type))); - - switch (type) - { - case DataType::__get: - ASSERT_NOT_REACHED(); - case DataType::None: - break; - case DataType::Text: - const size_t size = data.size(); - TRY(send_sized(&size, sizeof(size))); - TRY(send_sized(data.data(), size)); - break; - } - - return {}; - } - - BAN::ErrorOr Clipboard::get_clipboard_text() - { - auto info = TRY(get_clipboard()); - if (info.type != DataType::Text) - return BAN::String {}; - - BAN::String string; - TRY(string.resize(info.data.size())); - memcpy(string.data(), info.data.data(), info.data.size()); - - return string; - } - - BAN::ErrorOr Clipboard::set_clipboard_text(BAN::StringView string) - { - return set_clipboard(DataType::Text, { reinterpret_cast(string.data()), string.size() }); - } - -} diff --git a/LibClipboard/include/LibClipboard/Clipboard.h b/LibClipboard/include/LibClipboard/Clipboard.h deleted file mode 100644 index 30c655e..0000000 --- a/LibClipboard/include/LibClipboard/Clipboard.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace LibClipboard -{ - - static constexpr BAN::StringView s_clipboard_server_socket = "/tmp/clipboard-server.socket"_sv; - - class Clipboard - { - public: - enum class DataType : uint32_t - { - None, - Text, - __get = UINT32_MAX, - }; - - struct Info - { - DataType type = DataType::None; - BAN::Vector data; - }; - - public: - static BAN::ErrorOr get_clipboard(); - static BAN::ErrorOr set_clipboard(DataType type, BAN::Span data); - - static BAN::ErrorOr get_clipboard_text(); - static BAN::ErrorOr set_clipboard_text(BAN::StringView string); - }; - -} diff --git a/LibDEFLATE/CMakeLists.txt b/LibDEFLATE/CMakeLists.txt deleted file mode 100644 index fe23970..0000000 --- a/LibDEFLATE/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(LIBDEFLATE_SOURCES - Compressor.cpp - Decompressor.cpp - HuffmanTree.cpp -) - -add_library(libdeflate ${LIBDEFLATE_SOURCES}) -banan_link_library(libdeflate ban) - -banan_install_headers(libdeflate) -install(TARGETS libdeflate OPTIONAL) diff --git a/LibDEFLATE/Compressor.cpp b/LibDEFLATE/Compressor.cpp deleted file mode 100644 index 9d45864..0000000 --- a/LibDEFLATE/Compressor.cpp +++ /dev/null @@ -1,647 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -namespace LibDEFLATE -{ - - constexpr size_t s_max_length = 258; - constexpr size_t s_max_distance = 32768; - - constexpr size_t s_max_symbols = 288; - constexpr uint8_t s_max_bits = 15; - - struct Leaf - { - uint16_t code; - uint8_t length; - }; - - static BAN::ErrorOr create_huffman_tree(BAN::Span freq, BAN::Span output) - { - ASSERT(freq.size() <= s_max_symbols); - ASSERT(freq.size() == output.size()); - - struct node_t - { - size_t symbol; - size_t freq; - node_t* left; - node_t* right; - }; - -#if LIBDEFLATE_AVOID_STACK - BAN::Vector nodes; - TRY(nodes.resize(s_max_symbols)); -#else - BAN::Array nodes; -#endif - - size_t node_count = 0; - for (size_t sym = 0; sym < freq.size(); sym++) - { - if (freq[sym] == 0) - continue; - nodes[node_count] = static_cast(BAN::allocator(sizeof(node_t))); - if (nodes[node_count] == nullptr) - { - for (size_t j = 0; j < node_count; j++) - BAN::deallocator(nodes[j]); - return BAN::Error::from_errno(ENOMEM); - } - *nodes[node_count++] = { - .symbol = sym, - .freq = freq[sym], - .left = nullptr, - .right = nullptr, - }; - } - - for (auto& symbol : output) - symbol = { .code = 0, .length = 0 }; - - if (node_count == 0) - { - output[0] = { .code = 0, .length = 1 }; - return {}; - } - - static void (*free_tree)(node_t*) = - [](node_t* root) -> void { - if (root == nullptr) - return; - free_tree(root->left); - free_tree(root->right); - BAN::deallocator(root); - }; - - const auto comp = - [](const node_t* a, const node_t* b) -> bool { - if (a->freq != b->freq) - return a->freq > b->freq; - return a->symbol > b->symbol; - }; - - auto end_it = nodes.begin() + node_count; - BAN::make_heap(nodes.begin(), end_it, comp); - - while (nodes.begin() + 1 != end_it) - { - node_t* parent = static_cast(BAN::allocator(sizeof(node_t))); - if (parent == nullptr) - { - for (auto it = nodes.begin(); it != end_it; it++) - free_tree(*it); - return BAN::Error::from_errno(ENOMEM); - } - - node_t* node1 = nodes.front(); - BAN::pop_heap(nodes.begin(), end_it--, comp); - - node_t* node2 = nodes.front(); - BAN::pop_heap(nodes.begin(), end_it--, comp); - - *parent = { - .symbol = 0, - .freq = node1->freq + node2->freq, - .left = node1, - .right = node2, - }; - - *end_it++ = parent; - BAN::push_heap(nodes.begin(), end_it, comp); - } - - static uint16_t (*gather_lengths)(const node_t*, BAN::Span, uint16_t) = - [](const node_t* node, BAN::Span symbols, uint16_t depth) -> uint16_t { - if (node == nullptr) - return 0; - uint16_t count = (depth > s_max_bits); - if (node->left == nullptr && node->right == nullptr) - symbols[node->symbol].length = BAN::Math::min(depth, s_max_bits); - else - { - count += gather_lengths(node->left, symbols, depth + 1); - count += gather_lengths(node->right, symbols, depth + 1); - } - return count; - }; - - const auto too_long_count = gather_lengths(nodes[0], output, 0); - free_tree(nodes[0]); - - uint16_t bl_count[s_max_bits + 1] {}; - for (size_t sym = 0; sym < freq.size(); sym++) - if (const uint8_t len = output[sym].length) - bl_count[len]++; - - if (too_long_count > 0) - { - for (size_t i = 0; i < too_long_count / 2; i++) - { - uint16_t bits = s_max_bits - 1; - while (bl_count[bits] == 0) - bits--; - bl_count[bits + 0]--; - bl_count[bits + 1] += 2; - bl_count[s_max_bits]--; - } - - struct SymFreq - { - size_t symbol; - size_t freq; - }; - - BAN::Vector sym_freq; - for (size_t sym = 0; sym < output.size(); sym++) - if (freq[sym] != 0) - TRY(sym_freq.push_back({ .symbol = sym, .freq = freq[sym] })); - - BAN::sort::sort(sym_freq.begin(), sym_freq.end(), - [](auto a, auto b) { return a.freq < b.freq; } - ); - - size_t index = 0; - for (uint16_t bits = s_max_bits; bits > 0; bits--) - for (size_t i = 0; i < bl_count[bits]; i++) - output[sym_freq[index++].symbol].length = bits; - ASSERT(index == sym_freq.size()); - } - - uint16_t next_code[s_max_bits + 1] {}; - uint16_t code = 0; - for (uint8_t bits = 1; bits <= s_max_bits; bits++) - { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - } - - for (size_t sym = 0; sym < freq.size(); sym++) - if (const uint16_t len = output[sym].length) - output[sym].code = next_code[len]++; - - return {}; - } - - struct Encoding - { - uint16_t symbol; - uint16_t extra_data { 0 }; - uint8_t extra_len { 0 }; - }; - - static constexpr Encoding get_len_encoding(uint16_t length) - { - ASSERT(3 <= length && length <= s_max_length); - - constexpr uint16_t base[] { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 - }; - constexpr uint8_t extra_bits[] { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - constexpr size_t count = sizeof(base) / sizeof(*base); - - for (size_t i = 0;; i++) - { - if (i + 1 < count && length >= base[i + 1]) - continue; - return { - .symbol = static_cast(257 + i), - .extra_data = static_cast(length - base[i]), - .extra_len = extra_bits[i], - }; - } - } - - static constexpr Encoding get_dist_encoding(uint16_t distance) - { - ASSERT(1 <= distance && distance <= s_max_distance); - - constexpr uint16_t base[] { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 - }; - constexpr uint8_t extra_bits[] { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - constexpr size_t count = sizeof(base) / sizeof(*base); - - for (size_t i = 0;; i++) - { - if (i + 1 < count && distance >= base[i + 1]) - continue; - return { - .symbol = static_cast(i), - .extra_data = static_cast(distance - base[i]), - .extra_len = extra_bits[i], - }; - } - } - - static void get_frequencies(BAN::Span entries, BAN::Span lit_len_freq, BAN::Span dist_freq) - { - ASSERT(lit_len_freq.size() == 286); - ASSERT(dist_freq.size() == 30); - - for (auto entry : entries) - { - switch (entry.type) - { - case Compressor::LZ77Entry::Type::Literal: - lit_len_freq[entry.as.literal]++; - break; - case Compressor::LZ77Entry::Type::DistLength: - lit_len_freq[get_len_encoding(entry.as.dist_length.length).symbol]++; - dist_freq[get_dist_encoding(entry.as.dist_length.distance).symbol]++; - break; - } - } - - lit_len_freq[256]++; - } - - struct CodeLengthInfo - { - uint16_t hlit; - uint8_t hdist; - uint8_t hclen; - BAN::Vector encoding; - BAN::Array code_length; - BAN::Array code_length_tree; - }; - - static BAN::ErrorOr build_code_length_info(BAN::Span lit_len_tree, BAN::Span dist_tree) - { - CodeLengthInfo result; - - const auto append_tree = - [&result](BAN::Span& tree) -> BAN::ErrorOr - { - while (!tree.empty() && tree[tree.size() - 1].length == 0) - tree = tree.slice(0, tree.size() - 1); - - for (size_t i = 0; i < tree.size();) - { - size_t count = 1; - while (i + count < tree.size() && tree[i].length == tree[i + count].length) - count++; - - if (tree[i].length == 0) - { - if (count > 138) - count = 138; - - if (count < 3) - { - for (size_t j = 0; j < count; j++) - TRY(result.encoding.push_back({ .symbol = 0 })); - } - else if (count < 11) - { - TRY(result.encoding.push_back({ - .symbol = 17, - .extra_data = static_cast(count - 3), - .extra_len = 3, - })); - } - else - { - TRY(result.encoding.push_back({ - .symbol = 18, - .extra_data = static_cast(count - 11), - .extra_len = 7, - })); - } - } - else - { - if (count >= 3 && !result.encoding.empty() && result.encoding.back().symbol == tree[i].length) - { - if (count > 6) - count = 6; - TRY(result.encoding.push_back({ - .symbol = 16, - .extra_data = static_cast(count - 3), - .extra_len = 2, - })); - } - else - { - count = 1; - TRY(result.encoding.push_back({ .symbol = tree[i].length })); - } - } - - i += count; - } - - return {}; - }; - - TRY(append_tree(lit_len_tree)); - result.hlit = lit_len_tree.size(); - - TRY(append_tree(dist_tree)); - result.hdist = dist_tree.size(); - - BAN::Array code_len_freq(0); - for (auto entry : result.encoding) - code_len_freq[entry.symbol]++; - TRY(create_huffman_tree(code_len_freq.span(), result.code_length_tree.span())); - - constexpr uint8_t code_length_order[] { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - for (size_t i = 0; i < result.code_length_tree.size(); i++) - result.code_length[i] = result.code_length_tree[code_length_order[i]].length; - result.hclen = 19; - while (result.hclen > 4 && result.code_length[result.hclen - 1] == 0) - result.hclen--; - - return BAN::move(result); - } - - uint32_t Compressor::get_hash_key(BAN::ConstByteSpan needle) const - { - ASSERT(needle.size() >= 3); - return (needle[2] << 16) | (needle[1] << 8) | needle[0]; - } - - BAN::ErrorOr Compressor::update_hash_chain(size_t count) - { - if (m_hash_chain.size() >= s_max_distance * 2) - { - const uint8_t* current = m_data.data() + m_hash_chain_index + count; - for (auto& [_, chain] : m_hash_chain) - { - for (auto it = chain.begin(); it != chain.end(); it++) - { - const size_t distance = current - it->data(); - if (distance < s_max_distance) - continue; - - while (it != chain.end()) - it = chain.remove(it); - break; - } - } - } - - for (size_t i = 0; i < count; i++) - { - auto slice = m_data.slice(m_hash_chain_index + i); - if (slice.size() < 3) - break; - - const uint32_t key = get_hash_key(slice); - - auto it = m_hash_chain.find(key); - if (it != m_hash_chain.end()) - TRY(it->value.insert(it->value.begin(), slice)); - else - { - HashChain new_chain; - TRY(new_chain.push_back(slice)); - TRY(m_hash_chain.insert(key, BAN::move(new_chain))); - } - } - - m_hash_chain_index += count; - - return {}; - } - - BAN::ErrorOr Compressor::find_longest_match(BAN::ConstByteSpan needle) const - { - LZ77Entry result = { - .type = LZ77Entry::Type::Literal, - .as = { .literal = needle[0] } - }; - - if (needle.size() < 3) - return result; - - const uint32_t key = get_hash_key(needle); - - auto it = m_hash_chain.find(key); - if (it == m_hash_chain.end()) - return result; - - auto& chain = it->value; - for (const auto node : chain) - { - const size_t distance = needle.data() - node.data(); - if (distance > s_max_distance) - break; - - size_t length = 3; - const size_t max_length = BAN::Math::min(needle.size(), s_max_length); - while (length < max_length && needle[length] == node[length]) - length++; - - if (result.type != LZ77Entry::Type::DistLength || length > result.as.dist_length.length) - { - result = LZ77Entry { - .type = LZ77Entry::Type::DistLength, - .as = { - .dist_length = { - .length = static_cast(length), - .distance = static_cast(distance), - } - } - }; - } - } - - return result; - } - - BAN::ErrorOr> Compressor::lz77_compress(BAN::ConstByteSpan data) - { - BAN::Vector result; - - size_t advance = 0; - for (size_t i = 0; i < data.size(); i += advance) - { - TRY(update_hash_chain(advance)); - - auto match = TRY(find_longest_match(data.slice(i))); - if (match.type == LZ77Entry::Type::Literal) - { - TRY(result.push_back(match)); - advance = 1; - continue; - } - - ASSERT(match.type == LZ77Entry::Type::DistLength); - - auto lazy_match = TRY(find_longest_match(data.slice(i + 1))); - if (lazy_match.type == LZ77Entry::Type::DistLength && lazy_match.as.dist_length.length > match.as.dist_length.length) - { - TRY(result.push_back({ .type = LZ77Entry::Type::Literal, .as = { .literal = data[i] }})); - TRY(result.push_back(lazy_match)); - advance = 1 + lazy_match.as.dist_length.length; - } - else - { - TRY(result.push_back(match)); - advance = match.as.dist_length.length; - } - } - - return result; - } - - BAN::ErrorOr Compressor::compress_block(BAN::ConstByteSpan data, bool final) - { - // FIXME: use fixed trees or uncompressed blocks - - auto lz77_entries = TRY(lz77_compress(data)); - -#if LIBDEFLATE_AVOID_STACK - BAN::Vector lit_len_freq, dist_freq; - TRY(lit_len_freq.resize(286, 0)); - TRY(dist_freq.resize(30, 0)); -#else - BAN::Array lit_len_freq(0); - BAN::Array dist_freq(0); -#endif - - get_frequencies(lz77_entries.span(), lit_len_freq.span(), dist_freq.span()); - -#if LIBDEFLATE_AVOID_STACK - BAN::Vector lit_len_tree, dist_tree; - TRY(lit_len_tree.resize(286)); - TRY(dist_tree.resize(30)); -#else - BAN::Array lit_len_tree; - BAN::Array dist_tree; -#endif - - TRY(create_huffman_tree(lit_len_freq.span(), lit_len_tree.span())); - TRY(create_huffman_tree(dist_freq.span(), dist_tree.span())); - - auto info = TRY(build_code_length_info(lit_len_tree.span(), dist_tree.span())); - - TRY(m_stream.write_bits(final, 1)); - TRY(m_stream.write_bits(2, 2)); - - TRY(m_stream.write_bits(info.hlit - 257, 5)); - TRY(m_stream.write_bits(info.hdist - 1, 5)); - TRY(m_stream.write_bits(info.hclen - 4, 4)); - - for (size_t i = 0; i < info.hclen; i++) - TRY(m_stream.write_bits(info.code_length[i], 3)); - - for (const auto entry : info.encoding) - { - const auto symbol = info.code_length_tree[entry.symbol]; - TRY(m_stream.write_bits(reverse_bits(symbol.code, symbol.length), symbol.length)); - TRY(m_stream.write_bits(entry.extra_data, entry.extra_len)); - } - - for (const auto entry : lz77_entries) - { - switch (entry.type) - { - case LZ77Entry::Type::Literal: - { - const auto symbol = lit_len_tree[entry.as.literal]; - TRY(m_stream.write_bits(reverse_bits(symbol.code, symbol.length), symbol.length)); - break; - } - case LZ77Entry::Type::DistLength: - { - const auto len_encoding = get_len_encoding(entry.as.dist_length.length); - const auto len_code = lit_len_tree[len_encoding.symbol]; - TRY(m_stream.write_bits(reverse_bits(len_code.code, len_code.length), len_code.length)); - TRY(m_stream.write_bits(len_encoding.extra_data, len_encoding.extra_len)); - - const auto dist_encoding = get_dist_encoding(entry.as.dist_length.distance); - const auto dist_code = dist_tree[dist_encoding.symbol]; - TRY(m_stream.write_bits(reverse_bits(dist_code.code, dist_code.length), dist_code.length)); - TRY(m_stream.write_bits(dist_encoding.extra_data, dist_encoding.extra_len)); - - break; - } - } - } - - const auto end_code = lit_len_tree[256]; - TRY(m_stream.write_bits(reverse_bits(end_code.code, end_code.length), end_code.length)); - - return {}; - } - - BAN::ErrorOr> Compressor::compress() - { - const uint32_t data_size = m_data.size(); - - uint32_t checksum = 0; - switch (m_type) - { - case StreamType::Raw: - break; - case StreamType::Zlib: - TRY(m_stream.write_bits(0x78, 8)); // deflate with 32k window - TRY(m_stream.write_bits(0x9C, 8)); // default compression - checksum = calculate_adler32(m_data); - break; - case StreamType::GZip: - { - const time_t current_time = time(nullptr); - TRY(m_stream.write_bits(0x1F, 8)); // ID1 - TRY(m_stream.write_bits(0x8B, 8)); // ID2 - TRY(m_stream.write_bits(8, 8)); // CM (deflate) - TRY(m_stream.write_bits(0, 8)); // FLG - TRY(m_stream.write_bits(current_time >> 0, 8)); // MTIME - TRY(m_stream.write_bits(current_time >> 8, 8)); - TRY(m_stream.write_bits(current_time >> 16, 8)); - TRY(m_stream.write_bits(current_time >> 24, 8)); - TRY(m_stream.write_bits(0, 8)); // XFL - TRY(m_stream.write_bits(3, 8)); // OS (Unix) - checksum = calculate_crc32(m_data); - } - } - - constexpr size_t max_block_size = 16 * 1024; - while (!m_data.empty()) - { - const size_t block_size = BAN::Math::min(m_data.size(), max_block_size); - TRY(compress_block(m_data.slice(0, block_size), block_size == m_data.size())); - m_data = m_data.slice(block_size); - } - - TRY(m_stream.pad_to_byte_boundary()); - - switch (m_type) - { - case StreamType::Raw: - break; - case StreamType::Zlib: - TRY(m_stream.write_bits(checksum >> 24, 8)); - TRY(m_stream.write_bits(checksum >> 16, 8)); - TRY(m_stream.write_bits(checksum >> 8, 8)); - TRY(m_stream.write_bits(checksum >> 0, 8)); - break; - case StreamType::GZip: - TRY(m_stream.write_bits(checksum >> 0, 8)); - TRY(m_stream.write_bits(checksum >> 8, 8)); - TRY(m_stream.write_bits(checksum >> 16, 8)); - TRY(m_stream.write_bits(checksum >> 24, 8)); - TRY(m_stream.write_bits(data_size >> 0, 8)); - TRY(m_stream.write_bits(data_size >> 8, 8)); - TRY(m_stream.write_bits(data_size >> 16, 8)); - TRY(m_stream.write_bits(data_size >> 24, 8)); - break; - } - - return m_stream.take_buffer(); - } - -} diff --git a/LibDEFLATE/Decompressor.cpp b/LibDEFLATE/Decompressor.cpp deleted file mode 100644 index f2179a5..0000000 --- a/LibDEFLATE/Decompressor.cpp +++ /dev/null @@ -1,355 +0,0 @@ -#include -#include - -namespace LibDEFLATE -{ - - union ZLibHeader - { - struct - { - uint8_t cm : 4; - uint8_t cinfo : 4; - uint8_t fcheck : 5; - uint8_t fdict : 1; - uint8_t flevel : 2; - }; - struct - { - uint8_t raw1; - uint8_t raw2; - }; - }; - - BAN::ErrorOr Decompressor::read_symbol(const HuffmanTree& tree) - { - const uint8_t instant_bits = tree.instant_bits(); - - uint16_t code = reverse_bits(TRY(m_stream.peek_bits(instant_bits)), instant_bits); - if (auto symbol = tree.get_symbol_instant(code); symbol.has_value()) - { - MUST(m_stream.take_bits(symbol->len)); - return symbol->symbol; - } - - MUST(m_stream.take_bits(instant_bits)); - - uint8_t len = instant_bits; - while (len < tree.max_bits()) - { - code = (code << 1) | TRY(m_stream.take_bits(1)); - len++; - if (auto symbol = tree.get_symbol(code, len); symbol.has_value()) - return symbol.value(); - } - - return BAN::Error::from_errno(EINVAL); - } - - BAN::ErrorOr Decompressor::inflate_block(const HuffmanTree& length_tree, const HuffmanTree& distance_tree) - { - uint16_t symbol; - while ((symbol = TRY(read_symbol(length_tree))) != 256) - { - if (symbol < 256) - { - TRY(m_output.push_back(symbol)); - continue; - } - - constexpr uint16_t length_base[] { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 - }; - constexpr uint8_t length_extra_bits[] { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - constexpr uint16_t distance_base[] { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 - }; - constexpr uint8_t distance_extra_bits[] { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - - if (symbol > 285) - return BAN::Error::from_errno(EINVAL); - symbol -= 257; - - const uint16_t length = length_base[symbol] + TRY(m_stream.take_bits(length_extra_bits[symbol])); - - uint16_t distance_code; - if (distance_tree.empty()) - distance_code = reverse_bits(TRY(m_stream.take_bits(5)), 5); - else - distance_code = TRY(read_symbol(distance_tree)); - if (distance_code > 29) - return BAN::Error::from_errno(EINVAL); - - const uint16_t distance = distance_base[distance_code] + TRY(m_stream.take_bits(distance_extra_bits[distance_code])); - - const size_t orig_size = m_output.size(); - const size_t offset = orig_size - distance; - TRY(m_output.resize(orig_size + length)); - for (size_t i = 0; i < length; i++) - m_output[orig_size + i] = m_output[offset + i]; - } - - return {}; - } - - BAN::ErrorOr Decompressor::handle_header() - { - switch (m_type) - { - case StreamType::Raw: - return {}; - case StreamType::Zlib: - { - ZLibHeader header; - header.raw1 = TRY(m_stream.take_bits(8)); - header.raw2 = TRY(m_stream.take_bits(8)); - - if (((header.raw1 << 8) | header.raw2) % 31) - { - dwarnln("zlib header checksum failed"); - return BAN::Error::from_errno(EINVAL); - } - - if (header.cm != 8) - { - dwarnln("zlib does not use DEFLATE"); - return BAN::Error::from_errno(EINVAL); - } - - if (header.fdict) - { - TRY(m_stream.take_bits(16)); - TRY(m_stream.take_bits(16)); - } - - return {}; - } - case StreamType::GZip: - { - const uint8_t id1 = TRY(m_stream.take_bits(8)); - const uint8_t id2 = TRY(m_stream.take_bits(8)); - if (id1 != 0x1F || id2 != 0x8B) - { - dwarnln("gzip header invalid identification"); - return BAN::Error::from_errno(EINVAL); - - } - - const uint8_t cm = TRY(m_stream.take_bits(8)); - if (cm != 8) - { - dwarnln("gzip does not use DEFLATE"); - return BAN::Error::from_errno(EINVAL); - } - - const uint8_t flg = TRY(m_stream.take_bits(8)); - - TRY(m_stream.take_bits(16)); // mtime - TRY(m_stream.take_bits(16)); - - TRY(m_stream.take_bits(8)); // xfl - - TRY(m_stream.take_bits(8)); // os - - // extra fields - if (flg & (1 << 2)) - { - const uint16_t xlen = TRY(m_stream.take_bits(16)); - for (size_t i = 0; i < xlen; i++) - TRY(m_stream.take_bits(8)); - } - - // file name - if (flg & (1 << 3)) - while (TRY(m_stream.take_bits(8)) != '\0') - continue; - - // file comment - if (flg & (1 << 4)) - while (TRY(m_stream.take_bits(8)) != '\0') - continue; - - // crc16 - // TODO: validate - if (flg & (1 << 1)) - TRY(m_stream.take_bits(16)); - - return {}; - } - } - - ASSERT_NOT_REACHED(); - } - - BAN::ErrorOr Decompressor::handle_footer() - { - switch (m_type) - { - case StreamType::Raw: - return {}; - case StreamType::Zlib: - { - m_stream.skip_to_byte_boundary(); - - uint32_t adler32 = 0; - for (size_t i = 0; i < 4; i++) - adler32 = (adler32 << 8) | TRY(m_stream.take_bits(8)); - - if (adler32 != calculate_adler32(m_output.span())) - { - dwarnln("zlib final adler32 checksum failed"); - return BAN::Error::from_errno(EINVAL); - } - - return {}; - } - case StreamType::GZip: - { - m_stream.skip_to_byte_boundary(); - - const uint32_t crc32 = - static_cast(TRY(m_stream.take_bits(16))) | - static_cast(TRY(m_stream.take_bits(16))) << 16; - - if (crc32 != calculate_crc32(m_output.span())) - { - dwarnln("gzip final crc32 checksum failed"); - return BAN::Error::from_errno(EINVAL); - } - - const uint32_t isize = - static_cast(TRY(m_stream.take_bits(16))) | - static_cast(TRY(m_stream.take_bits(16))) << 16; - - if (isize != m_output.size() % UINT32_MAX) - { - dwarnln("gzip final isize does not match {} vs {}", isize, m_output.size()); - return BAN::Error::from_errno(EINVAL); - } - - return {}; - } - } - - ASSERT_NOT_REACHED(); - } - - BAN::ErrorOr Decompressor::decompress_type0() - { - m_stream.skip_to_byte_boundary(); - const uint16_t len = TRY(m_stream.take_bits(16)); - const uint16_t nlen = TRY(m_stream.take_bits(16)); - if (len != 0xFFFF - nlen) - return BAN::Error::from_errno(EINVAL); - - const size_t orig_size = m_output.size(); - TRY(m_output.resize(orig_size + len)); - TRY(m_stream.take_byte_aligned(&m_output[orig_size], len)); - - return {}; - } - - BAN::ErrorOr Decompressor::decompress_type1() - { - if (!m_fixed_tree.has_value()) - m_fixed_tree = TRY(HuffmanTree::fixed_tree()); - TRY(inflate_block(m_fixed_tree.value(), {})); - return {}; - } - - BAN::ErrorOr Decompressor::decompress_type2() - { - constexpr uint8_t code_length_order[] { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - const uint16_t hlit = TRY(m_stream.take_bits(5)) + 257; - const uint8_t hdist = TRY(m_stream.take_bits(5)) + 1; - const uint8_t hclen = TRY(m_stream.take_bits(4)) + 4; - - uint8_t code_lengths[19] {}; - for (size_t i = 0; i < hclen; i++) - code_lengths[code_length_order[i]] = TRY(m_stream.take_bits(3)); - const auto code_length_tree = TRY(HuffmanTree::create({ code_lengths, 19 })); - - uint8_t bit_lengths[286 + 32] {}; - size_t bit_lengths_len = 0; - - uint16_t last_symbol = 0; - while (bit_lengths_len < hlit + hdist) - { - uint16_t symbol = TRY(read_symbol(code_length_tree)); - if (symbol > 18) - return BAN::Error::from_errno(EINVAL); - - uint8_t count; - if (symbol <= 15) - { - count = 1; - } - else if (symbol == 16) - { - symbol = last_symbol; - count = TRY(m_stream.take_bits(2)) + 3; - } - else if (symbol == 17) - { - symbol = 0; - count = TRY(m_stream.take_bits(3)) + 3; - } - else - { - symbol = 0; - count = TRY(m_stream.take_bits(7)) + 11; - } - - ASSERT(bit_lengths_len + count <= hlit + hdist); - - for (uint8_t i = 0; i < count; i++) - bit_lengths[bit_lengths_len++] = symbol; - last_symbol = symbol; - } - - TRY(inflate_block( - TRY(HuffmanTree::create({ bit_lengths, hlit })), - TRY(HuffmanTree::create({ bit_lengths + hlit, hdist })) - )); - - return {}; - } - - BAN::ErrorOr> Decompressor::decompress() - { - TRY(handle_header()); - - bool bfinal = false; - while (!bfinal) - { - bfinal = TRY(m_stream.take_bits(1)); - switch (TRY(m_stream.take_bits(2))) - { - case 0b00: - TRY(decompress_type0()); - break; - case 0b01: - TRY(decompress_type1()); - break; - case 0b10: - TRY(decompress_type2()); - break; - default: - return BAN::Error::from_errno(EINVAL); - } - } - - TRY(handle_footer()); - - return BAN::move(m_output); - } - -} diff --git a/LibDEFLATE/HuffmanTree.cpp b/LibDEFLATE/HuffmanTree.cpp deleted file mode 100644 index 17bcc25..0000000 --- a/LibDEFLATE/HuffmanTree.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include - -namespace LibDEFLATE -{ - - HuffmanTree& HuffmanTree::operator=(HuffmanTree&& other) - { - m_instant_bits = other.m_instant_bits; - m_min_bits = other.m_min_bits; - m_max_bits = other.m_max_bits; - - m_instant = BAN::move(other.m_instant); - m_min_code = BAN::move(other.m_min_code); - m_slow_table = BAN::move(other.m_slow_table); - - return *this; - } - - BAN::ErrorOr HuffmanTree::create(BAN::Span bit_lengths) - { - HuffmanTree result; - TRY(result.initialize(bit_lengths)); - return result; - } - - BAN::ErrorOr HuffmanTree::initialize(BAN::Span bit_lengths) - { - m_max_bits = 0; - m_min_bits = MAX_BITS; - - uint16_t max_sym = 0; - uint16_t bl_count[MAX_BITS + 1] {}; - for (size_t sym = 0; sym < bit_lengths.size(); sym++) - { - if (bit_lengths[sym] == 0) - continue; - m_max_bits = BAN::Math::max(bit_lengths[sym], m_max_bits); - m_min_bits = BAN::Math::min(bit_lengths[sym], m_min_bits); - bl_count[bit_lengths[sym]]++; - max_sym = sym; - } - - uint16_t next_code[MAX_BITS + 1] {}; - - uint16_t code = 0; - for (uint8_t bits = 1; bits <= MAX_BITS; bits++) - { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = code; - m_min_code[bits] = code; - } - - BAN::Vector tree; - TRY(tree.resize(max_sym + 1, { .code = 0, .len = 0 })); - for (uint16_t sym = 0; sym <= max_sym; sym++) - { - tree[sym].len = bit_lengths[sym]; - if (const uint8_t len = tree[sym].len) - tree[sym].code = next_code[len]++; - } - - TRY(build_instant_table(tree.span())); - TRY(build_slow_table(tree.span())); - - return {}; - } - - BAN::ErrorOr HuffmanTree::build_instant_table(BAN::Span tree) - { - m_instant_bits = BAN::Math::min(9, m_max_bits); - TRY(m_instant.resize(1 << m_instant_bits, {})); - - for (uint16_t sym = 0; sym < tree.size(); sym++) - { - if (tree[sym].len == 0 || tree[sym].len > m_instant_bits) - continue; - const uint16_t code = tree[sym].code; - const uint16_t shift = m_instant_bits - tree[sym].len; - for (uint16_t j = code << shift; j < (code + 1) << shift; j++) - m_instant[j] = { sym, tree[sym].len }; - } - - return {}; - } - - BAN::ErrorOr HuffmanTree::build_slow_table(BAN::Span tree) - { - TRY(m_slow_table.resize(MAX_BITS + 1)); - for (uint16_t sym = 0; sym < tree.size(); sym++) - { - const auto leaf = tree[sym]; - if (leaf.len == 0) - continue; - const size_t offset = leaf.code - m_min_code[leaf.len]; - if (offset >= m_slow_table[leaf.len].size()) - TRY(m_slow_table[leaf.len].resize(offset + 1)); - m_slow_table[leaf.len][offset] = sym; - } - - return {}; - } - - - BAN::ErrorOr HuffmanTree::fixed_tree() - { - struct BitLengths - { - consteval BitLengths() - { - size_t i = 0; - for (; i <= 143; i++) values[i] = 8; - for (; i <= 255; i++) values[i] = 9; - for (; i <= 279; i++) values[i] = 7; - for (; i <= 287; i++) values[i] = 8; - } - - BAN::Array values; - }; - static constexpr BitLengths bit_lengths; - return TRY(HuffmanTree::create(bit_lengths.values.span())); - } - - BAN::Optional HuffmanTree::get_symbol_instant(uint16_t code) const - { - ASSERT(code < m_instant.size()); - if (const auto entry = m_instant[code]; entry.len) - return entry; - return {}; - } - - BAN::Optional HuffmanTree::get_symbol(uint16_t code, uint8_t len) const - { - ASSERT(len <= m_max_bits); - const auto& symbols = m_slow_table[len]; - const size_t offset = code - m_min_code[len]; - if (symbols.size() <= offset) - return {}; - return symbols[offset]; - } - -} diff --git a/LibDEFLATE/include/LibDEFLATE/BitStream.h b/LibDEFLATE/include/LibDEFLATE/BitStream.h deleted file mode 100644 index dbde3ca..0000000 --- a/LibDEFLATE/include/LibDEFLATE/BitStream.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once - -#include -#include - -namespace LibDEFLATE -{ - - class BitInputStream - { - public: - BitInputStream(BAN::ConstByteSpan data) - : m_data(data) - { } - - BAN::ErrorOr peek_bits(size_t count) - { - ASSERT(count <= 16); - - while (m_bit_buffer_len < count) - { - if (m_data.empty()) - return BAN::Error::from_errno(ENOBUFS); - m_bit_buffer |= m_data[0] << m_bit_buffer_len; - m_bit_buffer_len += 8; - m_data = m_data.slice(1); - } - - return m_bit_buffer & ((1 << count) - 1); - } - - BAN::ErrorOr take_bits(size_t count) - { - const uint16_t result = TRY(peek_bits(count)); - m_bit_buffer >>= count; - m_bit_buffer_len -= count; - return result; - } - - BAN::ErrorOr take_byte_aligned(uint8_t* output, size_t bytes) - { - ASSERT(m_bit_buffer % 8 == 0); - - while (m_bit_buffer_len && bytes) - { - *output++ = m_bit_buffer; - m_bit_buffer >>= 8; - m_bit_buffer_len -= 8; - bytes--; - } - - if (bytes > m_data.size()) - return BAN::Error::from_errno(EINVAL); - memcpy(output, m_data.data(), bytes); - m_data = m_data.slice(bytes); - - return {}; - } - - void skip_to_byte_boundary() - { - const size_t bits_to_remove = m_bit_buffer_len % 8; - m_bit_buffer >>= bits_to_remove; - m_bit_buffer_len -= bits_to_remove; - } - - private: - BAN::ConstByteSpan m_data; - uint32_t m_bit_buffer { 0 }; - uint8_t m_bit_buffer_len { 0 }; - }; - - class BitOutputStream - { - public: - BAN::ErrorOr write_bits(uint16_t value, size_t count) - { - ASSERT(m_bit_buffer_len < 8); - ASSERT(count <= 16); - - const uint16_t mask = (1 << count) - 1; - m_bit_buffer |= (value & mask) << m_bit_buffer_len; - m_bit_buffer_len += count; - - while (m_bit_buffer_len >= 8) - { - TRY(m_data.push_back(m_bit_buffer)); - m_bit_buffer >>= 8; - m_bit_buffer_len -= 8; - } - - return {}; - } - - BAN::ErrorOr pad_to_byte_boundary() - { - ASSERT(m_bit_buffer_len < 8); - if (m_bit_buffer_len == 0) - return {}; - TRY(m_data.push_back(m_bit_buffer)); - m_bit_buffer = 0; - m_bit_buffer_len = 0; - return {}; - } - - BAN::Vector take_buffer() - { - ASSERT(m_bit_buffer_len == 0); - return BAN::move(m_data); - } - - private: - BAN::Vector m_data; - uint32_t m_bit_buffer { 0 }; - uint8_t m_bit_buffer_len { 0 }; - }; - -} diff --git a/LibDEFLATE/include/LibDEFLATE/Compressor.h b/LibDEFLATE/include/LibDEFLATE/Compressor.h deleted file mode 100644 index fccc524..0000000 --- a/LibDEFLATE/include/LibDEFLATE/Compressor.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -namespace LibDEFLATE -{ - - class Compressor - { - BAN_NON_COPYABLE(Compressor); - BAN_NON_MOVABLE(Compressor); - - public: - using HashChain = BAN::LinkedList; - - struct LZ77Entry - { - enum class Type - { - Literal, - DistLength, - } type; - union - { - uint8_t literal; - struct - { - uint16_t length; - uint16_t distance; - } dist_length; - } as; - }; - - public: - Compressor(BAN::ConstByteSpan data, StreamType type) - : m_type(type) - , m_data(data) - { } - - BAN::ErrorOr> compress(); - - private: - BAN::ErrorOr compress_block(BAN::ConstByteSpan, bool final); - - uint32_t get_hash_key(BAN::ConstByteSpan needle) const; - BAN::ErrorOr update_hash_chain(size_t count); - - BAN::ErrorOr find_longest_match(BAN::ConstByteSpan needle) const; - BAN::ErrorOr> lz77_compress(BAN::ConstByteSpan data); - - private: - const StreamType m_type; - BAN::ConstByteSpan m_data; - BitOutputStream m_stream; - - size_t m_hash_chain_index { 0 }; - BAN::HashMap m_hash_chain; - }; - -} diff --git a/LibDEFLATE/include/LibDEFLATE/Decompressor.h b/LibDEFLATE/include/LibDEFLATE/Decompressor.h deleted file mode 100644 index f293a47..0000000 --- a/LibDEFLATE/include/LibDEFLATE/Decompressor.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - - -#include -#include -#include - -#include -#include -#include - -namespace LibDEFLATE -{ - - class Decompressor - { - BAN_NON_COPYABLE(Decompressor); - BAN_NON_MOVABLE(Decompressor); - - public: - Decompressor(BAN::ConstByteSpan data, StreamType type) - : m_type(type) - , m_stream(data) - { } - - BAN::ErrorOr> decompress(); - - private: - BAN::ErrorOr read_symbol(const HuffmanTree& tree); - BAN::ErrorOr inflate_block(const HuffmanTree& length_tree, const HuffmanTree& distance_tree); - - BAN::ErrorOr decompress_type0(); - BAN::ErrorOr decompress_type1(); - BAN::ErrorOr decompress_type2(); - - BAN::ErrorOr handle_header(); - BAN::ErrorOr handle_footer(); - - private: - const StreamType m_type; - BitInputStream m_stream; - BAN::Vector m_output; - BAN::Optional m_fixed_tree; - }; - -} diff --git a/LibDEFLATE/include/LibDEFLATE/HuffmanTree.h b/LibDEFLATE/include/LibDEFLATE/HuffmanTree.h deleted file mode 100644 index 89fdb7e..0000000 --- a/LibDEFLATE/include/LibDEFLATE/HuffmanTree.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace LibDEFLATE -{ - - class HuffmanTree - { - BAN_NON_COPYABLE(HuffmanTree); - - public: - static constexpr uint8_t MAX_BITS = 15; - - struct Leaf - { - uint16_t code; - uint8_t len; - }; - - struct Instant - { - uint16_t symbol; - uint8_t len; - }; - - HuffmanTree() {} - HuffmanTree(HuffmanTree&& other) { *this = BAN::move(other); } - HuffmanTree& operator=(HuffmanTree&& other); - - static BAN::ErrorOr create(BAN::Span bit_lengths); - - static BAN::ErrorOr fixed_tree(); - BAN::Optional get_symbol_instant(uint16_t code) const; - - BAN::Optional get_symbol(uint16_t code, uint8_t len) const; - - uint8_t instant_bits() const { return m_instant_bits; } - uint8_t min_bits() const { return m_min_bits; } - uint8_t max_bits() const { return m_max_bits; } - bool empty() const { return m_min_bits == 0; } - - private: - BAN::ErrorOr initialize(BAN::Span bit_lengths); - BAN::ErrorOr build_instant_table(BAN::Span tree); - BAN::ErrorOr build_slow_table(BAN::Span tree); - - private: - uint8_t m_instant_bits { 0 }; - uint8_t m_min_bits { 0 }; - uint8_t m_max_bits { 0 }; - - BAN::Vector m_instant; - BAN::Array m_min_code; - BAN::Vector> m_slow_table; - }; - -} diff --git a/LibDEFLATE/include/LibDEFLATE/StreamType.h b/LibDEFLATE/include/LibDEFLATE/StreamType.h deleted file mode 100644 index 894bd58..0000000 --- a/LibDEFLATE/include/LibDEFLATE/StreamType.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace LibDEFLATE -{ - - enum class StreamType - { - Raw, - Zlib, - GZip, - }; - -} diff --git a/LibDEFLATE/include/LibDEFLATE/Utils.h b/LibDEFLATE/include/LibDEFLATE/Utils.h deleted file mode 100644 index ed4bef4..0000000 --- a/LibDEFLATE/include/LibDEFLATE/Utils.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include - -namespace LibDEFLATE -{ - - inline uint32_t calculate_adler32(BAN::ConstByteSpan data) - { - uint32_t s1 = 1; - uint32_t s2 = 0; - - for (size_t i = 0; i < data.size(); i++) - { - s1 = (s1 + data[i]) % 65521; - s2 = (s2 + s1) % 65521; - } - - return (s2 << 16) | s1; - } - - inline uint32_t calculate_crc32(BAN::ConstByteSpan data) - { - uint32_t crc32 = 0xFFFFFFFF; - uint32_t polynomial = 0xEDB88320; - - for (size_t i = 0; i < data.size(); i++) { - crc32 ^= data[i]; - - for (size_t j = 0; j < 8; j++) { - if (crc32 & 1) - crc32 = (crc32 >> 1) ^ polynomial; - else - crc32 >>= 1; - } - } - - return ~crc32; - } - - inline constexpr uint16_t reverse_bits(uint16_t value, size_t count) - { - uint16_t reverse = 0; - for (uint8_t bit = 0; bit < count; bit++) - reverse |= ((value >> bit) & 1) << (count - bit - 1); - return reverse; - } - -} diff --git a/LibFont/CMakeLists.txt b/LibFont/CMakeLists.txt deleted file mode 100644 index a2a9bd4..0000000 --- a/LibFont/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(LIBGUI_SOURCES - Font.cpp - PSF.cpp -) - -add_library(libfont ${LIBGUI_SOURCES}) -banan_link_library(libfont ban) - -banan_install_headers(libfont) -install(TARGETS libfont OPTIONAL) diff --git a/LibFont/Font.cpp b/LibFont/Font.cpp deleted file mode 100644 index c21b6cb..0000000 --- a/LibFont/Font.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include - -#include -#include - -#include -#include -#include -#include - -namespace LibFont -{ - - BAN::ErrorOr Font::load(BAN::StringView path) - { - BAN::Vector file_data; - - char path_buffer[PATH_MAX]; - strncpy(path_buffer, path.data(), path.size()); - path_buffer[path.size()] = '\0'; - - int fd = open(path_buffer, O_RDONLY); - if (fd == -1) - return BAN::Error::from_errno(errno); - BAN::ScopeGuard file_closer([fd] { close(fd); }); - - struct stat st; - if (fstat(fd, &st) == -1) - return BAN::Error::from_errno(errno); - TRY(file_data.resize(st.st_size)); - - ssize_t total_read = 0; - while (total_read < st.st_size) - { - ssize_t nread = read(fd, file_data.data() + total_read, st.st_size - total_read); - if (nread == -1) - return BAN::Error::from_errno(errno); - total_read += nread; - } - - return load(BAN::ConstByteSpan(file_data.span())); - } - - BAN::ErrorOr Font::load(BAN::ConstByteSpan font_data) - { - if (is_psf1(font_data)) - return TRY(parse_psf1(font_data)); - if (is_psf2(font_data)) - return TRY(parse_psf2(font_data)); - return BAN::Error::from_errno(ENOTSUP); - } - -} diff --git a/LibFont/PSF.cpp b/LibFont/PSF.cpp deleted file mode 100644 index 242b587..0000000 --- a/LibFont/PSF.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include -#include - -#include - -#define PSF1_MAGIC0 0x36 -#define PSF1_MAGIC1 0x04 -#define PSF1_MODE512 0x01 -#define PSF1_MODEHASTAB 0x02 -#define PSF1_MODEHASSEQ 0x04 -#define PSF1_STARTSEQ 0xFFFE -#define PSF1_SEPARATOR 0xFFFF - -#define PSF2_MAGIC0 0x72 -#define PSF2_MAGIC1 0xB5 -#define PSF2_MAGIC2 0x4A -#define PSF2_MAGIC3 0x86 -#define PSF2_HAS_UNICODE_TABLE 0x01 -#define PSF2_STARTSEQ 0xFE -#define PSF2_SEPARATOR 0xFF - -namespace LibFont -{ - - bool is_psf1(BAN::ConstByteSpan font_data) - { - if (font_data.size() < 2) - return false; - return font_data[0] == PSF1_MAGIC0 && font_data[1] == PSF1_MAGIC1; - } - - BAN::ErrorOr parse_psf1(BAN::ConstByteSpan font_data) - { - struct PSF1Header - { - uint8_t magic[2]; - uint8_t mode; - uint8_t char_size; - }; - - if (font_data.size() < sizeof(PSF1Header)) - return BAN::Error::from_errno(EINVAL); - const auto& header = font_data.as(); - - uint32_t glyph_count = header.mode & PSF1_MODE512 ? 512 : 256; - uint32_t glyph_size = header.char_size; - uint32_t glyph_data_size = glyph_size * glyph_count; - - if (font_data.size() < sizeof(PSF1Header) + glyph_data_size) - return BAN::Error::from_errno(EINVAL); - - BAN::Vector glyph_data; - TRY(glyph_data.resize(glyph_data_size)); - memcpy(glyph_data.data(), font_data.data() + sizeof(PSF1Header), glyph_data_size); - - BAN::HashMap glyph_offsets; - TRY(glyph_offsets.reserve(glyph_count)); - - bool codepoint_redef = false; - bool codepoint_sequence = false; - - if (header.mode & (PSF1_MODEHASTAB | PSF1_MODEHASSEQ)) - { - uint32_t current_index = sizeof(PSF1Header) + glyph_data_size; - - uint32_t glyph_index = 0; - while (current_index < font_data.size()) - { - uint16_t lo = font_data[current_index]; - uint16_t hi = font_data[current_index + 1]; - uint16_t codepoint = (hi << 8) | lo; - - if (codepoint == PSF1_STARTSEQ) - { - codepoint_sequence = true; - break; - } - else if (codepoint == PSF1_SEPARATOR) - { - glyph_index++; - } - else - { - if (glyph_offsets.contains(codepoint)) - codepoint_redef = true; - else - TRY(glyph_offsets.insert(codepoint, glyph_index * glyph_size)); - } - - current_index += 2; - } - } - else - { - for (uint32_t i = 0; i < glyph_count; i++) - TRY(glyph_offsets.insert(i, i * glyph_size)); - } - - if (codepoint_redef) - dwarnln("Font contains multiple definitions for same codepoint(s)"); - if (codepoint_sequence) - dwarnln("Font contains codepoint sequences (not supported)"); - - return Font(BAN::move(glyph_offsets), BAN::move(glyph_data), 8, header.char_size, 1); - } - - bool is_psf2(BAN::ConstByteSpan font_data) - { - if (font_data.size() < 4) - return false; - return font_data[0] == PSF2_MAGIC0 && font_data[1] == PSF2_MAGIC1 && font_data[2] == PSF2_MAGIC2 && font_data[3] == PSF2_MAGIC3; - } - - BAN::ErrorOr parse_psf2(BAN::ConstByteSpan font_data) - { - struct PSF2Header - { - uint8_t magic[4]; - BAN::LittleEndian version; - BAN::LittleEndian header_size; - BAN::LittleEndian flags; - BAN::LittleEndian glyph_count; - BAN::LittleEndian glyph_size; - BAN::LittleEndian height; - BAN::LittleEndian width; - }; - - if (font_data.size() < sizeof(PSF2Header)) - return BAN::Error::from_errno(EINVAL); - const auto& header = font_data.as(); - - uint32_t glyph_data_size = header.glyph_count * header.glyph_size; - - if (font_data.size() < glyph_data_size + header.header_size) - return BAN::Error::from_errno(EINVAL); - - BAN::Vector glyph_data; - TRY(glyph_data.resize(glyph_data_size)); - memcpy(glyph_data.data(), font_data.data() + header.header_size, glyph_data_size); - - BAN::HashMap glyph_offsets; - TRY(glyph_offsets.reserve(400)); - - bool invalid_utf = false; - bool codepoint_redef = false; - bool codepoint_sequence = false; - - uint8_t bytes[4] {}; - uint32_t byte_index = 0; - if (header.flags & PSF2_HAS_UNICODE_TABLE) - { - uint32_t glyph_index = 0; - for (uint32_t i = glyph_data_size + header.header_size; i < font_data.size(); i++) - { - uint8_t byte = font_data[i]; - - if (byte == PSF2_STARTSEQ) - { - codepoint_sequence = true; - break; - } - else if (byte == PSF2_SEPARATOR) - { - if (byte_index) - { - invalid_utf = true; - byte_index = 0; - } - glyph_index++; - } - else - { - ASSERT(byte_index < 4); - bytes[byte_index++] = byte; - - uint32_t len = BAN::UTF8::byte_length(bytes[0]); - - if (len == BAN::UTF8::invalid) - { - invalid_utf = true; - byte_index = 0; - } - else if (len == byte_index) - { - uint32_t codepoint = BAN::UTF8::to_codepoint(bytes); - if (codepoint == BAN::UTF8::invalid) - invalid_utf = true; - else if (glyph_offsets.contains(codepoint)) - codepoint_redef = true; - else - TRY(glyph_offsets.insert(codepoint, glyph_index * header.glyph_size)); - byte_index = 0; - } - } - } - } - else - { - for (uint32_t i = 0; i < header.glyph_count; i++) - TRY(glyph_offsets.insert(i, i * header.glyph_size)); - } - - if (invalid_utf) - dwarnln("Font contains invalid UTF-8 codepoint(s)"); - if (codepoint_redef) - dwarnln("Font contains multiple definitions for same codepoint(s)"); - if (codepoint_sequence) - dwarnln("Font contains codepoint sequences (not supported)"); - - return Font(BAN::move(glyph_offsets), BAN::move(glyph_data), header.width, header.height, header.glyph_size / header.height); - } - -} diff --git a/LibFont/TTF.cpp b/LibFont/TTF.cpp deleted file mode 100644 index 3a7ba41..0000000 --- a/LibFont/TTF.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -namespace LibFont -{ - - - -} diff --git a/LibFont/include/LibFont/Font.h b/LibFont/include/LibFont/Font.h deleted file mode 100644 index e2ae91a..0000000 --- a/LibFont/include/LibFont/Font.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace LibFont -{ - - class Font - { - public: - Font() = default; - Font(BAN::HashMap&& glyph_offsets, BAN::Vector&& glyph_data, uint32_t width, uint32_t height, uint32_t pitch) - : m_glyph_offsets(BAN::move(glyph_offsets)) - , m_glyph_data(BAN::move(glyph_data)) - , m_width(width) - , m_height(height) - , m_pitch(pitch) - { } - - static BAN::ErrorOr load(BAN::StringView path); - static BAN::ErrorOr load(BAN::ConstByteSpan font_data); -#if __is_kernel - static BAN::ErrorOr prefs(); -#endif - - uint32_t width() const { return m_width; } - uint32_t height() const { return m_height; } - uint32_t pitch() const { return m_pitch; } - - bool has_glyph(uint32_t codepoint) const { return glyph(codepoint) != nullptr; } - const uint8_t* glyph(uint32_t codepoint) const - { - auto it = m_glyph_offsets.find(codepoint); - if (it == m_glyph_offsets.end()) - return nullptr; - return m_glyph_data.data() + it->value; - } - - private: - BAN::HashMap m_glyph_offsets; - BAN::Vector m_glyph_data; - uint32_t m_width = 0; - uint32_t m_height = 0; - uint32_t m_pitch = 0; - }; - -} diff --git a/LibFont/include/LibFont/PSF.h b/LibFont/include/LibFont/PSF.h deleted file mode 100644 index 84f8df8..0000000 --- a/LibFont/include/LibFont/PSF.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace LibFont -{ - - bool is_psf1(BAN::ConstByteSpan); - BAN::ErrorOr parse_psf1(BAN::ConstByteSpan); - - bool is_psf2(BAN::ConstByteSpan); - BAN::ErrorOr parse_psf2(BAN::ConstByteSpan); - -} diff --git a/LibGUI/CMakeLists.txt b/LibGUI/CMakeLists.txt deleted file mode 100644 index da0bb0e..0000000 --- a/LibGUI/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -set(LIBGUI_SOURCES - MessageBox.cpp - Texture.cpp - Widget/Button.cpp - Widget/Grid.cpp - Widget/Label.cpp - Widget/RoundedWidget.cpp - Widget/TextArea.cpp - Widget/Widget.cpp - Window.cpp -) - -add_library(libgui ${LIBGUI_SOURCES}) -banan_link_library(libgui ban) -banan_link_library(libgui libfont) -banan_link_library(libgui libinput) - -banan_install_headers(libgui) -install(TARGETS libgui OPTIONAL) diff --git a/LibGUI/MessageBox.cpp b/LibGUI/MessageBox.cpp deleted file mode 100644 index b5a4519..0000000 --- a/LibGUI/MessageBox.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace LibGUI -{ - - BAN::ErrorOr MessageBox::create(BAN::StringView message, BAN::StringView title) - { - BAN::StringView ok_button = "OK"; - TRY(create(message, title, { &ok_button, 1 })); - return {}; - } - - BAN::ErrorOr MessageBox::create(BAN::StringView message, BAN::StringView title, BAN::Span buttons) - { - if (buttons.empty()) - return BAN::Error::from_errno(EINVAL); - - const uint32_t window_width = 300; - - auto root_widget = TRY(Widget::Widget::create({}, 0xFFFFFF, { 0, 0, window_width, 0 })); - - auto text_area = TRY(Widget::TextArea::create(root_widget, message, { 0, 0, window_width, 0})); - text_area->style().border_width = 0; - text_area->style().color_normal = Widget::Widget::color_invisible; - text_area->style().corner_radius = 0; - TRY(text_area->set_relative_geometry({ 0.0, 0.0, 1.0, 0.8 })); - text_area->show(); - - bool waiting = true; - size_t result = 0; - - auto button_area = TRY(Widget::Grid::create(root_widget, buttons.size(), 1)); - for (size_t i = 0; i < buttons.size(); i++) - { - auto button = TRY(Widget::Button::create(button_area, buttons[i])); - TRY(button_area->set_widget_position(button, i, 1, 0, 1)); - button->set_click_callback([&result, &waiting, i] { result = i; waiting = false; }); - button->show(); - } - TRY(button_area->set_relative_geometry({ 0.0, 0.8, 1.0, 0.2 })); - button_area->show(); - - const uint32_t button_height = 20; - const uint32_t window_height = text_area->get_required_height() + button_height; - - auto attributes = Window::default_attributes; - attributes.resizable = true; - - auto window = TRY(Window::create(window_width, window_height, title, attributes)); - TRY(window->set_root_widget(root_widget)); - window->set_close_window_event_callback([&waiting] { waiting = false; }); - - while (waiting) - { - window->wait_events(); - window->poll_events(); - } - - return result; - } - -} diff --git a/LibGUI/Texture.cpp b/LibGUI/Texture.cpp deleted file mode 100644 index 7620b77..0000000 --- a/LibGUI/Texture.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include -#include - -namespace LibGUI -{ - - BAN::ErrorOr Texture::create(uint32_t width, uint32_t height, uint32_t color) - { - if (BAN::Math::will_addition_overflow(width, height)) - return BAN::Error::from_errno(EOVERFLOW); - - BAN::Vector pixels; - TRY(pixels.resize(width * height, color)); - return Texture(BAN::move(pixels), width, height, color); - } - - BAN::ErrorOr Texture::resize(uint32_t new_width, uint32_t new_height) - { - if (BAN::Math::will_addition_overflow(new_width, new_height)) - return BAN::Error::from_errno(EOVERFLOW); - - BAN::Vector pixels; - TRY(pixels.resize(new_width * new_height, m_bg_color)); - - const uint32_t max_x = BAN::Math::min(new_width, m_width); - const uint32_t max_y = BAN::Math::min(new_height, m_height); - for (uint32_t y = 0; y < max_y; y++) - for (uint32_t x = 0; x < max_x; x++) - pixels[y * new_width + x] = m_pixels[y * m_width + x]; - - m_width = new_width; - m_height = new_height; - m_pixels = BAN::move(pixels); - - if (m_has_set_clip) - set_clip_area(m_clip_x, m_clip_y, m_clip_w, m_clip_h); - else - { - m_clip_w = new_width; - m_clip_h = new_height; - } - - return {}; - } - - void Texture::set_clip_area(int32_t x, int32_t y, uint32_t width, uint32_t height) - { - m_clip_x = 0; - m_clip_y = 0; - m_clip_w = this->width(); - m_clip_h = this->height(); - - - if (!clamp_to_texture(x, y, width, height)) - { - m_clip_h = 0; - m_clip_w = 0; - } - else - { - m_clip_x = x; - m_clip_y = y; - m_clip_w = width; - m_clip_h = height; - } - - m_has_set_clip = true; - } - - void Texture::fill_rect(int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t color) - { - if (!clamp_to_texture(x, y, width, height)) - return; - for (uint32_t y_off = 0; y_off < height; y_off++) - for (uint32_t x_off = 0; x_off < width; x_off++) - set_pixel(x + x_off, y + y_off, color); - } - - void Texture::copy_texture(const Texture& texture, int32_t x, int32_t y, uint32_t sub_x, uint32_t sub_y, uint32_t width, uint32_t height) - { - int32_t src_x = sub_x, src_y = sub_y; - if (!clamp_to_texture(x, y, src_x, src_y, width, height, texture)) - return; - sub_x = src_x; - sub_y = src_y; - - for (uint32_t y_off = 0; y_off < height; y_off++) - for (uint32_t x_off = 0; x_off < width; x_off++) - if (const uint32_t color = texture.get_pixel(sub_x + x_off, sub_y + y_off); color != color_invisible) - set_pixel(x + x_off, y + y_off, color); - } - - void Texture::draw_character(uint32_t codepoint, const LibFont::Font& font, int32_t tl_x, int32_t tl_y, uint32_t color) - { - if (tl_y + (int32_t)font.height() < 0 || tl_y >= (int32_t)height()) - return; - if (tl_x + (int32_t)font.width() < 0 || tl_x >= (int32_t)width()) - return; - - auto glyph = font.glyph(codepoint); - if (glyph == nullptr) - return; - - for (int32_t off_y = 0; off_y < (int32_t)font.height(); off_y++) - { - if (tl_y + off_y < 0) - continue; - uint32_t abs_y = tl_y + off_y; - if (abs_y >= height()) - break; - for (int32_t off_x = 0; off_x < (int32_t)font.width(); off_x++) - { - if (tl_x + off_x < 0) - continue; - uint32_t abs_x = tl_x + off_x; - if (abs_x >= width()) - break; - const uint8_t bitmask = 1 << (font.width() - off_x - 1); - if (glyph[off_y * font.pitch()] & bitmask) - set_pixel(abs_x, abs_y, color); - } - } - } - - void Texture::draw_text(BAN::StringView text, const LibFont::Font& font, int32_t tl_x, int32_t tl_y, uint32_t color) - { - for (size_t i = 0; i < text.size(); i++) - draw_character(text[i], font, tl_x + (int32_t)(i * font.width()), tl_y, color); - } - - void Texture::shift_vertical(int32_t amount) - { - const uint32_t amount_abs = BAN::Math::abs(amount); - if (amount_abs == 0 || amount_abs >= height()) - return; - - uint32_t* dst = (amount > 0) ? m_pixels.data() + width() * amount_abs : m_pixels.data(); - uint32_t* src = (amount < 0) ? m_pixels.data() + width() * amount_abs : m_pixels.data(); - memmove(dst, src, width() * (height() - amount_abs) * 4); - } - - void Texture::copy_horizontal_slice(int32_t dst_y, int32_t src_y, uint32_t uamount) - { - int32_t amount = uamount; - if (dst_y < 0) - { - amount -= -dst_y; - src_y += -dst_y; - dst_y = 0; - } - - amount = BAN::Math::min(amount, height() - dst_y); - if (amount <= 0) - return; - - const int32_t copy_src_y = BAN::Math::clamp(src_y, 0, height()); - const int32_t copy_amount = BAN::Math::clamp(src_y + amount, 0, height()) - copy_src_y; - if (copy_amount > 0) - { - memmove( - &m_pixels[width() * (dst_y + (copy_src_y - src_y))], - &m_pixels[width() * copy_src_y], - copy_amount * width() * 4 - ); - } - } - - void Texture::copy_rect(int32_t dst_x, int32_t dst_y, int32_t src_x, int32_t src_y, uint32_t width, uint32_t height) - { - if (!clamp_to_texture(dst_x, dst_y, src_x, src_y, width, height, *this)) - return; - - const bool copy_dir = dst_y < src_y; - for (uint32_t i = 0; i < height; i++) - { - const uint32_t y_off = copy_dir ? i : height - i - 1; - memmove( - &m_pixels[(dst_y + y_off) * this->width() + dst_x], - &m_pixels[(src_y + y_off) * this->width() + src_x], - width * 4 - ); - } - } - - bool Texture::clamp_to_texture(int32_t& signed_x, int32_t& signed_y, uint32_t& width, uint32_t& height) const - { - const int32_t min_x = BAN::Math::max(signed_x, m_clip_x); - const int32_t min_y = BAN::Math::max(signed_y, m_clip_y); - const int32_t max_x = BAN::Math::min(signed_x + (int32_t)width, m_clip_x + m_clip_w); - const int32_t max_y = BAN::Math::min(signed_y + (int32_t)height, m_clip_y + m_clip_h); - - if (min_x >= max_x) - return false; - if (min_y >= max_y) - return false; - - signed_x = min_x; - signed_y = min_y; - width = max_x - min_x; - height = max_y - min_y; - return true; - } - - bool Texture::clamp_to_texture(int32_t& dst_x, int32_t& dst_y, int32_t& src_x, int32_t& src_y, uint32_t& width, uint32_t& height, const Texture& texture) const - { - if (width > texture.width()) - width = texture.width(); - if (height > texture.height()) - height = texture.height(); - - if (dst_x >= static_cast(m_clip_x + m_clip_w)) - return false; - if (dst_y >= static_cast(m_clip_y + m_clip_h)) - return false; - - if (src_x >= static_cast(texture.width())) - return false; - if (src_y >= static_cast(texture.height())) - return false; - - if (dst_x + static_cast(width) > static_cast(m_clip_x + m_clip_w)) - width = m_clip_x + m_clip_w - dst_x; - if (src_x + static_cast(width) > static_cast(texture.width())) - width = texture.width() - src_x; - - if (dst_y + static_cast(height) > static_cast(m_clip_y + m_clip_h)) - height = m_clip_y + m_clip_h - dst_y; - if (src_y + static_cast(height) > static_cast(texture.height())) - height = texture.height() - src_y; - - int32_t off_x = 0; - if (dst_x < static_cast(m_clip_x)) - off_x = m_clip_x - dst_x; - if (src_x + off_x < 0) - off_x = -src_x; - if (off_x >= static_cast(width)) - return false; - - int32_t off_y = 0; - if (dst_y < static_cast(m_clip_y)) - off_y = m_clip_y - dst_y; - if (src_y + off_y < 0) - off_y = -src_y; - if (off_y >= static_cast(height)) - return false; - - dst_x += off_x; - src_x += off_x; - dst_y += off_y; - src_y += off_y; - - width -= off_x; - height -= off_y; - - return true; - } - -} diff --git a/LibGUI/Widget/Button.cpp b/LibGUI/Widget/Button.cpp deleted file mode 100644 index eeebc96..0000000 --- a/LibGUI/Widget/Button.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include - -namespace LibGUI::Widget -{ - - BAN::ErrorOr> Button::create(BAN::RefPtr parent, BAN::StringView text, Rectangle geometry) - { - auto* button_ptr = new Button(parent, geometry); - if (button_ptr == nullptr) - return BAN::Error::from_errno(ENOMEM); - auto button = BAN::RefPtr