Bladeren bron

change(vector): change the behavior of resize

greatbridf 1 jaar geleden
bovenliggende
commit
188c55e96e
4 gewijzigde bestanden met toevoegingen van 158 en 218 verwijderingen
  1. 5 13
      include/types/hash_map.hpp
  2. 6 5
      include/types/string.hpp
  3. 130 165
      include/types/vector.hpp
  4. 17 35
      src/types/elf.cpp

+ 5 - 13
include/types/hash_map.hpp

@@ -196,21 +196,13 @@ protected:
 
 public:
     explicit constexpr hash_map(void)
-        : buckets(INITIAL_BUCKETS_ALLOCATED)
-    {
-        for (size_type i = 0; i < INITIAL_BUCKETS_ALLOCATED; ++i)
-            buckets.emplace_back();
-    }
+        : buckets(INITIAL_BUCKETS_ALLOCATED) {}
 
     constexpr hash_map(const hash_map& v)
-        : buckets(v.buckets)
-    {
-    }
+        : buckets(v.buckets) {}
 
     constexpr hash_map(hash_map&& v)
-        : buckets(std::move(v.buckets))
-    {
-    }
+        : buckets(std::move(v.buckets)) {}
 
     constexpr ~hash_map()
     {
@@ -276,8 +268,8 @@ public:
 
     constexpr void clear(void)
     {
-        for (size_t i = 0; i < buckets.size(); ++i)
-            buckets.at(i).clear();
+        for (auto& bucket : buckets)
+            bucket.clear();
     }
 };
 

+ 6 - 5
include/types/string.hpp

@@ -15,9 +15,10 @@ public:
     static inline constexpr size_type npos = (-1U);
 
 public:
-    explicit constexpr string(size_type capacity = 8)
-        : inner_vector_type(capacity)
+    constexpr string()
+        : inner_vector_type()
     {
+        this->reserve(8);
         this->push_back(0x00);
     }
     constexpr string(const char* str, size_type n = npos)
@@ -84,9 +85,9 @@ public:
     constexpr char pop(void)
     {
         this->pop_back();
-        auto iter = inner_vector_type::back();
-        char c = *iter;
-        *iter = 0x00;
+        auto& ref = inner_vector_type::back();
+        char c = ref;
+        ref = 0x00;
         return c;
     }
     constexpr typename inner_vector_type::iterator_type back(void)

+ 130 - 165
include/types/vector.hpp

@@ -15,10 +15,15 @@ public:
     class iterator;
 
     using value_type = T;
-    using pointer_type = value_type*;
-    using reference_type = value_type&;
-    using iterator_type = iterator<value_type*>;
-    using const_iterator_type = iterator<const value_type*>;
+    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;
@@ -32,105 +37,107 @@ public:
         using Reference = std::add_lvalue_reference_t<Value>;
 
     public:
-        constexpr iterator(const iterator& iter) noexcept
-            : p(iter.p)
-        {
-        }
+        explicit constexpr iterator(Pointer p) noexcept
+            : p(p) {}
 
+        constexpr iterator(const iterator& iter) noexcept
+            : p(iter.p) {}
         constexpr iterator(iterator&& iter) noexcept
-            : p(iter.p)
-        {
-            iter.p = nullptr;
-        }
+            : p(std::exchange(iter.p, nullptr)) {}
 
         constexpr iterator& operator=(const iterator& iter)
         {
             p = iter.p;
             return *this;
         }
-
-        explicit constexpr iterator(Pointer p) noexcept
-            : p(p)
+        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;
-        }
-
+        { return this->p == iter.p; }
         constexpr bool operator!=(const iterator& iter) const noexcept
-        {
-            return !(*this == iter);
-        }
+        { return !operator==(iter); }
 
         constexpr iterator& operator++(void) noexcept
-        {
-            ++p;
-            return *this;
-        }
-
+        { ++p; return *this; }
         constexpr iterator operator++(int) noexcept
