diff --git a/include_std/list b/include_std/list
new file mode 100644
index 0000000..a15d258
--- /dev/null
+++ b/include_std/list
@@ -0,0 +1,221 @@
+/*
+ This file is part of Fennix Kernel.
+
+ Fennix Kernel is free software: you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of
+ the License, or (at your option) any later version.
+
+ Fennix Kernel is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fennix Kernel. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+namespace std
+{
+ template
+ class list
+ {
+ private:
+ struct lNode
+ {
+ T value;
+ lNode *prev;
+ lNode *next;
+
+ lNode(const T &v, lNode *p = nullptr, lNode *n = nullptr)
+ : value(v), prev(p), next(n) {}
+ };
+
+ lNode *head;
+ lNode *tail;
+ size_t size;
+
+ public:
+ list() : head(nullptr), tail(nullptr), size(0) {}
+ ~list() { clear(); }
+ list(const list &other) : head(nullptr), tail(nullptr), size(0) { *this = other; }
+
+ void push_back(const T &value)
+ {
+ lNode *new_node = new lNode(value, tail, nullptr);
+ if (empty())
+ {
+ head = tail = new_node;
+ }
+ else
+ {
+ tail->next = new_node;
+ tail = new_node;
+ }
+ ++size;
+ }
+
+ void pop_back()
+ {
+ if (empty())
+ {
+ throw std::runtime_error("list is empty");
+ }
+ else if (head == tail)
+ {
+ delete tail;
+ head = tail = nullptr;
+ --size;
+ }
+ else
+ {
+ lNode *old_tail = tail;
+ tail = tail->prev;
+ tail->next = nullptr;
+ delete old_tail;
+ --size;
+ }
+ }
+
+ void push_front(const T &value)
+ {
+ lNode *new_node = new lNode(value, nullptr, head);
+ if (empty())
+ {
+ head = tail = new_node;
+ }
+ else
+ {
+ head->prev = new_node;
+ head = new_node;
+ }
+ ++size;
+ }
+
+ void pop_front()
+ {
+ if (empty())
+ {
+ throw std::runtime_error("list is empty");
+ }
+ else if (head == tail)
+ {
+ delete head;
+ head = tail = nullptr;
+ --size;
+ }
+ else
+ {
+ lNode *old_head = head;
+ head = head->next;
+ head->prev = nullptr;
+ delete old_head;
+ --size;
+ }
+ }
+
+ bool empty() const { return size == 0; }
+
+ void clear()
+ {
+ while (!empty())
+ pop_back();
+ }
+
+ list &operator=(const list &other)
+ {
+ if (this != &other)
+ {
+ clear();
+ for (const T &value : other)
+ {
+ push_back(value);
+ }
+ }
+ return *this;
+ }
+
+ class iterator
+ {
+ private:
+ lNode *node;
+ friend class list;
+
+ public:
+ iterator(lNode *p = nullptr) : node(p) {}
+ T &operator*() const { return node->value; }
+ T *operator->() const { return &node->value; }
+
+ iterator &operator++()
+ {
+ node = node->next;
+ return *this;
+ }
+
+ iterator &operator--()
+ {
+ node = node->prev;
+ return *this;
+ }
+
+ iterator operator++(int)
+ {
+ iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ iterator operator--(int)
+ {
+ iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ bool operator==(const iterator &rhs) const { return node == rhs.node; }
+ bool operator!=(const iterator &rhs) const { return node != rhs.node; }
+ };
+
+ iterator begin() { return iterator(head); }
+ iterator end() { return iterator(nullptr); }
+
+ iterator insert(iterator pos, const T &value)
+ {
+ if (pos == end())
+ {
+ push_back(value);
+ return iterator(tail);
+ }
+ else if (pos == begin())
+ {
+ push_front(value);
+ return iterator(head);
+ }
+ else
+ {
+ lNode *p = pos.node;
+ lNode *new_node = new lNode(value, p->prev, p);
+ p->prev->next = new_node;
+ p->prev = new_node;
+ ++size;
+ return iterator(new_node);
+ }
+ }
+
+ iterator erase(iterator pos)
+ {
+ lNode *p = pos.node;
+ iterator next(p->next);
+ p->prev->next = p->next;
+ p->next->prev = p->prev;
+ delete p;
+ --size;
+ return next;
+ }
+ };
+}
diff --git a/include_std/std.hpp b/include_std/std.hpp
index 61e32f7..181436e 100644
--- a/include_std/std.hpp
+++ b/include_std/std.hpp
@@ -22,13 +22,13 @@
#define __FENNIX_KERNEL_STD_H__
#include
+#include
#include
#include
+#include
+#include
#include
-#include
#include
-#include
-#include
#include
#include
diff --git a/include_std/std/functional.hpp b/include_std/std/functional.hpp
index 12c6a4e..bd8cfd1 100644
--- a/include_std/std/functional.hpp
+++ b/include_std/std/functional.hpp
@@ -23,28 +23,28 @@
namespace std
{
- template
- struct hash
- {
- size_t operator()(const Key &key) const
- {
- static_assert(sizeof(size_t) == sizeof(uint64_t)); // size_t and uint64_t must have the same size
- const uint64_t fnv_offset_basis = 14695981039346656037ull;
- const uint64_t fnv_prime = 1099511628211ull;
+ template
+ struct hash
+ {
+ size_t operator()(const Key &key) const
+ {
+ static_assert(sizeof(size_t) == sizeof(uint64_t)); // size_t and uint64_t must have the same size
+ const uint64_t fnv_offset_basis = 14695981039346656037ull;
+ const uint64_t fnv_prime = 1099511628211ull;
- const uint8_t *data = reinterpret_cast(&key);
- const size_t size = sizeof(Key);
- uint64_t ret = fnv_offset_basis;
+ const uint8_t *data = reinterpret_cast(&key);
+ const size_t size = sizeof(Key);
+ uint64_t ret = fnv_offset_basis;
- for (size_t i = 0; i < size; ++i)
- {
- ret ^= static_cast(data[i]);
- ret *= fnv_prime;
- }
+ for (size_t i = 0; i < size; ++i)
+ {
+ ret ^= static_cast(data[i]);
+ ret *= fnv_prime;
+ }
- return static_cast(ret);
- }
- };
+ return static_cast(ret);
+ }
+ };
}
#endif // !__FENNIX_KERNEL_STD_FUNCTIONAL_H__
diff --git a/include_std/std/list.hpp b/include_std/std/list.hpp
deleted file mode 100644
index 5869cb0..0000000
--- a/include_std/std/list.hpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- This file is part of Fennix Kernel.
-
- Fennix Kernel is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- Fennix Kernel is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Fennix Kernel. If not, see .
-*/
-
-#ifndef __FENNIX_KERNEL_STD_LIST_H__
-#define __FENNIX_KERNEL_STD_LIST_H__
-
-#include
-#include
-
-namespace std
-{
- template
- class list
- {
- private:
- struct Node
- {
- T value;
- Node *prev;
- Node *next;
-
- Node(const T &v, Node *p = nullptr, Node *n = nullptr)
- : value(v), prev(p), next(n) {}
- };
-
- Node *head;
- Node *tail;
- size_t size;
-
- public:
- list() : head(nullptr), tail(nullptr), size(0) {}
- ~list() { clear(); }
- list(const list &other) : head(nullptr), tail(nullptr), size(0) { *this = other; }
-
- void push_back(const T &value)
- {
- Node *new_node = new Node(value, tail, nullptr);
- if (empty())
- {
- head = tail = new_node;
- }
- else
- {
- tail->next = new_node;
- tail = new_node;
- }
- ++size;
- }
-
- void pop_back()
- {
- if (empty())
- {
- throw std::runtime_error("list is empty");
- }
- else if (head == tail)
- {
- delete tail;
- head = tail = nullptr;
- --size;
- }
- else
- {
- Node *old_tail = tail;
- tail = tail->prev;
- tail->next = nullptr;
- delete old_tail;
- --size;
- }
- }
-
- void push_front(const T &value)
- {
- Node *new_node = new Node(value, nullptr, head);
- if (empty())
- {
- head = tail = new_node;
- }
- else
- {
- head->prev = new_node;
- head = new_node;
- }
- ++size;
- }
-
- void pop_front()
- {
- if (empty())
- {
- throw std::runtime_error("list is empty");
- }
- else if (head == tail)
- {
- delete head;
- head = tail = nullptr;
- --size;
- }
- else
- {
- Node *old_head = head;
- head = head->next;
- head->prev = nullptr;
- delete old_head;
- --size;
- }
- }
-
- bool empty() const { return size == 0; }
-
- void clear()
- {
- while (!empty())
- pop_back();
- }
-
- list &operator=(const list &other)
- {
- if (this != &other)
- {
- clear();
- for (const T &value : other)
- {
- push_back(value);
- }
- }
- return *this;
- }
-
- class iterator
- {
- private:
- Node *node;
- friend class list;
-
- public:
- iterator(Node *p = nullptr) : node(p) {}
- T &operator*() const { return node->value; }
- T *operator->() const { return &node->value; }
-
- iterator &operator++()
- {
- node = node->next;
- return *this;
- }
-
- iterator &operator--()
- {
- node = node->prev;
- return *this;
- }
-
- iterator operator++(int)
- {
- iterator tmp = *this;
- ++*this;
- return tmp;
- }
-
- iterator operator--(int)
- {
- iterator tmp = *this;
- --*this;
- return tmp;
- }
-
- bool operator==(const iterator &rhs) const { return node == rhs.node; }
- bool operator!=(const iterator &rhs) const { return node != rhs.node; }
- };
-
- iterator begin() { return iterator(head); }
- iterator end() { return iterator(nullptr); }
-
- iterator insert(iterator pos, const T &value)
- {
- if (pos == end())
- {
- push_back(value);
- return iterator(tail);
- }
- else if (pos == begin())
- {
- push_front(value);
- return iterator(head);
- }
- else
- {
- Node *p = pos.node;
- Node *new_node = new Node(value, p->prev, p);
- p->prev->next = new_node;
- p->prev = new_node;
- ++size;
- return iterator(new_node);
- }
- }
-
- iterator erase(iterator pos)
- {
- Node *p = pos.node;
- iterator next(p->next);
- p->prev->next = p->next;
- p->next->prev = p->prev;
- delete p;
- --size;
- return next;
- }
- };
-}
-
-#endif // !__FENNIX_KERNEL_STD_LIST_H__
diff --git a/include_std/std/smart_ptr.hpp b/include_std/std/smart_ptr.hpp
index f6bc275..996fd59 100644
--- a/include_std/std/smart_ptr.hpp
+++ b/include_std/std/smart_ptr.hpp
@@ -34,242 +34,242 @@
namespace std
{
- /**
- * @brief A smart pointer class
- *
- * This class is a smart pointer class. It is used to manage the lifetime of
- * objects. It is a reference counted pointer, so when the last reference to
- * the object is removed, the object is deleted.
- *
- * Basic Usage:
- * smart_ptr pointer(new char());
- * *pointer = 'a';
- * printf("%c", *pointer); // Prints "a"
- */
- template
- class smart_ptr
- {
- T *RealPointer;
+ /**
+ * @brief A smart pointer class
+ *
+ * This class is a smart pointer class. It is used to manage the lifetime of
+ * objects. It is a reference counted pointer, so when the last reference to
+ * the object is removed, the object is deleted.
+ *
+ * Basic Usage:
+ * smart_ptr pointer(new char());
+ * *pointer = 'a';
+ * printf("%c", *pointer); // Prints "a"
+ */
+ template
+ class smart_ptr
+ {
+ T *RealPointer;
- public:
- explicit smart_ptr(T *Pointer = nullptr)
- {
- spdbg("Smart pointer created (%#lx)", this->RealPointer);
- this->RealPointer = Pointer;
- }
+ public:
+ explicit smart_ptr(T *Pointer = nullptr)
+ {
+ spdbg("Smart pointer created (%#lx)", this->RealPointer);
+ this->RealPointer = Pointer;
+ }
- ~smart_ptr()
- {
- spdbg("Smart pointer deleted (%#lx)", this->RealPointer);
- delete this->RealPointer, this->RealPointer = nullptr;
- }
+ ~smart_ptr()
+ {
+ spdbg("Smart pointer deleted (%#lx)", this->RealPointer);
+ delete this->RealPointer, this->RealPointer = nullptr;
+ }
- T &operator*()
- {
- spdbg("Smart pointer dereferenced (%#lx)", this->RealPointer);
- return *this->RealPointer;
- }
+ T &operator*()
+ {
+ spdbg("Smart pointer dereferenced (%#lx)", this->RealPointer);
+ return *this->RealPointer;
+ }
- T *operator->()
- {
- spdbg("Smart pointer dereferenced (%#lx)", this->RealPointer);
- return this->RealPointer;
- }
+ T *operator->()
+ {
+ spdbg("Smart pointer dereferenced (%#lx)", this->RealPointer);
+ return this->RealPointer;
+ }
- T *get()
- {
- spdbg("Smart pointer returned (%#lx)", this->RealPointer);
- return this->RealPointer;
- }
- };
+ T *get()
+ {
+ spdbg("Smart pointer returned (%#lx)", this->RealPointer);
+ return this->RealPointer;
+ }
+ };
- template
- class auto_ptr
- {
- };
+ template
+ class auto_ptr
+ {
+ };
- template
- class unique_ptr
- {
- };
+ template
+ class unique_ptr
+ {
+ };
- template
- class weak_ptr
- {
- };
+ template
+ class weak_ptr
+ {
+ };
- template
- class shared_ptr
- {
- private:
- class counter
- {
- private:
- unsigned int RefCount{};
+ template
+ class shared_ptr
+ {
+ private:
+ class counter
+ {
+ private:
+ unsigned int RefCount{};
- public:
- counter() : RefCount(0) { spdbg("Counter %#lx created", this); };
- counter(const counter &) = delete;
- counter &operator=(const counter &) = delete;
- ~counter() { spdbg("Counter %#lx deleted", this); }
- void reset()
- {
- this->RefCount = 0;
- spdbg("reset");
- }
+ public:
+ counter() : RefCount(0) { spdbg("Counter %#lx created", this); };
+ counter(const counter &) = delete;
+ counter &operator=(const counter &) = delete;
+ ~counter() { spdbg("Counter %#lx deleted", this); }
+ void reset()
+ {
+ this->RefCount = 0;
+ spdbg("reset");
+ }
- unsigned int get()
- {
- return this->RefCount;
- spdbg("return");
- }
+ unsigned int get()
+ {
+ return this->RefCount;
+ spdbg("return");
+ }
- void operator++()
- {
- this->RefCount++;
- spdbg("increment");
- }
+ void operator++()
+ {
+ this->RefCount++;
+ spdbg("increment");
+ }
- void operator++(int)
- {
- this->RefCount++;
- spdbg("increment");
- }
+ void operator++(int)
+ {
+ this->RefCount++;
+ spdbg("increment");
+ }
- void operator--()
- {
- this->RefCount--;
- spdbg("decrement");
- }
+ void operator--()
+ {
+ this->RefCount--;
+ spdbg("decrement");
+ }
- void operator--(int)
- {
- this->RefCount--;
- spdbg("decrement");
- }
- };
+ void operator--(int)
+ {
+ this->RefCount--;
+ spdbg("decrement");
+ }
+ };
- counter *ReferenceCounter;
- T *RealPointer;
+ counter *ReferenceCounter;
+ T *RealPointer;
- public:
- explicit shared_ptr(T *Pointer = nullptr)
- {
- this->RealPointer = Pointer;
- this->ReferenceCounter = new counter();
- spdbg("[%#lx] Shared pointer created (ptr=%#lx, ref=%#lx)", this, Pointer, this->ReferenceCounter);
- if (Pointer)
- (*this->ReferenceCounter)++;
- }
+ public:
+ explicit shared_ptr(T *Pointer = nullptr)
+ {
+ this->RealPointer = Pointer;
+ this->ReferenceCounter = new counter();
+ spdbg("[%#lx] Shared pointer created (ptr=%#lx, ref=%#lx)", this, Pointer, this->ReferenceCounter);
+ if (Pointer)
+ (*this->ReferenceCounter)++;
+ }
- shared_ptr(shared_ptr &SPtr)
- {
- spdbg("[%#lx] Shared pointer copied (ptr=%#lx, ref=%#lx)", this, SPtr.RealPointer, SPtr.ReferenceCounter);
- this->RealPointer = SPtr.RealPointer;
- this->ReferenceCounter = SPtr.ReferenceCounter;
- (*this->ReferenceCounter)++;
- }
+ shared_ptr(shared_ptr &SPtr)
+ {
+ spdbg("[%#lx] Shared pointer copied (ptr=%#lx, ref=%#lx)", this, SPtr.RealPointer, SPtr.ReferenceCounter);
+ this->RealPointer = SPtr.RealPointer;
+ this->ReferenceCounter = SPtr.ReferenceCounter;
+ (*this->ReferenceCounter)++;
+ }
- ~shared_ptr()
- {
- spdbg("[%#lx] Shared pointer destructor called", this);
- (*this->ReferenceCounter)--;
- if (this->ReferenceCounter->get() == 0)
- {
- spdbg("[%#lx] Shared pointer deleted (ptr=%#lx, ref=%#lx)", this, this->RealPointer, this->ReferenceCounter);
- delete this->ReferenceCounter, this->ReferenceCounter = nullptr;
- delete this->RealPointer, this->RealPointer = nullptr;
- }
- }
+ ~shared_ptr()
+ {
+ spdbg("[%#lx] Shared pointer destructor called", this);
+ (*this->ReferenceCounter)--;
+ if (this->ReferenceCounter->get() == 0)
+ {
+ spdbg("[%#lx] Shared pointer deleted (ptr=%#lx, ref=%#lx)", this, this->RealPointer, this->ReferenceCounter);
+ delete this->ReferenceCounter, this->ReferenceCounter = nullptr;
+ delete this->RealPointer, this->RealPointer = nullptr;
+ }
+ }
- unsigned int get_count()
- {
- spdbg("[%#lx] Shared pointer count (%d)", this, this->ReferenceCounter->get());
- return this->ReferenceCounter->get();
- }
+ unsigned int get_count()
+ {
+ spdbg("[%#lx] Shared pointer count (%d)", this, this->ReferenceCounter->get());
+ return this->ReferenceCounter->get();
+ }
- T *get()
- {
- spdbg("[%#lx] Shared pointer get (%#lx)", this, this->RealPointer);
- return this->RealPointer;
- }
+ T *get()
+ {
+ spdbg("[%#lx] Shared pointer get (%#lx)", this, this->RealPointer);
+ return this->RealPointer;
+ }
- T &operator*()
- {
- spdbg("[%#lx] Shared pointer dereference (ptr*=%#lx)", this, *this->RealPointer);
- return *this->RealPointer;
- }
+ T &operator*()
+ {
+ spdbg("[%#lx] Shared pointer dereference (ptr*=%#lx)", this, *this->RealPointer);
+ return *this->RealPointer;
+ }
- T *operator->()
- {
- spdbg("[%#lx] Shared pointer dereference (ptr->%#lx)", this, this->RealPointer);
- return this->RealPointer;
- }
+ T *operator->()
+ {
+ spdbg("[%#lx] Shared pointer dereference (ptr->%#lx)", this, this->RealPointer);
+ return this->RealPointer;
+ }
- void reset(T *Pointer = nullptr)
- {
- if (this->RealPointer == Pointer)
- return;
- spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, Pointer, this->ReferenceCounter);
- (*this->ReferenceCounter)--;
- if (this->ReferenceCounter->get() == 0)
- {
- delete this->RealPointer;
- delete this->ReferenceCounter;
- }
- this->RealPointer = Pointer;
- this->ReferenceCounter = new counter();
- if (Pointer)
- (*this->ReferenceCounter)++;
- }
+ void reset(T *Pointer = nullptr)
+ {
+ if (this->RealPointer == Pointer)
+ return;
+ spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, Pointer, this->ReferenceCounter);
+ (*this->ReferenceCounter)--;
+ if (this->ReferenceCounter->get() == 0)
+ {
+ delete this->RealPointer;
+ delete this->ReferenceCounter;
+ }
+ this->RealPointer = Pointer;
+ this->ReferenceCounter = new counter();
+ if (Pointer)
+ (*this->ReferenceCounter)++;
+ }
- void reset()
- {
- spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, this->RealPointer, this->ReferenceCounter);
- if (this->ReferenceCounter->get() == 1)
- {
- delete this->RealPointer, this->RealPointer = nullptr;
- delete this->ReferenceCounter, this->ReferenceCounter = nullptr;
- }
- else
- {
- (*this->ReferenceCounter)--;
- }
- }
+ void reset()
+ {
+ spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, this->RealPointer, this->ReferenceCounter);
+ if (this->ReferenceCounter->get() == 1)
+ {
+ delete this->RealPointer, this->RealPointer = nullptr;
+ delete this->ReferenceCounter, this->ReferenceCounter = nullptr;
+ }
+ else
+ {
+ (*this->ReferenceCounter)--;
+ }
+ }
- void swap(shared_ptr &Other)
- {
- spdbg("[%#lx] Shared pointer swap (ptr=%#lx, ref=%#lx <=> ptr=%#lx, ref=%#lx)",
- this, this->RealPointer, this->ReferenceCounter, Other.RealPointer, Other.ReferenceCounter);
- T *tempRealPointer = this->RealPointer;
- counter *tempReferenceCounter = this->ReferenceCounter;
- this->RealPointer = Other.RealPointer;
- this->ReferenceCounter = Other.ReferenceCounter;
- Other.RealPointer = tempRealPointer;
- Other.ReferenceCounter = tempReferenceCounter;
- }
- };
+ void swap(shared_ptr &Other)
+ {
+ spdbg("[%#lx] Shared pointer swap (ptr=%#lx, ref=%#lx <=> ptr=%#lx, ref=%#lx)",
+ this, this->RealPointer, this->ReferenceCounter, Other.RealPointer, Other.ReferenceCounter);
+ T *tempRealPointer = this->RealPointer;
+ counter *tempReferenceCounter = this->ReferenceCounter;
+ this->RealPointer = Other.RealPointer;
+ this->ReferenceCounter = Other.ReferenceCounter;
+ Other.RealPointer = tempRealPointer;
+ Other.ReferenceCounter = tempReferenceCounter;
+ }
+ };
- template
- using remove_reference_t = typename remove_reference::type;
+ template
+ using remove_reference_t = typename remove_reference::type;
- template
- T &&forward(remove_reference_t &t) { return static_cast(t); };
+ template
+ T &&forward(remove_reference_t &t) { return static_cast(t); };
- template
- T &&forward(remove_reference_t &&t) { return static_cast(t); };
+ template
+ T &&forward(remove_reference_t &&t) { return static_cast(t); };
- template
- shared_ptr make_shared(Args &&...args)
- {
- return shared_ptr(new T(forward(args)...));
- };
+ template
+ shared_ptr make_shared(Args &&...args)
+ {
+ return shared_ptr(new T(forward(args)...));
+ };
- template
- smart_ptr make_smart(Args &&...args)
- {
- return smart_ptr(new T(forward(args)...));
- };
+ template
+ smart_ptr make_smart(Args &&...args)
+ {
+ return smart_ptr(new T(forward(args)...));
+ };
}
#endif // !__FENNIX_KERNEL_STD_SMART_POINTER_H__
diff --git a/include_std/std/string.hpp b/include_std/std/string.hpp
deleted file mode 100644
index f0dd0ad..0000000
--- a/include_std/std/string.hpp
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- This file is part of Fennix Kernel.
-
- Fennix Kernel is free software: you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of
- the License, or (at your option) any later version.
-
- Fennix Kernel is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Fennix Kernel. If not, see .
-*/
-
-#ifndef __FENNIX_KERNEL_STD_STRING_H__
-#define __FENNIX_KERNEL_STD_STRING_H__
-
-#include
-#include
-#include
-
-// Show debug messages
-// #define DEBUG_CPP_STRING 1
-// #define DEBUG_CPP_STRING_VERBOSE 1
-
-#ifdef DEBUG_CPP_STRING
-#define strdbg(m, ...) debug(m, ##__VA_ARGS__)
-#else
-#define strdbg(m, ...)
-#endif
-
-#ifdef DEBUG_CPP_STRING_VERBOSE
-#define v_strdbg(m, ...) debug(m, ##__VA_ARGS__)
-#else
-#define v_strdbg(m, ...)
-#endif
-
-// TODO: Somewhere the delete is called twice, causing a double free error.
-
-namespace std
-{
- /**
- * @brief String class
- * String class that can be used to store strings.
- */
- class string
- {
- private:
- char *Data{};
- size_t Length{};
- size_t Capacity{};
-
- public:
- static const size_t npos = -1;
-
- string(const char *Str = "")
- {
- this->Length = strlen(Str);
- this->Capacity = this->Length + 1;
- this->Data = new char[this->Capacity];
- strcpy(this->Data, Str);
- strdbg("%#lx: New string created: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- ~string()
- {
- strdbg("%#lx: String deleted: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- delete[] this->Data, this->Data = nullptr;
- }
-
- size_t length() const
- {
- v_strdbg("%#lx: String length: %d",
- this, this->Length);
- return this->Length;
- }
-
- size_t capacity() const
- {
- v_strdbg("%#lx: String capacity: %d",
- this, this->Capacity);
- return this->Capacity;
- }
-
- const char *c_str() const
- {
- v_strdbg("%#lx: String data: \"%s\"",
- this, this->Data);
- return this->Data;
- }
-
- void resize(size_t NewLength)
- {
- strdbg("%#lx: String resize: %d",
- this, NewLength);
- if (NewLength < this->Capacity)
- {
- this->Length = NewLength;
- this->Data[this->Length] = '\0';
-
- strdbg("%#lx: String resized: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return;
- }
-
- size_t newCapacity = NewLength + 1;
- char *newData = new char[newCapacity];
- strcpy(newData, this->Data);
-
- strdbg("%#lx: old: %#lx, new: %#lx",
- this, this->Data, newData);
-
- delete[] this->Data;
- this->Data = newData;
- this->Length = NewLength;
- this->Capacity = newCapacity;
-
- strdbg("%#lx: String resized: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- void concat(const string &Other)
- {
- size_t NewLength = this->Length + Other.Length;
- this->resize(NewLength);
-
- strcat(this->Data, Other.Data);
- strdbg("%#lx: String concatenated: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- bool empty() const
- {
- strdbg("%#lx: String empty: %d",
- this, this->Length == 0);
- return this->Length == 0;
- }
-
- size_t size() const
- {
- strdbg("%#lx: String size: %d",
- this, this->Length);
- return this->Length;
- }
-
- void clear()
- {
- strdbg("%#lx: String clear", this);
- this->resize(0);
- }
-
- size_t find(const char *Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String find: \"%s\", %d",
- this, Str, Pos);
- if (Pos >= this->Length)
- return npos;
-
- for (size_t i = Pos; i < this->Length; i++)
- {
- bool found = true;
- for (size_t j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i + j] != Str[j])
- {
- found = false;
- break;
- }
- }
- if (found)
- return i;
- }
- return npos;
- }
-
- size_t find(const string &Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String find: \"%s\", %d",
- this, Str.c_str(), Pos);
- return this->find(Str.c_str(), Pos);
- }
-
- void erase(int Index, int Count = 1)
- {
- strdbg("%#lx: String erase: %d, %d",
- this, Index, Count);
- if (Index < 0 || (size_t)Index >= this->Length)
- return;
-
- if (Count < 0)
- return;
-
- if ((size_t)(Index + Count) > this->Length)
- Count = (int)this->Length - Index;
-
- for (size_t i = Index; i < this->Length - Count; i++)
- this->Data[i] = this->Data[i + Count];
-
- this->Length -= Count;
- this->Data[this->Length] = '\0';
- strdbg("%#lx: String erased: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- size_t find_last_not_of(const char *Str, size_t Pos = npos) const
- {
- strdbg("%#lx: String find_last_not_of: \"%s\", %d",
- this, Str, Pos);
- if (Pos == npos)
- Pos = this->Length - 1;
-
- for (int i = (int)Pos; i >= 0; i--)
- {
- bool found = false;
- for (size_t j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i] == Str[j])
- {
- found = true;
- break;
- }
- }
- if (!found)
- return i;
- }
- return npos;
- }
-
- size_t find_first_not_of(const char *Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String find_first_not_of: \"%s\", %d",
- this, Str, Pos);
- if (Pos >= this->Length)
- return npos;
-
- for (size_t i = Pos; i < this->Length; i++)
- {
- bool found = false;
- for (size_t j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i] == Str[j])
- {
- found = true;
- break;
- }
- }
- if (!found)
- return i;
- }
- return npos;
- }
-
- size_t find_first_of(const char *Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String find_first_of: \"%s\", %d",
- this, Str, Pos);
- if (Pos >= this->Length)
- return npos;
-
- for (size_t i = Pos; i < this->Length; i++)
- {
- bool found = false;
- for (size_t j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i] == Str[j])
- {
- found = true;
- break;
- }
- }
- if (found)
- return i;
- }
- return npos;
- }
-
- size_t find_last_of(const char *Str, size_t Pos = npos) const
- {
- strdbg("%#lx: String find_last_of: \"%s\", %d",
- this, Str, Pos);
- if (Pos == npos)
- Pos = this->Length - 1;
-
- for (int i = (int)Pos; i >= 0; i--)
- {
- bool found = false;
- for (int j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i] == Str[j])
- {
- found = true;
- break;
- }
- }
- if (found)
- return i;
- }
- return npos;
- }
-
- size_t find_first_of(char C, size_t Pos = 0) const
- {
- strdbg("%#lx: String find_first_of: '%c', %d",
- this, C, Pos);
- if (Pos >= this->Length)
- return npos;
-
- for (size_t i = Pos; i < this->Length; i++)
- {
- if (this->Data[i] == C)
- return i;
- }
- return npos;
- }
-
- size_t find_last_of(char C, size_t Pos = npos) const
- {
- strdbg("%#lx: String find_last_of: '%c', %d",
- this, C, Pos);
- if (Pos == npos)
- Pos = this->Length - 1;
-
- for (int i = (int)Pos; i >= 0; i--)
- {
- if (this->Data[i] == C)
- return i;
- }
- return npos;
- }
-
- size_t substr(const char *Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String substr: \"%s\", %d",
- this, Str, Pos);
- if (Pos >= this->Length)
- return npos;
-
- for (size_t i = Pos; i < this->Length; i++)
- {
- bool found = true;
- for (size_t j = 0; Str[j] != '\0'; j++)
- {
- if (this->Data[i + j] != Str[j])
- {
- found = false;
- break;
- }
- }
- if (found)
- return i;
- }
- return npos;
- }
-
- size_t substr(const string &Str, size_t Pos = 0) const
- {
- strdbg("%#lx: String substr: \"%s\", %d",
- this, Str.c_str(), Pos);
- return this->substr(Str.c_str(), Pos);
- }
-
- string substr(size_t Pos = 0, size_t Count = npos) const
- {
- strdbg("%#lx: String substr: %d, %d",
- this, Pos, Count);
- if (Pos >= this->Length)
- return string();
-
- if (Count == npos)
- Count = this->Length - Pos;
-
- if (Pos + Count > this->Length)
- Count = this->Length - Pos;
-
- string ret;
- ret.resize(Count);
- for (size_t i = 0; i < Count; i++)
- ret.Data[i] = this->Data[Pos + i];
- ret.Data[Count] = '\0';
- return ret;
- }
-
- void replace(size_t Pos, size_t Count, const char *Str)
- {
- strdbg("%#lx: String replace: %d, %d, \"%s\"",
- this, Pos, Count, Str);
- if (Pos >= this->Length)
- return;
-
- if ((int64_t)Count <= 0)
- return;
-
- if (Pos + Count > this->Length)
- Count = this->Length - Pos;
-
- size_t NewLength = this->Length - Count + strlen(Str);
- this->resize(NewLength);
-
- for (size_t i = this->Length - 1; i >= Pos + strlen(Str); i--)
- this->Data[i] = this->Data[i - strlen(Str) + Count];
-
- for (unsigned long i = 0; i < strlen(Str); i++)
- this->Data[Pos + i] = Str[i];
-
- strdbg("%#lx: String replaced: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- void replace(size_t Pos, size_t Count, const string &Str)
- {
- strdbg("%#lx: String replace: %d, %d, \"%s\"",
- this, Pos, Count, Str.Data);
- if (Pos >= this->Length)
- return;
-
- if ((int64_t)Count <= 0)
- return;
-
- if (Pos + Count > this->Length)
- Count = this->Length - Pos;
-
- size_t NewLength = this->Length - Count + Str.Length;
- this->resize(NewLength);
-
- for (size_t i = this->Length - 1; i >= Pos + Str.Length; i--)
- this->Data[i] = this->Data[i - Str.Length + Count];
-
- for (size_t i = 0; i < Str.Length; i++)
- this->Data[Pos + i] = Str.Data[i];
-
- strdbg("%#lx: String replaced: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- }
-
- void pop_back()
- {
- strdbg("%#lx: String pop_back", this);
- if (this->Length > 0)
- {
- this->Data[this->Length - 1] = '\0';
- this->Length--;
- }
- }
-
- string operator+(const string &Other) const
- {
- string result = *this;
- result.concat(Other);
- strdbg("%#lx: String added: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, result.Data, result.Data, result.Length, result.Capacity);
- return result;
- }
-
- string operator+(const char *Other) const
- {
- string result = *this;
- result.concat(Other);
- strdbg("%#lx: String added: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, result.Data, result.Data, result.Length, result.Capacity);
- return result;
- }
-
- string &operator+=(const string &Other)
- {
- this->concat(Other);
- strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- string &operator+=(const char *Other)
- {
- this->concat(Other);
- strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- string &operator+=(char Other)
- {
- const char str[2] = {Other, '\0'};
- this->concat(str);
- strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- /* 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->Data;
- // this->Data = Other.Data;
- // this->Length = Other.Length;
- // this->Capacity = Other.Capacity;
- // strdbg("%#lx: String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- // this, this->Data, this->Data, this->Length, this->Capacity);
- // }
- // return *this;
- // }
-
- string &operator=(const char *Other)
- {
- this->Length = strlen(Other);
- this->Capacity = this->Length + 1;
- delete[] this->Data;
- this->Data = new char[this->Capacity];
- strcpy(this->Data, Other);
- strdbg("%#lx: String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- string &operator<<(const string &Other)
- {
- this->concat(Other);
- strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- string &operator<<(const char *Other)
- {
- this->concat(Other);
- strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
- this, this->Data, this->Data, this->Length, this->Capacity);
- return *this;
- }
-
- char &operator[](int Index)
- {
- strdbg("%#lx: String index: %d", this, Index);
- return this->Data[Index];
- }
-
- const char &operator[](int Index) const
- {
- strdbg("%#lx: String index: %d", this, Index);
- return this->Data[Index];
- }
-
- char &operator[](size_t Index)
- {
- strdbg("%#lx: String index: %d", this, Index);
- return this->Data[Index];
- }
-
- const char &operator[](size_t Index) const
- {
- strdbg("%#lx: String index: %d", this, Index);
- return this->Data[Index];
- }
-
- bool operator==(const string &Other) const
- {
- strdbg("%#lx: String compared: \"%s\" == \"%s\"",
- this, this->Data, Other.Data);
- return strcmp(this->Data, Other.Data) == 0;
- }
-
- bool operator!=(const char *Other) const
- {
- strdbg("%#lx: String compared: \"%s\" != \"%s\"",
- this, this->Data, Other);
- return strcmp(this->Data, Other) != 0;
- }
-
- bool operator!=(const string &Other) const
- {
- strdbg("%#lx: String compared: \"%s\" != \"%s\"",
- this, this->Data, Other.Data);
- return strcmp(this->Data, Other.Data) != 0;
- }
-
- bool operator==(const char *Other) const
- {
- strdbg("%#lx: String compared: \"%s\" == \"%s\"",
- this, this->Data, Other);
- return strcmp(this->Data, Other) == 0;
- }
-
- class iterator
- {
- private:
- char *Pointer;
-
- public:
- iterator(char *Pointer) : Pointer(Pointer) {}
-
- iterator &operator++()
- {
- ++this->Pointer;
- strdbg("%#lx: String iterator incremented: %#lx",
- this, this->Pointer);
- return *this;
- }
-
- char &operator*()
- {
- strdbg("%#lx: String iterator dereferenced: %#lx",
- this, this->Pointer);
- return *this->Pointer;
- }
-
- bool operator!=(const iterator &Other) const
- {
- strdbg("%#lx: String iterator compared: %#lx != %#lx",
- this, this->Pointer, Other.Pointer);
- return this->Pointer != Other.Pointer;
- }
-
- bool operator==(const iterator &Other) const
- {
- strdbg("%#lx: String iterator compared: %#lx == %#lx",
- this, this->Pointer, Other.Pointer);
- return this->Pointer == Other.Pointer;
- }
- };
-
- iterator begin()
- {
- strdbg("%#lx: String iterator begin: %#lx",
- this, this->Data);
- return iterator(this->Data);
- }
-
- iterator end()
- {
- strdbg("%#lx: String iterator end: %#lx",
- this, this->Data + this->Length);
- return iterator(this->Data + this->Length);
- }
- };
-}
-
-#endif // !__FENNIX_KERNEL_STD_STRING_H__
diff --git a/include_std/std/unordered_map.hpp b/include_std/std/unordered_map.hpp
index 84ae6e7..1532b16 100644
--- a/include_std/std/unordered_map.hpp
+++ b/include_std/std/unordered_map.hpp
@@ -21,8 +21,8 @@
#include
#include
#include
-#include
#include
+#include
namespace std
{
diff --git a/include_std/std/utility.hpp b/include_std/std/utility.hpp
index 518fdfe..9c2b16e 100644
--- a/include_std/std/utility.hpp
+++ b/include_std/std/utility.hpp
@@ -22,18 +22,18 @@
namespace std
{
- template
- struct pair
- {
- typedef T1 first_type;
- typedef T2 second_type;
+ template
+ struct pair
+ {
+ typedef T1 first_type;
+ typedef T2 second_type;
- T1 first;
- T2 second;
+ T1 first;
+ T2 second;
- pair() : first(T1()), second(T2()) {}
- pair(const T1 &x, const T2 &y) : first(x), second(y) {}
- };
+ pair() : first(T1()), second(T2()) {}
+ pair(const T1 &x, const T2 &y) : first(x), second(y) {}
+ };
}
#endif // !__FENNIX_KERNEL_STD_UTILITY_H__
diff --git a/include_std/std/stdexcept.hpp b/include_std/stdexcept
similarity index 65%
rename from include_std/std/stdexcept.hpp
rename to include_std/stdexcept
index 5f35d50..c5aef13 100644
--- a/include_std/std/stdexcept.hpp
+++ b/include_std/stdexcept
@@ -15,22 +15,17 @@
along with Fennix Kernel. If not, see .
*/
-#ifndef __FENNIX_KERNEL_STD_STDEXCEPT_H__
-#define __FENNIX_KERNEL_STD_STDEXCEPT_H__
-
-#include
+#pragma once
namespace std
{
- class runtime_error
- {
- private:
- const char *m_what;
+ class runtime_error
+ {
+ private:
+ const char *m_what;
- public:
- runtime_error(const char *what_arg) : m_what(what_arg) {}
- const char *what() const { return this->m_what; }
- };
+ public:
+ runtime_error(const char *what_arg) : m_what(what_arg) {}
+ const char *what() const { return this->m_what; }
+ };
}
-
-#endif // !__FENNIX_KERNEL_STD_STDEXCEPT_H__
diff --git a/include_std/string b/include_std/string
index 928ea3f..a1ba00d 100644
--- a/include_std/string
+++ b/include_std/string
@@ -16,4 +16,667 @@
*/
#pragma once
-#include
+#include
+#include
+#include
+
+// Show debug messages
+// #define DEBUG_CPP_STRING 1
+// #define DEBUG_CPP_STRING_VERBOSE 1
+
+#ifdef DEBUG_CPP_STRING
+#define strdbg(m, ...) debug(m, ##__VA_ARGS__)
+#else
+#define strdbg(m, ...)
+#endif
+
+#ifdef DEBUG_CPP_STRING_VERBOSE
+#define v_strdbg(m, ...) debug(m, ##__VA_ARGS__)
+#else
+#define v_strdbg(m, ...)
+#endif
+
+// TODO: Somewhere the delete is called twice, causing a double free error.
+
+namespace std
+{
+ template
+ char *to_string(T value)
+ {
+ static char buffer[1024];
+ bool isNegative = false;
+ int index = 0;
+
+ if (value < 0)
+ {
+ isNegative = true;
+ value = -value;
+ }
+
+ if (value == 0)
+ buffer[index++] = '0';
+ else
+ {
+ while (value > 0)
+ {
+ buffer[index++] = (char)(48 /*'0'*/ + (value % 10));
+ value /= 10;
+ }
+ }
+
+ if (isNegative)
+ buffer[index++] = '-';
+
+ int start = isNegative ? 1 : 0;
+ int end = index - 1;
+ while (start < end)
+ {
+ char temp = buffer[start];
+ buffer[start] = buffer[end];
+ buffer[end] = temp;
+ start++;
+ end--;
+ }
+
+ buffer[index] = '\0';
+ return buffer;
+ }
+
+ /**
+ * @brief String class
+ * String class that can be used to store strings.
+ */
+ class string
+ {
+ private:
+ char *Data{};
+ size_t Length{};
+ size_t Capacity{};
+
+ public:
+ static const size_t npos = -1;
+
+ string(const char *Str = "")
+ {
+ this->Length = strlen(Str);
+ this->Capacity = this->Length + 1;
+ this->Data = new char[this->Capacity];
+ strcpy(this->Data, Str);
+ strdbg("%#lx: New string created: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ ~string()
+ {
+ strdbg("%#lx: String deleted: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ delete[] this->Data, this->Data = nullptr;
+ }
+
+ size_t length() const
+ {
+ v_strdbg("%#lx: String length: %d",
+ this, this->Length);
+ return this->Length;
+ }
+
+ size_t capacity() const
+ {
+ v_strdbg("%#lx: String capacity: %d",
+ this, this->Capacity);
+ return this->Capacity;
+ }
+
+ const char *c_str() const
+ {
+ v_strdbg("%#lx: String data: \"%s\"",
+ this, this->Data);
+ return this->Data;
+ }
+
+ void resize(size_t NewLength)
+ {
+ strdbg("%#lx: String resize: %d",
+ this, NewLength);
+ if (NewLength < this->Capacity)
+ {
+ this->Length = NewLength;
+ this->Data[this->Length] = '\0';
+
+ strdbg("%#lx: String resized: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return;
+ }
+
+ size_t newCapacity = NewLength + 1;
+ char *newData = new char[newCapacity];
+ strcpy(newData, this->Data);
+
+ strdbg("%#lx: old: %#lx, new: %#lx",
+ this, this->Data, newData);
+
+ delete[] this->Data;
+ this->Data = newData;
+ this->Length = NewLength;
+ this->Capacity = newCapacity;
+
+ strdbg("%#lx: String resized: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ void concat(const string &Other)
+ {
+ size_t NewLength = this->Length + Other.Length;
+ this->resize(NewLength);
+
+ strcat(this->Data, Other.Data);
+ strdbg("%#lx: String concatenated: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ bool empty() const
+ {
+ strdbg("%#lx: String empty: %d",
+ this, this->Length == 0);
+ return this->Length == 0;
+ }
+
+ size_t size() const
+ {
+ strdbg("%#lx: String size: %d",
+ this, this->Length);
+ return this->Length;
+ }
+
+ void clear()
+ {
+ strdbg("%#lx: String clear", this);
+ this->resize(0);
+ }
+
+ size_t find(const char *Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String find: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos >= this->Length)
+ return npos;
+
+ for (size_t i = Pos; i < this->Length; i++)
+ {
+ bool found = true;
+ for (size_t j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i + j] != Str[j])
+ {
+ found = false;
+ break;
+ }
+ }
+ if (found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find(const string &Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String find: \"%s\", %d",
+ this, Str.c_str(), Pos);
+ return this->find(Str.c_str(), Pos);
+ }
+
+ void erase(int Index, int Count = 1)
+ {
+ strdbg("%#lx: String erase: %d, %d",
+ this, Index, Count);
+ if (Index < 0 || (size_t)Index >= this->Length)
+ return;
+
+ if (Count < 0)
+ return;
+
+ if ((size_t)(Index + Count) > this->Length)
+ Count = (int)this->Length - Index;
+
+ for (size_t i = Index; i < this->Length - Count; i++)
+ this->Data[i] = this->Data[i + Count];
+
+ this->Length -= Count;
+ this->Data[this->Length] = '\0';
+ strdbg("%#lx: String erased: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ size_t find_last_not_of(const char *Str, size_t Pos = npos) const
+ {
+ strdbg("%#lx: String find_last_not_of: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos == npos)
+ Pos = this->Length - 1;
+
+ for (int i = (int)Pos; i >= 0; i--)
+ {
+ bool found = false;
+ for (size_t j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i] == Str[j])
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find_first_not_of(const char *Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String find_first_not_of: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos >= this->Length)
+ return npos;
+
+ for (size_t i = Pos; i < this->Length; i++)
+ {
+ bool found = false;
+ for (size_t j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i] == Str[j])
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find_first_of(const char *Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String find_first_of: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos >= this->Length)
+ return npos;
+
+ for (size_t i = Pos; i < this->Length; i++)
+ {
+ bool found = false;
+ for (size_t j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i] == Str[j])
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find_last_of(const char *Str, size_t Pos = npos) const
+ {
+ strdbg("%#lx: String find_last_of: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos == npos)
+ Pos = this->Length - 1;
+
+ for (int i = (int)Pos; i >= 0; i--)
+ {
+ bool found = false;
+ for (int j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i] == Str[j])
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find_first_of(char C, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String find_first_of: '%c', %d",
+ this, C, Pos);
+ if (Pos >= this->Length)
+ return npos;
+
+ for (size_t i = Pos; i < this->Length; i++)
+ {
+ if (this->Data[i] == C)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t find_last_of(char C, size_t Pos = npos) const
+ {
+ strdbg("%#lx: String find_last_of: '%c', %d",
+ this, C, Pos);
+ if (Pos == npos)
+ Pos = this->Length - 1;
+
+ for (int i = (int)Pos; i >= 0; i--)
+ {
+ if (this->Data[i] == C)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t substr(const char *Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String substr: \"%s\", %d",
+ this, Str, Pos);
+ if (Pos >= this->Length)
+ return npos;
+
+ for (size_t i = Pos; i < this->Length; i++)
+ {
+ bool found = true;
+ for (size_t j = 0; Str[j] != '\0'; j++)
+ {
+ if (this->Data[i + j] != Str[j])
+ {
+ found = false;
+ break;
+ }
+ }
+ if (found)
+ return i;
+ }
+ return npos;
+ }
+
+ size_t substr(const string &Str, size_t Pos = 0) const
+ {
+ strdbg("%#lx: String substr: \"%s\", %d",
+ this, Str.c_str(), Pos);
+ return this->substr(Str.c_str(), Pos);
+ }
+
+ string substr(size_t Pos = 0, size_t Count = npos) const
+ {
+ strdbg("%#lx: String substr: %d, %d",
+ this, Pos, Count);
+ if (Pos >= this->Length)
+ return string();
+
+ if (Count == npos)
+ Count = this->Length - Pos;
+
+ if (Pos + Count > this->Length)
+ Count = this->Length - Pos;
+
+ string ret;
+ ret.resize(Count);
+ for (size_t i = 0; i < Count; i++)
+ ret.Data[i] = this->Data[Pos + i];
+ ret.Data[Count] = '\0';
+ return ret;
+ }
+
+ void replace(size_t Pos, size_t Count, const char *Str)
+ {
+ strdbg("%#lx: String replace: %d, %d, \"%s\"",
+ this, Pos, Count, Str);
+ if (Pos >= this->Length)
+ return;
+
+ if ((int64_t)Count <= 0)
+ return;
+
+ if (Pos + Count > this->Length)
+ Count = this->Length - Pos;
+
+ size_t NewLength = this->Length - Count + strlen(Str);
+ this->resize(NewLength);
+
+ for (size_t i = this->Length - 1; i >= Pos + strlen(Str); i--)
+ this->Data[i] = this->Data[i - strlen(Str) + Count];
+
+ for (unsigned long i = 0; i < strlen(Str); i++)
+ this->Data[Pos + i] = Str[i];
+
+ strdbg("%#lx: String replaced: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ void replace(size_t Pos, size_t Count, const string &Str)
+ {
+ strdbg("%#lx: String replace: %d, %d, \"%s\"",
+ this, Pos, Count, Str.Data);
+ if (Pos >= this->Length)
+ return;
+
+ if ((int64_t)Count <= 0)
+ return;
+
+ if (Pos + Count > this->Length)
+ Count = this->Length - Pos;
+
+ size_t NewLength = this->Length - Count + Str.Length;
+ this->resize(NewLength);
+
+ for (size_t i = this->Length - 1; i >= Pos + Str.Length; i--)
+ this->Data[i] = this->Data[i - Str.Length + Count];
+
+ for (size_t i = 0; i < Str.Length; i++)
+ this->Data[Pos + i] = Str.Data[i];
+
+ strdbg("%#lx: String replaced: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ }
+
+ void pop_back()
+ {
+ strdbg("%#lx: String pop_back", this);
+ if (this->Length > 0)
+ {
+ this->Data[this->Length - 1] = '\0';
+ this->Length--;
+ }
+ }
+
+ string operator+(const string &Other) const
+ {
+ string result = *this;
+ result.concat(Other);
+ strdbg("%#lx: String added: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, result.Data, result.Data, result.Length, result.Capacity);
+ return result;
+ }
+
+ string operator+(const char *Other) const
+ {
+ string result = *this;
+ result.concat(Other);
+ strdbg("%#lx: String added: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, result.Data, result.Data, result.Length, result.Capacity);
+ return result;
+ }
+
+ string &operator+=(const string &Other)
+ {
+ this->concat(Other);
+ strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ string &operator+=(const char *Other)
+ {
+ this->concat(Other);
+ strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ string &operator+=(char Other)
+ {
+ const char str[2] = {Other, '\0'};
+ this->concat(str);
+ strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ /* 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->Data;
+ // this->Data = Other.Data;
+ // this->Length = Other.Length;
+ // this->Capacity = Other.Capacity;
+ // strdbg("%#lx: String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ // this, this->Data, this->Data, this->Length, this->Capacity);
+ // }
+ // return *this;
+ // }
+
+ string &operator=(const char *Other)
+ {
+ this->Length = strlen(Other);
+ this->Capacity = this->Length + 1;
+ delete[] this->Data;
+ this->Data = new char[this->Capacity];
+ strcpy(this->Data, Other);
+ strdbg("%#lx: String assigned: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ string &operator<<(const string &Other)
+ {
+ this->concat(Other);
+ strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ string &operator<<(const char *Other)
+ {
+ this->concat(Other);
+ strdbg("%#lx: String appended: \"%s\" (data: %#lx, length: %d, capacity: %d)",
+ this, this->Data, this->Data, this->Length, this->Capacity);
+ return *this;
+ }
+
+ char &operator[](int Index)
+ {
+ strdbg("%#lx: String index: %d", this, Index);
+ return this->Data[Index];
+ }
+
+ const char &operator[](int Index) const
+ {
+ strdbg("%#lx: String index: %d", this, Index);
+ return this->Data[Index];
+ }
+
+ char &operator[](size_t Index)
+ {
+ strdbg("%#lx: String index: %d", this, Index);
+ return this->Data[Index];
+ }
+
+ const char &operator[](size_t Index) const
+ {
+ strdbg("%#lx: String index: %d", this, Index);
+ return this->Data[Index];
+ }
+
+ bool operator==(const string &Other) const
+ {
+ strdbg("%#lx: String compared: \"%s\" == \"%s\"",
+ this, this->Data, Other.Data);
+ return strcmp(this->Data, Other.Data) == 0;
+ }
+
+ bool operator!=(const char *Other) const
+ {
+ strdbg("%#lx: String compared: \"%s\" != \"%s\"",
+ this, this->Data, Other);
+ return strcmp(this->Data, Other) != 0;
+ }
+
+ bool operator!=(const string &Other) const
+ {
+ strdbg("%#lx: String compared: \"%s\" != \"%s\"",
+ this, this->Data, Other.Data);
+ return strcmp(this->Data, Other.Data) != 0;
+ }
+
+ bool operator==(const char *Other) const
+ {
+ strdbg("%#lx: String compared: \"%s\" == \"%s\"",
+ this, this->Data, Other);
+ return strcmp(this->Data, Other) == 0;
+ }
+
+ class iterator
+ {
+ private:
+ char *Pointer;
+
+ public:
+ iterator(char *Pointer) : Pointer(Pointer) {}
+
+ iterator &operator++()
+ {
+ ++this->Pointer;
+ strdbg("%#lx: String iterator incremented: %#lx",
+ this, this->Pointer);
+ return *this;
+ }
+
+ char &operator*()
+ {
+ strdbg("%#lx: String iterator dereferenced: %#lx",
+ this, this->Pointer);
+ return *this->Pointer;
+ }
+
+ bool operator!=(const iterator &Other) const
+ {
+ strdbg("%#lx: String iterator compared: %#lx != %#lx",
+ this, this->Pointer, Other.Pointer);
+ return this->Pointer != Other.Pointer;
+ }
+
+ bool operator==(const iterator &Other) const
+ {
+ strdbg("%#lx: String iterator compared: %#lx == %#lx",
+ this, this->Pointer, Other.Pointer);
+ return this->Pointer == Other.Pointer;
+ }
+ };
+
+ iterator begin()
+ {
+ strdbg("%#lx: String iterator begin: %#lx",
+ this, this->Data);
+ return iterator(this->Data);
+ }
+
+ iterator end()
+ {
+ strdbg("%#lx: String iterator end: %#lx",
+ this, this->Data + this->Length);
+ return iterator(this->Data + this->Length);
+ }
+ };
+}
diff --git a/tests/std_string.cpp b/tests/std_string.cpp
index 8163cc5..af506c7 100644
--- a/tests/std_string.cpp
+++ b/tests/std_string.cpp
@@ -17,9 +17,9 @@
#ifdef DEBUG
-#include
#include
#include
+#include
void TestString()
{