mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Update kernel
This commit is contained in:
@ -53,14 +53,54 @@ namespace std
|
||||
}
|
||||
|
||||
template <class InputIt, class T>
|
||||
InputIt find(InputIt first, InputIt last, const T &value)
|
||||
constexpr InputIt find(InputIt first, InputIt last, const T &value)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
if (*first == value)
|
||||
return first;
|
||||
++first;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
template <class InputIt, class UnaryPredicate>
|
||||
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
if (p(*first))
|
||||
return first;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
template <class InputIt, class UnaryPredicate>
|
||||
constexpr InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
if (!q(*first))
|
||||
return first;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
template <class ForwardIt, class T>
|
||||
ForwardIt remove(ForwardIt first, ForwardIt last, const T &value)
|
||||
{
|
||||
first = std::find(first, last, value);
|
||||
if (first != last)
|
||||
for (ForwardIt i = first; ++i != last;)
|
||||
if (!(*i == value))
|
||||
*first++ = std::move(*i);
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class ForwardIt, class UnaryPredicate>
|
||||
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
|
||||
{
|
||||
first = std::find_if(first, last, p);
|
||||
if (first != last)
|
||||
for (ForwardIt i = first; ++i != last;)
|
||||
if (!p(*i))
|
||||
*first++ = std::move(*i);
|
||||
return first;
|
||||
}
|
||||
}
|
||||
|
@ -20,27 +20,24 @@
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#define assert(x) \
|
||||
do \
|
||||
{ \
|
||||
if (!(x)) \
|
||||
{ \
|
||||
error("Assertion failed! [%s] [%s:%s:%d]", \
|
||||
#x, __FILE__, __FUNCTION__, __LINE__); \
|
||||
int3; \
|
||||
while (true) \
|
||||
; \
|
||||
} \
|
||||
#define assert(x) \
|
||||
do \
|
||||
{ \
|
||||
if (__builtin_expect(!!(!(x)), 0)) \
|
||||
{ \
|
||||
error("Assertion failed! [%s]", #x); \
|
||||
int3; \
|
||||
__builtin_unreachable(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define assert_allow_continue(x) \
|
||||
do \
|
||||
{ \
|
||||
if (!(x)) \
|
||||
{ \
|
||||
error("Assertion failed! [%s] [%s:%s:%d]", \
|
||||
#x, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
#define assert_allow_continue(x) \
|
||||
do \
|
||||
{ \
|
||||
if (__builtin_expect(!!(!(x)), 0)) \
|
||||
{ \
|
||||
error("Assertion failed! [%s]", #x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
|
||||
|
@ -68,12 +68,12 @@ namespace std
|
||||
*/
|
||||
enum class memory_order : int
|
||||
{
|
||||
relaxed,
|
||||
consume,
|
||||
acquire,
|
||||
release,
|
||||
acq_rel,
|
||||
seq_cst
|
||||
relaxed = __ATOMIC_RELAXED,
|
||||
consume = __ATOMIC_CONSUME,
|
||||
acquire = __ATOMIC_ACQUIRE,
|
||||
release = __ATOMIC_RELEASE,
|
||||
acq_rel = __ATOMIC_ACQ_REL,
|
||||
seq_cst = __ATOMIC_SEQ_CST
|
||||
};
|
||||
|
||||
/**
|
||||
@ -172,7 +172,7 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable
|
||||
*/
|
||||
T load(memory_order order = memory_order::seq_cst) const
|
||||
inline __always_inline T load(memory_order order = memory_order::seq_cst) const
|
||||
{
|
||||
return builtin_atomic_n(load)(&this->value,
|
||||
static_cast<int>(order));
|
||||
@ -181,7 +181,7 @@ namespace std
|
||||
/**
|
||||
* @copydoc load()
|
||||
*/
|
||||
T load(memory_order order = memory_order::seq_cst) const volatile
|
||||
inline __always_inline T load(memory_order order = memory_order::seq_cst) const volatile
|
||||
{
|
||||
return builtin_atomic_n(load)(&this->value,
|
||||
static_cast<int>(order));
|
||||
@ -196,7 +196,7 @@ namespace std
|
||||
* @param desired The value to store
|
||||
* @param order Memory order constraint to use
|
||||
*/
|
||||
void store(T desired, memory_order order = memory_order::seq_cst)
|
||||
inline __always_inline void store(T desired, memory_order order = memory_order::seq_cst)
|
||||
{
|
||||
builtin_atomic_n(store)(&this->value, desired,
|
||||
static_cast<int>(order));
|
||||
@ -205,8 +205,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc store()
|
||||
*/
|
||||
void store(T desired,
|
||||
memory_order order = memory_order::seq_cst) volatile
|
||||
inline __always_inline void store(T desired,
|
||||
memory_order order = memory_order::seq_cst) volatile
|
||||
{
|
||||
builtin_atomic_n(store)(&this->value, desired,
|
||||
static_cast<int>(order));
|
||||
@ -219,7 +219,7 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the exchange
|
||||
*/
|
||||
T exchange(T desired, memory_order order = memory_order::seq_cst)
|
||||
inline __always_inline T exchange(T desired, memory_order order = memory_order::seq_cst)
|
||||
{
|
||||
return builtin_atomic_n(exchange)(&this->value, desired,
|
||||
static_cast<int>(order));
|
||||
@ -228,8 +228,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc exchange()
|
||||
*/
|
||||
T exchange(T desired,
|
||||
memory_order order = memory_order::seq_cst) volatile
|
||||
inline __always_inline T exchange(T desired,
|
||||
memory_order order = memory_order::seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic_n(exchange)(&this->value, desired,
|
||||
static_cast<int>(order));
|
||||
@ -244,9 +244,9 @@ namespace std
|
||||
* @param failure Memory order constraint to use if the exchange fails
|
||||
* @return True if the exchange succeeded, false otherwise
|
||||
*/
|
||||
bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure)
|
||||
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure)
|
||||
{
|
||||
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
|
||||
desired, false, success,
|
||||
@ -256,9 +256,9 @@ namespace std
|
||||
/**
|
||||
* @copydoc compare_exchange_weak()
|
||||
*/
|
||||
bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure) volatile
|
||||
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure) volatile
|
||||
{
|
||||
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
|
||||
desired, false, success,
|
||||
@ -273,9 +273,9 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return True if the exchange succeeded, false otherwise
|
||||
*/
|
||||
bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
|
||||
desired, false, order,
|
||||
@ -285,9 +285,9 @@ namespace std
|
||||
/**
|
||||
* @copydoc compare_exchange_weak()
|
||||
*/
|
||||
bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
|
||||
desired, false, order,
|
||||
@ -303,9 +303,9 @@ namespace std
|
||||
* @param failure Memory order constraint to use if the exchange fails
|
||||
* @return True if the exchange succeeded, false otherwise
|
||||
*/
|
||||
bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure)
|
||||
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure)
|
||||
{
|
||||
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
|
||||
desired, true, success,
|
||||
@ -315,9 +315,9 @@ namespace std
|
||||
/**
|
||||
* @copydoc compare_exchange_strong()
|
||||
*/
|
||||
bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure) volatile
|
||||
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order success,
|
||||
memory_order failure) volatile
|
||||
{
|
||||
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
|
||||
desired, true, success,
|
||||
@ -332,9 +332,9 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return True if the exchange succeeded, false otherwise
|
||||
*/
|
||||
bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
|
||||
desired, true, order,
|
||||
@ -344,9 +344,9 @@ namespace std
|
||||
/**
|
||||
* @copydoc compare_exchange_strong()
|
||||
*/
|
||||
bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
|
||||
memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
|
||||
desired, true, order,
|
||||
@ -360,8 +360,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the addition
|
||||
*/
|
||||
T fetch_add(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_add(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_add)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -370,8 +370,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_add()
|
||||
*/
|
||||
T fetch_add(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_add(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_add)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -384,8 +384,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the subtraction
|
||||
*/
|
||||
T fetch_sub(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_sub(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_sub)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -394,8 +394,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_sub()
|
||||
*/
|
||||
T fetch_sub(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_sub(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_sub)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -408,8 +408,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the AND
|
||||
*/
|
||||
T fetch_and(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_and(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_and)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -418,8 +418,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_and()
|
||||
*/
|
||||
T fetch_and(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_and(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_and)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -432,8 +432,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the OR
|
||||
*/
|
||||
T fetch_or(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_or(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_or)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -442,8 +442,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_or()
|
||||
*/
|
||||
T fetch_or(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_or(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_or)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -456,8 +456,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the XOR
|
||||
*/
|
||||
T fetch_xor(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_xor(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_xor)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -466,8 +466,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_xor()
|
||||
*/
|
||||
T fetch_xor(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_xor(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_xor)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -480,8 +480,8 @@ namespace std
|
||||
* @param order Memory order constraint to use
|
||||
* @return The value of the atomic variable before the NAND
|
||||
*/
|
||||
T fetch_nand(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
inline __always_inline T fetch_nand(T arg, memory_order order =
|
||||
memory_order_seq_cst)
|
||||
{
|
||||
return builtin_atomic(fetch_nand)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
@ -490,8 +490,8 @@ namespace std
|
||||
/**
|
||||
* @copydoc fetch_nand()
|
||||
*/
|
||||
T fetch_nand(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
inline __always_inline T fetch_nand(T arg, memory_order order =
|
||||
memory_order_seq_cst) volatile
|
||||
{
|
||||
return builtin_atomic(fetch_nand)(&this->value, arg,
|
||||
static_cast<int>(order));
|
||||
|
19
include_std/cassert
Normal file
19
include_std/cassert
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <assert.h>
|
@ -405,7 +405,17 @@
|
||||
/** State not recoverable */
|
||||
#define ENOTRECOVERABLE 131
|
||||
|
||||
extern int *__errno_location(void) __attribute__((const));
|
||||
#include <types.h>
|
||||
EXTERNC int *__errno_location(void) __attribute__((const));
|
||||
#define errno (*__errno_location())
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
const char *strerror(int errnum);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !_ERRNO_H
|
||||
|
@ -19,12 +19,43 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T>
|
||||
struct equal_to
|
||||
{
|
||||
bool operator()(const T &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
struct equal_to
|
||||
{
|
||||
bool operator()(const T &lhs, const T &rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
struct hash
|
||||
{
|
||||
size_t operator()(const Key &key) const
|
||||
{
|
||||
#if defined(a64)
|
||||
static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
|
||||
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
|
||||
const uint64_t FNV_PRIME = 1099511628211ull;
|
||||
#elif defined(a32)
|
||||
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
|
||||
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
|
||||
const uint32_t FNV_PRIME = 16777619u;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
|
||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(&key);
|
||||
const size_t size = sizeof(Key);
|
||||
uintptr_t hash = FNV_OFFSET_BASIS;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
hash ^= static_cast<uintptr_t>(data[i]);
|
||||
hash *= FNV_PRIME;
|
||||
}
|
||||
|
||||
return static_cast<size_t>(hash);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
349
include_std/list
349
include_std/list
@ -18,6 +18,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <assert.h>
|
||||
#include <lock.hpp>
|
||||
|
||||
namespace std
|
||||
{
|
||||
@ -25,75 +27,77 @@ namespace std
|
||||
class list
|
||||
{
|
||||
private:
|
||||
struct lNode
|
||||
NewLock(lock);
|
||||
|
||||
struct node
|
||||
{
|
||||
T value;
|
||||
lNode *prev;
|
||||
lNode *next;
|
||||
node *prev;
|
||||
node *next;
|
||||
|
||||
lNode(const T &v, lNode *p = nullptr, lNode *n = nullptr)
|
||||
node(const T &v, node *p = nullptr, node *n = nullptr)
|
||||
: value(v), prev(p), next(n) {}
|
||||
};
|
||||
|
||||
lNode *head;
|
||||
lNode *tail;
|
||||
size_t size;
|
||||
node *head = nullptr;
|
||||
node *tail = nullptr;
|
||||
std::atomic_size_t lSize = 0;
|
||||
|
||||
public:
|
||||
list() : head(nullptr), tail(nullptr), size(0) {}
|
||||
list() {}
|
||||
~list() { clear(); }
|
||||
list(const list &other) : head(nullptr), tail(nullptr), size(0) { *this = other; }
|
||||
list(const list &other) { *this = other; }
|
||||
|
||||
void push_back(const T &value)
|
||||
{
|
||||
lNode *new_node = new lNode(value, tail, nullptr);
|
||||
SmartLock(this->lock);
|
||||
|
||||
node *nNode = new node(value, tail);
|
||||
if (empty())
|
||||
{
|
||||
head = tail = new_node;
|
||||
}
|
||||
head = tail = nNode;
|
||||
else
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
tail->next = nNode;
|
||||
tail = nNode;
|
||||
}
|
||||
++size;
|
||||
++lSize;
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
|
||||
if (unlikely(empty()))
|
||||
{
|
||||
assert(!"list is empty");
|
||||
}
|
||||
else if (head == tail)
|
||||
{
|
||||
delete tail;
|
||||
head = tail = nullptr;
|
||||
--size;
|
||||
--lSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
lNode *old_tail = tail;
|
||||
node *oldTail = tail;
|
||||
tail = tail->prev;
|
||||
tail->next = nullptr;
|
||||
delete old_tail;
|
||||
--size;
|
||||
delete oldTail;
|
||||
--lSize;
|
||||
}
|
||||
}
|
||||
|
||||
void push_front(const T &value)
|
||||
{
|
||||
lNode *new_node = new lNode(value, nullptr, head);
|
||||
SmartLock(this->lock);
|
||||
|
||||
node *nNode = new node(value, nullptr, head);
|
||||
if (empty())
|
||||
{
|
||||
head = tail = new_node;
|
||||
}
|
||||
head = tail = nNode;
|
||||
else
|
||||
{
|
||||
head->prev = new_node;
|
||||
head = new_node;
|
||||
head->prev = nNode;
|
||||
head = nNode;
|
||||
}
|
||||
++size;
|
||||
++lSize;
|
||||
}
|
||||
|
||||
void pop_front()
|
||||
@ -105,21 +109,84 @@ namespace std
|
||||
|
||||
if (head == tail)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
delete head;
|
||||
head = tail = nullptr;
|
||||
--size;
|
||||
--lSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
lNode *old_head = head;
|
||||
SmartLock(this->lock);
|
||||
node *old_head = head;
|
||||
head = head->next;
|
||||
head->prev = nullptr;
|
||||
delete old_head;
|
||||
--size;
|
||||
--lSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool empty() const { return size == 0; }
|
||||
template <class... Args>
|
||||
void emplace_back(Args &&...args)
|
||||
{
|
||||
assert(sizeof...(args) > 0);
|
||||
|
||||
SmartLock(this->lock);
|
||||
|
||||
node *nNode = new node(T(std::forward<Args>(args)...), tail);
|
||||
if (this->empty())
|
||||
head = tail = nNode;
|
||||
else
|
||||
{
|
||||
tail->next = nNode;
|
||||
tail = nNode;
|
||||
}
|
||||
++lSize;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void emplace_front(Args &&...args)
|
||||
{
|
||||
assert(sizeof...(args) > 0);
|
||||
|
||||
SmartLock(this->lock);
|
||||
|
||||
node *nNode = new node(T(std::forward<Args>(args)...), nullptr, head);
|
||||
if (this->empty())
|
||||
head = tail = nNode;
|
||||
else
|
||||
{
|
||||
head->prev = nNode;
|
||||
head = nNode;
|
||||
}
|
||||
++lSize;
|
||||
}
|
||||
|
||||
T &front()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return head->value;
|
||||
}
|
||||
|
||||
const T &front() const
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return head->value;
|
||||
}
|
||||
|
||||
T &back()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return tail->value;
|
||||
}
|
||||
|
||||
const T &back() const
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return tail->value;
|
||||
}
|
||||
|
||||
bool empty() const { return lSize.load() == 0; }
|
||||
size_t size() const { return lSize; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
@ -127,39 +194,179 @@ namespace std
|
||||
pop_back();
|
||||
}
|
||||
|
||||
list &operator=(const list &other)
|
||||
void merge(list &other)
|
||||
{
|
||||
if (this != &other)
|
||||
if (this == &other)
|
||||
return;
|
||||
|
||||
while (other.empty() == false)
|
||||
{
|
||||
clear();
|
||||
for (const T &value : other)
|
||||
T &fr = other.front();
|
||||
push_back(fr);
|
||||
other.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void remove(const T &value)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
node *p = head;
|
||||
while (p != nullptr)
|
||||
{
|
||||
if (p->value == value)
|
||||
{
|
||||
push_back(value);
|
||||
if (p->prev)
|
||||
p->prev->next = p->next;
|
||||
if (p->next)
|
||||
p->next->prev = p->prev;
|
||||
if (p == head)
|
||||
head = p->next;
|
||||
if (p == tail)
|
||||
tail = p->prev;
|
||||
delete p;
|
||||
--lSize;
|
||||
return;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
|
||||
template <class UnaryPredicate>
|
||||
void remove_if(UnaryPredicate p)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
node *n = head;
|
||||
while (n != nullptr)
|
||||
{
|
||||
if (p(n->value))
|
||||
{
|
||||
if (n->prev)
|
||||
n->prev->next = n->next;
|
||||
if (n->next)
|
||||
n->next->prev = n->prev;
|
||||
if (n == head)
|
||||
head = n->next;
|
||||
if (n == tail)
|
||||
tail = n->prev;
|
||||
delete n;
|
||||
--lSize;
|
||||
return;
|
||||
}
|
||||
n = n->next;
|
||||
}
|
||||
}
|
||||
|
||||
void reverse()
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
SmartLock(this->lock);
|
||||
node *p = head;
|
||||
while (p != nullptr)
|
||||
{
|
||||
node *tmp = p->next;
|
||||
p->next = p->prev;
|
||||
p->prev = tmp;
|
||||
p = tmp;
|
||||
}
|
||||
node *tmp = head;
|
||||
head = tail;
|
||||
tail = tmp;
|
||||
}
|
||||
|
||||
void sort()
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
SmartLock(this->lock);
|
||||
bool swapped = true;
|
||||
while (swapped)
|
||||
{
|
||||
swapped = false;
|
||||
node *p = head;
|
||||
while (p->next != nullptr)
|
||||
{
|
||||
if (p->value > p->next->value)
|
||||
{
|
||||
T tmp = p->value;
|
||||
p->value = p->next->value;
|
||||
p->next->value = tmp;
|
||||
swapped = true;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Compare>
|
||||
void sort(Compare comp)
|
||||
{
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
SmartLock(this->lock);
|
||||
bool swapped = true;
|
||||
while (swapped)
|
||||
{
|
||||
swapped = false;
|
||||
node *p = head;
|
||||
while (p->next != nullptr)
|
||||
{
|
||||
if (comp(p->value, p->next->value))
|
||||
{
|
||||
T tmp = p->value;
|
||||
p->value = p->next->value;
|
||||
p->next->value = tmp;
|
||||
swapped = true;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-STL function */
|
||||
T &operator[](size_t Index)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
node *p = head;
|
||||
for (size_t i = 0; i < Index; ++i)
|
||||
p = p->next;
|
||||
return p->value;
|
||||
}
|
||||
|
||||
list &operator=(const list &other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
for (const T &value : other)
|
||||
push_back(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
class iterator
|
||||
{
|
||||
private:
|
||||
lNode *node;
|
||||
node *_node;
|
||||
friend class list;
|
||||
|
||||
public:
|
||||
iterator(lNode *p = nullptr) : node(p) {}
|
||||
T &operator*() const { return node->value; }
|
||||
T *operator->() const { return &node->value; }
|
||||
iterator(node *p = nullptr) : _node(p) {}
|
||||
T &operator*() const { return _node->value; }
|
||||
T *operator->() const { return &_node->value; }
|
||||
|
||||
iterator &operator++()
|
||||
{
|
||||
node = node->next;
|
||||
_node = _node->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator &operator--()
|
||||
{
|
||||
node = node->prev;
|
||||
_node = _node->prev;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -177,12 +384,14 @@ namespace std
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator &rhs) const { return node == rhs.node; }
|
||||
bool operator!=(const iterator &rhs) const { return node != rhs.node; }
|
||||
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); }
|
||||
const iterator begin() const { return iterator(head); }
|
||||
const iterator end() const { return iterator(nullptr); }
|
||||
|
||||
iterator insert(iterator pos, const T &value)
|
||||
{
|
||||
@ -198,24 +407,46 @@ namespace std
|
||||
}
|
||||
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);
|
||||
SmartLock(this->lock);
|
||||
node *p = pos.node;
|
||||
node *nNode = new node(value, p->prev, p);
|
||||
p->prev->next = nNode;
|
||||
p->prev = nNode;
|
||||
++lSize;
|
||||
return iterator(nNode);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
if (pos == end())
|
||||
return end();
|
||||
else if (pos == begin())
|
||||
{
|
||||
pop_front();
|
||||
return begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
node *p = pos._node;
|
||||
if (p->prev)
|
||||
p->prev->next = p->next;
|
||||
|
||||
if (p->next)
|
||||
p->next->prev = p->prev;
|
||||
|
||||
if (head == p)
|
||||
head = p->next;
|
||||
|
||||
if (tail == p)
|
||||
tail = p->prev;
|
||||
|
||||
iterator ret(p->next);
|
||||
delete p;
|
||||
--lSize;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -15,7 +15,4 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SCHED_H
|
||||
#define _SCHED_H
|
||||
|
||||
#endif // !_SCHED_H
|
||||
#pragma once
|
||||
|
@ -1,50 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 ret = fnv_offset_basis;
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
ret ^= static_cast<uint64_t>(data[i]);
|
||||
ret *= fnv_prime;
|
||||
}
|
||||
|
||||
return static_cast<size_t>(ret);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_FUNCTIONAL_H__
|
@ -250,15 +250,6 @@ namespace std
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1,131 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 <vector>
|
||||
#include <list>
|
||||
|
||||
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> bkts;
|
||||
|
||||
size_t hash(const key_type &key) const
|
||||
{
|
||||
std::hash<key_type> hash_function;
|
||||
return hash_function(key) % this->bkts.size();
|
||||
}
|
||||
|
||||
public:
|
||||
unordered_map() : bkts(DEFAULT_NUM_BUCKETS) {}
|
||||
unordered_map(size_t num_buckets) : bkts(num_buckets) {}
|
||||
|
||||
void insert(const key_value_pair &pair)
|
||||
{
|
||||
size_t bucket_index = hash(pair.first);
|
||||
bucket &bkt = this->bkts[bucket_index];
|
||||
for (auto it = bkt.begin(); it != bkt.end(); ++it)
|
||||
{
|
||||
if (it->first == pair.first)
|
||||
{
|
||||
it->second = pair.second;
|
||||
return;
|
||||
}
|
||||
}
|
||||
bkt.push_back(pair);
|
||||
}
|
||||
|
||||
bool contains(const key_type &key) const
|
||||
{
|
||||
size_t bucket_index = hash(key);
|
||||
const bucket &bkt = this->bkts[bucket_index];
|
||||
for (auto it = bkt.begin(); it != bkt.end(); ++it)
|
||||
{
|
||||
if (it->first == key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
iterator find(const key_type &k)
|
||||
{
|
||||
size_t bucket_index = hash(k);
|
||||
bucket &bkt = this->bkts[bucket_index];
|
||||
for (auto it = bkt.begin(); it != bkt.end(); ++it)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
}
|
||||
return bkt.end();
|
||||
}
|
||||
|
||||
const_iterator find(const key_type &k) const
|
||||
{
|
||||
size_t bucket_index = hash(k);
|
||||
const bucket &bkt = this->bkts[bucket_index];
|
||||
for (auto it = bkt.begin(); it != bkt.end(); ++it)
|
||||
{
|
||||
if (it->first == k)
|
||||
return it;
|
||||
}
|
||||
return bkt.end();
|
||||
}
|
||||
|
||||
iterator end() { return this->bkts.end(); }
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
size_t count = 0;
|
||||
foreach (const auto &bkt in this->bkts)
|
||||
count += bkt.size();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
value_type &operator[](const key_type &key)
|
||||
{
|
||||
size_t bucket_index = hash(key);
|
||||
bucket &bkt = this->bkts[bucket_index];
|
||||
for (auto it = bkt.begin(); it != bkt.end(); ++it)
|
||||
{
|
||||
if (it->first == key)
|
||||
return it->second;
|
||||
}
|
||||
bkt.emplace_back(key, value_type());
|
||||
return bkt.back().second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_STD_UNORDERED_MAP_H__
|
88
include_std/stdatomic.h
Normal file
88
include_std/stdatomic.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum
|
||||
{
|
||||
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
memory_order_consume = __ATOMIC_CONSUME,
|
||||
memory_order_acquire = __ATOMIC_ACQUIRE,
|
||||
memory_order_release = __ATOMIC_RELEASE,
|
||||
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||
} memory_order;
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
__atomic_store_n(object, desired, order)
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
__atomic_store_n(object, desired, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
__atomic_load_n(object, order)
|
||||
|
||||
#define atomic_load(object) \
|
||||
__atomic_load_n(object, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
__atomic_exchange_n(object, desired, order)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
__atomic_exchange_n(object, desired, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
__atomic_compare_exchange_n(object, expected, desired, 0, success, failure)
|
||||
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||
__atomic_compare_exchange_n(object, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
__atomic_compare_exchange_n(object, expected, desired, 1, success, failure)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
__atomic_compare_exchange_n(object, expected, desired, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
__atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
__atomic_fetch_add(object, operand, order)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
__atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
__atomic_fetch_sub(object, operand, order)
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
__atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
__atomic_fetch_or(object, operand, order)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
__atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
__atomic_fetch_xor(object, operand, order)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
__atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
__atomic_fetch_and(object, operand, order)
|
@ -113,14 +113,14 @@ namespace std
|
||||
delete[] this->Data, this->Data = nullptr;
|
||||
}
|
||||
|
||||
size_t length() const
|
||||
size_t length()
|
||||
{
|
||||
v_strdbg("%#lx: String length: %d",
|
||||
this, this->Length);
|
||||
return this->Length;
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
size_t capacity()
|
||||
{
|
||||
v_strdbg("%#lx: String capacity: %d",
|
||||
this, this->Capacity);
|
||||
@ -174,14 +174,14 @@ namespace std
|
||||
this, this->Data, this->Data, this->Length, this->Capacity);
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
bool empty()
|
||||
{
|
||||
strdbg("%#lx: String empty: %d",
|
||||
this, this->Length == 0);
|
||||
return this->Length == 0;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
size_t size()
|
||||
{
|
||||
strdbg("%#lx: String size: %d",
|
||||
this, this->Length);
|
||||
@ -530,7 +530,7 @@ namespace std
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* warning: implicitly-declared ‘constexpr String::String(const String&)’ is deprecated [-Wdeprecated-copy] */
|
||||
/* warning: implicitly-declared 'constexpr String::String(const String&)' is deprecated [-Wdeprecated-copy] */
|
||||
string &operator=(const string &Other) = default;
|
||||
|
||||
// string &operator=(const string &Other)
|
||||
|
@ -18,4 +18,6 @@
|
||||
#ifndef _STRING_H
|
||||
#define _STRING_H
|
||||
|
||||
#include <convert.h>
|
||||
|
||||
#endif // !_STRING_H
|
||||
|
45
include_std/sys/mman.h
Normal file
45
include_std/sys/mman.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
/* stubs */
|
||||
|
||||
#ifndef MAP_PRIVATE
|
||||
#define MAP_PRIVATE 0x0
|
||||
#endif
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS 0x0
|
||||
#endif
|
||||
|
||||
#ifndef PROT_READ
|
||||
#define PROT_READ 0x0
|
||||
#endif
|
||||
|
||||
#ifndef PROT_WRITE
|
||||
#define PROT_WRITE 0x0
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED 0x0
|
||||
#endif
|
||||
|
||||
#ifndef POSIX_MADV_DONTNEED
|
||||
#define POSIX_MADV_DONTNEED 0x0
|
||||
#endif
|
@ -15,7 +15,15 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TIME_H
|
||||
#define _SYS_TIME_H
|
||||
#ifndef _TIME_H
|
||||
#define _TIME_H
|
||||
|
||||
#endif // !_SYS_TIME_H
|
||||
#include <types.h>
|
||||
|
||||
struct timespec
|
||||
{
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
};
|
||||
|
||||
#endif // !_TIME_H
|
@ -18,4 +18,9 @@
|
||||
#ifndef _UNISTD_H
|
||||
#define _UNISTD_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define _SC_PAGESIZE 30
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
||||
|
||||
#endif // !_UNISTD_H
|
||||
|
282
include_std/unordered_map
Normal file
282
include_std/unordered_map
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lock.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#define DEBUG_UMAP_MESSAGES 1
|
||||
|
||||
#ifdef DEBUG_UMAP_MESSAGES
|
||||
#define umDebug(m, ...) debug("%#lx: " m, this, ##__VA_ARGS__)
|
||||
#else
|
||||
#define umDebug(m, ...)
|
||||
#endif
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename Key, typename T>
|
||||
class unordered_map
|
||||
{
|
||||
public:
|
||||
typedef std::pair<Key, T> pair_t;
|
||||
typedef std::list<pair_t> bucket_t;
|
||||
|
||||
private:
|
||||
NewLock(lock);
|
||||
std::vector<bucket_t> Buckets;
|
||||
|
||||
size_t hash(const Key &key) const
|
||||
{
|
||||
size_t ret = std::hash<Key>()(key) % this->Buckets.size();
|
||||
// debug("Hashed %#lx to %d", key, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
unordered_map()
|
||||
: Buckets(16)
|
||||
{
|
||||
umDebug("Created unordered_map with 16 buckets (default)");
|
||||
}
|
||||
|
||||
unordered_map(size_t num)
|
||||
: Buckets(num)
|
||||
{
|
||||
umDebug("Created unordered_map with %d buckets", num);
|
||||
}
|
||||
|
||||
~unordered_map()
|
||||
{
|
||||
umDebug("Destroyed unordered_map");
|
||||
}
|
||||
|
||||
void insert(const pair_t &p)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(p.first) % Buckets.size();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
for (auto &element : bucket)
|
||||
{
|
||||
if (element.first == p.first)
|
||||
{
|
||||
element.second = p.second;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bucket.push_back(p);
|
||||
}
|
||||
|
||||
void erase(const Key &key)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(key) % Buckets.size();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
bucket.remove_if([key](const pair_t &element)
|
||||
{ return element.first == key; });
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
for (auto &bucket : Buckets)
|
||||
{
|
||||
bucket.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool contains(const Key &key)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(key) % Buckets.size();
|
||||
const auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
for (const auto &element : bucket)
|
||||
{
|
||||
if (element.first == key)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t count = 0;
|
||||
for (const auto &bucket : Buckets)
|
||||
{
|
||||
count += bucket.size();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool empty() { return size() == 0; }
|
||||
|
||||
T &operator[](const Key &key)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(key) % Buckets.size();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
for (auto &element : bucket)
|
||||
{
|
||||
if (element.first == key)
|
||||
return element.second;
|
||||
}
|
||||
|
||||
bucket.emplace_back(key, T{});
|
||||
return bucket.back().second;
|
||||
}
|
||||
|
||||
class iterator
|
||||
{
|
||||
private:
|
||||
using BucketIterator = typename std::list<pair_t>::iterator;
|
||||
size_t bucketIndex;
|
||||
BucketIterator bucketIterator;
|
||||
std::vector<std::list<pair_t>> *buckets;
|
||||
|
||||
public:
|
||||
size_t GetBucketIndex() const { return bucketIndex; }
|
||||
BucketIterator &GetBucketIterator() const { return bucketIterator; }
|
||||
|
||||
iterator(size_t index,
|
||||
BucketIterator it,
|
||||
std::vector<std::list<pair_t>> *buckets)
|
||||
: bucketIndex(index),
|
||||
bucketIterator(it),
|
||||
buckets(buckets) {}
|
||||
|
||||
iterator &operator++()
|
||||
{
|
||||
++bucketIterator;
|
||||
|
||||
while (bucketIndex < buckets->size() &&
|
||||
bucketIterator == (*buckets)[bucketIndex].end())
|
||||
{
|
||||
++bucketIndex;
|
||||
if (bucketIndex < buckets->size())
|
||||
{
|
||||
bucketIterator = (*buckets)[bucketIndex].begin();
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator &other) const
|
||||
{
|
||||
return bucketIndex != other.bucketIndex ||
|
||||
bucketIterator != other.bucketIterator;
|
||||
}
|
||||
|
||||
pair_t &operator*()
|
||||
{
|
||||
return *bucketIterator;
|
||||
}
|
||||
|
||||
pair_t *operator->()
|
||||
{
|
||||
return &(*bucketIterator);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return bucketIndex < buckets->size();
|
||||
}
|
||||
};
|
||||
|
||||
iterator find(const Key &key)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(key) % Buckets.size();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
auto it = std::find_if(bucket.begin(), bucket.end(),
|
||||
[key](const pair_t &element)
|
||||
{ return element.first == key; });
|
||||
|
||||
if (it != bucket.end())
|
||||
{
|
||||
return iterator(bucketIndex,
|
||||
it,
|
||||
&Buckets);
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
for (size_t i = 0; i < Buckets.size(); ++i)
|
||||
{
|
||||
if (!Buckets[i].empty())
|
||||
{
|
||||
return iterator(i,
|
||||
Buckets[i].begin(),
|
||||
&Buckets);
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(Buckets.size(),
|
||||
Buckets.back().end(),
|
||||
&Buckets);
|
||||
}
|
||||
|
||||
iterator insert(iterator pos, const pair_t &p)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = hash(p.first) % Buckets.size();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
auto itr = std::find_if(bucket.begin(), bucket.end(),
|
||||
[p](const pair_t &element)
|
||||
{ return element.first == p.first; });
|
||||
|
||||
if (itr != bucket.end())
|
||||
return end();
|
||||
|
||||
return iterator(bucketIndex,
|
||||
bucket.insert(pos.bucketIterator, p),
|
||||
&Buckets);
|
||||
}
|
||||
|
||||
iterator erase(iterator pos)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
size_t bucketIndex = pos.GetBucketIndex();
|
||||
auto &bucket = Buckets[bucketIndex];
|
||||
|
||||
return iterator(bucketIndex,
|
||||
bucket.erase(pos.GetBucketIterator()),
|
||||
&Buckets);
|
||||
}
|
||||
};
|
||||
}
|
@ -26,4 +26,29 @@ namespace std
|
||||
{
|
||||
return static_cast<typename std::remove_reference<T>::type &&>(arg);
|
||||
}
|
||||
|
||||
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) {}
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
pair<T1, T2> make_pair(T1 x, T2 y)
|
||||
{
|
||||
return pair<T1, T2>(x, y);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &&forward(typename std::remove_reference<T>::type &arg)
|
||||
{
|
||||
return static_cast<T &&>(arg);
|
||||
}
|
||||
}
|
||||
|
@ -15,25 +15,20 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_STD_UTILITY_H__
|
||||
#define __FENNIX_KERNEL_STD_UTILITY_H__
|
||||
#ifndef __FENNIX_KERNEL_UTSNAME_H__
|
||||
#define __FENNIX_KERNEL_UTSNAME_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace std
|
||||
#define _UTSNAME_LENGTH 65
|
||||
|
||||
struct utsname
|
||||
{
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
char sysname[_UTSNAME_LENGTH];
|
||||
char nodename[_UTSNAME_LENGTH];
|
||||
char release[_UTSNAME_LENGTH];
|
||||
char version[_UTSNAME_LENGTH];
|
||||
char machine[_UTSNAME_LENGTH];
|
||||
};
|
||||
|
||||
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__
|
||||
#endif // !__FENNIX_KERNEL_UTSNAME_H__
|
@ -23,13 +23,14 @@
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <lock.hpp>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
// #define DEBUG_VECTOR_MESSAGES 1
|
||||
|
||||
#ifdef DEBUG_VECTOR_MESSAGES
|
||||
#define vDebug(m, ...) debug(m, ##__VA_ARGS__)
|
||||
#define vDebug(m, ...) debug("%#lx: " m, this, ##__VA_ARGS__)
|
||||
#else
|
||||
#define vDebug(m, ...)
|
||||
#endif
|
||||
@ -40,22 +41,23 @@ namespace std
|
||||
class vector
|
||||
{
|
||||
private:
|
||||
size_t VectorSize = 0;
|
||||
size_t VectorCapacity = 0;
|
||||
NewLock(lock);
|
||||
std::atomic_size_t VectorSize = 0;
|
||||
std::atomic_size_t VectorCapacity = 0;
|
||||
T *VectorBuffer = nullptr;
|
||||
|
||||
public:
|
||||
typedef T *iterator;
|
||||
typedef const T *const_iterator;
|
||||
|
||||
vector() { vDebug("%#lx: ( empty init )", this); }
|
||||
vector() { vDebug("( empty init )"); }
|
||||
|
||||
vector(size_t Size)
|
||||
: VectorSize(Size),
|
||||
VectorCapacity(Size),
|
||||
VectorBuffer(new T[Size])
|
||||
{
|
||||
vDebug("%#lx: ( init w/size: %lld )", this, Size);
|
||||
vDebug("( init w/size: %lld )", Size);
|
||||
}
|
||||
|
||||
vector(size_t Size, const T &Initial)
|
||||
@ -63,34 +65,40 @@ namespace std
|
||||
VectorCapacity(Size),
|
||||
VectorBuffer(new T[Size])
|
||||
{
|
||||
vDebug("%#lx: ( init w/size: %lld, initial vector: %llx )", this,
|
||||
vDebug("( init w/size: %lld, initial vector: %llx )",
|
||||
Size, Initial);
|
||||
|
||||
assert(Size > 0);
|
||||
|
||||
SmartLock(this->lock);
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
VectorBuffer[i] = Initial;
|
||||
}
|
||||
|
||||
vector(const vector<T> &v)
|
||||
: VectorSize(v.VectorSize),
|
||||
VectorCapacity(v.VectorCapacity),
|
||||
: VectorSize(v.VectorSize.load()),
|
||||
VectorCapacity(v.VectorCapacity.load()),
|
||||
VectorBuffer(nullptr)
|
||||
{
|
||||
vDebug("%#lx: ( vector copy: %#lx )", this, &v);
|
||||
vDebug("( vector copy: %#lx )", &v);
|
||||
|
||||
if (!v.VectorBuffer || VectorSize <= 0)
|
||||
if (!v.VectorBuffer || VectorSize.load() <= 0)
|
||||
return;
|
||||
|
||||
VectorBuffer = new T[VectorSize];
|
||||
std::copy(v.VectorBuffer, v.VectorBuffer + VectorSize, VectorBuffer);
|
||||
SmartLock(this->lock);
|
||||
VectorBuffer = new T[VectorSize.load()];
|
||||
std::copy(v.VectorBuffer, v.VectorBuffer + VectorSize.load(), VectorBuffer);
|
||||
}
|
||||
|
||||
~vector()
|
||||
{
|
||||
vDebug("%#lx: ( deinit )", this);
|
||||
vDebug("( deinit )");
|
||||
|
||||
VectorSize.store(0);
|
||||
VectorCapacity.store(0);
|
||||
|
||||
SmartLock(this->lock);
|
||||
|
||||
VectorSize = 0;
|
||||
VectorCapacity = 0;
|
||||
if (VectorBuffer != nullptr)
|
||||
{
|
||||
delete[] VectorBuffer;
|
||||
@ -100,8 +108,8 @@ namespace std
|
||||
|
||||
void erase(iterator Position)
|
||||
{
|
||||
vDebug("%#lx: Erasing element at position %lld (v. size: %lld)", this,
|
||||
Position - this->VectorBuffer, this->VectorSize);
|
||||
vDebug("Erasing element at position %lld (v. size: %lld)",
|
||||
Position - this->VectorBuffer, this->VectorSize.load());
|
||||
|
||||
if (Position == this->end())
|
||||
{
|
||||
@ -112,24 +120,25 @@ namespace std
|
||||
|
||||
assert(Position <= this->end());
|
||||
assert(Position >= this->VectorBuffer);
|
||||
assert(Position < this->VectorBuffer + this->VectorSize);
|
||||
assert(Position < this->VectorBuffer + this->VectorSize.load());
|
||||
|
||||
SmartLock(this->lock);
|
||||
size_t index = Position - this->VectorBuffer;
|
||||
|
||||
if (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
this->VectorBuffer[index] = T();
|
||||
vDebug("%#lx: %#lx is trivially copyable", this,
|
||||
vDebug("%#lx is trivially copyable",
|
||||
&this->VectorBuffer[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->VectorBuffer[index].~T();
|
||||
vDebug("%#lx: %#lx is not trivially copyable", this,
|
||||
vDebug("%#lx is not trivially copyable",
|
||||
&this->VectorBuffer[index]);
|
||||
}
|
||||
|
||||
for (size_t i = index; i < this->VectorSize - 1; ++i)
|
||||
for (size_t i = index; i < this->VectorSize.load() - 1; ++i)
|
||||
{
|
||||
this->VectorBuffer[i] = std::move(this->VectorBuffer[i + 1]);
|
||||
}
|
||||
@ -138,7 +147,9 @@ namespace std
|
||||
|
||||
T &next(size_t Position)
|
||||
{
|
||||
if (Position + 1 < this->VectorSize)
|
||||
SmartLock(this->lock);
|
||||
|
||||
if (Position + 1 < this->VectorSize.load())
|
||||
return this->VectorBuffer[Position + 1];
|
||||
|
||||
warn("%#lx: next( %lld ) is null (requested by %#lx)", this,
|
||||
@ -149,6 +160,8 @@ namespace std
|
||||
|
||||
T &prev(size_t Position)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
|
||||
if (Position > 0)
|
||||
return this->VectorBuffer[Position - 1];
|
||||
|
||||
@ -160,11 +173,13 @@ namespace std
|
||||
|
||||
T &next(const T &Value)
|
||||
{
|
||||
for (size_t i = 0; i < this->VectorSize; i++)
|
||||
SmartLock(this->lock);
|
||||
|
||||
for (size_t i = 0; i < this->VectorSize.load(); i++)
|
||||
{
|
||||
if (std::equal_to<T>()(this->VectorBuffer[i], Value))
|
||||
{
|
||||
if (i + 1 < this->VectorSize)
|
||||
if (i + 1 < this->VectorSize.load())
|
||||
return this->VectorBuffer[i + 1];
|
||||
else
|
||||
break;
|
||||
@ -179,7 +194,9 @@ namespace std
|
||||
|
||||
T &prev(const T &Value)
|
||||
{
|
||||
for (size_t i = 0; i < this->VectorSize; i++)
|
||||
SmartLock(this->lock);
|
||||
|
||||
for (size_t i = 0; i < this->VectorSize.load(); i++)
|
||||
{
|
||||
if (std::equal_to<T>()(this->VectorBuffer[i], Value))
|
||||
{
|
||||
@ -198,25 +215,44 @@ namespace std
|
||||
|
||||
void push_back(const T &Value)
|
||||
{
|
||||
vDebug("%#lx: push_back( %#lx )", this, Value);
|
||||
vDebug("push_back( %#lx )", Value);
|
||||
|
||||
if (this->VectorSize >= this->VectorCapacity)
|
||||
if (this->VectorSize.load() >= this->VectorCapacity.load())
|
||||
{
|
||||
size_t newCapacity = this->VectorCapacity == 0
|
||||
size_t newCapacity = this->VectorCapacity.load() == 0
|
||||
? 1
|
||||
: this->VectorCapacity * 2;
|
||||
: this->VectorCapacity.load() * 2;
|
||||
reserve(newCapacity);
|
||||
}
|
||||
|
||||
SmartLock(this->lock);
|
||||
this->VectorBuffer[this->VectorSize++] = Value;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
void emplace_back(Args &&...args)
|
||||
{
|
||||
vDebug("emplace_back( %#lx )", args...);
|
||||
|
||||
if (this->VectorSize.load() >= this->VectorCapacity.load())
|
||||
{
|
||||
size_t newCapacity = this->VectorCapacity.load() == 0
|
||||
? 1
|
||||
: this->VectorCapacity.load() * 2;
|
||||
reserve(newCapacity);
|
||||
}
|
||||
|
||||
SmartLock(this->lock);
|
||||
this->VectorBuffer[this->VectorSize++] = T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void reverse()
|
||||
{
|
||||
if (this->VectorSize <= 1)
|
||||
if (this->VectorSize.load() <= 1)
|
||||
return;
|
||||
|
||||
for (size_t i = 0, j = this->VectorSize - 1; i < j; i++, j--)
|
||||
SmartLock(this->lock);
|
||||
for (size_t i = 0, j = this->VectorSize.load() - 1; i < j; i++, j--)
|
||||
{
|
||||
T &elem1 = this->VectorBuffer[i];
|
||||
T &elem2 = this->VectorBuffer[j];
|
||||
@ -226,31 +262,35 @@ namespace std
|
||||
|
||||
void reserve(size_t Capacity)
|
||||
{
|
||||
assert(!(Capacity <= VectorCapacity));
|
||||
assert(!(Capacity <= VectorCapacity.load()));
|
||||
|
||||
SmartLock(this->lock);
|
||||
|
||||
T *NewBuffer = new T[Capacity];
|
||||
size_t Size = std::min(Capacity, this->VectorSize);
|
||||
size_t Size = std::min(Capacity, this->VectorSize.load());
|
||||
for (size_t i = 0; i < Size; i++)
|
||||
NewBuffer[i] = std::move(this->VectorBuffer[i]);
|
||||
|
||||
vDebug("%#lx: reserve( %lld )->Buffer:~%#lx", this,
|
||||
vDebug("reserve( %lld )->Buffer:~%#lx",
|
||||
Capacity, this->VectorBuffer);
|
||||
|
||||
delete[] this->VectorBuffer;
|
||||
this->VectorBuffer = NewBuffer;
|
||||
this->VectorCapacity = Capacity;
|
||||
this->VectorCapacity.store(Capacity);
|
||||
}
|
||||
|
||||
void resize(size_t Size)
|
||||
{
|
||||
reserve(Size);
|
||||
this->VectorSize = Size;
|
||||
this->VectorSize.store(Size);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->VectorCapacity = 0;
|
||||
this->VectorSize = 0;
|
||||
this->VectorCapacity.store(0);
|
||||
this->VectorSize.store(0);
|
||||
|
||||
SmartLock(this->lock);
|
||||
if (VectorBuffer != nullptr)
|
||||
{
|
||||
delete[] this->VectorBuffer;
|
||||
@ -260,7 +300,8 @@ namespace std
|
||||
|
||||
T &operator[](size_t Index)
|
||||
{
|
||||
if (Index >= this->VectorSize || !this->VectorBuffer)
|
||||
SmartLock(this->lock);
|
||||
if (Index >= this->VectorSize.load() || !this->VectorBuffer)
|
||||
{
|
||||
warn("%#lx: operator[]( %lld ) is null (requested by %#lx)", this,
|
||||
Index, __builtin_return_address(0));
|
||||
@ -273,33 +314,71 @@ namespace std
|
||||
|
||||
vector<T> &operator=(const vector<T> &v)
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
|
||||
if (this == &v)
|
||||
return *this;
|
||||
|
||||
delete[] this->VectorBuffer;
|
||||
this->VectorSize = v.VectorSize;
|
||||
this->VectorCapacity = v.VectorCapacity;
|
||||
this->VectorSize.store(v.VectorSize.load());
|
||||
this->VectorCapacity.store(v.VectorCapacity.load());
|
||||
|
||||
vDebug("%#lx: operator=( <vector> )->Size:%lld", this,
|
||||
this->VectorSize);
|
||||
vDebug("operator=( <vector> )->Size:%lld",
|
||||
this->VectorSize.load());
|
||||
|
||||
this->VectorBuffer = new T[this->VectorSize];
|
||||
for (size_t i = 0; i < this->VectorSize; i++)
|
||||
this->VectorBuffer = new T[this->VectorSize.load()];
|
||||
for (size_t i = 0; i < this->VectorSize.load(); i++)
|
||||
this->VectorBuffer[i] = v.VectorBuffer[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void pop_back() { this->VectorSize--; }
|
||||
T &front() { return this->VectorBuffer[0]; }
|
||||
T &back() { return this->VectorBuffer[this->VectorSize - 1]; }
|
||||
T *data() { return this->VectorBuffer; }
|
||||
bool empty() const { return this->VectorSize == 0; }
|
||||
size_t capacity() const { return this->VectorCapacity; }
|
||||
size_t size() const { return this->VectorSize; }
|
||||
iterator begin() { return this->VectorBuffer; }
|
||||
iterator end() { return this->VectorBuffer + size(); }
|
||||
const_iterator begin() const { return this->VectorBuffer; }
|
||||
const_iterator end() const { return this->VectorBuffer + size(); }
|
||||
|
||||
T &front()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer[0];
|
||||
}
|
||||
|
||||
T &back()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer[this->VectorSize.load() - 1];
|
||||
}
|
||||
|
||||
T *data()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer;
|
||||
}
|
||||
|
||||
bool empty() const { return this->VectorSize.load() == 0; }
|
||||
size_t capacity() const { return this->VectorCapacity.load(); }
|
||||
size_t size() const { return this->VectorSize.load(); }
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer;
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer + size();
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer;
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
SmartLock(this->lock);
|
||||
return this->VectorBuffer + size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user