aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2017-11-11 21:45:37 -0800
committerRobert Schumacher <roschuma@microsoft.com>2017-11-11 21:45:37 -0800
commite4d38bb874fe47317e1dd4128c013af882408bbf (patch)
tree25b3f85191b921c09bb6a30eb8da88b0f5457baf /toolsrc/include
parentec2bbaec849dd1e1e6d76a0573148ca04053bf5c (diff)
downloadvcpkg-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.h73
-rw-r--r--toolsrc/include/vcpkg/base/util.h18
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&>())));