Fetch the repository succeeded.
#pragma once
#include <type_traits>
#include <utility>
#include <stdexcept>
template<typename T>
class Optional
{
using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
public:
Optional() : has_init_(false) {}
Optional(const T& v)
{
create(v);
}
Optional(T&& v) : has_init_(false)
{
create(std::move(v));
}
~Optional()
{
destroy();
}
Optional(const Optional& other) : has_init_(false)
{
if (other.isInit())
assign(other);
}
Optional(Optional&& other) : has_init_(false)
{
if (other.isInit())
{
assign(std::move(other));
other.destroy();
}
}
Optional& operator=(Optional &&other)
{
assign(std::move(other));
return *this;
}
Optional& operator=(const Optional &other)
{
assign(other);
return *this;
}
template<class... Args>
void emplace(Args&&... args)
{
destroy();
create(std::forward<Args>(args)...);
}
bool isInit() const { return has_init_; }
explicit operator bool() const
{
return isInit();
}
T& operator*()
{
if(isInit())
{
return *((T*) (&data_));
}
throw std::logic_error{"try to get data in a Optional which is not initialized"};
}
const T& operator*() const
{
if(isInit())
{
return *((T*) (&data_));
}
throw std::logic_error{"try to get data in a Optional which is not initialized"};
}
T* operator->()
{
return &operator*();
}
const T* operator->() const
{
return &operator*();
}
bool operator==(const Optional<T>& rhs) const
{
return (!bool(*this)) != (!rhs) ? false : (!bool(*this) ? true : (*(*this)) == (*rhs));
}
bool operator<(const Optional<T>& rhs) const
{
return !rhs ? false : (!bool(*this) ? true : (*(*this) < (*rhs)));
}
bool operator!=(const Optional<T>& rhs)
{
return !(*this == (rhs));
}
private:
template<class... Args>
void create(Args&&... args)
{
new (&data_) T(std::forward<Args>
(args)...);
has_init_ = true;
}
void destroy()
{
if (has_init_)
{
has_init_ = false;
((T*) (&data_))->~T();
}
}
void assign(const Optional& other)
{
if (other.isInit())
{
copy(other.data_);
has_init_ = true;
}
else
{
destroy();
}
}
void assign(Optional&& other)
{
if (other.isInit())
{
move(std::move(other.data_));
has_init_ = true;
other.destroy();
}
else
{
destroy();
}
}
void move(data_t&& val)
{
destroy();
new (&data_) T(std::move(*((T*)(&val))));
}
void copy(const data_t& val)
{
destroy();
new (&data_) T(*((T*) (&val)));
}
private:
bool has_init_;
data_t data_;
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。