diff options
| author | Robert Schumacher <roschuma@microsoft.com> | 2019-04-08 23:26:18 -0700 |
|---|---|---|
| committer | Phil Christensen <philc@microsoft.com> | 2019-04-08 23:26:18 -0700 |
| commit | b39b0899cb403aa1f2e86f9e111d16d6f1328737 (patch) | |
| tree | f4bacd15759c9a8fb334eadfd5d46253a238a1ac /toolsrc/include | |
| parent | ccbef646051dca6ddfb30e957aa77044c3a3bd11 (diff) | |
| download | vcpkg-b39b0899cb403aa1f2e86f9e111d16d6f1328737.tar.gz vcpkg-b39b0899cb403aa1f2e86f9e111d16d6f1328737.zip | |
[vcpkg] Synchronize vcpkg-base with external repo (#5934)
Diffstat (limited to 'toolsrc/include')
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; |
