Explorar el Código

feat(string): add string class

greatbridf hace 2 años
padre
commit
f581b0765b
Se han modificado 4 ficheros con 202 adiciones y 17 borrados
  1. 2 0
      CMakeLists.txt
  2. 53 0
      include/types/cplusplus.hpp
  3. 71 0
      include/types/string.hpp
  4. 76 17
      include/types/vector.hpp

+ 2 - 0
CMakeLists.txt

@@ -79,7 +79,9 @@ set(KERNEL_MAIN_SOURCES src/kernel_main.c
                         include/types/stdint.h
                         include/types/list.h
                         include/types/allocator.hpp
+                        include/types/cplusplus.hpp
                         include/types/list.hpp
+                        include/types/string.hpp
                         include/types/vector.hpp
                         include/kernel_main.h
                         )

+ 53 - 0
include/types/cplusplus.hpp

@@ -0,0 +1,53 @@
+#pragma once
+
+#ifdef __cplusplus
+
+namespace types::traits::inner {
+
+template <typename Tp, typename>
+struct remove_pointer {
+    using type = Tp;
+};
+
+template <typename Tp, typename T>
+struct remove_pointer<Tp, T*> {
+    using type = T;
+};
+
+template <typename Tr, typename>
+struct remove_reference {
+    using type = Tr;
+};
+
+template <typename Tr, typename T>
+struct remove_reference<Tr, T&> {
+    using type = T;
+};
+
+} // namespace types::traits::inner
+
+namespace types::traits {
+
+template <typename Tp>
+struct remove_pointer
+    : inner::remove_pointer<Tp, Tp> {
+};
+
+template <typename Tr>
+struct remove_reference
+    : inner::remove_reference<Tr, Tr> {
+};
+
+template <typename T>
+struct add_pointer {
+    using type = T*;
+};
+
+template <typename T>
+struct add_reference {
+    using type = T&;
+};
+
+} // namespace types
+
+#endif

+ 71 - 0
include/types/string.hpp

@@ -0,0 +1,71 @@
+#pragma once
+
+#include <kernel/stdio.h>
+#include <types/allocator.hpp>
+#include <types/types.h>
+#include <types/vector.hpp>
+
+#ifdef __cplusplus
+
+namespace types {
+template <template <typename _value_type> class Allocator = kernel_allocator>
+class string : public types::vector<char, Allocator> {
+public:
+    using inner_vector_type = types::vector<char, Allocator>;
+    using size_type = typename inner_vector_type::size_type;
+
+    static inline constexpr size_type npos = (-1U);
+
+public:
+    explicit string(size_type capacity = 8)
+        : inner_vector_type(capacity)
+    {
+        this->push_back(0x00);
+    }
+    string(const char* str, size_type n = npos)
+        : string()
+    {
+        this->append(str, n);
+    }
+    string(const string& str)
+        : inner_vector_type((const inner_vector_type&)str)
+    {
+    }
+    string& append(const char* str, size_type n = npos)
+    {
+        this->pop_back();
+
+        while (n-- && *str != 0x00) {
+            this->push_back(*str);
+            ++str;
+        }
+
+        this->push_back(0x00);
+        return *this;
+    }
+    string& append(const string& str)
+    {
+        return this->append(str.data());
+    }
+    string& operator+=(const char c)
+    {
+        *this->back() = c;
+        this->push_back(0x00);
+        return *this;
+    }
+    string& operator+=(const char* str)
+    {
+        return this->append(str);
+    }
+    string& operator+=(const string& str)
+    {
+        return this->append(str);
+    }
+    string substr(size_type pos, size_type n = npos)
+    {
+        return string(this->m_arr + pos, n);
+    }
+};
+} // namespace types
+
+#endif

+ 76 - 17
include/types/vector.hpp

@@ -2,6 +2,7 @@
 
 #include <kernel/mem.h>
 #include <types/allocator.hpp>
+#include <types/cplusplus.hpp>
 #include <types/types.h>
 
 namespace types {
@@ -9,19 +10,26 @@ 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 = value_type*;
     using reference_type = value_type&;
-    using iterator_type = iterator;
+    using iterator_type = iterator<value_type*>;
+    using const_iterator_type = iterator<const value_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 = typename types::traits::remove_pointer<Pointer>::type;
+        using Reference = typename types::traits::add_reference<Value>::type;
+
     public:
         explicit iterator(const iterator& iter) noexcept
             : p(iter.p)
@@ -33,7 +41,7 @@ public:
         {
         }
 
-        explicit iterator(pointer_type p) noexcept
+        explicit iterator(Pointer p) noexcept
             : p(p)
         {
         }
@@ -74,25 +82,33 @@ public:
             return iter;
         }
 
-        reference_type operator*() const noexcept
+        Reference operator*() const noexcept
         {
             return *p;
         }
 
-        pointer_type operator->() const noexcept
+        Pointer operator->() const noexcept
         {
             return p;
         }
 
     protected:
-        pointer_type p;
+        Pointer p;
     };
 
 public:
-    vector() noexcept
+    explicit vector(size_type capacity = 1) noexcept
+        : m_size(0)
+    {
+        resize(capacity);
+    }
+
+    vector(const vector<T, Allocator>& arr) noexcept
         : m_size(0)
     {
-        resize(1);
+        resize(arr.capacity());
+        for (const auto& item : arr)
+            push_back(item);
     }
 
     ~vector() noexcept
@@ -122,11 +138,11 @@ public:
     // 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;
-    }
+    // 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
@@ -196,29 +212,68 @@ public:
         ++m_size;
     }
 
-    size_t size(void) const noexcept
+    void pop_back(void) noexcept
+    {
+        allocator_traits<allocator_type>::deconstruct(&*back());
+        --m_size;
+    }
+
+    size_type size(void) const noexcept
     {
         return m_size;
     }
 
+    size_type capacity(void) const noexcept
+    {
+        return m_capacity;
+    }
+
+    const_iterator_type cbegin() const noexcept
+    {
+        return const_iterator_type(m_arr);
+    }
+
+    const_iterator_type cend() const noexcept
+    {
+        return const_iterator_type(m_arr + m_size);
+    }
+
     iterator_type begin() noexcept
     {
         return iterator_type(m_arr);
     }
 
+    const_iterator_type begin() const noexcept
+    {
+        return cbegin();
+    }
+
     iterator_type end() noexcept
     {
         return iterator_type(m_arr + m_size);
     }
 
+    const_iterator_type end() const noexcept
+    {
+        return cend();
+    }
+
+    iterator_type back() noexcept
+    {
+        return iterator_type(m_arr + m_size - 1);
+    }
+
+    const iterator_type back() const noexcept
+    {
+        return const_iterator_type(m_arr + m_size - 1);
+    }
+
     bool empty(void) const noexcept
     {
         return size() == 0;
     }
 
     // TODO
-    // iterator_type cstart() noexcept;
-    // iterator_type cend() noexcept;
 
     // iterator_type r_start() noexcept;
     // iterator_type r_end() noexcept;
@@ -226,13 +281,17 @@ public:
     // iterator_type cr_start() noexcept;
     // iterator_type cr_end() noexcept;
 
-private:
+protected:
+    inline const value_type& _at(index_type i) const
+    {
+        return m_arr[i];
+    }
     inline value_type& _at(index_type i)
     {
         return m_arr[i];
     }
 
-private:
+protected:
     value_type* m_arr;
     size_type m_capacity;
     size_type m_size;