81 lines
1.5 KiB
Plaintext
81 lines
1.5 KiB
Plaintext
|
|
#pragma GCC system_header
|
||
|
|
|
||
|
|
#ifndef _LIBCXX_OPTIONAL
|
||
|
|
#define _LIBCXX_OPTIONAL
|
||
|
|
|
||
|
|
#include <__config>
|
||
|
|
#include <type_traits>
|
||
|
|
|
||
|
|
_LIBCXX_BEGIN_NAMESPACE_STD
|
||
|
|
|
||
|
|
struct nullopt_t {
|
||
|
|
explicit constexpr nullopt_t() { }
|
||
|
|
};
|
||
|
|
inline constexpr nullopt_t nullopt {};
|
||
|
|
|
||
|
|
template <typename T>
|
||
|
|
class optional {
|
||
|
|
public:
|
||
|
|
using value_type = T;
|
||
|
|
|
||
|
|
optional() = default;
|
||
|
|
optional(nullopt_t)
|
||
|
|
: m_has_value(false)
|
||
|
|
, m_value()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class U = T>
|
||
|
|
optional(U&& value)
|
||
|
|
: m_value(std::forward<U>(value))
|
||
|
|
, m_has_value(true)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class... Args>
|
||
|
|
optional(in_place_t, Args&&... args)
|
||
|
|
: m_value(std::forward<Args>(args)...)
|
||
|
|
, m_has_value(true)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
~optional() = default;
|
||
|
|
|
||
|
|
bool has_value() const { return m_has_value; }
|
||
|
|
operator bool() const { return has_value(); }
|
||
|
|
|
||
|
|
T* operator->() { return &m_value; }
|
||
|
|
const T* operator->() const { return &m_value; }
|
||
|
|
|
||
|
|
T& operator*() { return m_value; }
|
||
|
|
const T& operator*() const { return m_value; }
|
||
|
|
|
||
|
|
T& value() { return m_value; }
|
||
|
|
const T& value() const { return m_value; }
|
||
|
|
|
||
|
|
template <class U>
|
||
|
|
T value_or(U&& def)
|
||
|
|
{
|
||
|
|
if (has_value()) {
|
||
|
|
return m_value;
|
||
|
|
}
|
||
|
|
return def;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class U>
|
||
|
|
T value_or(U&& def) const
|
||
|
|
{
|
||
|
|
if (has_value()) {
|
||
|
|
return m_value;
|
||
|
|
}
|
||
|
|
return def;
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
bool m_has_value { false };
|
||
|
|
T m_value;
|
||
|
|
};
|
||
|
|
|
||
|
|
_LIBCXX_END_NAMESPACE_STD
|
||
|
|
|
||
|
|
#endif // _LIBCXX_OPTIONAL
|