Просмотр исходного кода

rewrite(string): new string class

remove types::string

the new string class supports on stack storage

use std::map for hash_map
greatbridf 11 месяцев назад
Родитель
Сommit
b4bb1feadf

+ 0 - 1
CMakeLists.txt

@@ -101,7 +101,6 @@ set(KERNEL_MAIN_SOURCES src/fs/fat.cpp
                         include/types/status.h
                         include/types/allocator.hpp
                         include/types/cplusplus.hpp
-                        include/types/string.hpp
                         include/kernel/log.hpp
                         )
 

+ 31 - 1
gblibstdc++/CMakeLists.txt

@@ -5,6 +5,36 @@ set(CMAKE_CXX_STANDARD 20)
 
 add_library(gblibstdc++ STATIC src/stdc++.cpp)
 
-file(GLOB_RECURSE GBSTDLIBCPP_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include)
+set(GBSTDLIBCPP_PUBLIC_HEADERS
+    gblibstdc++/include
+    gblibstdc++/include/bit
+    gblibstdc++/include/memory
+    gblibstdc++/include/tuple
+    gblibstdc++/include/type_traits
+    gblibstdc++/include/algorithm
+    gblibstdc++/include/cstddef
+    gblibstdc++/include/map
+    gblibstdc++/include/bits
+    gblibstdc++/include/bits/fwd_functional
+    gblibstdc++/include/bits/rbtree
+    gblibstdc++/include/bits/iter_ops
+    gblibstdc++/include/bits/type_traits
+    gblibstdc++/include/bits/type_traits/is_es
+    gblibstdc++/include/bits/type_traits/remove_add
+    gblibstdc++/include/bits/type_traits/base
+    gblibstdc++/include/bits/tuple_tools
+    gblibstdc++/include/bits/sequence
+    gblibstdc++/include/bits/forward
+    gblibstdc++/include/list
+    gblibstdc++/include/initializer_list
+    gblibstdc++/include/new
+    gblibstdc++/include/queue
+    gblibstdc++/include/string
+    gblibstdc++/include/set
+    gblibstdc++/include/vector
+    gblibstdc++/include/functional
+    gblibstdc++/include/utility
+    )
+
 target_include_directories(gblibstdc++ PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
 set_target_properties(gblibstdc++ PROPERTIES PUBLIC_HEADER "${GBSTDLIBCPP_PUBLIC_HEADERS}")

+ 3 - 3
gblibstdc++/include/bits/rbtree

@@ -237,9 +237,9 @@ struct rbtree {
         { p = p->prev(); return *this; }
         constexpr _iterator operator--(int)
         { _iterator ret(p); (void)this->operator--(); return ret; }
-        constexpr operator bool(void)
+        constexpr operator bool() const
         { return p; }
-        constexpr operator _iterator<true>()
+        constexpr operator _iterator<true>() const
         { return _iterator<true> { p }; }
     };
 
@@ -597,7 +597,7 @@ public:
         node* nextpos = erase(pos.p);
         delnode(pos.p);
         --_size;
-        return const_iterator { nextpos };
+        return iterator { nextpos };
     }
 
     template <typename U>

+ 540 - 0
gblibstdc++/include/string

