update main #1

Merged
Sinipelto merged 240 commits from Bananymous/banan-os:main into main 2023-11-20 13:20:51 +02:00
2 changed files with 43 additions and 40 deletions
Showing only changes of commit f72fdeeb59 - Show all commits

View File

@ -1,6 +1,5 @@
#include <BAN/String.h>
#include <BAN/New.h>
#include <BAN/Variant.h>
namespace BAN
{
@ -32,8 +31,7 @@ namespace BAN
String& String::operator=(const String& other)
{
clear();
if (!other.fits_in_sso())
MUST(ensure_capacity(other.size()));
MUST(ensure_capacity(other.size()));
memcpy(data(), other.data(), other.size() + 1);
m_size = other.size();
return *this;
@ -43,14 +41,18 @@ namespace BAN
{
clear();
if (other.fits_in_sso())
if (other.has_sso())
memcpy(data(), other.data(), other.size() + 1);
else
m_storage = other.m_storage.get<GeneralStorage>();
{
m_storage.general_storage = other.m_storage.general_storage;
m_has_sso = false;
}
m_size = other.m_size;
other.m_size = 0;
other.m_storage = SSOStorage();
other.m_storage.sso_storage = SSOStorage();
other.m_has_sso = true;
return *this;
}
@ -58,8 +60,7 @@ namespace BAN
String& String::operator=(StringView other)
{
clear();
if (!fits_in_sso(other.size()))
MUST(ensure_capacity(other.size()));
MUST(ensure_capacity(other.size()));
memcpy(data(), other.data(), other.size());
m_size = other.size();
data()[m_size] = '\0';
@ -125,8 +126,9 @@ namespace BAN
{
if (!has_sso())
{
deallocator(m_storage.get<GeneralStorage>().data);
m_storage = SSOStorage();
deallocator(m_storage.general_storage.data);
m_storage.sso_storage = SSOStorage();
m_has_sso = true;
}
m_size = 0;
data()[m_size] = '\0';
@ -166,15 +168,6 @@ namespace BAN
data()[m_size] = '\0';
return {};
}
// shrink general -> sso
if (!has_sso() && fits_in_sso(new_size))
{
char* data = m_storage.get<GeneralStorage>().data;
m_storage = SSOStorage();
memcpy(m_storage.get<SSOStorage>().storage, data, new_size);
deallocator(data);
}
m_size = new_size;
data()[m_size] = '\0';
@ -194,20 +187,21 @@ namespace BAN
if (fits_in_sso())
{
char* data = m_storage.get<GeneralStorage>().data;
m_storage = SSOStorage();
memcpy(m_storage.get<SSOStorage>().storage, data, m_size + 1);
char* data = m_storage.general_storage.data;
m_storage.sso_storage = SSOStorage();
m_has_sso = true;
memcpy(this->data(), data, m_size + 1);
deallocator(data);
return {};
}
GeneralStorage& storage = m_storage.get<GeneralStorage>();
GeneralStorage& storage = m_storage.general_storage;
if (storage.capacity == m_size)
return {};
char* new_data = (char*)allocator(m_size + 1);
if (new_data == nullptr)
return BAN::Error::from_errno(ENOMEM);
return Error::from_errno(ENOMEM);
memcpy(new_data, storage.data, m_size);
deallocator(storage.data);
@ -222,40 +216,45 @@ namespace BAN
{
if (has_sso())
return sso_capacity;
return m_storage.get<GeneralStorage>().capacity;
return m_storage.general_storage.capacity;
}
char* String::data()
{
if (has_sso())
return m_storage.get<SSOStorage>().storage;
return m_storage.get<GeneralStorage>().data;
return m_storage.sso_storage.data;
return m_storage.general_storage.data;
}
const char* String::data() const
{
if (has_sso())
return m_storage.get<SSOStorage>().storage;
return m_storage.get<GeneralStorage>().data;
return m_storage.sso_storage.data;
return m_storage.general_storage.data;
}
ErrorOr<void> String::ensure_capacity(size_type new_size)
{
if (m_size >= new_size || fits_in_sso(new_size))
if (m_size >= new_size)
return {};
if (has_sso() && fits_in_sso(new_size))
return {};
char* new_data = (char*)allocator(new_size + 1);
if (new_data == nullptr)
return BAN::Error::from_errno(ENOMEM);
return Error::from_errno(ENOMEM);
memcpy(new_data, data(), m_size + 1);
if (has_sso())
m_storage = GeneralStorage();
{
m_storage.general_storage = GeneralStorage();
m_has_sso = false;
}
else
deallocator(m_storage.get<GeneralStorage>().data);
deallocator(m_storage.general_storage.data);
auto& storage = m_storage.get<GeneralStorage>();
auto& storage = m_storage.general_storage;
storage.capacity = new_size;
storage.data = new_data;
@ -264,7 +263,7 @@ namespace BAN
bool String::has_sso() const
{
return m_storage.has<SSOStorage>();
return m_has_sso;
}
}

View File

@ -82,17 +82,21 @@ namespace BAN
private:
struct SSOStorage
{
char storage[sso_capacity + 1] {};
char data[sso_capacity + 1] {};
};
struct GeneralStorage
{
size_type capacity { 0 };
char* data;
size_type capacity { 0 };
char* data { nullptr };
};
private:
Variant<SSOStorage, GeneralStorage> m_storage { SSOStorage() };
size_type m_size { 0 };
union {
SSOStorage sso_storage;
GeneralStorage general_storage;
} m_storage { .sso_storage = SSOStorage() };
size_type m_size : sizeof(size_type) * 8 - 1 { 0 };
size_type m_has_sso : 1 { true };
};
template<typename... Args>