-        {
-            iterator iter(*this);
-            ++p;
-            return iter;
-        }
+        { iterator iter(*this); ++p; return iter; }
 
         constexpr iterator& operator--(void) noexcept
-        {
-            --p;
-            return *this;
-        }
-
+        { --p; return *this; }
         constexpr iterator operator--(int) noexcept
-        {
-            iterator iter(*this);
-            --p;
-            return iter;
-        }
+        { iterator iter(*this); --p; return iter; }
 
         constexpr iterator operator+(size_type n) noexcept
-        {
-            iterator iter(p + n);
-            return iter;
-        }
-
+        { return iterator { p + n }; }
         constexpr iterator operator-(size_type n) noexcept
-        {
-            iterator iter(p - n);
-            return iter;
-        }
+        { return iterator { p - n }; }
 
         constexpr Reference operator*(void) const noexcept
-        {
-            return *p;
-        }
-
+        { return *p; }
         constexpr Pointer operator&(void) const noexcept
-        {
-            return p;
-        }
-
+        { return p; }
         constexpr Pointer operator->(void) const noexcept
-        {
-            return p;
-        }
+        { return p; }
 
     protected:
         Pointer p;
     };
 
-public:
-    explicit constexpr vector(size_type capacity = 1) noexcept
-        : m_arr(nullptr)
-        , m_size(0)
+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)
     {
-        resize(capacity);
+        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(arr.capacity())
+        : vector()
     {
         for (const auto& item : arr)
             push_back(item);
@@ -138,61 +145,62 @@ public:
 
     constexpr vector(vector&& arr) noexcept
     {
-        m_arr = arr.m_arr;
-        m_capacity = arr.m_capacity;
-        m_size = arr.m_size;
-
-        arr.m_arr = nullptr;
-        arr.m_capacity = 0;
-        arr.m_size = 0;
+        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);
-        m_arr = arr.m_arr;
-        m_capacity = arr.m_capacity;
-        m_size = arr.m_size;
+        shrink_to_fit();
 
-        arr.m_arr = nullptr;
-        arr.m_capacity = 0;
-        arr.m_size = 0;
+        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));
+        return operator=(vector {arr});
     }
 
     constexpr ~vector() noexcept
     {
         resize(0);
+        shrink_to_fit();
     }
 
-    constexpr void resize(size_type n)
+    constexpr void shrink_to_fit()
     {
-        if (m_size == n)
+        if (m_size == m_capacity)
             return;
 
-        value_type* new_ptr = allocator_traits<allocator_type>::allocate(n);
-        assert(!n || (n && new_ptr));
+        _reallocate_safe(m_size);
+    }
 
-        m_capacity = n;
-        size_t orig_size = m_size;
-        if (m_size > m_capacity)
-            m_size = m_capacity;
+    constexpr void reserve(size_type n)
+    {
+        if (n <= m_capacity)
+            return;
 
-        for (size_t i = 0; i < m_size; ++i)
-            allocator_traits<allocator_type>::construct(new_ptr + i, _at(i));
+        _reallocate_safe(n);
+    }
 
-        for (size_t i = 0; i < orig_size; ++i)
-            allocator_traits<allocator_type>::deconstruct(m_arr + i);
+    constexpr void resize(size_type n)
+    {
+        _pre_resize(n);
+        while (n > m_size)
+            emplace_back();
+    }
 
-        if (m_arr)
-            allocator_traits<allocator_type>::deallocate(m_arr);
-        m_arr = new_ptr;
+    constexpr void resize(size_type n, const value_type& value)
+    {
+        _pre_resize(n);
+        while (n > m_size)
+            emplace_back(value);
     }
 
     // TODO: find
@@ -225,21 +233,15 @@ public:
     // }
 
     constexpr value_type* data(void) noexcept
