This commit introduce three new `til` features: * "til/latch.h": A std::latch clone, until we're on C++20. * "til/mutex.h": A safe mutex wrapper, which only allows you access to the protected data after locking it. No more forgetting to lock mutexes! * "til/throttled_func.h": Function invocation throttling used to be available as the `ThrottledFunc` class already. But this class is vastly more efficient and doesn't rely on any WinRT types. This PR also adds a `til::ends_with` string helper which is `til::starts_with` counterpart. ## Validation Steps Performed * Scrollbar throttling still works as it used to ✔️ * No performance regressions when printing big.txt ✔️ Closes #10393
74 lines
2.5 KiB
C++
74 lines
2.5 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
|
{
|
|
_TIL_INLINEPREFIX std::wstring visualize_control_codes(std::wstring str) noexcept
|
|
{
|
|
for (auto& ch : str)
|
|
{
|
|
if (ch < 0x20)
|
|
{
|
|
ch += 0x2400;
|
|
}
|
|
else if (ch == 0x20)
|
|
{
|
|
ch = 0x2423; // replace space with ␣
|
|
}
|
|
else if (ch == 0x7f)
|
|
{
|
|
ch = 0x2421; // replace del with ␡
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
_TIL_INLINEPREFIX std::wstring visualize_control_codes(std::wstring_view str)
|
|
{
|
|
return visualize_control_codes(std::wstring{ str });
|
|
}
|
|
|
|
template<typename T, typename Traits>
|
|
constexpr bool starts_with(const std::basic_string_view<T, Traits> str, const std::basic_string_view<T, Traits> prefix) noexcept
|
|
{
|
|
#ifdef __cpp_lib_starts_ends_with
|
|
#error This code can be replaced in C++20, which natively supports .starts_with().
|
|
#endif
|
|
return str.size() >= prefix.size() && Traits::compare(str.data(), prefix.data(), prefix.size()) == 0;
|
|
};
|
|
|
|
constexpr bool starts_with(const std::string_view str, const std::string_view prefix) noexcept
|
|
{
|
|
return starts_with<>(str, prefix);
|
|
};
|
|
|
|
constexpr bool starts_with(const std::wstring_view str, const std::wstring_view prefix) noexcept
|
|
{
|
|
return starts_with<>(str, prefix);
|
|
};
|
|
|
|
template<typename T, typename Traits>
|
|
constexpr bool ends_with(const std::basic_string_view<T, Traits> str, const std::basic_string_view<T, Traits> prefix) noexcept
|
|
{
|
|
#ifdef __cpp_lib_ends_ends_with
|
|
#error This code can be replaced in C++20, which natively supports .ends_with().
|
|
#endif
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
|
|
return str.size() >= prefix.size() && Traits::compare(str.data() + (str.size() - prefix.size()), prefix.data(), prefix.size()) == 0;
|
|
#pragma warning(pop)
|
|
};
|
|
|
|
constexpr bool ends_with(const std::string_view str, const std::string_view prefix) noexcept
|
|
{
|
|
return ends_with<>(str, prefix);
|
|
};
|
|
|
|
constexpr bool ends_with(const std::wstring_view str, const std::wstring_view prefix) noexcept
|
|
{
|
|
return ends_with<>(str, prefix);
|
|
};
|
|
}
|