Procházet zdrojové kódy

feat(libstdc++): add vector

greatbridf před 1 rokem
rodič
revize
2355016228

+ 0 - 1
CMakeLists.txt

@@ -86,7 +86,6 @@ set(KERNEL_MAIN_SOURCES src/fs/fat.cpp
                         include/types/cplusplus.hpp
                         include/types/lock.hpp
                         include/types/string.hpp
-                        include/types/vector.hpp
                         include/kernel/log.hpp
                         )
 

+ 122 - 0
gblibstdc++/include/initializer_list

@@ -0,0 +1,122 @@
+#ifndef __GBLIBCPP_INITIALIZER_LIST__
+#define __GBLIBCPP_INITIALIZER_LIST__
+
+#include <cstddef>
+
+namespace std {
+
+#if defined(__GNUC__)
+
+template <typename T>
+class initializer_list {
+public:
+    using value_type = T;
+    using reference = const T&;
+    using const_reference = const T&;
+    using size_type = std::size_t;
+    using iterator = const T*;
+    using const_iterator = const T*;
+
+private:
+    const T* __begin;
+    std::size_t __size;
+
+public:
+    constexpr initializer_list() noexcept
+        : __begin { }, __size { } { };
+
+    constexpr const T* begin() const noexcept
+    { return __begin; }
+    constexpr const T* end() const noexcept
+    { return __begin + __size; }
+    constexpr size_type size() const noexcept
+    { return __size; }
+
+};
+
+#elif defined(__clang__)
+
+template <typename T>
+class initializer_list {
+public:
+    using value_type = T;
+    using reference = const T&;
+    using const_reference = const T&;
+    using size_type = std::size_t;
+    using iterator = const T*;
+    using const_iterator = const T*;
+
+private:
+    const T* __begin;
+    const T* __end;
+
+public:
+    constexpr initializer_list() noexcept
+        : __begin { }, __end { } { };
+
+    constexpr const T* begin() const noexcept
+    { return __begin; }
+    constexpr const T* end() const noexcept
+    { return __end; }
+    constexpr size_type size() const noexcept
+    { return static_cast<size_type>(__end - __begin); }
+
+};
+
+#elif defined(_MSC_VER)
+
+template <typename T>
+class initializer_list {
+public:
+    using value_type = T;
+    using reference = const T&;
+    using const_reference = const T&;
+    using size_type = std::size_t;
+    using iterator = const T*;
+    using const_iterator = const T*;
+
+private:
+    const T* __begin;
+    const T* __end;
+
+public:
+    constexpr initializer_list() noexcept
+        : __begin { }, __end { } { };
+
+    constexpr const T* begin() const noexcept
+    { return __begin; }
+    constexpr const T* end() const noexcept
+    { return __end; }
+    constexpr size_type size() const noexcept
+    { return static_cast<size_type>(__end - __begin); }
+
+};
+
+#else
+
+template <typename T>
+class initializer_list;
+
+#endif
+
+template <typename T>
+constexpr const T* begin(initializer_list<T> il) noexcept
+{ return il.begin(); }
+
+template <typename T>
+constexpr const T* end(initializer_list<T> il) noexcept
+{ return il.end(); }
+
+template <typename T>
+[[nodiscard]] constexpr bool empty(initializer_list<T> il) noexcept
+{ return il.size() == 0; }
+
+template <typename T>
+constexpr const T* data(initializer_list<T> il) noexcept
+{ return il.begin(); }
+
+// TODO: std::rbegin() and std::rend() for std::initializer_list
+
+} // namespace std
+
+#endif

+ 13 - 0
gblibstdc++/include/memory

@@ -234,6 +234,17 @@ template <typename Alloc>
 using allocator_prop_swap_t =
     typename allocator_prop_swap<Alloc>::type;
 
