diff --git a/BAN/BAN/String.cpp b/BAN/BAN/String.cpp index ca9d1a78..b1b4c95a 100644 --- a/BAN/BAN/String.cpp +++ b/BAN/BAN/String.cpp @@ -185,6 +185,19 @@ namespace BAN return {}; } + ErrorOr String::shrink_to_fit() + { + size_type temp = m_capacity; + m_capacity = 0; + auto error_or = ensure_capacity(m_size); + if (error_or.is_error()) + { + m_capacity = temp; + return error_or; + } + return {}; + } + StringView String::sv() const { return StringView(*this); @@ -214,7 +227,7 @@ namespace BAN { if (m_capacity >= size) return {}; - size_type new_cap = BAN::Math::max(size, m_capacity * 3 / 2); + size_type new_cap = BAN::Math::max(size, m_capacity * 2); void* new_data = BAN::allocator(new_cap); if (new_data == nullptr) return Error::from_string("String: Could not allocate memory"); diff --git a/BAN/include/BAN/HashMap.h b/BAN/include/BAN/HashMap.h index e40df93a..d869c3c5 100644 --- a/BAN/include/BAN/HashMap.h +++ b/BAN/include/BAN/HashMap.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include namespace BAN @@ -29,6 +28,8 @@ namespace BAN template ErrorOr emplace(const Key&, Args&&...); + ErrorOr reserve(size_type); + void remove(const Key&); void clear(); @@ -55,11 +56,11 @@ namespace BAN private: ErrorOr rebucket(size_type); - LinkedList& get_bucket(const Key&); - const LinkedList& get_bucket(const Key&) const; + Vector& get_bucket(const Key&); + const Vector& get_bucket(const Key&) const; private: - Vector> m_buckets; + Vector> m_buckets; size_type m_size = 0; }; @@ -126,6 +127,13 @@ namespace BAN return {}; } + template + ErrorOr HashMap::reserve(size_type size) + { + TRY(rebucket(size)); + return {}; + } + template void HashMap::remove(const Key& key) { @@ -200,8 +208,8 @@ namespace BAN if (m_buckets.size() >= bucket_count) return {}; - size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 3 / 2); - Vector> new_buckets; + size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 2); + Vector> new_buckets; if (new_buckets.resize(new_bucket_count).is_error()) return Error::from_string("HashMap: Could not allocate memory"); @@ -222,7 +230,7 @@ namespace BAN } template - LinkedList::Entry>& HashMap::get_bucket(const Key& key) + Vector::Entry>& HashMap::get_bucket(const Key& key) { ASSERT(!m_buckets.empty()); auto index = HASH()(key) % m_buckets.size(); @@ -230,7 +238,7 @@ namespace BAN } template - const LinkedList::Entry>& HashMap::get_bucket(const Key& key) const + const Vector::Entry>& HashMap::get_bucket(const Key& key) const { ASSERT(!m_buckets.empty()); auto index = HASH()(key) % m_buckets.size(); diff --git a/BAN/include/BAN/HashSet.h b/BAN/include/BAN/HashSet.h index 6b435a37..7656ba77 100644 --- a/BAN/include/BAN/HashSet.h +++ b/BAN/include/BAN/HashSet.h @@ -33,6 +33,8 @@ namespace BAN void remove(const T&); void clear(); + ErrorOr reserve(size_type); + const_iterator begin() const { return const_iterator(this, m_buckets.begin()); } const_iterator end() const { return const_iterator(this, m_buckets.end()); } @@ -160,6 +162,13 @@ namespace BAN m_size = 0; } + template + ErrorOr HashSet::reserve(size_type size) + { + TRY(rebucket(size)); + return {}; + } + template bool HashSet::contains(const T& key) const { @@ -185,7 +194,7 @@ namespace BAN if (m_buckets.size() >= bucket_count) return {}; - size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 3 / 2); + size_type new_bucket_count = BAN::Math::max(bucket_count, m_buckets.size() * 2); Vector> new_buckets; if (new_buckets.resize(new_bucket_count).is_error()) return Error::from_string("HashSet: Could not allocate memory"); diff --git a/BAN/include/BAN/Queue.h b/BAN/include/BAN/Queue.h index 51e221bd..0ca50972 100644 --- a/BAN/include/BAN/Queue.h +++ b/BAN/include/BAN/Queue.h @@ -29,6 +29,9 @@ namespace BAN template ErrorOr emplace(Args&&...); + ErrorOr reserve(size_type); + ErrorOr shrink_to_fit(); + void pop(); void clear(); @@ -126,6 +129,27 @@ namespace BAN return {}; } + template + ErrorOr Queue::reserve(size_type size) + { + TRY(ensure_capacity(size)); + return {}; + } + + template + ErrorOr Queue::shrink_to_fit() + { + size_type temp = m_capacity; + m_capacity = 0; + auto error_or = ensure_capacity(m_size); + if (error_or.is_error()) + { + m_capacity = temp; + return error_or; + } + return {}; + } + template void Queue::pop() { @@ -178,7 +202,7 @@ namespace BAN { if (m_capacity > size) return {}; - size_type new_cap = BAN::Math::max(size, m_capacity * 3 / 2); + size_type new_cap = BAN::Math::max(size, m_capacity * 2); T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); if (new_data == nullptr) return Error::from_string("Queue: Could not allocate memory"); diff --git a/BAN/include/BAN/String.h b/BAN/include/BAN/String.h index fc3d993e..8747df36 100644 --- a/BAN/include/BAN/String.h +++ b/BAN/include/BAN/String.h @@ -30,7 +30,7 @@ namespace BAN ErrorOr insert(StringView, size_type); ErrorOr append(StringView); ErrorOr append(const String&); - + void pop_back(); void remove(size_type); void erase(size_type, size_type); @@ -46,6 +46,7 @@ namespace BAN ErrorOr resize(size_type, char = '\0'); ErrorOr reserve(size_type); + ErrorOr shrink_to_fit(); StringView sv() const; diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h index 5aa89739..3c1d01aa 100644 --- a/BAN/include/BAN/Vector.h +++ b/BAN/include/BAN/Vector.h @@ -64,6 +64,7 @@ namespace BAN ErrorOr resize(size_type); ErrorOr reserve(size_type); + ErrorOr shrink_to_fit(); bool empty() const; size_type size() const; @@ -330,6 +331,7 @@ namespace BAN ASSERT(m_size > 0); return m_data[0]; } + template T& Vector::front() { @@ -358,6 +360,20 @@ namespace BAN return {}; } + template + ErrorOr Vector::shrink_to_fit() + { + size_type temp = m_capacity; + m_capacity = 0; + auto error_or = ensure_capacity(m_size); + if (error_or.is_error()) + { + m_capacity = temp; + return error_or; + } + return {}; + } + template bool Vector::empty() const { @@ -381,7 +397,7 @@ namespace BAN { if (m_capacity >= size) return {}; - size_type new_cap = BAN::Math::max(size, m_capacity * 3 / 2); + size_type new_cap = BAN::Math::max(size, m_capacity * 2); T* new_data = (T*)BAN::allocator(new_cap * sizeof(T)); if (new_data == nullptr) return Error::from_string("Vector: Could not allocate memory");