[vcpkg-ci] Fix crash when not passed --exclude.
Added Util::Maps::maybe_find.
Added Optional<T&>.
MODIFY
include/vcpkg/base/optional.h
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>

MODIFY
include/vcpkg/base/util.h
include/vcpkg/base/util.h
#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&>())));

MODIFY
src/vcpkg/commands.ci.cpp
src/vcpkg/commands.ci.cpp
@@ -75,8 +75,14 @@ namespace vcpkg::Commands::CI
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
{
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
- const std::vector<std::string> exclusions = Strings::split(options.settings.at(OPTION_EXCLUDE), ",");
- const std::set<std::string> exclusions_set(exclusions.cbegin(), exclusions.cend());
+
+ std::set<std::string> exclusions_set;
+ auto maybe_exclusions = Util::Maps::maybe_find(options.settings, OPTION_EXCLUDE);
+ if (auto p_exclusions = maybe_exclusions.get())
+ {
+ auto exclusions = Strings::split(*p_exclusions, ",");
+ exclusions_set.insert(exclusions.begin(), exclusions.end());
+ }
std::vector<Triplet> triplets;
for (const std::string& triplet : args.command_arguments)

[vcpkg-ci] Fix crash when not passed --exclude.

Added Util::Maps::maybe_find.
Added Optional<T&>.