-    {
-        return m_arr;
-    }
-
+    { return m_arr; }
     constexpr const value_type* data(void) const noexcept
-    {
-        return m_arr;
-    }
+    { 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());
@@ -247,19 +249,14 @@ public:
     }
 
     constexpr value_type& operator[](index_type i) noexcept
-    {
-        return at(i);
-    }
-
+    { return at(i); }
     constexpr const value_type& operator[](index_type i) const noexcept
-    {
-        return at(i);
-    }
+    { return at(i); }
 
     constexpr void push_back(const value_type& v) noexcept
     {
         if (m_size == m_capacity)
-            resize(m_capacity * 2);
+            reserve(m_capacity ? m_capacity * 2 : 1);
         allocator_traits<allocator_type>::construct(m_arr + m_size, v);
         ++m_size;
     }
@@ -267,7 +264,7 @@ public:
     constexpr void push_back(value_type&& v) noexcept
     {
         if (m_size == m_capacity)
-            resize(m_capacity * 2);
+            reserve(m_capacity ? m_capacity * 2 : 1);
         allocator_traits<allocator_type>::construct(m_arr + m_size, std::move(v));
         ++m_size;
     }
@@ -276,76 +273,54 @@ public:
     constexpr iterator_type emplace_back(Args&&... args)
     {
         push_back(value_type(std::forward<Args>(args)...));
-        return back();
+        return iterator_type(m_arr + m_size - 1);
     }
 
     constexpr void pop_back(void) noexcept
     {
-        allocator_traits<allocator_type>::deconstruct(&*back());
+        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;
-    }
+    { return m_size; }
 
     constexpr size_type capacity(void) const noexcept
-    {
-        return m_capacity;
-    }
+    { return m_capacity; }
 
     constexpr const_iterator_type cbegin() const noexcept
-    {
-        return const_iterator_type(m_arr);
-    }
+    { return const_iterator_type(m_arr); }
 
     constexpr const_iterator_type cend() const noexcept
-    {
-        return const_iterator_type(m_arr + m_size);
-    }
+    { return const_iterator_type(m_arr + m_size); }
 
     constexpr iterator_type begin() noexcept
-    {
-        return iterator_type(m_arr);
-    }
-
+    { return iterator_type(m_arr); }
     constexpr const_iterator_type begin() const noexcept
-    {
-        return cbegin();
-    }
+    { return cbegin(); }
 
     constexpr iterator_type end() noexcept
-    {
-        return iterator_type(m_arr + m_size);
-    }
-
+    { return iterator_type(m_arr + m_size); }
     constexpr const_iterator_type end() const noexcept
-    {
-        return cend();
-    }
+    { return cend(); }
 
-    constexpr iterator_type back() noexcept
+    constexpr value_type& back() noexcept
     {
-        return iterator_type(m_arr + m_size - 1);
+        assert(m_size != 0);
+        return at(m_size - 1);
     }
-
-    constexpr const_iterator_type back() const noexcept
+    constexpr const value_type& back() const noexcept
     {
-        return const_iterator_type(m_arr + m_size - 1);
+        assert(m_size != 0);
+        return at(m_size - 1);
     }
 
     constexpr bool empty(void) const noexcept
-    {
-        return size() == 0;
-    }
+    { return m_size == 0; }
 
     constexpr void clear(void)
-    {
-        for (size_t i = 0; i < size(); ++i)
-            allocator_traits<allocator_type>::deconstruct(m_arr + i);
-        m_size = 0;
-    }
+    { resize(0); }
 
     // TODO
 
@@ -355,16 +330,6 @@ public:
     // iterator_type cr_start() noexcept;
     // iterator_type cr_end() noexcept;
 
-protected:
-    inline constexpr const value_type& _at(index_type i) const
-    {
-        return m_arr[i];
-    }
-    inline constexpr value_type& _at(index_type i)
-    {
-        return m_arr[i];
-    }
-
 protected:
     T* m_arr;
     size_type m_capacity;

