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

Added Util::Maps::maybe_find.
Added Optional<T&>.
This commit is contained in:
Robert Schumacher 2017-11-11 21:45:37 -08:00
parent ec2bbaec84
commit e4d38bb874
3 changed files with 83 additions and 20 deletions

View File

@ -11,59 +11,98 @@ namespace vcpkg
const static constexpr NullOpt nullopt{0};
template<class T>
class Optional
namespace details
{
public:
constexpr Optional() : m_is_present(false), m_t() {}
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>
struct Optional
{
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>

View File

@ -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&>())));

View File

@ -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)