2017-01-31 08:14:48 +08:00
|
|
|
#pragma once
|
2017-03-29 06:05:55 +08:00
|
|
|
#include "vcpkg_Checks.h"
|
2017-01-31 08:14:48 +08:00
|
|
|
|
2017-03-29 06:05:55 +08:00
|
|
|
namespace vcpkg
|
|
|
|
{
|
2017-04-04 07:27:51 +08:00
|
|
|
struct NullOpt
|
2017-03-29 06:05:55 +08:00
|
|
|
{
|
2017-04-04 07:27:51 +08:00
|
|
|
explicit constexpr NullOpt(int) {}
|
2017-03-29 06:05:55 +08:00
|
|
|
};
|
|
|
|
|
2017-04-29 03:55:50 +08:00
|
|
|
const static constexpr NullOpt nullopt{0};
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
template<class T>
|
2017-04-04 07:27:51 +08:00
|
|
|
class Optional
|
2017-03-29 06:05:55 +08:00
|
|
|
{
|
|
|
|
public:
|
2017-04-28 08:56:06 +08:00
|
|
|
constexpr Optional() : m_is_present(false), m_t() {}
|
2017-04-13 07:11:31 +08:00
|
|
|
|
2017-03-29 06:05:55 +08:00
|
|
|
// Constructors are intentionally implicit
|
2017-04-28 08:56:06 +08:00
|
|
|
constexpr Optional(NullOpt) : m_is_present(false), m_t() {}
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
Optional(const T& t) : m_is_present(true), m_t(t) {}
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {}
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-01 07:29:04 +08:00
|
|
|
T&& value_or_exit(const LineInfo& line_info) &&
|
2017-03-29 06:05:55 +08:00
|
|
|
{
|
|
|
|
this->exit_if_null(line_info);
|
|
|
|
return std::move(this->m_t);
|
|
|
|
}
|
|
|
|
|
2017-04-01 07:29:04 +08:00
|
|
|
const T& value_or_exit(const LineInfo& line_info) const &
|
2017-03-29 06:05:55 +08:00
|
|
|
{
|
|
|
|
this->exit_if_null(line_info);
|
|
|
|
return this->m_t;
|
|
|
|
}
|
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
constexpr explicit operator bool() const { return this->m_is_present; }
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
constexpr bool has_value() const { return m_is_present; }
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
template<class U>
|
2017-03-29 06:05:55 +08:00
|
|
|
T value_or(U&& default_value) const &
|
|
|
|
{
|
|
|
|
return bool(*this) ? this->m_t : static_cast<T>(std::forward<U>(default_value));
|
|
|
|
}
|
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
template<class U>
|
2017-03-29 06:05:55 +08:00
|
|
|
T value_or(U&& default_value) &&
|
|
|
|
{
|
|
|
|
return bool(*this) ? std::move(this->m_t) : static_cast<T>(std::forward<U>(default_value));
|
|
|
|
}
|
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
const T* get() const { return bool(*this) ? &this->m_t : nullptr; }
|
2017-03-29 06:05:55 +08:00
|
|
|
|
2017-04-28 08:56:06 +08:00
|
|
|
T* get() { return bool(*this) ? &this->m_t : nullptr; }
|
2017-03-29 06:05:55 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
void exit_if_null(const LineInfo& line_info) const
|
|
|
|
{
|
|
|
|
Checks::check_exit(line_info, this->m_is_present, "Value was null");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool m_is_present;
|
|
|
|
T m_t;
|
|
|
|
};
|
2017-04-29 08:27:07 +08:00
|
|
|
|
2017-07-27 07:25:24 +08:00
|
|
|
template<class U>
|
|
|
|
Optional<std::decay_t<U>> make_optional(U&& u)
|
|
|
|
{
|
|
|
|
return Optional<std::decay_t<U>>(std::forward<U>(u));
|
|
|
|
}
|
|
|
|
|
2017-04-29 08:27:07 +08:00
|
|
|
template<class T>
|
|
|
|
bool operator==(const Optional<T>& o, const T& t)
|
|
|
|
{
|
|
|
|
if (auto p = o.get()) return *p == t;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
template<class T>
|
|
|
|
bool operator==(const T& t, const Optional<T>& o)
|
|
|
|
{
|
|
|
|
if (auto p = o.get()) return t == *p;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
template<class T>
|
|
|
|
bool operator!=(const Optional<T>& o, const T& t)
|
|
|
|
{
|
|
|
|
if (auto p = o.get()) return *p != t;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
template<class T>
|
|
|
|
bool operator!=(const T& t, const Optional<T>& o)
|
|
|
|
{
|
|
|
|
if (auto p = o.get()) return t != *p;
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-29 06:05:55 +08:00
|
|
|
}
|