+ 17 - 35
src/types/elf.cpp

@@ -50,33 +50,28 @@ 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;
-    auto* phents = new types::elf::elf32_program_header_entry[hdr.phnum];
+    vector<types::elf::elf32_program_header_entry> phents(hdr.phnum);
     n_read = fs::vfs_read(
         ent_exec->ind,
-        (char*)phents,
+        (char*)phents.data(),
         phents_size,
         hdr.phoff, phents_size);
 
     // broken file or I/O error
     if (n_read != phents_size) {
-        delete[] phents;
-
         d->errcode = EINVAL;
         return GB_FAILED;
     }
 
-    auto* shents = new types::elf::elf32_section_header_entry[hdr.shnum];
+    vector<types::elf::elf32_section_header_entry> shents(hdr.shnum);
     n_read = fs::vfs_read(
         ent_exec->ind,
-        (char*)shents,
+        (char*)shents.data(),
         shents_size,
         hdr.shoff, shents_size);
 
     // broken file or I/O error
     if (n_read != shents_size) {
-        delete[] phents;
-        delete[] shents;
-
         d->errcode = EINVAL;
         return GB_FAILED;
     }
@@ -95,33 +90,30 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     fs::inode* null_ind = nullptr;
     {
         auto* dent = fs::vfs_open("/dev/null");
-        if (!dent) {
-            delete[] phents;
-            delete[] shents;
+        if (!dent)
             kill_current(-1);
-        }
         null_ind = dent->ind;
     }
 
-    for (int i = 0; i < hdr.phnum; ++i) {
-        if (phents[i].type != types::elf::elf32_program_header_entry::PT_LOAD)
+    for (const auto& phent : phents) {
+        if (phent.type != types::elf::elf32_program_header_entry::PT_LOAD)
             continue;
 
-        auto vaddr = align_down<12>(phents[i].vaddr);
-        auto vlen = align_up<12>(phents[i].vaddr + phents[i].memsz) - vaddr;
-        auto flen = align_up<12>(phents[i].vaddr + phents[i].filesz) - vaddr;
-        auto fileoff = align_down<12>(phents[i].offset);
+        auto vaddr = align_down<12>(phent.vaddr);
+        auto vlen = align_up<12>(phent.vaddr + phent.memsz) - vaddr;
+        auto flen = align_up<12>(phent.vaddr + phent.filesz) - vaddr;
+        auto fileoff = align_down<12>(phent.offset);
 
         auto ret = mmap(
             (char*)vaddr,
-            phents[i].filesz + (phents[i].vaddr & 0xfff),
+            phent.filesz + (phent.vaddr & 0xfff),
             ent_exec->ind,
             fileoff,
             1,
             d->system);
 
         if (ret != GB_OK)
-            goto error;
+            kill_current(-1);
 
         if (vlen > flen) {
             ret = mmap(
@@ -133,20 +125,13 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
                 d->system);
 
             if (ret != GB_OK)
-                goto error;
+                kill_current(-1);
         }
-
-        continue;
-
-    error:
-        delete[] phents;
-        delete[] shents;
-        kill_current(-1);
     }
 
-    for (int i = 0; i < hdr.shnum; ++i) {
-        if (shents[i].sh_type == elf32_section_header_entry::SHT_NOBITS)
-            memset((char*)shents[i].sh_addr, 0x00, shents[i].sh_size);
+    for (const auto& shent : shents) {
+        if (shent.sh_type == elf32_section_header_entry::SHT_NOBITS)
+            memset((char*)shent.sh_addr, 0x00, shent.sh_size);
     }
 
     // map stack area
@@ -192,8 +177,5 @@ int types::elf::elf32_load(types::elf::elf32_load_data* d)
     // push argc
     _user_push(sp, args.size());
 
-    delete[] phents;
-    delete[] shents;
-
     return GB_OK;
 }