aboutsummaryrefslogtreecommitdiff
path: root/toolsrc/include
diff options
context:
space:
mode:
authorRobert Schumacher <roschuma@microsoft.com>2019-04-08 23:26:18 -0700
committerPhil Christensen <philc@microsoft.com>2019-04-08 23:26:18 -0700
commitb39b0899cb403aa1f2e86f9e111d16d6f1328737 (patch)
treef4bacd15759c9a8fb334eadfd5d46253a238a1ac /toolsrc/include
parentccbef646051dca6ddfb30e957aa77044c3a3bd11 (diff)
downloadvcpkg-b39b0899cb403aa1f2e86f9e111d16d6f1328737.tar.gz
vcpkg-b39b0899cb403aa1f2e86f9e111d16d6f1328737.zip
[vcpkg] Synchronize vcpkg-base with external repo (#5934)
Diffstat (limited to 'toolsrc/include')
-rw-r--r--toolsrc/include/pch.h10
-rw-r--r--toolsrc/include/vcpkg/base/checks.h6
-rw-r--r--toolsrc/include/vcpkg/base/chrono.h8
-rw-r--r--toolsrc/include/vcpkg/base/cstringview.h4
-rw-r--r--toolsrc/include/vcpkg/base/expected.h43
-rw-r--r--toolsrc/include/vcpkg/base/graphs.h7
-rw-r--r--toolsrc/include/vcpkg/base/lineinfo.h12
-rw-r--r--toolsrc/include/vcpkg/base/optional.h152
-rw-r--r--toolsrc/include/vcpkg/base/span.h41
-rw-r--r--toolsrc/include/vcpkg/base/stringliteral.h20
-rw-r--r--toolsrc/include/vcpkg/base/stringrange.h33
-rw-r--r--toolsrc/include/vcpkg/base/strings.h92
-rw-r--r--toolsrc/include/vcpkg/base/stringview.h49
-rw-r--r--toolsrc/include/vcpkg/base/system.debug.h50
-rw-r--r--toolsrc/include/vcpkg/base/system.h101
-rw-r--r--toolsrc/include/vcpkg/base/system.print.h44
-rw-r--r--toolsrc/include/vcpkg/base/system.process.h45
-rw-r--r--toolsrc/include/vcpkg/base/util.h17
-rw-r--r--toolsrc/include/vcpkg/base/view.h9
-rw-r--r--toolsrc/include/vcpkg/base/zstringview.h52
-rw-r--r--toolsrc/include/vcpkg/globalstate.h22
-rw-r--r--toolsrc/include/vcpkg/input.h4
-rw-r--r--toolsrc/include/vcpkg/packagespec.h2
-rw-r--r--toolsrc/include/vcpkg/packagespecparseresult.h2
-rw-r--r--toolsrc/include/vcpkg/triplet.h3
25 files changed, 575 insertions, 253 deletions
diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h
index 9c9deeb3f..fa2c2bb72 100644
--- a/toolsrc/include/pch.h
+++ b/toolsrc/include/pch.h
@@ -1,5 +1,15 @@
#pragma once
+#if defined(_MSC_VER) && _MSC_VER < 1911
+// [[nodiscard]] is not recognized before VS 2017 version 15.3
+#pragma warning(disable : 5030)
+#endif
+
+#if defined(__GNUC__) && __GNUC__ < 7
+// [[nodiscard]] is not recognized before GCC version 7
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
+
#if defined(_WIN32)
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h
index bceee3428..3c0c073d2 100644
--- a/toolsrc/include/vcpkg/base/checks.h
+++ b/toolsrc/include/vcpkg/base/checks.h
@@ -6,7 +6,7 @@
namespace vcpkg::Checks
{
- void register_console_ctrl_handler();
+ void register_global_shutdown_handler(void (*func)());
// Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been
// broken.
@@ -21,7 +21,7 @@ namespace vcpkg::Checks
[[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); }
// Display an error message to the user and exit the tool.
- [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message);
+ [[noreturn]] void exit_with_message(const LineInfo& line_info, StringView error_message);
template<class Arg1, class... Args>
// Display an error message to the user and exit the tool.
@@ -36,7 +36,7 @@ namespace vcpkg::Checks
void check_exit(const LineInfo& line_info, bool expression);
- void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message);
+ void check_exit(const LineInfo& line_info, bool expression, StringView error_message);
template<class Conditional, class Arg1, class... Args>
void check_exit(const LineInfo& line_info,
diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h
index 6f6e2b317..26294fdf8 100644
--- a/toolsrc/include/vcpkg/base/chrono.h
+++ b/toolsrc/include/vcpkg/base/chrono.h
@@ -1,8 +1,10 @@
#pragma once
+#include <vcpkg/base/cstringview.h>
+#include <vcpkg/base/optional.h>
+
#include <chrono>
#include <string>
-#include <vcpkg/base/optional.h>
namespace vcpkg::Chrono
{
@@ -21,6 +23,7 @@ namespace vcpkg::Chrono
}
std::string to_string() const;
+ void to_string(std::string& into) const;
private:
std::chrono::high_resolution_clock::time_point::duration m_duration;
@@ -41,6 +44,7 @@ namespace vcpkg::Chrono
double microseconds() const { return elapsed().as<std::chrono::duration<double, std::micro>>().count(); }
std::string to_string() const;
+ void to_string(std::string& into) const;
private:
std::chrono::high_resolution_clock::time_point m_start_tick;
@@ -65,5 +69,7 @@ namespace vcpkg::Chrono
mutable tm m_tm;
};
+ tm get_current_date_time();
+
tm get_current_date_time_local();
}
diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h
index f285aa36c..d49bfc82f 100644
--- a/toolsrc/include/vcpkg/base/cstringview.h
+++ b/toolsrc/include/vcpkg/base/cstringview.h
@@ -1,6 +1,6 @@
#pragma once
-#include <string.h>
+#include <cstring>
#include <string>
namespace vcpkg
@@ -14,6 +14,8 @@ namespace vcpkg
constexpr const char* c_str() const { return cstr; }
+ void to_string(std::string& str) const { str.append(cstr); }
+
private:
const char* cstr;
};
diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h
index e20f723db..c273d71e6 100644
--- a/toolsrc/include/vcpkg/base/expected.h
+++ b/toolsrc/include/vcpkg/base/expected.h
@@ -1,6 +1,7 @@
#pragma once
#include <vcpkg/base/checks.h>
+#include <vcpkg/base/stringliteral.h>
#include <system_error>
@@ -20,7 +21,7 @@ namespace vcpkg
const Err& error() const { return m_err; }
Err& error() { return m_err; }
- CStringView to_string() const { return "value was error"; }
+ StringLiteral to_string() const { return "value was error"; }
private:
bool m_is_error;
@@ -28,6 +29,27 @@ namespace vcpkg
};
template<>
+ struct ErrorHolder<std::string>
+ {
+ ErrorHolder() : m_is_error(false) {}
+ template<class U>
+ ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward<U>(err))
+ {
+ }
+
+ bool has_error() const { return m_is_error; }
+
+ const std::string& error() const { return m_err; }
+ std::string& error() { return m_err; }
+
+ const std::string& to_string() const { return m_err; }
+
+ private:
+ bool m_is_error;
+ std::string m_err;
+ };
+
+ template<>
struct ErrorHolder<std::error_code>
{
ErrorHolder() = default;
@@ -38,12 +60,21 @@ namespace vcpkg
const std::error_code& error() const { return m_err; }
std::error_code& error() { return m_err; }
- CStringView to_string() const { return m_err.message(); }
+ std::string to_string() const { return m_err.message(); }
private:
std::error_code m_err;
};
+ struct ExpectedLeftTag
+ {
+ };
+ struct ExpectedRightTag
+ {
+ };
+ constexpr ExpectedLeftTag expected_left_tag;
+ constexpr ExpectedRightTag expected_right_tag;
+
template<class T, class S>
class ExpectedT
{
@@ -52,11 +83,11 @@ namespace vcpkg
// Constructors are intentionally implicit
- ExpectedT(const S& s) : m_s(s) {}
- ExpectedT(S&& s) : m_s(std::move(s)) {}
+ ExpectedT(const S& s, ExpectedRightTag = {}) : m_s(s) {}
+ ExpectedT(S&& s, ExpectedRightTag = {}) : m_s(std::move(s)) {}
- ExpectedT(const T& t) : m_t(t) {}
- ExpectedT(T&& t) : m_t(std::move(t)) {}
+ ExpectedT(const T& t, ExpectedLeftTag = {}) : m_t(t) {}
+ ExpectedT(T&& t, ExpectedLeftTag = {}) : m_t(std::move(t)) {}
ExpectedT(const ExpectedT&) = default;
ExpectedT(ExpectedT&&) = default;
diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h
index 6cff75ad3..46831a911 100644
--- a/toolsrc/include/vcpkg/base/graphs.h
+++ b/toolsrc/include/vcpkg/base/graphs.h
@@ -2,10 +2,11 @@
#include <unordered_map>
#include <unordered_set>
+#include <utility>
#include <vcpkg/base/checks.h>
#include <vcpkg/base/span.h>
-#include <vcpkg/base/system.h>
+#include <vcpkg/base/system.print.h>
namespace vcpkg::Graphs
{
@@ -66,12 +67,12 @@ namespace vcpkg::Graphs
case ExplorationStatus::FULLY_EXPLORED: return;
case ExplorationStatus::PARTIALLY_EXPLORED:
{
- System::println("Cycle detected within graph at %s:", f.to_string(vertex));
+ System::print2("Cycle detected within graph at ", f.to_string(vertex), ":\n");
for (auto&& node : exploration_status)
{
if (node.second == ExplorationStatus::PARTIALLY_EXPLORED)
{
- System::println(" %s", f.to_string(node.first));
+ System::print2(" ", f.to_string(node.first), '\n');
}
}
Checks::exit_fail(VCPKG_LINE_INFO);
diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h
index e0eb8bec9..2f03fef16 100644
--- a/toolsrc/include/vcpkg/base/lineinfo.h
+++ b/toolsrc/include/vcpkg/base/lineinfo.h
@@ -6,13 +6,15 @@ namespace vcpkg
{
struct LineInfo
{
- int line_number;
- const char* file_name;
-
- constexpr LineInfo() noexcept : line_number(0), file_name("") {}
- constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {}
+ constexpr LineInfo() noexcept : m_line_number(0), m_file_name("") {}
+ constexpr LineInfo(const int lineno, const char* filename) : m_line_number(lineno), m_file_name(filename) {}
std::string to_string() const;
+ void to_string(std::string& out) const;
+
+ private:
+ int m_line_number;
+ const char* m_file_name;
};
}
diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h
index 6b84b10aa..4d386a961 100644
--- a/toolsrc/include/vcpkg/base/optional.h
+++ b/toolsrc/include/vcpkg/base/optional.h
@@ -1,6 +1,9 @@
#pragma once
-#include <vcpkg/base/checks.h>
+#include <vcpkg/base/lineinfo.h>
+
+#include <type_traits>
+#include <utility>
namespace vcpkg
{
@@ -13,25 +16,146 @@ namespace vcpkg
namespace details
{
- template<class T>
+ template<class T, bool B = std::is_copy_constructible<T>::value>
struct OptionalStorage
{
- constexpr OptionalStorage() noexcept : m_is_present(false), m_t() {}
+ constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() {}
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)) {}
+ ~OptionalStorage() noexcept
+ {
+ if (m_is_present) m_t.~T();
+ }
+
+ OptionalStorage(const OptionalStorage& o) : m_is_present(o.m_is_present), m_inactive()
+ {
+ if (m_is_present) new (&m_t) T(o.m_t);
+ }
+
+ OptionalStorage(OptionalStorage&& o) : m_is_present(o.m_is_present), m_inactive()
+ {
+ if (m_is_present)
+ {
+ new (&m_t) T(std::move(o.m_t));
+ }
+ }
+
+ OptionalStorage& operator=(const OptionalStorage& o)
+ {
+ if (m_is_present && o.m_is_present)
+ {
+ m_t = o.m_t;
+ }
+ else if (!m_is_present && o.m_is_present)
+ {
+ m_is_present = true;
+ new (&m_t) T(o.m_t);
+ }
+ else if (m_is_present && !o.m_is_present)
+ {
+ clear();
+ }
+ return *this;
+ }
+
+ OptionalStorage& operator=(OptionalStorage&& o)
+ {
+ if (m_is_present && o.m_is_present)
+ {
+ m_t = std::move(o.m_t);
+ }
+ else if (!m_is_present && o.m_is_present)
+ {
+ m_is_present = true;
+ new (&m_t) T(std::move(o.m_t));
+ }
+ else if (m_is_present && !o.m_is_present)
+ {
+ clear();
+ }
+ return *this;
+ }
+
constexpr bool has_value() const { return m_is_present; }
const T& value() const { return this->m_t; }
T& value() { return this->m_t; }
private:
+ void clear()
+ {
+ m_is_present = false;
+ m_t.~T();
+ m_inactive = '\0';
+ }
+
bool m_is_present;
- T m_t;
+ union {
+ char m_inactive;
+ T m_t;
+ };
};
template<class T>
- struct OptionalStorage<T&>
+ struct OptionalStorage<T, false>
+ {
+ constexpr OptionalStorage() noexcept : m_is_present(false), m_inactive() {}
+ constexpr OptionalStorage(T&& t) : m_is_present(true), m_t(std::move(t)) {}
+
+ ~OptionalStorage() noexcept
+ {
+ if (m_is_present) m_t.~T();
+ }
+
+ OptionalStorage(OptionalStorage&& o) : m_is_present(o.m_is_present), m_inactive()
+ {
+ if (m_is_present)
+ {
+ new (&m_t) T(std::move(o.m_t));
+ }
+ }
+
+ OptionalStorage& operator=(OptionalStorage&& o)
+ {
+ if (m_is_present && o.m_is_present)
+ {
+ m_t = std::move(o.m_t);
+ }
+ else if (!m_is_present && o.m_is_present)
+ {
+ m_is_present = true;
+ new (&m_t) T(std::move(o.m_t));
+ }
+ else if (m_is_present && !o.m_is_present)
+ {
+ clear();
+ }
+ return *this;
+ }
+
+ constexpr bool has_value() const { return m_is_present; }
+
+ const T& value() const { return this->m_t; }
+ T& value() { return this->m_t; }
+
+ private:
+ void clear()
+ {
+ m_is_present = false;
+ m_t.~T();
+ m_inactive = '\0';
+ }
+
+ bool m_is_present;
+ union {
+ char m_inactive;
+ T m_t;
+ };
+ };
+
+ template<class T, bool B>
+ struct OptionalStorage<T&, B>
{
constexpr OptionalStorage() noexcept : m_t(nullptr) {}
constexpr OptionalStorage(T& t) : m_t(&t) {}
@@ -43,6 +167,9 @@ namespace vcpkg
private:
T* m_t;
};
+
+ // Note: implemented in checks.cpp to cut the header dependency
+ void exit_if_null(bool b, const LineInfo& line_info);
}
template<class T>
@@ -53,26 +180,26 @@ namespace vcpkg
// Constructors are intentionally implicit
constexpr Optional(NullOpt) {}
- template<class U>
- Optional(U&& t) : m_base(std::forward<U>(t))
+ template<class U, class = std::enable_if_t<!std::is_same<std::decay_t<U>, Optional>::value>>
+ constexpr Optional(U&& t) : m_base(std::forward<U>(t))
{
}
T&& value_or_exit(const LineInfo& line_info) &&
{
- this->exit_if_null(line_info);
+ details::exit_if_null(this->m_base.has_value(), line_info);
return std::move(this->m_base.value());
}
T& value_or_exit(const LineInfo& line_info) &
{
- this->exit_if_null(line_info);
+ details::exit_if_null(this->m_base.has_value(), line_info);
return this->m_base.value();
}
const T& value_or_exit(const LineInfo& line_info) const&
{
- this->exit_if_null(line_info);
+ details::exit_if_null(this->m_base.has_value(), line_info);
return this->m_base.value();
}
@@ -101,11 +228,6 @@ namespace vcpkg
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_base.has_value(), "Value was null");
- }
-
details::OptionalStorage<T> m_base;
};
diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h
index 2b067d0ac..4c805e2b4 100644
--- a/toolsrc/include/vcpkg/base/span.h
+++ b/toolsrc/include/vcpkg/base/span.h
@@ -11,8 +11,9 @@ namespace vcpkg
struct Span
{
public:
- static_assert(!std::is_reference<T>::value, "Span<&> is illegal");
+ static_assert(std::is_object<T>::value, "Span<non-object-type> is illegal");
+ using value_type = std::decay_t<T>;
using element_type = T;
using pointer = std::add_pointer_t<T>;
using reference = std::add_lvalue_reference_t<T>;
@@ -30,46 +31,28 @@ namespace vcpkg
}
template<size_t N>
- constexpr Span(const std::array<std::remove_const_t<T>, N>& arr) noexcept
- : m_ptr(arr.data()), m_count(arr.size())
+ constexpr Span(std::remove_const_t<T> (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
{
}
- Span(std::vector<T>& v) noexcept : Span(v.data(), v.size()) {}
- Span(const std::vector<std::remove_const_t<T>>& v) noexcept : Span(v.data(), v.size()) {}
+ template<class Range,
+ class = decltype(std::declval<Range>().data()),
+ class = std::enable_if_t<!std::is_same<std::decay_t<Range>, Span>::value>>
+ constexpr Span(Range&& v) noexcept : Span(v.data(), v.size())
+ {
+ static_assert(std::is_same<typename std::decay_t<Range>::value_type, value_type>::value,
+ "Cannot convert incompatible ranges");
+ }
constexpr iterator begin() const { return m_ptr; }
constexpr iterator end() const { return m_ptr + m_count; }
constexpr reference operator[](size_t i) const { return m_ptr[i]; }
+ constexpr pointer data() const { return m_ptr; }
constexpr size_t size() const { return m_count; }
private:
pointer m_ptr;
size_t m_count;
};
-
- template<class T>
- Span<T> make_span(std::vector<T>& v)
- {
- return {v.data(), v.size()};
- }
-
- template<class T>
- Span<const T> make_span(const std::vector<T>& v)
- {
- return {v.data(), v.size()};
- }
-
- template<class T>
- constexpr T* begin(Span<T> sp)
- {
- return sp.begin();
- }
-
- template<class T>
- constexpr T* end(Span<T> sp)
- {
- return sp.end();
- }
}
diff --git a/toolsrc/include/vcpkg/base/stringliteral.h b/toolsrc/include/vcpkg/base/stringliteral.h
index 9970adc2a..602e0bfd2 100644
--- a/toolsrc/include/vcpkg/base/stringliteral.h
+++ b/toolsrc/include/vcpkg/base/stringliteral.h
@@ -1,27 +1,17 @@
#pragma once
-#include <vcpkg/base/cstringview.h>
+#include <string>
+#include <vcpkg/base/zstringview.h>
namespace vcpkg
{
- struct StringLiteral
+ struct StringLiteral : ZStringView
{
template<int N>
- constexpr StringLiteral(const char (&str)[N])
- : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str)
+ constexpr StringLiteral(const char (&str)[N]) : ZStringView(str)
{
}
- constexpr const char* c_str() const { return m_cstr; }
- constexpr size_t size() const { return m_size; }
-
- operator CStringView() const { return m_cstr; }
- operator std::string() const { return m_cstr; }
-
- private:
- size_t m_size;
- const char* m_cstr;
+ operator std::string() const { return std::string(data(), size()); }
};
-
- inline const char* to_printf_arg(const StringLiteral str) { return str.c_str(); }
}
diff --git a/toolsrc/include/vcpkg/base/stringrange.h b/toolsrc/include/vcpkg/base/stringrange.h
deleted file mode 100644
index 6126ec48f..000000000
--- a/toolsrc/include/vcpkg/base/stringrange.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <vcpkg/base/optional.h>
-
-#include <string>
-#include <vector>
-
-namespace vcpkg
-{
- struct StringRange
- {
- static std::vector<StringRange> find_all_enclosed(const StringRange& input,
- const std::string& left_delim,
- const std::string& right_delim);
-
- static StringRange find_exactly_one_enclosed(const StringRange& input,
- const std::string& left_tag,
- const std::string& right_tag);
-
- static Optional<StringRange> find_at_most_one_enclosed(const StringRange& input,
- const std::string& left_tag,
- const std::string& right_tag);
-
- StringRange() = default;
- StringRange(const std::string& s); // Implicit by design
- StringRange(const std::string::const_iterator begin, const std::string::const_iterator end);
-
- std::string::const_iterator begin;
- std::string::const_iterator end;
-
- std::string to_string() const;
- };
-}
diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h
index 4b39b0a28..16876cf5c 100644
--- a/toolsrc/include/vcpkg/base/strings.h
+++ b/toolsrc/include/vcpkg/base/strings.h
@@ -1,7 +1,10 @@
#pragma once
#include <vcpkg/base/cstringview.h>
+#include <vcpkg/base/optional.h>
#include <vcpkg/base/stringliteral.h>
+#include <vcpkg/base/stringview.h>
+#include <vcpkg/base/view.h>
#include <vector>
@@ -24,10 +27,63 @@ namespace vcpkg::Strings::details
}
std::string format_internal(const char* fmtstr, ...);
+
+ inline void append_internal(std::string& into, char c) { into += c; }
+ template<class T, class = decltype(std::to_string(std::declval<T>()))>
+ inline void append_internal(std::string& into, T x)
+ {
+ into += std::to_string(x);
+ }
+ inline void append_internal(std::string& into, const char* v) { into.append(v); }
+ inline void append_internal(std::string& into, const std::string& s) { into.append(s); }
+
+ template<class T, class = decltype(std::declval<const T&>().to_string(std::declval<std::string&>()))>
+ void append_internal(std::string& into, const T& t)
+ {
+ t.to_string(into);
+ }
+
+ template<class T, class=void, class = decltype(to_string(std::declval<std::string&>(), std::declval<const T&>()))>
+ void append_internal(std::string& into, const T& t)
+ {
+ to_string(into, t);
+ }
}
namespace vcpkg::Strings
{
+ template<class Arg>
+ std::string& append(std::string& into, const Arg& a)
+ {
+ details::append_internal(into, a);
+ return into;
+ }
+ template<class Arg, class... Args>
+ std::string& append(std::string& into, const Arg& a, const Args&... args)
+ {
+ append(into, a);
+ return append(into, args...);
+ }
+
+ template<class... Args>
+ [[nodiscard]] std::string concat(const Args&... args) {
+ std::string ret;
+ append(ret, args...);
+ return ret;
+ }
+
+ template<class... Args, class = void>
+ std::string concat_or_view(const Args&... args)
+ {
+ return Strings::concat(args...);
+ }
+
+ template<class T, class = std::enable_if_t<std::is_convertible<T, StringView>::value>>
+ StringView concat_or_view(const T& v)
+ {
+ return v;
+ }
+
template<class... Args>
std::string format(const char* fmtstr, const Args&... args)
{
@@ -36,25 +92,25 @@ namespace vcpkg::Strings
}
#if defined(_WIN32)
- std::wstring to_utf16(const CStringView& s);
+ std::wstring to_utf16(StringView s);
std::string to_utf8(const wchar_t* w);
+ inline std::string to_utf8(const std::wstring& ws) { return to_utf8(ws.c_str()); }
#endif
- std::string escape_string(const CStringView& s, char char_to_escape, char escape_char);
+ std::string escape_string(std::string&& s, char char_to_escape, char escape_char);
- std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern);
+ bool case_insensitive_ascii_contains(StringView s, StringView pattern);
- bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern);
+ bool case_insensitive_ascii_equals(StringView left, StringView right);
- bool case_insensitive_ascii_equals(const CStringView left, const CStringView right);
+ std::string ascii_to_lowercase(std::string&& s);
- std::string ascii_to_lowercase(std::string s);
+ std::string ascii_to_uppercase(std::string&& s);
- std::string ascii_to_uppercase(std::string s);
-
- bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern);
- bool ends_with(const std::string& s, StringLiteral pattern);
+ bool case_insensitive_ascii_starts_with(StringView s, StringView pattern);
+ bool ends_with(StringView s, StringView pattern);
+ bool starts_with(StringView s, StringView pattern);
template<class Container, class Transformer>
std::string join(const char* delimiter, const Container& v, Transformer transformer)
@@ -84,7 +140,7 @@ namespace vcpkg::Strings
return join(delimiter, v, [](const Element& x) -> const Element& { return x; });
}
- std::string replace_all(std::string&& s, const std::string& search, const std::string& rep);
+ std::string replace_all(std::string&& s, const std::string& search, StringView rep);
std::string trim(std::string&& s);
@@ -92,6 +148,16 @@ namespace vcpkg::Strings
std::vector<std::string> split(const std::string& s, const std::string& delimiter);
+ std::vector<std::string> split(const std::string& s, const std::string& delimiter, int max_count);
+
+ std::vector<StringView> find_all_enclosed(StringView input, StringView left_delim, StringView right_delim);
+
+ StringView find_exactly_one_enclosed(StringView input, StringView left_tag, StringView right_tag);
+
+ Optional<StringView> find_at_most_one_enclosed(StringView input, StringView left_tag, StringView right_tag);
+
+ bool equals(StringView a, StringView b);
+
template<class T>
std::string serialize(const T& t)
{
@@ -99,4 +165,8 @@ namespace vcpkg::Strings
serialize(t, ret);
return ret;
}
+
+ const char* search(StringView haystack, StringView needle);
+
+ bool contains(StringView haystack, StringView needle);
}
diff --git a/toolsrc/include/vcpkg/base/stringview.h b/toolsrc/include/vcpkg/base/stringview.h
new file mode 100644
index 000000000..fef5bef4e
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/stringview.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <vcpkg/base/optional.h>
+
+#include <string>
+#include <vector>
+
+namespace vcpkg
+{
+ struct StringView
+ {
+ static std::vector<StringView> find_all_enclosed(const StringView& input,
+ const std::string& left_delim,
+ const std::string& right_delim);
+
+ static StringView find_exactly_one_enclosed(const StringView& input,
+ const std::string& left_tag,
+ const std::string& right_tag);
+
+ static Optional<StringView> find_at_most_one_enclosed(const StringView& input,
+ const std::string& left_tag,
+ const std::string& right_tag);
+
+ constexpr StringView() = default;
+ StringView(const std::string& s); // Implicit by design
+ template<size_t Sz>
+ StringView(const char (&arr)[Sz]) : m_ptr(arr), m_size(Sz - 1)
+ {
+ }
+
+ constexpr StringView(const char* ptr, size_t size) : m_ptr(ptr), m_size(size) {}
+ constexpr StringView(const char* b, const char* e) : m_ptr(b), m_size(static_cast<size_t>(e - b)) {}
+
+ constexpr const char* begin() const { return m_ptr; }
+ constexpr const char* end() const { return m_ptr + m_size; }
+
+ constexpr const char* data() const { return m_ptr; }
+ constexpr size_t size() const { return m_size; }
+
+ std::string to_string() const;
+ void to_string(std::string& out) const;
+
+ bool operator==(StringView other) const;
+
+ private:
+ const char* m_ptr = 0;
+ size_t m_size = 0;
+ };
+}
diff --git a/toolsrc/include/vcpkg/base/system.debug.h b/toolsrc/include/vcpkg/base/system.debug.h
new file mode 100644
index 000000000..d9c50ac8e
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/system.debug.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <vcpkg/base/chrono.h>
+#include <vcpkg/base/system.print.h>
+
+#include <atomic>
+
+namespace vcpkg::Debug
+{
+ extern std::atomic<bool> g_debugging;
+
+ template<class... Args>
+ void print(System::Color c, const Args&... args)
+ {
+ if (g_debugging) System::print2(c, "[DEBUG] ", args...);
+ }
+
+ template<class... Args>
+ void print(const Args&... args)
+ {
+ if (g_debugging) System::print2("[DEBUG] ", args...);
+ }
+
+ template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<!std::is_void<R>::value>>
+ R time(LineInfo line, F&& f)
+ {
+ if (g_debugging)
+ {
+ auto timer = Chrono::ElapsedTimer::create_started();
+ auto&& result = f();
+ System::print2("[DEBUG] ", line, " took ", timer, '\n');
+ return static_cast<R&&>(result);
+ }
+ else
+ return f();
+ }
+
+ template<class F, class R = std::result_of_t<F && ()>, class = std::enable_if_t<std::is_void<R>::value>>
+ void time(LineInfo line, F&& f)
+ {
+ if (g_debugging)
+ {
+ auto timer = Chrono::ElapsedTimer::create_started();
+ f();
+ System::print2("[DEBUG] ", line, " took ", timer, '\n');
+ }
+ else
+ f();
+ }
+}
diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h
index af56e45c1..0245b684a 100644
--- a/toolsrc/include/vcpkg/base/system.h
+++ b/toolsrc/include/vcpkg/base/system.h
@@ -1,85 +1,15 @@
#pragma once
-#include <unordered_map>
-
#include <vcpkg/base/files.h>
#include <vcpkg/base/optional.h>
-#include <vcpkg/base/strings.h>
+#include <vcpkg/base/stringview.h>
+#include <vcpkg/base/zstringview.h>
namespace vcpkg::System
{
- fs::path get_exe_path_of_current_process();
-
- struct CMakeVariable
- {
- CMakeVariable(const CStringView varname, const char* varvalue);
- CMakeVariable(const CStringView varname, const std::string& varvalue);
- CMakeVariable(const CStringView varname, const fs::path& path);
-
- std::string s;
- };
-
- std::string make_cmake_cmd(const fs::path& cmake_exe,
- const fs::path& cmake_script,
- const std::vector<CMakeVariable>& pass_variables);
-
- struct ExitCodeAndOutput
- {
- int exit_code;
- std::string output;
- };
+ Optional<std::string> get_environment_variable(ZStringView varname) noexcept;
- int cmd_execute_clean(const CStringView cmd_line,
- const std::unordered_map<std::string, std::string>& extra_env = {}) noexcept;
-
- int cmd_execute(const CStringView cmd_line) noexcept;
-
-#if defined(_WIN32)
- void cmd_execute_no_wait(const CStringView cmd_line) noexcept;
-#endif
-
- ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line) noexcept;
-
- enum class Color
- {
- success = 10,
- error = 12,
- warning = 14,
- };
-
- void println();
- void print(const CStringView message);
- void println(const CStringView message);
- void print(const Color c, const CStringView message);
- void println(const Color c, const CStringView message);
-
- template<class Arg1, class... Args>
- void print(const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return System::print(Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class Arg1, class... Args>
- void print(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return System::print(c, Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class Arg1, class... Args>
- void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return System::println(Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class Arg1, class... Args>
- void println(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return System::println(c, Strings::format(message_template, message_arg1, message_args...));
- }
-
- Optional<std::string> get_environment_variable(const CStringView varname) noexcept;
-
- Optional<std::string> get_registry_string(void* base_hkey, const CStringView subkey, const CStringView valuename);
+ Optional<std::string> get_registry_string(void* base_hkey, StringView subkey, StringView valuename);
enum class CPUArchitecture
{
@@ -89,7 +19,7 @@ namespace vcpkg::System
ARM64,
};
- Optional<CPUArchitecture> to_cpu_architecture(const CStringView& arch);
+ Optional<CPUArchitecture> to_cpu_architecture(StringView arch);
CPUArchitecture get_host_processor();
@@ -99,24 +29,3 @@ namespace vcpkg::System
const Optional<fs::path>& get_program_files_platform_bitness();
}
-
-namespace vcpkg::Debug
-{
- void println(const CStringView message);
- void println(const System::Color c, const CStringView message);
-
- template<class Arg1, class... Args>
- void println(const char* message_template, const Arg1& message_arg1, const Args&... message_args)
- {
- return Debug::println(Strings::format(message_template, message_arg1, message_args...));
- }
-
- template<class Arg1, class... Args>
- void println(const System::Color c,
- const char* message_template,
- const Arg1& message_arg1,
- const Args&... message_args)
- {
- return Debug::println(c, Strings::format(message_template, message_arg1, message_args...));
- }
-}
diff --git a/toolsrc/include/vcpkg/base/system.print.h b/toolsrc/include/vcpkg/base/system.print.h
new file mode 100644
index 000000000..890c13667
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/system.print.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <vcpkg/base/strings.h>
+#include <vcpkg/base/view.h>
+
+namespace vcpkg::System
+{
+ enum class Color
+ {
+ success = 10,
+ error = 12,
+ warning = 14,
+ };
+
+ namespace details
+ {
+ void print(StringView message);
+ void print(const Color c, StringView message);
+ }
+
+ template<class Arg1, class... Args>
+ void printf(const char* message_template, const Arg1& message_arg1, const Args&... message_args)
+ {
+ return ::vcpkg::System::details::print(Strings::format(message_template, message_arg1, message_args...));
+ }
+
+ template<class Arg1, class... Args>
+ void printf(const Color c, const char* message_template, const Arg1& message_arg1, const Args&... message_args)
+ {
+ return ::vcpkg::System::details::print(c, Strings::format(message_template, message_arg1, message_args...));
+ }
+
+ template<class... Args>
+ void print2(const Color c, const Args&... args)
+ {
+ ::vcpkg::System::details::print(c, Strings::concat_or_view(args...));
+ }
+
+ template<class... Args>
+ void print2(const Args&... args)
+ {
+ ::vcpkg::System::details::print(Strings::concat_or_view(args...));
+ }
+}
diff --git a/toolsrc/include/vcpkg/base/system.process.h b/toolsrc/include/vcpkg/base/system.process.h
new file mode 100644
index 000000000..e409ff950
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/system.process.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <vcpkg/base/files.h>
+#include <vcpkg/base/zstringview.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace vcpkg::System
+{
+ struct CMakeVariable
+ {
+ CMakeVariable(const StringView varname, const char* varvalue);
+ CMakeVariable(const StringView varname, const std::string& varvalue);
+ CMakeVariable(const StringView varname, const fs::path& path);
+
+ std::string s;
+ };
+
+ std::string make_cmake_cmd(const fs::path& cmake_exe,
+ const fs::path& cmake_script,
+ const std::vector<CMakeVariable>& pass_variables);
+
+ fs::path get_exe_path_of_current_process();
+
+ struct ExitCodeAndOutput
+ {
+ int exit_code;
+ std::string output;
+ };
+
+ int cmd_execute_clean(const ZStringView cmd_line,
+ const std::unordered_map<std::string, std::string>& extra_env = {});
+
+ int cmd_execute(const ZStringView cmd_line);
+
+#if defined(_WIN32)
+ void cmd_execute_no_wait(const StringView cmd_line);
+#endif
+
+ ExitCodeAndOutput cmd_execute_and_capture_output(const ZStringView cmd_line);
+
+ void register_console_ctrl_handler();
+}
diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h
index 65ce02b99..213adb67c 100644
--- a/toolsrc/include/vcpkg/base/util.h
+++ b/toolsrc/include/vcpkg/base/util.h
@@ -10,7 +10,8 @@
namespace vcpkg::Util
{
template<class Container>
- using ElementT = std::remove_reference_t<decltype(*begin(std::declval<Container>()))>;
+ using ElementT =
+ std::remove_reference_t<decltype(*std::declval<typename std::remove_reference_t<Container>::iterator>())>;
namespace Vectors
{
@@ -41,11 +42,11 @@ namespace vcpkg::Util
}
}
- template<class Cont, class Func>
- using FmapOut = decltype(std::declval<Func&>()(*begin(std::declval<Cont&>())));
+ template<class Range, class Func>
+ using FmapOut = std::remove_reference_t<decltype(std::declval<Func&>()(*std::declval<Range>().begin()))>;
- template<class Cont, class Func, class Out = FmapOut<Cont, Func>>
- std::vector<Out> fmap(Cont&& xs, Func&& f)
+ template<class Range, class Func, class Out = FmapOut<Range, Func>>
+ std::vector<Out> fmap(Range&& xs, Func&& f)
{
std::vector<Out> ret;
ret.reserve(xs.size());
@@ -93,12 +94,6 @@ namespace vcpkg::Util
return std::find_if(begin(cont), end(cont), pred);
}
- template<class Container, class T = ElementT<Container>>
- std::vector<T*> element_pointers(Container&& cont)
- {
- return fmap(cont, [](auto&& x) { return &x; });
- }
-
template<class Container, class Pred>
auto find_if_not(Container&& cont, Pred pred)
{
diff --git a/toolsrc/include/vcpkg/base/view.h b/toolsrc/include/vcpkg/base/view.h
new file mode 100644
index 000000000..8a9c40994
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/view.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <vcpkg/base/span.h>
+
+namespace vcpkg
+{
+ template<class T>
+ using View = Span<const T>;
+}
diff --git a/toolsrc/include/vcpkg/base/zstringview.h b/toolsrc/include/vcpkg/base/zstringview.h
new file mode 100644
index 000000000..7f80bf726
--- /dev/null
+++ b/toolsrc/include/vcpkg/base/zstringview.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <string>
+
+#include <vcpkg/base/stringview.h>
+
+namespace vcpkg
+{
+ // A counted view of a null-terminated string
+ struct ZStringView
+ {
+ using value_type = char;
+
+ constexpr ZStringView() : m_size(0), m_cstr("") {}
+
+ template<int N>
+ constexpr ZStringView(const char (&str)[N])
+ : m_size(N - 1) /* -1 here accounts for the null byte at the end*/, m_cstr(str)
+ {
+ }
+
+ ZStringView(const std::string& s) : m_size(s.size()), m_cstr(s.c_str()) {}
+ constexpr ZStringView(const char* str, size_t sz) : m_size(sz), m_cstr(str) {}
+
+ constexpr const char* data() const { return m_cstr; }
+ constexpr size_t size() const { return m_size; }
+ constexpr char operator[](ptrdiff_t off) const { return m_cstr[off]; }
+
+ constexpr const char* c_str() const { return m_cstr; }
+
+ constexpr const char* begin() const { return m_cstr; }
+ constexpr const char* end() const { return m_cstr + m_size; }
+
+ std::string to_string() const { return std::string(m_cstr, m_size); }
+ void to_string(std::string& out) const { out.append(m_cstr, m_size); }
+
+ constexpr operator StringView() const { return StringView(m_cstr, m_size); }
+
+ private:
+ size_t m_size;
+ const char* m_cstr;
+ };
+
+ inline bool operator==(ZStringView l, ZStringView r) { return std::equal(l.begin(), l.end(), r.begin(), r.end()); }
+ inline bool operator!=(ZStringView l, ZStringView r) { return !std::equal(l.begin(), l.end(), r.begin(), r.end()); }
+
+ inline bool operator==(const char* l, ZStringView r) { return strcmp(l, r.c_str()) == 0; }
+ inline bool operator==(ZStringView l, const char* r) { return strcmp(l.c_str(), r) == 0; }
+}
diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h
index ae66ca355..2026ea369 100644
--- a/toolsrc/include/vcpkg/globalstate.h
+++ b/toolsrc/include/vcpkg/globalstate.h
@@ -4,6 +4,7 @@
#include <vcpkg/base/util.h>
#include <atomic>
+#include <string>
namespace vcpkg
{
@@ -19,26 +20,5 @@ namespace vcpkg
static std::atomic<int> g_init_console_cp;
static std::atomic<int> g_init_console_output_cp;
static std::atomic<bool> g_init_console_initialized;
-
- struct CtrlCStateMachine
- {
- CtrlCStateMachine();
-
- void transition_to_spawn_process() noexcept;
- void transition_from_spawn_process() noexcept;
- void transition_handle_ctrl_c() noexcept;
-
- private:
- enum class CtrlCState
- {
- normal,
- blocked_on_child,
- exit_requested,
- };
-
- std::atomic<CtrlCState> m_state;
- };
-
- static CtrlCStateMachine g_ctrl_c_state;
};
}
diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h
index 621139427..ef481bf52 100644
--- a/toolsrc/include/vcpkg/input.h
+++ b/toolsrc/include/vcpkg/input.h
@@ -4,10 +4,10 @@
namespace vcpkg::Input
{
- PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string,
+ PackageSpec check_and_get_package_spec(std::string&& spec_string,
const Triplet& default_triplet,
CStringView example_text);
- FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string,
+ FullPackageSpec check_and_get_full_package_spec(std::string&& spec_string,
const Triplet& default_triplet,
CStringView example_text);
diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h
index 299a9c401..c87c6a2c6 100644
--- a/toolsrc/include/vcpkg/packagespec.h
+++ b/toolsrc/include/vcpkg/packagespec.h
@@ -35,6 +35,7 @@ namespace vcpkg
std::string dir() const;
std::string to_string() const;
+ void to_string(std::string& s) const;
bool operator<(const PackageSpec& other) const
{
@@ -65,6 +66,7 @@ namespace vcpkg
const PackageSpec& spec() const { return m_spec; }
std::string to_string() const;
+ void to_string(std::string& out) const;
static std::vector<FeatureSpec> from_strings_and_triplet(const std::vector<std::string>& depends,
const Triplet& t);
diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h
index be3497152..4c99c84c7 100644
--- a/toolsrc/include/vcpkg/packagespecparseresult.h
+++ b/toolsrc/include/vcpkg/packagespecparseresult.h
@@ -12,6 +12,8 @@ namespace vcpkg
INVALID_CHARACTERS
};
+ void to_string(std::string& out, ::vcpkg::PackageSpecParseResult p);
+
CStringView to_string(PackageSpecParseResult ev) noexcept;
template<>
diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h
index 334960e49..f33f40fd5 100644
--- a/toolsrc/include/vcpkg/triplet.h
+++ b/toolsrc/include/vcpkg/triplet.h
@@ -11,7 +11,7 @@ namespace vcpkg
public:
constexpr Triplet() noexcept : m_instance(&DEFAULT_INSTANCE) {}
- static Triplet from_canonical_name(const std::string& triplet_as_string);
+ static Triplet from_canonical_name(std::string&& triplet_as_string);
static const Triplet X86_WINDOWS;
static const Triplet X64_WINDOWS;
@@ -24,6 +24,7 @@ namespace vcpkg
const std::string& canonical_name() const;
const std::string& to_string() const;
+ void to_string(std::string& out) const;
size_t hash_code() const;
bool operator==(const Triplet& other) const;