@@ -0,0 +1,540 @@
+#ifndef __GBLIBCPP_STRING__
+#define __GBLIBCPP_STRING__
+
+#include <bits/iter_ops>
+
+#include <algorithm>
+#include <functional>
+#include <memory>
+#include <initializer_list>
+#include <cstddef>
+
+#include <string.h>
+
+namespace std {
+
+template <typename T>
+class char_traits;
+
+template <>
+class char_traits<char>
+{
+public:
+    static std::size_t length(const char* str) { return strlen(str); }
+
+    static int compare(const char* s1, const char* s2, std::size_t cnt)
+    {
+        return strncmp(s1, s2, cnt);
+    }
+};
+
+template <typename Char,
+         typename Traits = std::char_traits<Char>,
+         typename Allocator = std::allocator<Char>>
+class basic_string {
+public:
+    using traits_type = Traits;
+    using value_type = Char;
+    using allocator_type = Allocator;
+    using size_type = typename std::allocator_traits<Allocator>::size_type;
+    using difference_type = typename std::allocator_traits<Allocator>::difference_type;
+    using reference = value_type&;
+    using const_reference = const value_type&;
+    using pointer = typename std::allocator_traits<Allocator>::pointer;
+    using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
+
+    template <bool Const>
+    class _iterator {
+    public:
+        // TODO:
+        // using iterator_category = std::random_access_iterator_tag;
+        using _reference = std::conditional_t<Const, const_reference, reference>;
+
+    private:
+        pointer m_ptr;
+
+    public:
+        constexpr _iterator(void) noexcept : m_ptr() {}
+        constexpr explicit _iterator(pointer ptr) noexcept
+            : m_ptr(ptr) {}
+        constexpr _iterator(const _iterator& other) noexcept = default;
+        constexpr _iterator(_iterator&& other) noexcept = default;
+        constexpr _iterator& operator=(const _iterator& other) noexcept = default;
+        constexpr _iterator& operator=(_iterator&& other) noexcept = default;
+        constexpr bool operator==(const _iterator& other) const noexcept = default;
+
+        constexpr _reference operator*() const noexcept { return *m_ptr; }
+        constexpr pointer operator&() const noexcept
+        { return std::addressof(this->operator*()); }
+        constexpr pointer operator->() const noexcept
+        { return this->operator&(); }
+        constexpr _iterator& operator++() noexcept
+        { ++m_ptr; return *this; }
+        constexpr _iterator operator++(int) noexcept
+        { _iterator ret(m_ptr); (void)this->operator++(); return ret; }
+        constexpr _iterator& operator--(void) noexcept
+        { --m_ptr; return *this; }
+        constexpr _iterator operator--(int) noexcept
+        { _iterator ret(m_ptr); (void)this->operator--(); return ret; }
+        constexpr _iterator& operator+=(difference_type n) noexcept
+        { m_ptr += n; return *this; }
+        constexpr _iterator& operator-=(difference_type n) noexcept
+        { m_ptr -= n; return *this; }
+        constexpr _iterator operator+(difference_type n) const noexcept
+        { return _iterator { m_ptr + n }; }
+        constexpr _iterator operator-(difference_type n) const noexcept
+        { return _iterator { m_ptr - n }; }
+        constexpr difference_type operator-(const _iterator& other) const noexcept
+        { return m_ptr - other.m_ptr; }
+        constexpr _reference operator[](difference_type n) const noexcept
+        { return m_ptr[n]; }
+        constexpr operator bool() { return m_ptr; }
+        constexpr operator _iterator<true>() { return _iterator<true> { m_ptr }; }
+        constexpr operator _iterator<false>() { return _iterator<false> { m_ptr }; }
+        constexpr operator pointer() { return m_ptr; }
+    };
+
+private:
+    using alloc_traits = std::allocator_traits<Allocator>;
+
+public:
+    using iterator = _iterator<false>;
+    using const_iterator = _iterator<true>;
+
+private:
+    static constexpr std::size_t STATIC_SIZE = 32;
+    static constexpr std::size_t STATIC_COUNT =
+        STATIC_SIZE / sizeof(Char) - 2;
+
+    union {
+        std::byte __data[STATIC_SIZE];
+
+        struct {
+            union {
+                Char __data;
+                unsigned char n;
+            } m_size;
+            Char str[STATIC_COUNT];
+            Char end;
+        } stackdata;
+
+        struct {
+            std::size_t m_size;
+            std::size_t m_capacity;
+            Char* m_ptr;
+        } heapdata;
+
+    } m_data;
+    Allocator m_alloc;
+
+    constexpr bool _stack_data() const
+    {
+        return m_data.stackdata.end == 0;
+    }
+
+    constexpr bool _stack_data(bool val)
+    {
+        return (m_data.stackdata.end = !val), val;
+    }
+
+    constexpr void _release()
+    {
+        if (_stack_data()) {
+            _size(0);
+            return;
+        }
+
+        alloc_traits::deallocate(m_alloc, data(), capacity()+1);
+
+        _stack_data(true);
+        _size(0);
+        _data()[0] = 0;
+    }
+
+    constexpr void _reserve(std::size_t cnt)
+    {
+        std::size_t cursize = size();
+        Char* newdata = alloc_traits::allocate(m_alloc, cnt+1);
+
+        memcpy(newdata, data(), size());
+        newdata[cursize] = 0;
+
+        if (_stack_data()) {
+            _stack_data(false);
+            _size(cursize);
+        }
+        else {
+            alloc_traits::deallocate(m_alloc, data(), capacity()+1);
+        }
+
+        _capacity(cnt);
+        _data(newdata);
+    }
+
+    constexpr std::size_t _size() const
+    {
+        if (_stack_data())
+            return m_data.stackdata.m_size.n;
+        else
+            return m_data.heapdata.m_size;
+    }
+
+    constexpr std::size_t _size(std::size_t val)
+    {
+        if (_stack_data())
+            return m_data.stackdata.m_size.n = (Char)val;
+        else
+            return m_data.heapdata.m_size = val;
+    }
+
+    constexpr std::size_t _capacity() const
+    {
+        if (_stack_data())
+            return STATIC_COUNT;
+        else
+            return m_data.heapdata.m_capacity;
+    }
+
+    constexpr std::size_t _capacity(std::size_t val)
+    {
+        if (_stack_data())
+            return STATIC_COUNT;
+        else
+            return m_data.heapdata.m_capacity = val;
+    }
+
+    constexpr const Char* _data() const
+    {
+        if (_stack_data())
+            return m_data.stackdata.str;
+        else
+            return m_data.heapdata.m_ptr;
+    }
+
+    constexpr Char* _data()
+    {
+        if (_stack_data())
+            return m_data.stackdata.str;
+        else
+            return m_data.heapdata.m_ptr;
+    }
+
+    constexpr Char* _data(Char* val)
+    {
+        if (_stack_data())
+            return m_data.stackdata.str;
+        else
+            return m_data.heapdata.m_ptr = val;
+    }
+
+public:
+    constexpr basic_string() noexcept(noexcept(Allocator()))
+        : basic_string{Allocator{}} { }
+
+    constexpr explicit basic_string(const Allocator& alloc) noexcept
+        : m_data{}, m_alloc{alloc} { }
+
+    constexpr basic_string(const basic_string& other, const Allocator& alloc)
+        : basic_string{alloc}
+    {
+        append(other.c_str(), other.size());
+    }
+
+    constexpr basic_string(const basic_string& other)
+        : basic_string{other, alloc_traits::
+            select_on_container_copy_construction(other.m_alloc)} { }
+
+    constexpr basic_string(basic_string&& other) noexcept
+        : m_alloc{std::move(other.m_alloc)}
+    {
+        memcpy(&m_data, &other.m_data, sizeof(m_data));
+        other._stack_data(true);
+        other._size(0);
+        other._data()[0] = 0;
+    }
+
+    constexpr basic_string(basic_string&& other, const Allocator& alloc)
+        : basic_string{alloc}
+    {
+        if (alloc == other.m_alloc) {
+            memcpy(&m_data, &other.m_data, sizeof(m_data));
+            other._stack_data(true);
+            other._size(0);
+            other._data()[0] = 0;
+        }
+        else {
+            append(other.c_str(), other.size());
+        }
+    }
+
+    constexpr basic_string(const basic_string& other, size_type pos,
+            const Allocator& alloc = Allocator{})
+        : basic_string{other.c_str() + pos, alloc} { }
+
+    // constexpr basic_string(std::initializer_list<Char> ilist,
+    //         const Allocator& alloc = Allocator{})
+    //     : basic_string {alloc}
+    // {
+    //     assign(ilist.begin(), ilist.end());
+    // }
+
+    constexpr basic_string(const Char* str, size_type count,
+            const Allocator& alloc = Allocator{})
+        : basic_string{alloc}
+    {
+        assign(str, count);
+    }
+
+    constexpr basic_string(const Char* str, const Allocator& alloc = Allocator{})
+        : basic_string{str, traits_type::length(str), alloc} { }
+
+    constexpr ~basic_string()
+    {
+        _release();
+    }
+
+    constexpr basic_string& operator=(const Char* str)
+    {
+        return assign(str);
+    }
+
+    constexpr basic_string& operator=(const basic_string& other)
+    {
+        return assign(other.c_str(), other.size());
+    }
+
+    constexpr basic_string& operator=(basic_string&& other)
+    {
+        if constexpr (alloc_traits::
+                propagate_on_container_move_assignment::value) {
+            _release();
+            m_alloc = std::move(other.m_alloc);
+        }
+        else {
+            if (m_alloc != other.m_alloc) {
+                assign(other.c_str(), other.size());
+                return *this;
+            }
+            _release();
+        }
+
+        memcpy(&m_data, &other.m_data, sizeof(m_data));
+        other._stack_data(true);
+        other._size(0);
+        other._data()[0] = 0;
+
+        return *this;
+    }
+
+    constexpr basic_string& operator=(Char ch)
+    {
+        return assign(1, ch);
+    }
+
+    // constexpr basic_string& operator=(std::initializer_list<Char> init)
+    // {
+    //     assign(init.begin(), init.end());
+    //     return *this;
+    // }
+
+    constexpr basic_string& append(std::size_t len, Char ch)
+    {
+        std::size_t cursize = size();
+        std::size_t newsize = cursize + len;
+
+        if (newsize > capacity())
+            _reserve(std::max(capacity() * 2, newsize));
+
+        auto* pdata = data();
+        for (std::size_t i = cursize; i < newsize; ++i)
+            pdata[i] = ch;
+        pdata[newsize] = 0;
+
+        _size(newsize);
+
+        return *this;
+    }
+
+    constexpr basic_string& append(const Char* str, std::size_t count)
+    {
+        std::size_t cursize = size();
+        std::size_t newsize = cursize + count;
+
+        if (newsize > capacity())
+            _reserve(std::max(capacity() * 2, newsize));
+
+        memcpy(data() + cursize, str, count);
+        data()[newsize] = 0;
+
+        _size(newsize);
+
+        return *this;
+    }
+
+    constexpr basic_string& append(const Char* str)
+    {
+        return append(str, traits_type::length(str));
+    }
+
+    constexpr basic_string& assign(size_type n, Char ch)
+    {
+        clear();
+        return append(n, ch);
+    }
+
+    constexpr basic_string& assign(const Char* str, size_type count)
+    {
+        clear();
+        return append(str, count);
+    }
+
+    constexpr basic_string& assign(const Char* str)
+    {
+        return assign(str, traits_type::length(str));
+    }
+
+    // TODO: check whether InputIter satisfies LegacyInputIterator
+    // template <typename InputIter>
+    // constexpr basic_string& assign(InputIter first, InputIter last)
+    // {
+    //     clear();
+    //     insert(cbegin(), first, last);
+    //     return *this;
+    // }
+    // constexpr basic_string& assign(std::initializer_list<T> init)
+    // {
+    //     clear();
+    //     insert(cbegin(), init.begin(), init.end());
+    //     return *this;
+    // }
+
+    constexpr basic_string& operator+=(Char ch)
+    {
+        return append(1, ch);
+    }
+
+    constexpr basic_string& operator+=(const Char* str)
+    {
+        return append(str);
+    }
+
+    constexpr basic_string& operator+=(const basic_string& str)
+    {
+        return append(str.c_str(), str.size());
+    }
+
+    constexpr bool empty() const noexcept
+    { return size() == 0; }
+    constexpr size_type size() const noexcept
+    { return _size(); }
+    constexpr size_type capacity() const noexcept
+    { return _capacity(); }
+
+    constexpr Char* data() noexcept { return _data(); }
+    constexpr const Char* data() const noexcept { return _data(); }
+    constexpr const Char* c_str() const noexcept { return data(); }
+
+    constexpr reference operator[](size_type pos)
+    { return data()[pos]; }
+    constexpr const_reference operator[](size_type pos) const
+    { return data()[pos]; }
+
+    // constexpr reference at(size_type pos)
+    // {
+    //     // TODO: exceptions
+    //     // if (pos >= size())
+    //     //     throw std::out_of_range("basic_string::at");
+    //     return operator[](pos);
+    // }
+    // constexpr const_reference at(size_type pos) const
+    // {
+    //     // TODO: exceptions
+    //     // if (pos >= size())
+    //     //     throw std::out_of_range("basic_string::at");
+    //     return operator[](pos);
+    // }
+
+    constexpr reference front() noexcept
+    { return operator[](0); }
+    constexpr const_reference front() const noexcept
+    { return operator[](0); }
+    constexpr reference back() noexcept
+    { return operator[](size() - 1); }
+    constexpr const_reference back() const noexcept
+    { return operator[](size() - 1); }
+
+    // TODO: std::reverse_iterator
+    constexpr iterator begin() noexcept
+    { return iterator { data() }; }
+    constexpr const_iterator begin() const noexcept
+    { return const_iterator { data() }; }
+    constexpr const_iterator cbegin() const noexcept
+    { return const_iterator { data() }; }
+    constexpr iterator end() noexcept
+    { return iterator { data() + size() }; }
+    constexpr const_iterator end() const noexcept
+    { return const_iterator { data() + size() }; }
+    constexpr const_iterator cend() const noexcept
+    { return const_iterator { data() + size() }; }
+
+    constexpr void clear() noexcept{ _size(0); }
+
+    constexpr void push_back(Char ch) { append(1, ch); }
+    constexpr void pop_back() { erase(cend()-1); }
+
+    constexpr void swap(basic_string& other) noexcept(
+        alloc_traits::propagate_on_container_swap::value
+        || alloc_traits::is_always_equal::value)
+    {
+        if (alloc_traits::propagate_on_container_swap::value)
+            std::swap(m_alloc, other.m_alloc);
+        std::swap(m_data, other.m_data);
+    }
+
+    constexpr int compare(const basic_string& str) const noexcept
+    {
+        return traits_type::compare(c_str(), str.c_str(), size());
+    }
+
+    constexpr int compare(const Char* str) const
+    {
+        return traits_type::compare(c_str(), str, size());
+    }
+};
+
+template <typename Char, typename Traits, typename Allocator>
+constexpr bool operator==(
+    const std::basic_string<Char, Traits, Allocator>& lhs,
+    const std::basic_string<Char, Traits, Allocator>& rhs) noexcept
+{
+    return lhs.compare(rhs) == 0;
+}
+
+template <typename Char, typename Traits, typename Allocator>
+constexpr bool operator==(
+    const std::basic_string<Char, Traits, Allocator>& lhs, const Char* rhs)
+{
+    return lhs.compare(rhs) == 0;
+}
+
+template <typename Char, typename Traits, typename Allocator>
+constexpr bool operator<(
+    const std::basic_string<Char, Traits, Allocator>& lhs,
+    const std::basic_string<Char, Traits, Allocator>& rhs) noexcept
+{
+    return lhs.compare(rhs) < 0;
+}
+
+template <typename Char, typename Traits, typename Allocator>
+constexpr void swap(
+    std::basic_string<Char, Traits, Allocator>& lhs,
+    std::basic_string<Char, Traits, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)))
+{
+    lhs.swap(rhs);
+}
+
+using string = basic_string<char>;
+
+} // namespace std
+
+#endif

