aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorAlexander Karatarakis <alkarata@microsoft.com>2017-03-28 15:05:55 -0700
committerAlexander Karatarakis <alkarata@microsoft.com>2017-03-28 18:59:57 -0700
commit42bd55e3ae815e43181facfdc161d29804014f26 (patch)
treed0e4db89947aa557ec6e3bf6065cfb43cbc796ff /toolsrc/include
parent67ce764c2ea7483860a3ad61441608d8978605ae (diff)
downloadvcpkg-42bd55e3ae815e43181facfdc161d29804014f26.tar.gz
vcpkg-42bd55e3ae815e43181facfdc161d29804014f26.zip
Rework optional<T>
Diffstat (limited to 'toolsrc/include')
-rw-r--r--toolsrc/include/vcpkg_optional.h79
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;
+ };
+}