diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2017-11-11 21:45:37 -0800 |
|---|---|---|
| committer | Robert Schumacher <roschuma@microsoft.com> | 2017-11-11 21:45:37 -0800 |
| commit | e4d38bb874fe47317e1dd4128c013af882408bbf (patch) | |
| tree | 25b3f85191b921c09bb6a30eb8da88b0f5457baf /toolsrc/include | |
| parent | ec2bbaec849dd1e1e6d76a0573148ca04053bf5c (diff) | |
| download | vcpkg-e4d38bb874fe47317e1dd4128c013af882408bbf.tar.gz vcpkg-e4d38bb874fe47317e1dd4128c013af882408bbf.zip | |
[vcpkg-ci] Fix crash when not passed --exclude.
Added Util::Maps::maybe_find.
Added Optional<T&>.
Diffstat (limited to 'toolsrc/include')
| -rw-r--r-- | toolsrc/include/vcpkg/base/optional.h | 73 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg/base/util.h | 18 |
2 files changed, 74 insertions, 17 deletions
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<class T> + 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<class T> + struct OptionalStorage<T&> + { + 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 T> - 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<class = std::enable_if_t<!std::is_reference<T>::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<class U> T value_or(U&& default_value) const& { - return bool(*this) ? this->m_t : static_cast<T>(std::forward<U>(default_value)); + return this->m_base.has_value() ? this->m_base.value() : 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)); + return this->m_base.has_value() ? std::move(this->m_base.value()) + : static_cast<T>(std::forward<U>(default_value)); } - const T* get() const { return bool(*this) ? &this->m_t : nullptr; } + typename std::add_pointer<const T>::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<T>::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<T> m_base; }; template<class U> 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 <utility> #include <vector> +#include <vcpkg/base/optional.h> + namespace vcpkg::Util { template<class Container> @@ -29,6 +31,22 @@ namespace vcpkg::Util } } + namespace Maps + { + template<class PairType> + using FirstT = std::remove_reference_t<decltype(std::declval<PairType>().first)>; + + template<class Container, class K, class T = FirstT<ElementT<Container>>> + Optional<T&> 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<class Cont, class Func> using FmapOut = decltype(std::declval<Func&>()(*begin(std::declval<Cont&>()))); |
