[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
|
||||
memory.hpp
|
||||
new.hpp
|
||||
optional.hpp
|
||||
random.hpp
|
||||
std.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 "memory.hpp"
|
||||
#include "new.hpp"
|
||||
#include "optional.hpp"
|
||||
#include "random.hpp"
|
||||
#include "stacktrace.hpp"
|
||||
#include "stddef.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user