feat: start adding physical memory allocator
This commit is contained in:
parent
8dc53f662e
commit
e2ea22ad53
15 changed files with 440 additions and 38 deletions
144
kernel/include/util/optional.h
Normal file
144
kernel/include/util/optional.h
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#pragma once
|
||||
|
||||
#include "memory/pointer.h"
|
||||
#include "util/number.h"
|
||||
#include "util/utility.h"
|
||||
|
||||
// Ported from legacy/CrackOS3 (include/features/optional.h), adapted to the
|
||||
// PrOSess freestanding environment: uses the in-tree move/forward (util/utility.h)
|
||||
// instead of <utility>. The CrackOS3 value_or_panic() helper is omitted because
|
||||
// there is no global panic() in this tree yet.
|
||||
|
||||
template<typename T>
|
||||
struct optional {
|
||||
private:
|
||||
char buffer[sizeof(T)];
|
||||
bool initialized;
|
||||
|
||||
void destroy() {
|
||||
if (initialized) {
|
||||
((T*) buffer)->~T();
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
constexpr optional() : initialized(false) {}
|
||||
optional(const T& value) : initialized(true) {
|
||||
new (buffer) T(value);
|
||||
}
|
||||
optional(T&& value) : initialized(true) {
|
||||
new (buffer) T(move(value));
|
||||
}
|
||||
|
||||
optional(const optional& other) : initialized(other.initialized) {
|
||||
if (initialized) {
|
||||
new (buffer) T(*other);
|
||||
}
|
||||
}
|
||||
|
||||
optional(optional&& other) : initialized(other.initialized) {
|
||||
if (initialized) {
|
||||
new (buffer) T(move(*other));
|
||||
}
|
||||
other.initialized = false;
|
||||
}
|
||||
|
||||
~optional() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return (T*) buffer;
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
return *((T*) buffer);
|
||||
}
|
||||
|
||||
const T* operator->() const {
|
||||
return (const T*) buffer;
|
||||
}
|
||||
|
||||
const T& operator*() const {
|
||||
return *((const T*) buffer);
|
||||
}
|
||||
|
||||
optional& operator=(const optional& other) {
|
||||
if (this == &other) return *this;
|
||||
destroy();
|
||||
if (other.initialized) {
|
||||
new (buffer) T(*other);
|
||||
initialized = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
optional& operator=(optional&& other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
destroy();
|
||||
if (other.initialized) {
|
||||
new (buffer) T(move(*other));
|
||||
initialized = true;
|
||||
}
|
||||
other.initialized = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_value() const {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
T& value() {
|
||||
return *((T*) buffer);
|
||||
}
|
||||
|
||||
const T& value() const {
|
||||
return *((const T*) buffer);
|
||||
}
|
||||
|
||||
template<typename Func, typename... ArgT>
|
||||
T value_or_create(Func func, ArgT... args) {
|
||||
if (initialized) {
|
||||
return value();
|
||||
} else {
|
||||
return func(args...);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func, typename... ArgT>
|
||||
T value_or_create(Func func, ArgT... args) const {
|
||||
if (initialized) {
|
||||
return value();
|
||||
} else {
|
||||
return func(args...);
|
||||
}
|
||||
}
|
||||
|
||||
const T& value_or(const T& default_value) const {
|
||||
if (initialized) {
|
||||
return *((const T*) buffer);
|
||||
} else {
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
bool operator!() const {
|
||||
return !initialized;
|
||||
}
|
||||
|
||||
template<typename R, typename Func, typename... ArgT>
|
||||
optional<R> map(Func func, ArgT... args) {
|
||||
if (initialized) {
|
||||
return func(value(), forward<ArgT>(args)...);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue