[ox/std] Add Optional
This commit is contained in:
parent
45d79e99e8
commit
fa06821d90
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
1
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -80,6 +80,7 @@ install(
|
|||||||
memops.hpp
|
memops.hpp
|
||||||
memory.hpp
|
memory.hpp
|
||||||
new.hpp
|
new.hpp
|
||||||
|
optional.hpp
|
||||||
random.hpp
|
random.hpp
|
||||||
std.hpp
|
std.hpp
|
||||||
stddef.hpp
|
stddef.hpp
|
||||||
|
144
deps/ox/src/ox/std/optional.hpp
vendored
Normal file
144
deps/ox/src/ox/std/optional.hpp
vendored
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2021 gary@drinkingtea.net
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "bit.hpp"
|
||||||
|
#include "initializerlist.hpp"
|
||||||
|
#include "iterator.hpp"
|
||||||
|
#include "new.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
template<typename T, std::size_t buffSize = sizeof(T)>
|
||||||
|
class Optional {
|
||||||
|
private:
|
||||||
|
T *m_ptr = nullptr;
|
||||||
|
char m_data[buffSize];
|
||||||
|
|
||||||
|
public:
|
||||||
|
Optional() noexcept = default;
|
||||||
|
|
||||||
|
Optional(const Optional &other) {
|
||||||
|
if (m_ptr) {
|
||||||
|
m_ptr->~T();
|
||||||
|
}
|
||||||
|
if (other.m_ptr) {
|
||||||
|
m_ptr = new(m_data) T(*other.m_ptr);
|
||||||
|
} else {
|
||||||
|
m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional(const Optional &&other) noexcept {
|
||||||
|
if (m_ptr) {
|
||||||
|
m_ptr->~T();
|
||||||
|
}
|
||||||
|
if (other.m_ptr) {
|
||||||
|
m_ptr = new(m_data) T(std::move(*other.m_ptr));
|
||||||
|
} else {
|
||||||
|
m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U = T>
|
||||||
|
constexpr U *get() noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U = T>
|
||||||
|
constexpr const U *get() const noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T &operator*() & noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const T &operator*() const & noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T &&operator*() && noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const T &&operator*() const && noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T *operator->() noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const T *operator->() const noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional &operator=(const Optional &other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (m_ptr) {
|
||||||
|
m_ptr->~T();
|
||||||
|
}
|
||||||
|
if (other.m_ptr) {
|
||||||
|
m_ptr = new(m_data) T(*other.m_ptr);
|
||||||
|
} else {
|
||||||
|
m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional &operator=(Optional &&other) noexcept {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (m_ptr) {
|
||||||
|
m_ptr->~T();
|
||||||
|
}
|
||||||
|
if (other.m_ptr) {
|
||||||
|
m_ptr = new(m_data) T(std::move(*other.m_ptr));
|
||||||
|
} else {
|
||||||
|
m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Args>
|
||||||
|
constexpr T &emplace(Args &&...args) {
|
||||||
|
m_ptr = new (m_data) T(ox::forward<Args>(args)...);
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename U, class... Args>
|
||||||
|
constexpr T &emplace_subclass(Args &&...args) {
|
||||||
|
static_assert(sizeof(U) <= buffSize, "Subclass is too large for this Optional");
|
||||||
|
m_ptr = new (m_data) U(ox::forward<Args>(args)...);
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool has_value() const noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit constexpr operator bool() const noexcept {
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void reset() noexcept {
|
||||||
|
get()->~T();
|
||||||
|
m_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
1
deps/ox/src/ox/std/std.hpp
vendored
1
deps/ox/src/ox/std/std.hpp
vendored
@ -24,6 +24,7 @@
|
|||||||
#include "memops.hpp"
|
#include "memops.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
#include "new.hpp"
|
#include "new.hpp"
|
||||||
|
#include "optional.hpp"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
#include "stacktrace.hpp"
|
#include "stacktrace.hpp"
|
||||||
#include "stddef.hpp"
|
#include "stddef.hpp"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user