Added string class

This commit is contained in:
Alex
2023-02-06 19:24:05 +02:00
parent 0ddda954f6
commit 70ffb9936e
4 changed files with 354 additions and 1 deletions

233
include/string.hpp Normal file
View File

@ -0,0 +1,233 @@
#ifndef __FENNIX_KERNEL_STRING_H__
#define __FENNIX_KERNEL_STRING_H__
#include <types.h>
#include <convert.h>
#include <debug.h>
// show debug messages
// #define DEBUG_CPP_STRING 1
#ifdef DEBUG_CPP_STRING
#define strdbg(m, ...) debug(m, ##__VA_ARGS__)
#else
#define strdbg(m, ...)
#endif
// TODO: Somewhere the delete is called twice, causing a double free error.
/**
* @brief String class
* String class that can be used to store strings.
*/
class String
{
private:
char *m_Data;
int m_Length;
int m_Capacity;
public:
String(const char *Str = "")
{
this->m_Length = strlen(Str);
this->m_Capacity = this->m_Length + 1;
this->m_Data = new char[m_Capacity];
strcpy(m_Data, Str);
strdbg("New string created: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
}
~String()
{
strdbg("String deleted: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
delete[] this->m_Data;
}
int length() const
{
strdbg("String length: %d", this->m_Length);
return this->m_Length;
}
int capacity() const
{
strdbg("String capacity: %d", this->m_Capacity);
return this->m_Capacity;
}
const char *c_str() const
{
strdbg("String data: \"%s\"", this->m_Data);
return this->m_Data;
}
void resize(int NewLength)
{
strdbg("String resize: %d", NewLength);
if (NewLength > this->m_Capacity)
{
int newCapacity = NewLength + 1;
char *newData = new char[newCapacity];
strcpy(newData, this->m_Data);
strdbg("old: %#lx, new: %#lx", this->m_Data, newData);
delete[] this->m_Data;
this->m_Data = newData;
this->m_Capacity = newCapacity;
}
this->m_Length = NewLength;
this->m_Data[m_Length] = '\0';
strdbg("String resized: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
}
void concat(const String &Other)
{
int NewLength = this->m_Length + Other.m_Length;
this->resize(NewLength);
strcat(m_Data, Other.m_Data);
strdbg("String concatenated: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
}
String operator+(const String &Other) const
{
String result = *this;
result.concat(Other);
strdbg("String added: \"%s\" (data: %#lx, length: %d, capacity: %d)", result.m_Data, result.m_Data, result.m_Length, result.m_Capacity);
return result;
}
String operator+(const char *Other) const
{
String result = *this;
result.concat(Other);
strdbg("String added: \"%s\" (data: %#lx, length: %d, capacity: %d)", result.m_Data, result.m_Data, result.m_Length, result.m_Capacity);
return result;
}
/* warning: implicitly-declared constexpr String::String(const String&) is deprecated [-Wdeprecated-copy] */
String &operator=(const String &Other) = default;
// String &operator=(const String &Other)
// {
// if (this != &Other)
// {
// delete[] this->m_Data;
// this->m_Data = Other.m_Data;
// this->m_Length = Other.m_Length;
// this->m_Capacity = Other.m_Capacity;
// strdbg("String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
// }
// return *this;
// }
String &operator=(const char *Other)
{
this->m_Length = strlen(Other);
this->m_Capacity = this->m_Length + 1;
delete[] this->m_Data;
this->m_Data = new char[m_Capacity];
strcpy(m_Data, Other);
strdbg("String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
return *this;
}
String &operator<<(const String &Other)
{
this->concat(Other);
strdbg("String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
return *this;
}
String &operator<<(const char *Other)
{
this->concat(Other);
strdbg("String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
return *this;
}
char &operator[](int Index)
{
strdbg("String index: %d", Index);
return this->m_Data[Index];
}
const char &operator[](int Index) const
{
strdbg("String index: %d", Index);
return this->m_Data[Index];
}
bool operator==(const String &Other) const
{
strdbg("String compared: \"%s\" == \"%s\"", this->m_Data, Other.m_Data);
return strcmp(this->m_Data, Other.m_Data) == 0;
}
bool operator!=(const String &Other) const
{
strdbg("String compared: \"%s\" != \"%s\"", this->m_Data, Other.m_Data);
return strcmp(this->m_Data, Other.m_Data) != 0;
}
bool operator==(const char *Other) const
{
strdbg("String compared: \"%s\" == \"%s\"", this->m_Data, Other);
return strcmp(this->m_Data, Other) == 0;
}
bool operator!=(const char *Other) const
{
strdbg("String compared: \"%s\" != \"%s\"", this->m_Data, Other);
return strcmp(this->m_Data, Other) != 0;
}
class Iterator
{
private:
char *m_Pointer;
public:
Iterator(char *Pointer) : m_Pointer(Pointer) {}
Iterator &operator++()
{
++this->m_Pointer;
strdbg("String iterator incremented: %#lx", this->m_Pointer);
return *this;
}
char &operator*()
{
strdbg("String iterator dereferenced: %#lx", this->m_Pointer);
return *this->m_Pointer;
}
bool operator!=(const Iterator &Other) const
{
strdbg("String iterator compared: %#lx != %#lx", this->m_Pointer, Other.m_Pointer);
return this->m_Pointer != Other.m_Pointer;
}
bool operator==(const Iterator &Other) const
{
strdbg("String iterator compared: %#lx == %#lx", this->m_Pointer, Other.m_Pointer);
return this->m_Pointer == Other.m_Pointer;
}
};
Iterator begin()
{
strdbg("String iterator begin: %#lx", this->m_Data);
return Iterator(this->m_Data);
}
Iterator end()
{
strdbg("String iterator end: %#lx", this->m_Data + this->m_Length);
return Iterator(this->m_Data + this->m_Length);
}
};
#endif // !__FENNIX_KERNEL_STRING_H__