From e4d38bb874fe47317e1dd4128c013af882408bbf Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 11 Nov 2017 21:45:37 -0800 Subject: [vcpkg-ci] Fix crash when not passed --exclude. Added Util::Maps::maybe_find. Added Optional. --- toolsrc/include/vcpkg/base/optional.h | 73 +++++++++++++++++++++++++++-------- toolsrc/include/vcpkg/base/util.h | 18 +++++++++ 2 files changed, 74 insertions(+), 17 deletions(-) (limited to 'toolsrc/include') diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h index ff7a210c7..aa9e480fd 100644 --- a/toolsrc/include/vcpkg/base/optional.h +++ b/toolsrc/include/vcpkg/base/optional.h @@ -11,59 +11,98 @@ namespace vcpkg const static constexpr NullOpt nullopt{0}; + namespace details + { + template + struct OptionalStorage + { + constexpr OptionalStorage() : m_is_present(false), m_t() {} + constexpr OptionalStorage(const T& t) : m_is_present(true), m_t(t) {} + constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {} + + constexpr bool has_value() const { return m_is_present; } + + const T& value() const { return this->m_t; } + T& value() { return this->m_t; } + + private: + bool m_is_present; + T m_t; + }; + + template + struct OptionalStorage + { + constexpr OptionalStorage() : m_t(nullptr) {} + constexpr OptionalStorage(T& t) : m_t(&t) {} + + constexpr bool has_value() const { return m_t != nullptr; } + + T& value() const { return *this->m_t; } + + private: + T* m_t; + }; + } + template - class Optional + struct Optional { - public: - constexpr Optional() : m_is_present(false), m_t() {} + constexpr Optional() {} // Constructors are intentionally implicit - constexpr Optional(NullOpt) : m_is_present(false), m_t() {} + constexpr Optional(NullOpt) {} - Optional(const T& t) : m_is_present(true), m_t(t) {} + Optional(const T& t) : m_base(t) {} - Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} + template::value>> + Optional(T&& t) : m_base(std::move(t)) + { + } T&& value_or_exit(const LineInfo& line_info) && { this->exit_if_null(line_info); - return std::move(this->m_t); + return std::move(this->m_base.value()); } const T& value_or_exit(const LineInfo& line_info) const& { this->exit_if_null(line_info); - return this->m_t; + return this->m_base.value(); } - constexpr explicit operator bool() const { return this->m_is_present; } + constexpr explicit operator bool() const { return this->m_base.has_value(); } - constexpr bool has_value() const { return m_is_present; } + constexpr bool has_value() const { return this->m_base.has_value(); } template T value_or(U&& default_value) const& { - return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); + return this->m_base.has_value() ? this->m_base.value() : static_cast(std::forward(default_value)); } template T value_or(U&& default_value) && { - return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); + return this->m_base.has_value() ? std::move(this->m_base.value()) + : static_cast(std::forward(default_value)); } - const T* get() const { return bool(*this) ? &this->m_t : nullptr; } + typename std::add_pointer::type get() const + { + return this->m_base.has_value() ? &this->m_base.value() : nullptr; + } - T* get() { return bool(*this) ? &this->m_t : nullptr; } + typename std::add_pointer::type get() { return this->m_base.has_value() ? &this->m_base.value() : nullptr; } private: void exit_if_null(const LineInfo& line_info) const { - Checks::check_exit(line_info, this->m_is_present, "Value was null"); + Checks::check_exit(line_info, this->m_base.has_value(), "Value was null"); } - bool m_is_present; - T m_t; + details::OptionalStorage m_base; }; template diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h index 155b16cf7..44d09ae15 100644 --- a/toolsrc/include/vcpkg/base/util.h +++ b/toolsrc/include/vcpkg/base/util.h @@ -6,6 +6,8 @@ #include #include +#include + namespace vcpkg::Util { template @@ -29,6 +31,22 @@ namespace vcpkg::Util } } + namespace Maps + { + template + using FirstT = std::remove_reference_t().first)>; + + template>> + Optional maybe_find(Container&& assoc_container, const K& key) + { + auto it = assoc_container.find(key); + if (it == assoc_container.end()) + return nullopt; + else + return it->second; + } + } + template using FmapOut = decltype(std::declval()(*begin(std::declval()))); -- cgit v1.2.3