diff options
| author | Alexander Karatarakis <alkarata@microsoft.com> | 2017-03-28 15:05:55 -0700 |
|---|---|---|
| committer | Alexander Karatarakis <alkarata@microsoft.com> | 2017-03-28 18:59:57 -0700 |
| commit | 42bd55e3ae815e43181facfdc161d29804014f26 (patch) | |
| tree | d0e4db89947aa557ec6e3bf6065cfb43cbc796ff /toolsrc/include | |
| parent | 67ce764c2ea7483860a3ad61441608d8978605ae (diff) | |
| download | vcpkg-42bd55e3ae815e43181facfdc161d29804014f26.tar.gz vcpkg-42bd55e3ae815e43181facfdc161d29804014f26.zip | |
Rework optional<T>
Diffstat (limited to 'toolsrc/include')
| -rw-r--r-- | toolsrc/include/vcpkg_optional.h | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h index 7b935bea9..745377a82 100644 --- a/toolsrc/include/vcpkg_optional.h +++ b/toolsrc/include/vcpkg_optional.h @@ -1,5 +1,78 @@ #pragma once -#include <memory> +#include "LineInfo.h" +#include "vcpkg_Checks.h" -template<class T> -using optional = std::unique_ptr<T>; +namespace vcpkg +{ + struct nullopt_t + { + explicit constexpr nullopt_t(int) {} + }; + + const static constexpr nullopt_t nullopt{ 0 }; + + template <class T> + class optional + { + public: + // Constructors are intentionally implicit + constexpr optional(nullopt_t) : m_is_present(false), m_t() { } + + optional(const T& t) : m_is_present(true), m_t(t) { } + + optional(T&& t) : m_is_present(true), m_t(std::move(t)) { } + + T&& get_or_exit(const LineInfo& line_info) && + { + this->exit_if_null(line_info); + return std::move(this->m_t); + } + + const T& get_or_exit(const LineInfo& line_info) const & + { + this->exit_if_null(line_info); + return this->m_t; + } + + constexpr explicit operator bool() const + { + return this->m_is_present; + } + + constexpr bool has_value() const + { + return m_is_present; + } + + template <class U> + T value_or(U&& default_value) const & + { + return bool(*this) ? this->m_t : static_cast<T>(std::forward<U>(default_value)); + } + + template <class U> + T value_or(U&& default_value) && + { + return bool(*this) ? std::move(this->m_t) : static_cast<T>(std::forward<U>(default_value)); + } + + const T* get() const + { + return bool(*this) ? &this->m_t : nullptr; + } + + T* get() + { + return bool(*this) ? &this->m_t : nullptr; + } + + 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; + }; +} |