+template <typename Alloc, typename = void>
+struct is_always_equal
+{ using type = std::false_type; };
+template <typename Alloc>
+struct is_always_equal<Alloc,
+    std::void_t<typename Alloc::is_always_equal>>
+{ using type = typename Alloc::is_always_equal; };
+template <typename Alloc>
+using is_always_equal_t =
+    typename is_always_equal<Alloc>::type;
+
 template <typename Alloc, typename = void>
 struct allocator_select_on_copy {
     static constexpr Alloc get(const Alloc& alloc)
@@ -326,6 +337,8 @@ struct allocator_traits {
         __helpers::allocator_prop_move_t<Allocator>;
     using propagate_on_container_swap =
         __helpers::allocator_prop_swap_t<Allocator>;
+    using is_always_equal =
+        __helpers::is_always_equal_t<Allocator>;
 
     template <typename T>
     using rebind_alloc =

+ 483 - 0
gblibstdc++/include/vector

@@ -0,0 +1,483 @@
+#ifndef __GBLIBCPP_VECTOR__
+#define __GBLIBCPP_VECTOR__
+
+#include <functional>
+#include <memory>
+#include <initializer_list>
+#include <cstddef>
+
+namespace std {
+
+template <typename T, typename Allocator = std::allocator<T>>
+class vector {
+public:
+    using value_type = T;
+    using allocator_type = Allocator;
+    using size_type = std::size_t;
+    using difference_type = std::ptrdiff_t;
+    using reference = T&;
+    using const_reference = const T&;
+
+    template <bool Const>
+    class _iterator {
+    public:
+        // TODO:
+        // using iterator_category = std::random_access_iterator_tag;
+        using value_type = std::conditional_t<Const, const T, T>;
+        using difference_type = std::ptrdiff_t;
+        using pointer = std::add_pointer_t<value_type>;
+        using reference = std::add_lvalue_reference_t<value_type>;
+
+    private:
+        T* m_ptr;
+
+    public:
+        constexpr _iterator(void) noexcept : m_ptr() {}
+        constexpr explicit _iterator(const T* ptr) noexcept
+            : m_ptr(const_cast<T*>(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 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 const T*() { return m_ptr; }
+    };
+
+private:
+    using alloc_traits = std::allocator_traits<Allocator>;
+
+public:
+    using pointer = typename alloc_traits::pointer;
+    using const_pointer = typename alloc_traits::const_pointer;
+    using iterator = _iterator<false>;
+    using const_iterator = _iterator<true>;
+
+private:
+    T* m_data;
+    size_type m_size;
+    size_type m_capacity;
+    allocator_type m_alloc;
+
+private:
+    // assert(n >= m_size)
+    constexpr void _reallocate_safe(size_type n)
+    {
+        auto* newptr = alloc_traits::allocate(m_alloc, n);
+        for (size_t i = 0; i < m_size; ++i) {
+            alloc_traits::construct(m_alloc, newptr + i, std::move(m_data[i]));
+            alloc_traits::destroy(m_alloc, m_data + i);
+        }
+
+        alloc_traits::deallocate(m_alloc, m_data, m_capacity);
+        m_data = newptr;
+        m_capacity = n;
+    }
+
+    // make m_capacity >= n >= m_size
+    constexpr void _pre_resize(size_type n)
+    {
+        if (n < m_size) {
+            while (n < m_size)
+                pop_back();
+        }
+        else if (n > m_size) {
+            reserve(n);
+        }
+    }
+
+public:
+    constexpr vector(void)
+        noexcept(noexcept(Allocator()))
+        : m_data(), m_size(), m_capacity(), m_alloc() {}
+
+    constexpr explicit vector(const Allocator& alloc) noexcept
+        : m_data(), m_size(), m_capacity(), m_alloc(alloc) {}
+
+    constexpr vector(size_type n, const T& val,
+        const Allocator& alloc = Allocator())
+        : vector(alloc) { resize(n, val); }
+
+    constexpr explicit vector(size_type n,
+        const Allocator& alloc = Allocator())
+        : vector(alloc) { resize(n); }
+
+    // TODO: check whether InputIter satisfies LegacyInputIterator
+    template <typename InputIter>
+    constexpr vector(InputIter first, InputIter last,
+        const Allocator& alloc = Allocator())
+        : vector(alloc) { insert(cbegin(), first, last); }
+
+    constexpr vector(const vector& other)
+        : vector(std::allocator_traits<allocator_type>::
+            select_on_container_copy_construction(other.m_alloc))
+    { insert(cbegin(), other.begin(), other.end()); }
+
+    constexpr vector(const vector& other, const Allocator& alloc)
+        : vector(alloc) { insert(cbegin(), other.begin(), other.end()); }
+
+    constexpr vector(vector&& other) noexcept
+        : m_data(std::exchange(other.m_data, nullptr))
+        , m_size(std::exchange(other.m_size, 0))
+        , m_capacity(std::exchange(other.m_capacity, 0))
+        , m_alloc(std::move(other.m_alloc)) {}
+    
+    constexpr vector(vector&& other, const Allocator& alloc)
+        : vector(alloc)
+    {
+        if (alloc == other.get_allocator()) {
+            m_data = std::exchange(other.m_data, nullptr);
+            m_size = std::exchange(other.m_size, 0);
+            m_capacity = std::exchange(other.m_capacity, 0);
+        } else {
+            // TODO: std::move_iterator
+            // insert(cbegin(), std::make_move_iterator(other.begin()),
+            //     std::make_move_iterator(other.end()));
+            for (auto& item : other)
+                emplace_back(std::move(item));
+        }
+    }
+
+    constexpr vector(std::initializer_list<T> init,
+        const Allocator& alloc = Allocator())
+        : vector(alloc) { insert(cbegin(), init.begin(), init.end()); }
+
+    constexpr ~vector()
+    {
+        resize(0);
+        shrink_to_fit();
+    }
+
+    vector& operator=(const vector& other)
+    {
+        clear();
+
+        if constexpr (alloc_traits::
+            propagate_on_container_copy_assignment::value) {
+            if (m_alloc != other.m_alloc)
+                shrink_to_fit();
+            m_alloc = other.m_alloc;
+        }
+
+        insert(cbegin(), other.begin(), other.end());
+        return *this;
+    }
+
+    vector& operator=(vector&& other)
+    {
+        clear();
+
+        if constexpr (alloc_traits::
+            propagate_on_container_move_assignment::value) {
+            shrink_to_fit();
+            m_alloc = std::move(other.m_alloc);
+        }
+        else {
+            if (m_alloc != other.m_alloc) {
+                // TODO: std::move_iterator
+                for (auto& item : other)
+                    emplace_back(std::move(item));
+                return *this;
+            }
+            shrink_to_fit();
+        }
+
+        m_data = std::exchange(other.m_data, nullptr);
+        m_size = std::exchange(other.m_size, 0);
+        m_capacity = std::exchange(other.m_capacity, 0);
+        return *this;
+    }
+
+    vector& operator=(std::initializer_list<T> init)
+    {
+        assign(init.begin(), init.end());
+        return *this;
+    }
+
+    constexpr void assign(size_type n, const T& val)
+    {
+        clear();
+        resize(n, val);
+    }
+
+    // TODO: check whether InputIter satisfies LegacyInputIterator
+    template <typename InputIter>
+    constexpr void assign(InputIter first, InputIter last)
+    {
+        clear();
+        insert(cbegin(), first, last);
+    }
+    constexpr void assign(std::initializer_list<T> init)
+    {
+        clear();
+        insert(cbegin(), init.begin(), init.end());
+    }
+
+    constexpr allocator_type get_allocator(void) const noexcept
+    { return m_alloc; }
+
+    constexpr reference at(size_type pos)
+    {
+        // TODO: exceptions
+        // if (pos >= sz)
+        //     throw std::out_of_range("vector::at");
+        return m_data[pos];
+    }
+    constexpr const_reference at(size_type pos) const
+    {
+        // TODO: exceptions
+        // if (pos >= sz)
+        //     throw std::out_of_range("vector::at");
+        return m_data[pos];
+    }
+
+    constexpr reference operator[](size_type pos) noexcept
+    { return m_data[pos]; }
+    constexpr const_reference operator[](size_type pos) const noexcept
+    { return m_data[pos]; }
+
+    constexpr reference front() noexcept
+    { return m_data[0]; }
+    constexpr const_reference front() const noexcept
+    { return m_data[0]; }
+    constexpr reference back() noexcept
+    { return m_data[m_size - 1]; }
+    constexpr const_reference back() const noexcept
+    { return m_data[m_size - 1]; }
+
+    constexpr T* data(void) noexcept
+    { return m_data; }
+    constexpr const T* data(void) const noexcept
+    { return m_data; }
+
+    // TODO: std::reverse_iterator
+    constexpr iterator begin() noexcept
+    { return iterator { m_data }; }
+    constexpr const_iterator begin() const noexcept
+    { return const_iterator { m_data }; }
+    constexpr const_iterator cbegin() const noexcept
+    { return const_iterator { m_data }; }
+    constexpr iterator end() noexcept
+    { return iterator { m_data + m_size }; }
+    constexpr const_iterator end() const noexcept
+    { return const_iterator { m_data + m_size }; }
+    constexpr const_iterator cend() const noexcept
+    { return const_iterator { m_data + m_size }; }
+
+    [[nodiscard]] constexpr bool empty() const noexcept
+    { return m_size == 0; }
+    constexpr size_type size() const noexcept
+    { return m_size; }
+    constexpr size_type capacity() const noexcept
+    { return m_capacity; }
+
+    constexpr void reserve(size_type new_cap)
+    {
+        if (new_cap > m_capacity)
+            _reallocate_safe(new_cap);
+    }
+
+    constexpr void resize(size_type n)
+    {
+        _pre_resize(n);
+        while (n > m_size)
+            emplace_back();
+    }
+    constexpr void resize(size_type n, const value_type& value)
+    {
+        _pre_resize(n);
+        while (n > m_size)
+            emplace_back(value);
+    }
+
+    constexpr void shrink_to_fit()
+    {
+        if (m_size != m_capacity)
+            _reallocate_safe(m_size);
+    }
+    constexpr void clear() noexcept
+    { resize(0); }
+
+    template <typename... Args>
+    constexpr iterator emplace(const_iterator pos, Args&&... args)
+    {
+        size_type idx = pos - m_data;
+
+        if (!pos)
+            reserve(1);
+
+        if (m_size == m_capacity)
+            reserve(m_capacity * 2);
+
+        for (size_type i = m_size; i > idx; --i)
+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-1]));
+
+        alloc_traits::construct(m_alloc, m_data + idx,
+            std::forward<Args>(args)...);
+
+        ++m_size;
+        return iterator { m_data + idx };
+    }
+
+    constexpr iterator insert(const_iterator pos, T&& val)
+    { return emplace(pos, std::move(val)); }
+    constexpr iterator insert(const_iterator pos, const T& val)
+    { return emplace(pos, val); }
+
+    constexpr iterator insert(const_iterator pos, size_type n, const T& val)
+    {
+        if (!n)
+            return pos;
+
+        size_type idx = pos - m_data;
+        if (!pos)
+            reserve(n);
+
+        if (m_size + n > m_capacity)
+            reserve(m_capacity * 2);
+        for (size_type i = m_size + n - 1; i >= idx + n; --i)
+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-n]));
+        for (size_type i = idx; i < idx + n; ++i)
+            alloc_traits::construct(m_alloc, m_data + i, val);
+        m_size += n;
+        return iterator { m_data + idx };
+    }
+
+    // TODO: LegacyInputIterator version of this
+    template <typename ForwardIter>
+    constexpr iterator insert(const_iterator pos,
+        ForwardIter first, ForwardIter last)
+    {
+        size_type idx = pos - m_data;
+        size_type n = 0;
+
+        ForwardIter tmp = first;
+        while (tmp != last)
+            ++n, ++tmp;
+
+        if (!n)
+            return pos;
+
+        if (!pos)
+            reserve(n);
+
+        if (m_size + n > m_capacity)
+            reserve(m_capacity * 2);
+        for (size_type i = m_size + n - 1; i >= idx + n; --i)
+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i-n]));
+        for (size_type i = idx; i < idx + n; ++i)
+            alloc_traits::construct(m_alloc, m_data + i, *first++);
+        m_size += n;
+        return iterator { m_data + idx };
+    }
+
+    constexpr iterator insert(const_iterator pos, std::initializer_list<T> init)
+    { return insert(pos, init.begin(), init.end()); }
+
+    constexpr iterator erase(const_iterator pos)
+    {
+        size_type idx = pos - m_data;
+        alloc_traits::destroy(m_alloc, m_data + idx);
+        for (size_type i = idx; i < m_size - 1; ++i)
+            alloc_traits::construct(m_alloc, m_data + i, std::move(m_data[i+1]));
+        --m_size;
+        return iterator { m_data + idx };
+    }
+
+    constexpr iterator erase(const_iterator first, const_iterator last)
+    {
+        size_type n = last - first;
+        if (!n)
+            return last;
+
+        size_type idx = first - m_data;
+        for (size_type i = idx; i < idx + n; ++i)
+            alloc_traits::destroy(m_alloc, m_data + i);
+
+        for (size_type i = idx; i < m_size - n; ++i)
+            m_alloc.construct(m_data + i, std::move(m_data[i+n]));
+
+        m_size -= n;
+        return iterator { m_data + idx };
+    }
+
+    constexpr void push_back(const T& val) { insert(cend(), val); }
+    constexpr void push_back(T&& val) { insert(cend(), std::move(val)); }
+
+    template <typename... Args>
+    constexpr void emplace_back(Args&&... args)
+    { emplace(cend(), std::forward<Args>(args)...); }
+
+    constexpr void pop_back() { erase(--cend()); }
+
+    constexpr void swap(vector& 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);
+        std::swap(m_size, other.m_size);
+        std::swap(m_capacity, other.m_capacity);
+    }
+};
+
+template <typename T, typename Allocator>
+constexpr void swap(
+    std::vector<T, Allocator>& lhs,
+    std::vector<T, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)))
+{ lhs.swap(rhs); }
+
+template <typename T, typename Allocator, typename U>
+constexpr typename std::vector<T, Allocator>::size_type
+erase(std::vector<T, Allocator>& vec, const U& value)
+{
+    typename std::vector<T, Allocator>::size_type n = 0;
+
+    for (auto iter = vec.begin(); iter != vec.end(); ) {
+        if (*iter == value) {
+            iter = vec.erase(iter);
+            ++n;
+        } else {
+            ++iter;
+        }
+    }
+    return n;
+}
+
+template <typename T, typename Allocator, typename Pred>
+constexpr typename std::vector<T, Allocator>::size_type
+erase_if(std::vector<T, Allocator>& vec, Pred pred)
+{
+    typename std::vector<T, Allocator>::size_type n = 0;
+
+    for (auto iter = vec.begin(); iter != vec.end(); ) {
+        if (pred(*iter)) {
+            iter = vec.erase(iter);
+            ++n;
+        } else {
+            ++iter;
+        }
+    }
+    return n;
+}
+
+} // namespace std
+
+#endif

