mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-13 08:19:18 +00:00
Rename std functions to match the standard
This commit is contained in:
33
include/std/functional.hpp
Normal file
33
include/std/functional.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_FUNCTIONAL_H__
|
||||
#define __FENNIX_KERNEL_STD_FUNCTIONAL_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename Key>
|
||||
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<const uint8_t *>(&key);
|
||||
const size_t size = sizeof(Key);
|
||||
uint64_t hash = fnv_offset_basis;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
hash ^= static_cast<uint64_t>(data[i]);
|
||||
hash *= fnv_prime;
|
||||
}
|
||||
|
||||
return static_cast<size_t>(hash);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_FUNCTIONAL_H__
|
207
include/std/list.hpp
Normal file
207
include/std/list.hpp
Normal file
@ -0,0 +1,207 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_LIST_H__
|
||||
#define __FENNIX_KERNEL_STD_LIST_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <std/stdexcept.hpp>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T>
|
||||
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__
|
263
include/std/smart_ptr.hpp
Normal file
263
include/std/smart_ptr.hpp
Normal file
@ -0,0 +1,263 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_SMART_POINTER_H__
|
||||
#define __FENNIX_KERNEL_STD_SMART_POINTER_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
// show debug messages
|
||||
// #define DEBUG_SMARTPOINTERS 1
|
||||
|
||||
#ifdef DEBUG_SMARTPOINTERS
|
||||
#define spdbg(m, ...) debug(m, ##__VA_ARGS__)
|
||||
#else
|
||||
#define spdbg(m, ...)
|
||||
#endif
|
||||
|
||||
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<char> pointer(new char());
|
||||
* *pointer = 'a';
|
||||
* printf("%c", *pointer); // Prints "a"
|
||||
*/
|
||||
template <class T>
|
||||
class smart_ptr
|
||||
{
|
||||
T *m_RealPointer;
|
||||
|
||||
public:
|
||||
explicit smart_ptr(T *Pointer = nullptr)
|
||||
{
|
||||
spdbg("Smart pointer created (%#lx)", m_RealPointer);
|
||||
m_RealPointer = Pointer;
|
||||
}
|
||||
|
||||
~smart_ptr()
|
||||
{
|
||||
spdbg("Smart pointer deleted (%#lx)", m_RealPointer);
|
||||
delete m_RealPointer, m_RealPointer = nullptr;
|
||||
}
|
||||
|
||||
T &operator*()
|
||||
{
|
||||
spdbg("Smart pointer dereferenced (%#lx)", m_RealPointer);
|
||||
return *m_RealPointer;
|
||||
}
|
||||
|
||||
T *operator->()
|
||||
{
|
||||
spdbg("Smart pointer dereferenced (%#lx)", m_RealPointer);
|
||||
return m_RealPointer;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class auto_ptr
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class unique_ptr
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class weak_ptr
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class shared_ptr
|
||||
{
|
||||
private:
|
||||
class Counter
|
||||
{
|
||||
private:
|
||||
unsigned int m_RefCount{};
|
||||
|
||||
public:
|
||||
Counter() : m_RefCount(0) { spdbg("Counter %#lx created", this); };
|
||||
Counter(const Counter &) = delete;
|
||||
Counter &operator=(const Counter &) = delete;
|
||||
~Counter() { spdbg("Counter %#lx deleted", this); }
|
||||
void Reset()
|
||||
{
|
||||
m_RefCount = 0;
|
||||
spdbg("Counter reset");
|
||||
}
|
||||
|
||||
unsigned int Get()
|
||||
{
|
||||
return m_RefCount;
|
||||
spdbg("Counter returned");
|
||||
}
|
||||
|
||||
void operator++()
|
||||
{
|
||||
m_RefCount++;
|
||||
spdbg("Counter incremented");
|
||||
}
|
||||
|
||||
void operator++(int)
|
||||
{
|
||||
m_RefCount++;
|
||||
spdbg("Counter incremented");
|
||||
}
|
||||
|
||||
void operator--()
|
||||
{
|
||||
m_RefCount--;
|
||||
spdbg("Counter decremented");
|
||||
}
|
||||
|
||||
void operator--(int)
|
||||
{
|
||||
m_RefCount--;
|
||||
spdbg("Counter decremented");
|
||||
}
|
||||
};
|
||||
|
||||
Counter *m_ReferenceCounter;
|
||||
T *m_RealPointer;
|
||||
|
||||
public:
|
||||
explicit shared_ptr(T *Pointer = nullptr)
|
||||
{
|
||||
m_RealPointer = Pointer;
|
||||
m_ReferenceCounter = new Counter();
|
||||
spdbg("[%#lx] Shared pointer created (ptr=%#lx, ref=%#lx)", this, Pointer, m_ReferenceCounter);
|
||||
if (Pointer)
|
||||
(*m_ReferenceCounter)++;
|
||||
}
|
||||
|
||||
shared_ptr(shared_ptr<T> &SPtr)
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer copied (ptr=%#lx, ref=%#lx)", this, SPtr.m_RealPointer, SPtr.m_ReferenceCounter);
|
||||
m_RealPointer = SPtr.m_RealPointer;
|
||||
m_ReferenceCounter = SPtr.m_ReferenceCounter;
|
||||
(*m_ReferenceCounter)++;
|
||||
}
|
||||
|
||||
~shared_ptr()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer destructor called", this);
|
||||
(*m_ReferenceCounter)--;
|
||||
if (m_ReferenceCounter->Get() == 0)
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer deleted (ptr=%#lx, ref=%#lx)", this, m_RealPointer, m_ReferenceCounter);
|
||||
delete m_ReferenceCounter, m_ReferenceCounter = nullptr;
|
||||
delete m_RealPointer, m_RealPointer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int GetCount()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer count (%d)", this, m_ReferenceCounter->Get());
|
||||
return m_ReferenceCounter->Get();
|
||||
}
|
||||
|
||||
T *Get()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer get (%#lx)", this, m_RealPointer);
|
||||
return m_RealPointer;
|
||||
}
|
||||
|
||||
T &operator*()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer dereference (ptr*=%#lx)", this, *m_RealPointer);
|
||||
return *m_RealPointer;
|
||||
}
|
||||
|
||||
T *operator->()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer dereference (ptr->%#lx)", this, m_RealPointer);
|
||||
return m_RealPointer;
|
||||
}
|
||||
|
||||
void reset(T *Pointer = nullptr)
|
||||
{
|
||||
if (m_RealPointer == Pointer)
|
||||
return;
|
||||
spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, Pointer, m_ReferenceCounter);
|
||||
(*m_ReferenceCounter)--;
|
||||
if (m_ReferenceCounter->Get() == 0)
|
||||
{
|
||||
delete m_RealPointer;
|
||||
delete m_ReferenceCounter;
|
||||
}
|
||||
m_RealPointer = Pointer;
|
||||
m_ReferenceCounter = new Counter();
|
||||
if (Pointer)
|
||||
(*m_ReferenceCounter)++;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer reset (ptr=%#lx, ref=%#lx)", this, m_RealPointer, m_ReferenceCounter);
|
||||
if (m_ReferenceCounter->Get() == 1)
|
||||
{
|
||||
delete m_RealPointer, m_RealPointer = nullptr;
|
||||
delete m_ReferenceCounter, m_ReferenceCounter = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*m_ReferenceCounter)--;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(shared_ptr<T> &Other)
|
||||
{
|
||||
spdbg("[%#lx] Shared pointer swap (ptr=%#lx, ref=%#lx <=> ptr=%#lx, ref=%#lx)",
|
||||
this, m_RealPointer, m_ReferenceCounter, Other.m_RealPointer, Other.m_ReferenceCounter);
|
||||
T *tempRealPointer = m_RealPointer;
|
||||
Counter *tempReferenceCounter = m_ReferenceCounter;
|
||||
m_RealPointer = Other.m_RealPointer;
|
||||
m_ReferenceCounter = Other.m_ReferenceCounter;
|
||||
Other.m_RealPointer = tempRealPointer;
|
||||
Other.m_ReferenceCounter = tempReferenceCounter;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct remove_reference
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct remove_reference<T &>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct remove_reference<T &&>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template <typename T>
|
||||
T &&forward(remove_reference_t<T> &t) { return static_cast<T &&>(t); };
|
||||
|
||||
template <typename T>
|
||||
T &&forward(remove_reference_t<T> &&t) { return static_cast<T &&>(t); };
|
||||
|
||||
template <typename T, typename... Args>
|
||||
shared_ptr<T> make_shared(Args &&...args)
|
||||
{
|
||||
return shared_ptr<T>(new T(forward<Args>(args)...));
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_SMART_POINTER_H__
|
19
include/std/stdexcept.hpp
Normal file
19
include/std/stdexcept.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_STDEXCEPT_H__
|
||||
#define __FENNIX_KERNEL_STD_STDEXCEPT_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
class runtime_error
|
||||
{
|
||||
private:
|
||||
const char *m_what;
|
||||
|
||||
public:
|
||||
runtime_error(const char *what_arg) : m_what(what_arg) {}
|
||||
const char *what() const { return m_what; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_STDEXCEPT_H__
|
536
include/std/string.hpp
Normal file
536
include/std/string.hpp
Normal file
@ -0,0 +1,536 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_STRING_H__
|
||||
#define __FENNIX_KERNEL_STD_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.
|
||||
|
||||
namespace std
|
||||
{
|
||||
/**
|
||||
* @brief String class
|
||||
* String class that can be used to store strings.
|
||||
*/
|
||||
class string
|
||||
{
|
||||
private:
|
||||
char *m_Data;
|
||||
size_t m_Length;
|
||||
size_t m_Capacity;
|
||||
|
||||
public:
|
||||
static const size_t npos = -1;
|
||||
|
||||
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, this->m_Data = nullptr;
|
||||
}
|
||||
|
||||
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(size_t NewLength)
|
||||
{
|
||||
strdbg("String resize: %d", NewLength);
|
||||
if (NewLength > this->m_Capacity)
|
||||
{
|
||||
size_t 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);
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
strdbg("String empty: %d", this->m_Length == 0);
|
||||
return this->m_Length == 0;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
strdbg("String size: %d", this->m_Length);
|
||||
return this->m_Length;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
strdbg("String clear");
|
||||
this->resize(0);
|
||||
}
|
||||
|
||||
size_t find(const char *Str, size_t Pos = 0) const
|
||||
{
|
||||
strdbg("String find: \"%s\", %d", Str, Pos);
|
||||
if (Pos >= this->m_Length)
|
||||
return npos;
|
||||
|
||||
for (size_t i = Pos; i < this->m_Length; i++)
|
||||
{
|
||||
bool found = true;
|
||||
for (size_t j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String find: \"%s\", %d", Str.c_str(), Pos);
|
||||
return this->find(Str.c_str(), Pos);
|
||||
}
|
||||
|
||||
void erase(int Index, int Count = 1)
|
||||
{
|
||||
strdbg("String erase: %d, %d", Index, Count);
|
||||
if (Index < 0 || (size_t)Index >= this->m_Length)
|
||||
return;
|
||||
|
||||
if (Count < 0)
|
||||
return;
|
||||
|
||||
if ((size_t)(Index + Count) > this->m_Length)
|
||||
Count = this->m_Length - Index;
|
||||
|
||||
for (size_t i = Index; i < this->m_Length - Count; i++)
|
||||
this->m_Data[i] = this->m_Data[i + Count];
|
||||
|
||||
this->m_Length -= Count;
|
||||
this->m_Data[m_Length] = '\0';
|
||||
strdbg("String erased: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
|
||||
}
|
||||
|
||||
size_t find_last_not_of(const char *Str, size_t Pos = npos) const
|
||||
{
|
||||
strdbg("String find_last_not_of: \"%s\", %d", Str, Pos);
|
||||
if (Pos == npos)
|
||||
Pos = this->m_Length - 1;
|
||||
|
||||
for (int i = (int)Pos; i >= 0; i--)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String find_first_not_of: \"%s\", %d", Str, Pos);
|
||||
if (Pos >= this->m_Length)
|
||||
return npos;
|
||||
|
||||
for (size_t i = Pos; i < this->m_Length; i++)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String find_first_of: \"%s\", %d", Str, Pos);
|
||||
if (Pos >= this->m_Length)
|
||||
return npos;
|
||||
|
||||
for (size_t i = Pos; i < this->m_Length; i++)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String find_last_of: \"%s\", %d", Str, Pos);
|
||||
if (Pos == npos)
|
||||
Pos = this->m_Length - 1;
|
||||
|
||||
for (int i = (int)Pos; i >= 0; i--)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String find_first_of: '%c', %d", C, Pos);
|
||||
if (Pos >= this->m_Length)
|
||||
return npos;
|
||||
|
||||
for (size_t i = Pos; i < this->m_Length; i++)
|
||||
{
|
||||
if (this->m_Data[i] == C)
|
||||
return i;
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_t find_last_of(char C, size_t Pos = npos) const
|
||||
{
|
||||
strdbg("String find_last_of: '%c', %d", C, Pos);
|
||||
if (Pos == npos)
|
||||
Pos = this->m_Length - 1;
|
||||
|
||||
for (int i = (int)Pos; i >= 0; i--)
|
||||
{
|
||||
if (this->m_Data[i] == C)
|
||||
return i;
|
||||
}
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_t substr(const char *Str, size_t Pos = 0) const
|
||||
{
|
||||
strdbg("String substr: \"%s\", %d", Str, Pos);
|
||||
if (Pos >= this->m_Length)
|
||||
return npos;
|
||||
|
||||
for (size_t i = Pos; i < this->m_Length; i++)
|
||||
{
|
||||
bool found = true;
|
||||
for (size_t j = 0; Str[j] != '\0'; j++)
|
||||
{
|
||||
if (this->m_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("String substr: \"%s\", %d", Str.c_str(), Pos);
|
||||
return this->substr(Str.c_str(), Pos);
|
||||
}
|
||||
|
||||
string substr(size_t Pos = 0, size_t Count = npos) const
|
||||
{
|
||||
strdbg("String substr: %d, %d", Pos, Count);
|
||||
if (Pos >= this->m_Length)
|
||||
return string();
|
||||
|
||||
if (Count == npos)
|
||||
Count = this->m_Length - Pos;
|
||||
|
||||
if (Pos + Count > this->m_Length)
|
||||
Count = this->m_Length - Pos;
|
||||
|
||||
string ret;
|
||||
ret.resize(Count);
|
||||
for (size_t i = 0; i < Count; i++)
|
||||
ret.m_Data[i] = this->m_Data[Pos + i];
|
||||
ret.m_Data[Count] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
void replace(size_t Pos, size_t Count, const char *Str)
|
||||
{
|
||||
strdbg("String replace: %d, %d, \"%s\"", Pos, Count, Str);
|
||||
if (Pos >= this->m_Length)
|
||||
return;
|
||||
|
||||
if ((int64_t)Count < 0)
|
||||
return;
|
||||
|
||||
if (Pos + Count > this->m_Length)
|
||||
Count = this->m_Length - Pos;
|
||||
|
||||
int NewLength = this->m_Length - Count + strlen(Str);
|
||||
this->resize(NewLength);
|
||||
|
||||
for (size_t i = this->m_Length - 1; i >= Pos + strlen(Str); i--)
|
||||
this->m_Data[i] = this->m_Data[i - strlen(Str) + Count];
|
||||
|
||||
for (unsigned long i = 0; i < strlen(Str); i++)
|
||||
this->m_Data[Pos + i] = Str[i];
|
||||
|
||||
strdbg("String replaced: \"%s\" (data: %#lx, length: %d, capacity: %d)", this->m_Data, this->m_Data, this->m_Length, this->m_Capacity);
|
||||
}
|
||||
|
||||
void replace(size_t Pos, size_t Count, const string &Str)
|
||||
{
|
||||
strdbg("String replace: %d, %d, \"%s\"", Pos, Count, Str.m_Data);
|
||||
if (Pos >= this->m_Length)
|
||||
return;
|
||||
|
||||
if ((int64_t)Count < 0)
|
||||
return;
|
||||
|
||||
if (Pos + Count > this->m_Length)
|
||||
Count = this->m_Length - Pos;
|
||||
|
||||
int NewLength = this->m_Length - Count + Str.m_Length;
|
||||
this->resize(NewLength);
|
||||
|
||||
for (size_t i = this->m_Length - 1; i >= Pos + Str.m_Length; i--)
|
||||
this->m_Data[i] = this->m_Data[i - Str.m_Length + Count];
|
||||
|
||||
for (size_t i = 0; i < Str.m_Length; i++)
|
||||
this->m_Data[Pos + i] = Str.m_Data[i];
|
||||
|
||||
strdbg("String replaced: \"%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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 char *Other) const
|
||||
{
|
||||
strdbg("String compared: \"%s\" != \"%s\"", this->m_Data, Other);
|
||||
return strcmp(this->m_Data, Other) != 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;
|
||||
}
|
||||
|
||||
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_STD_STRING_H__
|
113
include/std/unordered_map.hpp
Normal file
113
include/std/unordered_map.hpp
Normal file
@ -0,0 +1,113 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_UNORDERED_MAP_H__
|
||||
#define __FENNIX_KERNEL_STD_UNORDERED_MAP_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <std/functional.hpp>
|
||||
#include <std/utility.hpp>
|
||||
#include <std/list.hpp>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename key_type, typename value_type>
|
||||
class unordered_map
|
||||
{
|
||||
public:
|
||||
typedef std::pair<key_type, value_type> key_value_pair;
|
||||
typedef std::list<key_value_pair> bucket;
|
||||
typedef typename std::vector<bucket>::iterator iterator;
|
||||
typedef typename std::vector<bucket>::const_iterator const_iterator;
|
||||
|
||||
private:
|
||||
static const size_t DEFAULT_NUM_BUCKETS = 10;
|
||||
std::vector<bucket> m_buckets;
|
||||
|
||||
size_t hash(const key_type &key) const
|
||||
{
|
||||
std::hash<key_type> hash_function;
|
||||
return hash_function(key) % m_buckets.size();
|
||||
}
|
||||
|
||||
public:
|
||||
unordered_map() : m_buckets(DEFAULT_NUM_BUCKETS) {}
|
||||
unordered_map(size_t num_buckets) : m_buckets(num_buckets) {}
|
||||
|
||||
void insert(const key_value_pair &pair)
|
||||
{
|
||||
size_t bucket_index = hash(pair.first);
|
||||
bucket &bucket = m_buckets[bucket_index];
|
||||
for (auto it = bucket.begin(); it != bucket.end(); ++it)
|
||||
{
|
||||
if (it->first == pair.first)
|
||||
{
|
||||
it->second = pair.second;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bucket.push_back(pair);
|
||||
}
|
||||
|
||||
bool contains(const key_type &key) const
|
||||
{
|
||||
size_t bucket_index = hash(key);
|
||||
const bucket &bucket = m_buckets[bucket_index];
|
||||
for (auto it = bucket.begin(); it != bucket.end(); ++it)
|
||||
{
|
||||
if (it->first == key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
iterator find(const key_type &k)
|
||||
{
|
||||
size_t bucket_index = hash(k);
|
||||
bucket &bucket = m_buckets[bucket_index];
|
||||
for (auto it = bucket.begin(); it != bucket.end(); ++it)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
}
|
||||
return bucket.end();
|
||||
}
|
||||
|
||||
const_iterator find(const key_type &k) const
|
||||
{
|
||||
size_t bucket_index = hash(k);
|
||||
const bucket &bucket = m_buckets[bucket_index];
|
||||
for (auto it = bucket.begin(); it != bucket.end(); ++it)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
}
|
||||
return bucket.end();
|
||||
}
|
||||
|
||||
iterator end() noexcept { return m_buckets.end(); }
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (const auto &bucket : m_buckets)
|
||||
count += bucket.size();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
value_type &operator[](const key_type &key)
|
||||
{
|
||||
size_t bucket_index = hash(key);
|
||||
bucket &bucket = m_buckets[bucket_index];
|
||||
for (auto it = bucket.begin(); it != bucket.end(); ++it)
|
||||
{
|
||||
if (it->first == key)
|
||||
return it->second;
|
||||
}
|
||||
bucket.emplace_back(key, value_type());
|
||||
return bucket.back().second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_UNORDERED_MAP_H__
|
22
include/std/utility.hpp
Normal file
22
include/std/utility.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_UTILITY_H__
|
||||
#define __FENNIX_KERNEL_STD_UTILITY_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
|
||||
T1 first;
|
||||
T2 second;
|
||||
|
||||
pair() : first(T1()), second(T2()) {}
|
||||
pair(const T1 &x, const T2 &y) : first(x), second(y) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_UTILITY_H__
|
267
include/std/vector.hpp
Normal file
267
include/std/vector.hpp
Normal file
@ -0,0 +1,267 @@
|
||||
#ifndef __FENNIX_KERNEL_STD_VECTOR_H__
|
||||
#define __FENNIX_KERNEL_STD_VECTOR_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <assert.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class T>
|
||||
class vector
|
||||
{
|
||||
private:
|
||||
size_t VectorSize = 0;
|
||||
size_t VectorCapacity = 0;
|
||||
T *VectorBuffer = nullptr;
|
||||
|
||||
public:
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
|
||||
NIF vector()
|
||||
{
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR INIT: vector( )");
|
||||
#endif
|
||||
VectorCapacity = 0;
|
||||
VectorSize = 0;
|
||||
VectorBuffer = 0;
|
||||
}
|
||||
|
||||
NIF vector(size_t Size)
|
||||
{
|
||||
VectorCapacity = Size;
|
||||
VectorSize = Size;
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR INIT: vector( %lld )", Size);
|
||||
#endif
|
||||
VectorBuffer = new T[Size];
|
||||
}
|
||||
|
||||
NIF vector(size_t Size, const T &Initial)
|
||||
{
|
||||
VectorSize = Size;
|
||||
VectorCapacity = Size;
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR INIT: vector( %lld %llx )", Size, Initial);
|
||||
#endif
|
||||
assert(Size > 0);
|
||||
VectorBuffer = new T[Size];
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
VectorBuffer[i] = Initial;
|
||||
}
|
||||
|
||||
NIF vector(const vector<T> &vector)
|
||||
{
|
||||
VectorSize = vector.VectorSize;
|
||||
VectorCapacity = vector.VectorCapacity;
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR INIT: vector( <vector> )->Size: %lld", VectorSize);
|
||||
#endif
|
||||
assert(VectorSize > 0);
|
||||
VectorBuffer = new T[VectorSize];
|
||||
for (size_t i = 0; i < VectorSize; i++)
|
||||
VectorBuffer[i] = vector.VectorBuffer[i];
|
||||
}
|
||||
|
||||
NIF ~vector()
|
||||
{
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR INIT: ~vector( ~%lx )", VectorBuffer);
|
||||
#endif
|
||||
VectorSize = 0;
|
||||
VectorCapacity = 0;
|
||||
if (VectorBuffer != nullptr)
|
||||
{
|
||||
delete[] VectorBuffer, VectorBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NIF void remove(size_t Position)
|
||||
{
|
||||
if (Position >= VectorSize)
|
||||
return;
|
||||
memset(&*(VectorBuffer + Position), 0, sizeof(T));
|
||||
for (size_t i = 0; i < VectorSize - 1; i++)
|
||||
{
|
||||
*(VectorBuffer + Position + i) = *(VectorBuffer + Position + i + 1);
|
||||
}
|
||||
VectorSize--;
|
||||
}
|
||||
|
||||
NIF void remove(const T &Value)
|
||||
{
|
||||
for (size_t i = 0; i < VectorSize; i++)
|
||||
{
|
||||
if (VectorBuffer[i] == Value)
|
||||
{
|
||||
remove(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NIF T &null_elem()
|
||||
{
|
||||
static T null_elem;
|
||||
return null_elem;
|
||||
}
|
||||
|
||||
NIF bool null_elem(size_t Index)
|
||||
{
|
||||
if (!reinterpret_cast<uintptr_t>(&VectorBuffer[Index]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NIF T &next(size_t Position)
|
||||
{
|
||||
if (Position + 1 < VectorSize && reinterpret_cast<uintptr_t>(&VectorBuffer[Position + 1]))
|
||||
return VectorBuffer[Position + 1];
|
||||
warn("next( %lld ) is null (requested by %#lx)", Position, __builtin_return_address(0));
|
||||
return this->null_elem();
|
||||
}
|
||||
|
||||
NIF T &prev(size_t Position)
|
||||
{
|
||||
if (Position > 0 && reinterpret_cast<uintptr_t>(&VectorBuffer[Position - 1]))
|
||||
return VectorBuffer[Position - 1];
|
||||
warn("prev( %lld ) is null (requested by %#lx)", Position, __builtin_return_address(0));
|
||||
return this->null_elem();
|
||||
}
|
||||
|
||||
NIF T &next(const T &Value)
|
||||
{
|
||||
for (size_t i = 0; i < VectorSize; i++)
|
||||
{
|
||||
if (VectorBuffer[i] == Value)
|
||||
{
|
||||
if (i + 1 < VectorSize && reinterpret_cast<uintptr_t>(&VectorBuffer[i + 1]))
|
||||
return VectorBuffer[i + 1];
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
warn("next( %#lx ) is null (requested by %#lx)", Value, __builtin_return_address(0));
|
||||
return this->null_elem();
|
||||
}
|
||||
|
||||
NIF T &prev(const T &Value)
|
||||
{
|
||||
for (size_t i = 0; i < VectorSize; i++)
|
||||
{
|
||||
if (VectorBuffer[i] == Value)
|
||||
{
|
||||
if (i > 0 && reinterpret_cast<uintptr_t>(&VectorBuffer[i - 1]))
|
||||
return VectorBuffer[i - 1];
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
warn("prev( %#lx ) is null (requested by %#lx)", Value, __builtin_return_address(0));
|
||||
return this->null_elem();
|
||||
}
|
||||
|
||||
NIF size_t capacity() const { return VectorCapacity; }
|
||||
|
||||
NIF size_t size() const { return VectorSize; }
|
||||
|
||||
NIF bool empty() const;
|
||||
|
||||
NIF iterator begin() { return VectorBuffer; }
|
||||
|
||||
NIF iterator end() { return VectorBuffer + size(); }
|
||||
|
||||
NIF T &front() { return VectorBuffer[0]; }
|
||||
|
||||
NIF T &back() { return VectorBuffer[VectorSize - 1]; }
|
||||
|
||||
NIF void push_back(const T &Value)
|
||||
{
|
||||
if (VectorSize >= VectorCapacity)
|
||||
reserve(VectorCapacity + 5);
|
||||
VectorBuffer[VectorSize++] = Value;
|
||||
}
|
||||
|
||||
NIF void pop_back() { VectorSize--; }
|
||||
|
||||
NIF void reverse()
|
||||
{
|
||||
if (VectorSize <= 1)
|
||||
return;
|
||||
for (size_t i = 0, j = VectorSize - 1; i < j; i++, j--)
|
||||
{
|
||||
T c = *(VectorBuffer + i);
|
||||
*(VectorBuffer + i) = *(VectorBuffer + j);
|
||||
*(VectorBuffer + j) = c;
|
||||
}
|
||||
}
|
||||
|
||||
NIF void reserve(size_t Capacity)
|
||||
{
|
||||
if (VectorBuffer == 0)
|
||||
{
|
||||
VectorSize = 0;
|
||||
VectorCapacity = 0;
|
||||
}
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR ALLOCATION: reverse( %lld )", Capacity);
|
||||
#endif
|
||||
T *NewBuffer = new T[Capacity];
|
||||
size_t _Size = Capacity < VectorSize ? Capacity : VectorSize;
|
||||
for (size_t i = 0; i < _Size; i++)
|
||||
NewBuffer[i] = VectorBuffer[i];
|
||||
VectorCapacity = Capacity;
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR ALLOCATION: reverse( <Capacity> )->Buffer:~%lld", VectorBuffer);
|
||||
#endif
|
||||
delete[] VectorBuffer;
|
||||
VectorBuffer = NewBuffer;
|
||||
}
|
||||
|
||||
NIF void resize(size_t Size)
|
||||
{
|
||||
reserve(Size);
|
||||
VectorSize = Size;
|
||||
}
|
||||
|
||||
NIF void clear()
|
||||
{
|
||||
VectorCapacity = 0;
|
||||
VectorSize = 0;
|
||||
if (VectorBuffer != nullptr)
|
||||
{
|
||||
delete[] VectorBuffer, VectorBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NIF T *data() { return VectorBuffer; }
|
||||
|
||||
NIF T &operator[](size_t Index)
|
||||
{
|
||||
if (!reinterpret_cast<uintptr_t>(&VectorBuffer[Index]))
|
||||
{
|
||||
warn("operator[]( %lld ) is null (requested by %#lx)", Index, __builtin_return_address(0));
|
||||
return this->null_elem();
|
||||
}
|
||||
return VectorBuffer[Index];
|
||||
}
|
||||
|
||||
NIF vector<T> &operator=(const vector<T> &vector)
|
||||
{
|
||||
delete[] VectorBuffer;
|
||||
VectorSize = vector.VectorSize;
|
||||
VectorCapacity = vector.VectorCapacity;
|
||||
#ifdef DEBUG_MEM_ALLOCATION
|
||||
debug("VECTOR ALLOCATION: operator=( <vector> )->Size:%lld", VectorSize);
|
||||
#endif
|
||||
VectorBuffer = new T[VectorSize];
|
||||
for (size_t i = 0; i < VectorSize; i++)
|
||||
VectorBuffer[i] = vector.VectorBuffer[i];
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_VECTOR_H__
|
Reference in New Issue
Block a user