+ 3 - 3
include/kernel/task/thread.hpp

@@ -1,11 +1,11 @@
 #pragma once
 
 #include <cstddef>
+#include <string>
 
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <types/string.hpp>
 #include <types/types.h>
 
 #include <kernel/signal.hpp>
@@ -45,11 +45,11 @@ public:
     int* __user set_child_tid {};
     int* __user clear_child_tid {};
 
-    types::string<> name {};
+    std::string name {};
 
     segment_descriptor tls_desc {};
 
-    explicit thread(types::string<> name, pid_t owner);
+    explicit thread(std::string name, pid_t owner);
     thread(const thread& val, pid_t owner);
 
     int set_thread_area(user::user_desc* ptr);

+ 2 - 2
include/kernel/vfs/dentry.hpp

@@ -1,8 +1,8 @@
 #pragma once
 
 #include <list>
+#include <string>
 
-#include <types/string.hpp>
 #include <types/hash_map.hpp>
 #include <types/path.hpp>
 
@@ -12,7 +12,7 @@ namespace fs {
 
 struct dentry {
 public:
-    using name_type = types::string<>;
+    using name_type = std::string;
 
 private:
     std::list<dentry>* children = nullptr;

+ 42 - 59
include/types/hash_map.hpp

@@ -1,15 +1,15 @@
 #pragma once
 #include <assert.h>
-#include <list>
-#include <vector>
 #include <bit>
-#include <utility>
+#include <map>
+#include <string>
 #include <type_traits>
+#include <utility>
+#include <vector>
 
 #include <stdint.h>
 #include <types/allocator.hpp>
 #include <types/cplusplus.hpp>
-#include <types/string.hpp>
 #include <types/types.h>
 
 namespace types {
@@ -31,33 +31,26 @@ static inline constexpr hash_t hash32(uint32_t val, uint32_t bits)
     return _hash32(val) >> (32 - bits);
 }
 
-template <typename T, typename = void>
-struct linux_hasher {};
-
 template <typename T>
-inline constexpr bool is_c_string_v = std::is_same_v<std::decay_t<T>, char*>
+constexpr bool is_c_string_v = std::is_same_v<std::decay_t<T>, char*>
     || std::is_same_v<std::decay_t<T>, const char*>;
 
-template <typename T>
-struct linux_hasher<T, std::enable_if_t<std::is_convertible_v<T, uint32_t>>> {
-    static inline constexpr hash_t hash(T val, uint32_t bits)
-    {
-        return hash32(static_cast<uint32_t>(val), bits);
-    }
-};
-template <typename T>
-struct linux_hasher<T,
-    std::enable_if_t<std::is_pointer_v<T> && !is_c_string_v<T>>> {
-    static inline constexpr hash_t hash(T val, uint32_t bits)
-    {
-        return hash32(std::bit_cast<uint32_t>(val), bits);
-    }
-};
+template <typename T,
+    std::enable_if_t<std::is_convertible_v<T, uint32_t>, bool> = true>
+inline hash_t hash(T val, std::size_t bits)
+{
+    return hash32(static_cast<uint32_t>(val), bits);
+}
 
-template <typename T>
-struct linux_hasher<T, std::enable_if_t<is_c_string_v<T>>> {
-    static inline constexpr hash_t hash(const char* str, uint32_t bits)
-    {
+template <typename T,
+    std::enable_if_t<std::is_pointer_v<T> && !is_c_string_v<T>, bool> = true>
+inline hash_t hash(T val, std::size_t bits)
+{
+    return hash32(std::bit_cast<uint32_t>(val), bits);
+}
+
+inline hash_t hash(const char* str, std::size_t bits)
+{
         constexpr uint32_t seed = 131;
         uint32_t hash = 0;
 
@@ -65,31 +58,25 @@ struct linux_hasher<T, std::enable_if_t<is_c_string_v<T>>> {
             hash = hash * seed + (*str++);
 
         return hash32(hash, bits);
-    }
 };
-template <template <typename> typename String, typename Allocator>
-struct linux_hasher<String<Allocator>,
+
+template <template <typename, typename, typename> typename String,
+    typename Char, typename Traits, typename Allocator,
     std::enable_if_t<
         std::is_same_v<
-            std::decay_t<String<Allocator>>, types::string<Allocator>
-        >
-    >
-> {
-    static inline constexpr hash_t hash(types::string<Allocator>&& str, uint32_t bits)
-    {
-        return linux_hasher<const char*>::hash(str.c_str(), bits);
-    }
-    static inline constexpr hash_t hash(const types::string<Allocator>& str, uint32_t bits)
-    {
-        return linux_hasher<const char*>::hash(str.c_str(), bits);
-    }
-};
+            std::decay_t<String<Char, Traits, Allocator>>,
+            std::basic_string<Char, Traits, Allocator>
+        >, bool
+    > = true>
+inline hash_t hash(const String<Char, Traits, Allocator>& str, std::size_t bits)
+{
+    return hash(str.c_str(), bits);
+}
 
 template <typename Key, typename Value,
-    template <typename _Key, typename...> class Hasher = types::linux_hasher,
     typename Allocator = std::allocator<std::pair<const Key, Value> >,
     std::enable_if_t<std::is_convertible_v<hash_t, decltype(
-        Hasher<Key>::hash(std::declval<Key>(), std::declval<uint32_t>())
+        hash(std::declval<Key>(), std::declval<std::size_t>())
     )>, bool> = true>
 class hash_map {
 public:
@@ -98,18 +85,17 @@ public:
 
     using key_type = std::add_const_t<Key>;
     using value_type = Value;
-    using pair_type = std::pair<key_type, value_type>;
     using size_type = size_t;
     using difference_type = ssize_t;
     using iterator_type = iterator<false>;
     using const_iterator_type = iterator<true>;
 
-    using bucket_type = std::list<pair_type, Allocator>;
+    using bucket_type = std::map<key_type,
+          value_type,std::less<key_type>, Allocator>;
+
     using bucket_array_type = std::vector<bucket_type, typename
         std::allocator_traits<Allocator>:: template rebind_alloc<bucket_type>>;
 
-    using hasher_type = Hasher<Key>;
-
     static constexpr size_type INITIAL_BUCKETS_ALLOCATED = 64;
 
 public:
@@ -250,16 +236,13 @@ public:
         buckets.clear();
     }
 
-    constexpr void emplace(pair_type p)
+    template <typename... Args>
+    constexpr void emplace(Args&&... args)
     {
-        auto hash_value = hasher_type::hash(p.first, hash_length());
-        buckets.at(hash_value).push_back(std::move(p));
-    }
+        std::pair<Key, Value> to_insert{std::forward<Args>(args)...};
 
-    template <typename _key_type, typename _value_type>
-    constexpr void emplace(_key_type&& key, _value_type&& value)
-    {
-        emplace(std::make_pair(std::forward<_key_type>(key), std::forward<_value_type>(value)));
+        auto hash_value = hash(to_insert.first, hash_length());
+        buckets.at(hash_value).emplace(to_insert);
     }
 
     constexpr void remove(const_iterator_type iter)
@@ -284,7 +267,7 @@ public:
 
     constexpr iterator_type find(const key_type& key)
     {
-        auto hash_value = hasher_type::hash(key, hash_length());
+        auto hash_value = hash(key, hash_length());
         auto& bucket = buckets.at(hash_value);
         for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) {
             if (key == iter->first)
@@ -295,7 +278,7 @@ public:
 
     constexpr const_iterator_type find(const key_type& key) const
     {
-        auto hash_value = hasher_type::hash(key, hash_length());
+        auto hash_value = hash(key, hash_length());
         const auto& bucket = buckets.at(hash_value);
         for (auto iter = bucket.cbegin(); iter != bucket.cend(); ++iter) {
             if (key == iter->first)

+ 4 - 4
include/types/path.hpp

@@ -1,16 +1,16 @@
 #pragma once
 
-#include <types/string.hpp>
-#include <vector>
 #include <cstddef>
+#include <string>
+#include <vector>
 
 namespace types {
 
 class path {
 public:
-    using item_string = types::string<>;
+    using item_string = std::string;
     using item_vector = std::vector<item_string>;
-    using string_type = types::string<>;
+    using string_type = std::string;
     using size_type = std::size_t;
     using iterator = item_vector::const_iterator;
 

+ 0 - 101
include/types/string.hpp

@@ -1,101 +0,0 @@
-#pragma once
-
-#include <vector>
-
-#include <string.h>
-#include <types/allocator.hpp>
-#include <types/types.h>
-
-namespace types {
-
-template <typename Allocator = std::allocator<char>>
-class string : public std::vector<char, Allocator> {
-public:
-    using _vector = std::vector<char, Allocator>;
-    using size_type = typename _vector::size_type;
-    using iterator = typename _vector::iterator;
-    using const_iterator = typename _vector::const_iterator;
-
-    static constexpr size_type npos = -1U;
-
-public:
-    constexpr string()
-        : _vector()
-    {
-        this->reserve(8);
-        this->push_back(0x00);
-    }
-    constexpr string(const char* str, size_type n = npos)
-        : string()
-    {
-        this->append(str, n);
-    }
-    constexpr string& append(const char* str, size_type n = npos)
-    {
-        size_type len = strlen(str);
-        const char* last = str + (len < n ? len : n);
-        this->insert(end(), str, last);
-        return *this;
-    }
-    constexpr string& append(const string& str)
-    {
-        return this->append(str.data());
-    }
-    constexpr string& operator+=(const char c)
-    {
-        this->insert(this->end(), c);
-        return *this;
-    }
-    constexpr string& operator+=(const char* str)
-    {
-        return this->append(str);
-    }
-    constexpr string& operator+=(const string& str)
-    {
-        return this->append(str);
-    }
-    constexpr bool operator==(const string& rhs) const
-    {
-        return strcmp(c_str(), rhs.c_str()) == 0;
-    }
-    constexpr string& assign(const char* str, size_type n = npos)
-    {
-        this->clear();
-        return this->append(str, n);
-    }
-    constexpr string substr(size_type pos, size_type n = npos)
-    {
-        return string(this->m_arr + pos, n);
-    }
-    constexpr const char* c_str(void) const noexcept
-    {
-        return this->data();
-    }
-    constexpr void clear()
-    {
-        _vector::clear();
-        this->push_back(0x00);
-    }
-    constexpr char pop(void)
-    {
-        this->pop_back();
-        auto& ref = _vector::back();
-        char c = ref;
-        ref = 0x00;
-        return c;
-    }
-    constexpr iterator end() noexcept
-    { return --_vector::end(); }
-    constexpr const_iterator end() const noexcept
-    { return --_vector::cend(); }
-    constexpr const_iterator cend() const noexcept
-    { return --_vector::cend(); }
-    constexpr char back() const noexcept
-    { return *--cend(); }
-    constexpr size_type size() const noexcept
-    { return _vector::size() - 1; }
-    constexpr bool empty() const noexcept
-    { return _vector::size() == 1; }
-};
-
-} // namespace types

+ 2 - 1
src/fs/fat.cpp

@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <string>
 
 #include <assert.h>
 #include <ctype.h>
@@ -120,7 +121,7 @@ int fat32::readdir(fs::inode* dir, size_t offset, const fs::vfs::filldir_func& f
                 ind->nlink = d->attributes.subdir ? 2 : 1;
             }
 
-            types::string<> fname;
+            std::string fname;
             for (int i = 0; i < 8; ++i) {
                 if (d->filename[i] == ' ')
                     break;

+ 1 - 1
src/kernel/mem.cpp

@@ -518,7 +518,7 @@ struct mapped_area {
     void* ptr;
 };
 
-static types::hash_map<page_t, mapped_area, types::linux_hasher,
+static types::hash_map<page_t, mapped_area,
     types::memory::ident_allocator<std::pair<page_t, mapped_area>>>
     mapped;
 static uint8_t _freebm[0x400 / 8];

+ 0 - 1
src/kernel/syscall.cpp

@@ -40,7 +40,6 @@
 #include <types/elf.hpp>
 #include <types/path.hpp>
 #include <types/status.h>
-#include <types/string.hpp>
 #include <types/types.h>
 
 #define SYSCALL_NO ((data)->s_regs.eax)

+ 1 - 1
src/kernel/task/thread.cc

@@ -10,7 +10,7 @@
 
 using namespace kernel::task;
 
-thread::thread(types::string<> name, pid_t owner)
+thread::thread(std::string name, pid_t owner)
     : owner { owner }, attr { READY | SYSTEM }, name { name }
 {
 }

+ 8 - 8
src/kernel/vfs.cpp

@@ -1,15 +1,16 @@
+#include <bit>
 #include <cstddef>
 #include <map>
-#include <sys/types.h>
-#include <vector>
-#include <bit>
+#include <string>
 #include <utility>
+#include <vector>
 
-#include <bits/alltypes.h>
 #include <assert.h>
+#include <bits/alltypes.h>
 #include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <sys/types.h>
 
 #include <kernel/log.hpp>
 #include <kernel/mem.h>
@@ -17,9 +18,8 @@
 #include <kernel/tty.hpp>
 #include <kernel/vfs.hpp>
 #include <types/allocator.hpp>
-#include <types/status.h>
 #include <types/path.hpp>
-#include <types/string.hpp>
+#include <types/status.h>
 
 using fs::vfs, fs::dentry;
 
@@ -597,11 +597,11 @@ int fs::register_char_device(dev_t node, const fs::chrdev_ops& ops)
     return 0;
 }
 
-static std::list<std::pair<types::string<>, fs::create_fs_func_t>> fs_list;
+static std::list<std::pair<std::string, fs::create_fs_func_t>> fs_list;
 
 int fs::register_fs(const char* name, fs::create_fs_func_t func)
 {
-    fs_list.push_back({ {name}, func });
+    fs_list.push_back({ name, func });
 
     return 0;
 }

+ 7 - 5
src/types/elf.cpp

@@ -1,15 +1,17 @@
+#include <string>
 #include <vector>
 
 #include <assert.h>
 #include <errno.h>
-#include <kernel/mem.h>
-#include <kernel/process.hpp>
-#include <kernel/vfs.hpp>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
+
 #include <types/elf.hpp>
-#include <types/string.hpp>
+
+#include <kernel/mem.h>
+#include <kernel/process.hpp>
+#include <kernel/vfs.hpp>
 
 #define align16_down(sp) (sp = ((char*)((uint32_t)(sp)&0xfffffff0)))
 
@@ -78,7 +80,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     }
 
     // copy argv and envp
-    std::vector<string<>> argv, envp;
+    std::vector<std::string> argv, envp;
     for (const char* const* p = d->argv; *p; ++p)
         argv.emplace_back(*p);
     for (const char* const* p = d->envp; *p; ++p)