+ 3 - 2
include/kernel/mm.hpp

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <list>
+#include <vector>
 #include <bit>
 #include <cstddef>
 #include <utility>
@@ -13,7 +14,6 @@
 #include <types/size.h>
 #include <types/status.h>
 #include <types/types.h>
-#include <types/vector.hpp>
 
 #define invalidate_tlb(addr) asm("invlpg (%0)" \
                                  :             \
@@ -50,7 +50,8 @@ int mmap(
     int write,
     int priv);
 
-using page_arr = types::vector<page, types::kernel_ident_allocator>;
+using page_arr = std::vector<page,
+    types::allocator_adapter<page, types::kernel_ident_allocator>>;
 
 // forward declaration
 namespace kernel {

+ 1 - 1
include/kernel/vfs.hpp

@@ -2,6 +2,7 @@
 
 #include <map>
 #include <list>
+#include <vector>
 #include <functional>
 
 #include <assert.h>
@@ -13,7 +14,6 @@
 #include <types/hash_map.hpp>
 #include <types/lock.hpp>
 #include <types/types.h>
-#include <types/vector.hpp>
 
 #define INODE_FILE (1 << 0)
 #define INODE_DIR (1 << 1)

+ 7 - 7
include/types/hash_map.hpp

@@ -1,5 +1,6 @@
 #pragma once
 #include <list>
+#include <vector>
 #include <bit>
 #include <utility>
 #include <type_traits>
@@ -9,7 +10,6 @@
 #include <types/cplusplus.hpp>
 #include <types/string.hpp>
 #include <types/types.h>
-#include <types/vector.hpp>
 
 namespace types {
 
@@ -66,9 +66,7 @@ struct linux_hasher<T, std::enable_if_t<is_c_string_v<T>>> {
         return hash32(hash, bits);
     }
 };
-template <
-    template <template <typename> class> class String,
-    template <typename> class Allocator>
+template <template <typename> typename String, typename Allocator>
 struct linux_hasher<String<Allocator>,
     std::enable_if_t<
         std::is_same_v<
@@ -105,9 +103,11 @@ public:
     using iterator_type = iterator<pair_type*>;
     using const_iterator_type = iterator<const pair_type*>;
 
-    using bucket_type = std::list<pair_type,
-        types::allocator_adapter<pair_type, Allocator>>;
-    using bucket_array_type = vector<bucket_type, Allocator>;
+    template <typename T>
+    using adapted_allocator = types::allocator_adapter<T, Allocator>;
+
+    using bucket_type = std::list<pair_type, adapted_allocator<pair_type>>;
+    using bucket_array_type = std::vector<bucket_type, adapted_allocator<bucket_type>>;
 
     using hasher_type = Hasher<Key>;
 

+ 16 - 31
include/types/string.hpp

@@ -1,16 +1,20 @@
 #pragma once
 
+#include <vector>
+
 #include <string.h>
 #include <types/allocator.hpp>
 #include <types/types.h>
-#include <types/vector.hpp>
 
 namespace types {
-template <template <typename _value_type> class Allocator = kernel_allocator>
-class string : public types::vector<char, Allocator> {
+template <typename Allocator =
+    types::allocator_adapter<char, types::kernel_allocator>>
+class string : public std::vector<char, Allocator> {
 public:
-    using inner_vector_type = types::vector<char, Allocator>;
+    using inner_vector_type = std::vector<char, Allocator>;
     using size_type = typename inner_vector_type::size_type;
+    using iterator = typename inner_vector_type::iterator;
+    using const_iterator = typename inner_vector_type::const_iterator;
 
     static inline constexpr size_type npos = (-1U);
 
@@ -42,15 +46,9 @@ public:
     {
         return this->append(str.data());
     }
-    constexpr string& append(string&& str)
-    {
-        return this->append(str.data());
-    }
     constexpr string& operator+=(const char c)
     {
-        this->pop_back();
-        this->push_back(c);
-        this->push_back(0x00);
+        this->insert(this->end(), c);
         return *this;
     }
     constexpr string& operator+=(const char* str)
@@ -61,10 +59,6 @@ public:
     {
         return this->append(str);
     }
-    constexpr string& operator+=(string&& str)
-    {
-        return this->append(move(str));
-    }
     constexpr bool operator==(const string& rhs) const
     {
         return strcmp(c_str(), rhs.c_str()) == 0;
@@ -77,7 +71,7 @@ public:
     {
         return this->data();
     }
-    constexpr void clear(void)
+    constexpr void clear()
     {
         inner_vector_type::clear();
         this->push_back(0x00);
@@ -90,20 +84,11 @@ public:
         ref = 0x00;
         return c;
     }
-    constexpr typename inner_vector_type::iterator_type back(void)
-    {
-        assert(!this->empty());
-        return --inner_vector_type::back();
-    }
-    constexpr typename inner_vector_type::const_iterator_type back(void) const
-    {
-        assert(!this->empty());
-        return --inner_vector_type::back();
-    }
-    constexpr typename inner_vector_type::const_iterator_type cback(void) const
-    {
-        assert(!this->empty());
-        return --inner_vector_type::cback();
-    }
+    constexpr iterator end() noexcept
+    { return --inner_vector_type::end(); }
+    constexpr const_iterator end() const noexcept
+    { return --inner_vector_type::cend(); }
+    constexpr const_iterator cend() const noexcept
+    { return --inner_vector_type::cend(); }
 };
 } // namespace types

+ 0 - 339
include/types/vector.hpp

@@ -1,339 +0,0 @@
-#pragma once
-#include <utility>
-#include <type_traits>
-
-#include <assert.h>
-#include <types/allocator.hpp>
-#include <types/types.h>
-
-namespace types {
-
-template <typename T, template <typename _value_type> class Allocator = kernel_allocator>
-class vector {
-public:
-    template <typename Pointer>
-    class iterator;
-
-    using value_type = T;
-    using pointer_type = std::add_pointer_t<value_type>;
-    using reference_type = std::add_lvalue_reference_t<value_type>;
-    using iterator_type = iterator<pointer_type>;
-
-    using const_value_type = std::add_const_t<value_type>;
-    using const_pointer_type = std::add_pointer_t<const_value_type>;
-    using const_reference_type = std::add_lvalue_reference_t<const_value_type>;
-    using const_iterator_type = iterator<const_pointer_type>;
-
-    using size_type = size_t;
-    using difference_type = ssize_t;
-    using index_type = size_type;
-    using allocator_type = Allocator<value_type>;
-
-public:
-    template <typename Pointer>
-    class iterator {
-    public:
-        using Value = std::remove_pointer_t<Pointer>;
-        using Reference = std::add_lvalue_reference_t<Value>;
-
-    public:
-        explicit constexpr iterator(Pointer p) noexcept
-            : p(p) {}
-
-        constexpr iterator(const iterator& iter) noexcept
-            : p(iter.p) {}
-        constexpr iterator(iterator&& iter) noexcept
-            : p(std::exchange(iter.p, nullptr)) {}
-
-        constexpr iterator& operator=(const iterator& iter)
-        {
-            p = iter.p;
-            return *this;
-        }
-        constexpr iterator& operator=(iterator&& iter)
-        {
-            p = std::exchange(iter.p, nullptr);
-            return *this;
-        }
-
-        constexpr bool operator==(const iterator& iter) const noexcept
-        { return this->p == iter.p; }
-        constexpr bool operator!=(const iterator& iter) const noexcept
-        { return !operator==(iter); }
-
-        constexpr iterator& operator++(void) noexcept
-        { ++p; return *this; }
-        constexpr iterator operator++(int) noexcept
-        { iterator iter(*this); ++p; return iter; }
-
-        constexpr iterator& operator--(void) noexcept
-        { --p; return *this; }
-        constexpr iterator operator--(int) noexcept
-        { iterator iter(*this); --p; return iter; }
-
-        constexpr iterator operator+(size_type n) noexcept
-        { return iterator { p + n }; }
-        constexpr iterator operator-(size_type n) noexcept
-        { return iterator { p - n }; }
-
-        constexpr Reference operator*(void) const noexcept
-        { return *p; }
-        constexpr Pointer operator&(void) const noexcept
-        { return p; }
-        constexpr Pointer operator->(void) const noexcept
-        { return p; }
-
-    protected:
-        Pointer p;
-    };
-
-protected:
-    constexpr const value_type& _at(index_type i) const
-    { return m_arr[i]; }
-    constexpr value_type& _at(index_type i)
-    { return m_arr[i]; }
-
-    // assert(n >= m_size)
-    constexpr void _reallocate_safe(size_type n)
-    {
-        auto* newptr = allocator_traits<allocator_type>::allocate(n);
-        for (size_t i = 0; i < m_size; ++i) {
-            allocator_traits<allocator_type>::construct(newptr + i, std::move(_at(i)));
-            allocator_traits<allocator_type>::deconstruct(m_arr + i);
-        }
-
-        allocator_traits<allocator_type>::deallocate(m_arr);
-        m_arr = newptr;
-        m_capacity = n;
-    }
-
-    // make m_capacity >= n >= m_size
-    constexpr void _pre_resize(size_type n)
-    {
-        if (n == m_size)
-            return;
-
-        if (n < m_size) {
-            while (n < m_size)
-                pop_back();
-            return;
-        }
-        assert(n > m_size);
-        reserve(n);
-    }
-
-public:
-    constexpr vector() noexcept
-        : m_arr(nullptr)
-        , m_capacity(0)
-        , m_size(0) { }
-
-    explicit constexpr vector(size_type size)
-        : vector()
-    { resize(size); }
-
-    constexpr vector(size_type size, const value_type& value)
-        : vector()
-    { resize(size, value); }
-
-    constexpr vector(const vector& arr) noexcept
-        : vector()
-    {
-        for (const auto& item : arr)
-            push_back(item);
-    }
-
-    constexpr vector(vector&& arr) noexcept
-    {
-        m_arr = std::exchange(arr.m_arr, nullptr);
-        m_capacity = std::exchange(arr.m_capacity, 0);
-        m_size = std::exchange(arr.m_size, 0);
-    }
-
-    constexpr vector& operator=(vector&& arr)
-    {
-        resize(0);
-        shrink_to_fit();
-
-        m_arr = std::exchange(arr.m_arr, nullptr);
-        m_capacity = std::exchange(arr.m_capacity, 0);
-        m_size = std::exchange(arr.m_size, 0);
-
-        return *this;
-    }
-
-    constexpr vector& operator=(const vector& arr)
-    {
-        return operator=(vector {arr});
-    }
-
-    constexpr ~vector() noexcept
-    {
-        resize(0);
-        shrink_to_fit();
-    }
-
-    constexpr void shrink_to_fit()
-    {
-        if (m_size == m_capacity)
-            return;
-
-        _reallocate_safe(m_size);
-    }
-
-    constexpr void reserve(size_type n)
-    {
-        if (n <= m_capacity)
-            return;
-
-        _reallocate_safe(n);
-    }
-
-    constexpr void resize(size_type n)
-    {
-        _pre_resize(n);
-        while (n > m_size)
-            emplace_back();
-    }
-
-    constexpr void resize(size_type n, const value_type& value)
-    {
-        _pre_resize(n);
-        while (n > m_size)
-            emplace_back(value);
-    }
-
-    // TODO: find
-
-    // erase the node which iter points to
-    // void erase(const iterator_type& iter) noexcept
-    // {
-    //     allocator_traits<allocator_type>::deconstruct(iter.p);
-    //     --m_size;
-    // }
-
-    // insert the value v in front of the given iterator
-    // void insert(const iterator_type& iter, const value_type& v) noexcept
-    // {
-    //     node_base_type* new_node = allocator_traits<allocator_type>::allocate(v);
-    //     iter._node()->prev->connect(new_node);
-    //     new_node->connect(iter._node());
-
-    //     ++_size();
-    // }
-
-    // insert the value v in front of the given iterator
-    // void insert(const iterator_type& iter, value_type&& v) noexcept
-    // {
-    //     node_base_type* new_node = allocator_traits<allocator_type>::allocate(v);
-    //     iter._node().prev->connect(new_node);
-    //     new_node->connect(iter._node());
-
-    //     ++_size();
-    // }
-
-    constexpr value_type* data(void) noexcept
-    { return m_arr; }
-    constexpr const value_type* data(void) const noexcept
-    { return m_arr; }
-
-    constexpr value_type& at(index_type i) noexcept
-    {
-        assert(i + 1 <= this->size());
-        return _at(i);
-    }
-    constexpr const value_type& at(index_type i) const noexcept
-    {
-        assert(i + 1 <= this->size());
-        return _at(i);
-    }
-
-    constexpr value_type& operator[](index_type i) noexcept
-    { return at(i); }
-    constexpr const value_type& operator[](index_type i) const noexcept
-    { return at(i); }
-
-    constexpr void push_back(const value_type& v) noexcept
-    {
-        if (m_size == m_capacity)
-            reserve(m_capacity ? m_capacity * 2 : 1);
-        allocator_traits<allocator_type>::construct(m_arr + m_size, v);
-        ++m_size;
-    }
-
-    constexpr void push_back(value_type&& v) noexcept
-    {
-        if (m_size == m_capacity)
-            reserve(m_capacity ? m_capacity * 2 : 1);
-        allocator_traits<allocator_type>::construct(m_arr + m_size, std::move(v));
-        ++m_size;
-    }
-
-    template <typename... Args>
-    constexpr iterator_type emplace_back(Args&&... args)
-    {
-        push_back(value_type(std::forward<Args>(args)...));
-        return iterator_type(m_arr + m_size - 1);
-    }
-
-    constexpr void pop_back(void) noexcept
-    {
-        assert(m_size > 0);
-        allocator_traits<allocator_type>::deconstruct(m_arr + m_size - 1);
-        --m_size;
-    }
-
-    constexpr size_type size(void) const noexcept
-    { return m_size; }
-
-    constexpr size_type capacity(void) const noexcept
-    { return m_capacity; }
-
-    constexpr const_iterator_type cbegin() const noexcept
-    { return const_iterator_type(m_arr); }
-
-    constexpr const_iterator_type cend() const noexcept
-    { return const_iterator_type(m_arr + m_size); }
-
-    constexpr iterator_type begin() noexcept
-    { return iterator_type(m_arr); }
-    constexpr const_iterator_type begin() const noexcept
-    { return cbegin(); }
-
-    constexpr iterator_type end() noexcept
-    { return iterator_type(m_arr + m_size); }
-    constexpr const_iterator_type end() const noexcept
-    { return cend(); }
-
-    constexpr value_type& back() noexcept
-    {
-        assert(m_size != 0);
-        return at(m_size - 1);
-    }
-    constexpr const value_type& back() const noexcept
-    {
-        assert(m_size != 0);
-        return at(m_size - 1);
-    }
-
-    constexpr bool empty(void) const noexcept
-    { return m_size == 0; }
-
-    constexpr void clear(void)
-    { resize(0); }
-
-    // TODO
-
-    // iterator_type r_start() noexcept;
-    // iterator_type r_end() noexcept;
-
-    // iterator_type cr_start() noexcept;
-    // iterator_type cr_end() noexcept;
-
-protected:
-    T* m_arr;
-    size_type m_capacity;
-    size_type m_size;
-};
-
-} // namespace types

+ 4 - 3
src/kernel/mem.cpp

@@ -281,9 +281,10 @@ int mm::append_page(page& pg, uint32_t attr, bool priv)
     }
     ++*pg.ref_count;
 
-    auto iter = this->pgs->emplace_back(pg);
-    iter->pg_pteidx = (pt_pg << 12) + pti;
-    iter->attr = attr;
+    this->pgs->emplace_back(pg);
+    auto& emplaced = this->pgs->back();
+    emplaced.pg_pteidx = (pt_pg << 12) + pti;
+    emplaced.attr = attr;
 
     return GB_OK;
 }

+ 7 - 7
src/kernel/vfs.cpp

@@ -1,4 +1,5 @@
 #include <map>
+#include <vector>
 #include <bit>
 #include <utility>
 
@@ -13,12 +14,10 @@
 #include <types/allocator.hpp>
 #include <types/status.h>
 #include <types/string.hpp>
-#include <types/vector.hpp>
 
 using types::allocator_traits;
 using types::kernel_allocator;
 using types::string;
-using types::vector;
 
 struct tmpfs_file_entry {
     size_t ino;
@@ -208,8 +207,8 @@ uint32_t fs::vfs::inode_getnode(fs::inode*)
 class tmpfs : public virtual fs::vfs {
 private:
     using fe_t = tmpfs_file_entry;
-    using vfe_t = vector<fe_t>;
-    using fdata_t = vector<char>;
+    using vfe_t = std::vector<fe_t>;
+    using fdata_t = std::vector<char>;
 
 private:
     std::map<fs::ino_t, void*> inode_data;
@@ -262,11 +261,12 @@ protected:
     void mklink(fs::inode* dir, fs::inode* inode, const char* filename)
     {
         auto* fes = as_vfe(_getdata(dir->ino));
-        auto iter = fes->emplace_back(fe_t {
+        fes->emplace_back(fe_t {
             .ino = inode->ino,
             .filename = {} });
-        strncpy(iter->filename, filename, sizeof(iter->filename));
-        iter->filename[sizeof(iter->filename) - 1] = 0;
+        auto& emplaced = fes->back();
+        strncpy(emplaced.filename, filename, sizeof(emplaced.filename));
+        emplaced.filename[sizeof(emplaced.filename) - 1] = 0;
         dir->size += sizeof(fe_t);
     }
 

+ 6 - 5
src/types/elf.cpp

@@ -1,3 +1,5 @@
+#include <vector>
+
 #include <assert.h>
 #include <kernel/errno.h>
 #include <kernel/mem.h>
@@ -8,7 +10,6 @@
 #include <string.h>
 #include <types/elf.hpp>
 #include <types/string.hpp>
-#include <types/vector.hpp>
 
 #define align16_down(sp) (sp = ((char*)((uint32_t)(sp)&0xfffffff0)))
 
@@ -50,7 +51,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
 
     size_t phents_size = hdr.phentsize * hdr.phnum;
     size_t shents_size = hdr.shentsize * hdr.shnum;
-    vector<types::elf::elf32_program_header_entry> phents(hdr.phnum);
+    std::vector<types::elf::elf32_program_header_entry> phents(hdr.phnum);
     n_read = fs::vfs_read(
         ent_exec->ind,
         (char*)phents.data(),
@@ -63,7 +64,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
         return GB_FAILED;
     }
 
-    vector<types::elf::elf32_section_header_entry> shents(hdr.shnum);
+    std::vector<types::elf::elf32_section_header_entry> shents(hdr.shnum);
     n_read = fs::vfs_read(
         ent_exec->ind,
         (char*)shents.data(),
@@ -77,7 +78,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     }
 
     // copy argv and envp
-    vector<string<>> argv, envp;
+    std::vector<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)
@@ -146,7 +147,7 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     auto* sp = (char**)&d->sp;
 
     // fill information block area
-    vector<char*> args, envs;
+    std::vector<char*> args, envs;
     for (const auto& env : envp) {
         _user_push(sp, env.c_str());
         envs.push_back(*sp);