From cfaa315de7078e356a3861b2184bc1584749e71f Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Fri, 11 Mar 2022 00:47:13 +0100 Subject: [PATCH] Fix compilation under and enable C++20 (#12658) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit enables `/std:c++20` for local development under VS17. Our CIs will continue to use VS16 and C++17 for now in order to reduce the likelihood of regressions during the current development cycle. It's expected that we'll migrate to VS17 soon, as this is what conhost is already being built with anyways. ## PR Checklist * [x] Closes #12510 * [x] I work here * [x] Tests added/passed ## Validation Steps Performed * Everything compiles under `/std:c++20` ✅ --- dep/CLI11/CLI11.hpp | 176 +++++++++++------- dep/CLI11/README.md | 5 +- .../ColorSchemeTests.cpp | 2 +- .../TerminalSettingsTests.cpp | 8 +- src/cascadia/TerminalApp/AppLogic.cpp | 2 +- src/cascadia/TerminalApp/TabBase.cpp | 2 +- src/cascadia/TerminalApp/TerminalTab.cpp | 4 +- src/cascadia/TerminalControl/TermControl.cpp | 2 +- .../TerminalSettingsModel/FileUtils.cpp | 2 +- src/common.build.pre.props | 3 +- src/host/ft_host/InitTests.cpp | 2 +- src/inc/til/bit.h | 4 +- src/inc/til/enumset.h | 15 +- .../parser/ft_fuzzer/fuzzing_directed.h | 36 ++-- 14 files changed, 151 insertions(+), 112 deletions(-) diff --git a/dep/CLI11/CLI11.hpp b/dep/CLI11/CLI11.hpp index a7efa607c9..9e502bf960 100644 --- a/dep/CLI11/CLI11.hpp +++ b/dep/CLI11/CLI11.hpp @@ -1,11 +1,11 @@ #pragma once -// CLI11: Version 1.9.0 +// CLI11: Version 1.9.1 // Originally designed by Henry Schreiner // https://github.com/CLIUtils/CLI11 // // This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts -// from: v1.9.0 +// from: v1.9.1 // // From LICENSE: // @@ -60,14 +60,14 @@ #include #include -// Verbatim copy from CLI/Version.hpp: +// Verbatim copy from Version.hpp: #define CLI11_VERSION_MAJOR 1 #define CLI11_VERSION_MINOR 9 -#define CLI11_VERSION_PATCH 0 -#define CLI11_VERSION "1.9.0" +#define CLI11_VERSION_PATCH 1 +#define CLI11_VERSION "1.9.1" -// Verbatim copy from CLI/Macros.hpp: +// Verbatim copy from Macros.hpp: // The following version macro is very similar to the one in PyBind11 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER) @@ -102,7 +102,7 @@ #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason))) #endif -// Verbatim copy from CLI/Validators.hpp: +// Verbatim copy from Validators.hpp: // C standard library // Only needed for existence checking @@ -114,7 +114,14 @@ #else #include #if defined __cpp_lib_filesystem && __cpp_lib_filesystem >= 201703 +#if defined _GLIBCXX_RELEASE && _GLIBCXX_RELEASE >= 9 #define CLI11_HAS_FILESYSTEM 1 +#elif defined(__GLIBCXX__) +// if we are using gcc and Version <9 default to no filesystem +#define CLI11_HAS_FILESYSTEM 0 +#else +#define CLI11_HAS_FILESYSTEM 1 +#endif #else #define CLI11_HAS_FILESYSTEM 0 #endif @@ -129,11 +136,11 @@ #include #endif -// From CLI/Version.hpp: +// From Version.hpp: -// From CLI/Macros.hpp: +// From Macros.hpp: -// From CLI/StringTools.hpp: +// From StringTools.hpp: namespace CLI { @@ -570,7 +577,7 @@ namespace CLI } // namespace CLI -// From CLI/Error.hpp: +// From Error.hpp: namespace CLI { @@ -844,11 +851,11 @@ public: { CLI11_ERROR_DEF(ParseError, ArgumentMismatch) CLI11_ERROR_SIMPLE(ArgumentMismatch) - ArgumentMismatch(std::string name, int expected, std::size_t recieved) : + ArgumentMismatch(std::string name, int expected, std::size_t received) : ArgumentMismatch(expected > 0 ? ("Expected exactly " + std::to_string(expected) + " arguments to " + name + - ", got " + std::to_string(recieved)) : + ", got " + std::to_string(received)) : ("Expected at least " + std::to_string(-expected) + " arguments to " + name + - ", got " + std::to_string(recieved)), + ", got " + std::to_string(received)), ExitCodes::ArgumentMismatch) {} static ArgumentMismatch AtLeast(std::string name, int num, std::size_t received) @@ -949,7 +956,7 @@ public: } // namespace CLI -// From CLI/TypeTools.hpp: +// From TypeTools.hpp: namespace CLI { @@ -1237,16 +1244,26 @@ namespace CLI }; /// Convert an object to a string (directly forward if this can become a string) - template::value, detail::enabler> = detail::dummy> + template::value, detail::enabler> = detail::dummy> auto to_string(T&& value) -> decltype(std::forward(value)) { return std::forward(value); } + /// Construct a string from the object + template::value && !std::is_convertible::value, + detail::enabler> = detail::dummy> + std::string to_string(const T& value) + { + return std::string(value); + } + /// Convert an object to a string (streaming must be supported for that type) template::value && is_ostreamable::value, detail::enabler> = - detail::dummy> + enable_if_t::value && !std::is_constructible::value && + is_ostreamable::value, + detail::enabler> = detail::dummy> std::string to_string(T&& value) { std::stringstream stream; @@ -1624,7 +1641,7 @@ namespace CLI // Lexical cast /// Convert a flag into an integer value typically binary flags - inline int64_t to_flag_value(std::string val) + inline std::int64_t to_flag_value(std::string val) { static const std::string trueString("true"); static const std::string falseString("false"); @@ -1637,12 +1654,12 @@ namespace CLI return -1; } val = detail::to_lower(val); - int64_t ret; + std::int64_t ret; if (val.size() == 1) { if (val[0] >= '1' && val[0] <= '9') { - return (static_cast(val[0]) - '0'); + return (static_cast(val[0]) - '0'); } switch (val[0]) { @@ -2127,7 +2144,7 @@ namespace CLI enable_if_t::value && std::is_unsigned::value, detail::enabler> = detail::dummy> void sum_flag_vector(const std::vector& flags, T& output) { - int64_t count{ 0 }; + std::int64_t count{ 0 }; for (auto& flag : flags) { count += detail::to_flag_value(flag); @@ -2144,7 +2161,7 @@ namespace CLI enable_if_t::value && std::is_signed::value, detail::enabler> = detail::dummy> void sum_flag_vector(const std::vector& flags, T& output) { - int64_t count{ 0 }; + std::int64_t count{ 0 }; for (auto& flag : flags) { count += detail::to_flag_value(flag); @@ -2155,7 +2172,7 @@ namespace CLI } // namespace detail } // namespace CLI -// From CLI/Split.hpp: +// From Split.hpp: namespace CLI { @@ -2307,7 +2324,7 @@ namespace CLI } // namespace detail } // namespace CLI -// From CLI/ConfigFwd.hpp: +// From ConfigFwd.hpp: namespace CLI { @@ -2436,7 +2453,7 @@ namespace CLI }; } // namespace CLI -// From CLI/Validators.hpp: +// From Validators.hpp: namespace CLI { @@ -2504,7 +2521,7 @@ namespace CLI } } return retstring; - }; + } /// This is the required operator for a Validator - provided to help /// users (CLI11 uses the member `func` directly) @@ -2512,7 +2529,7 @@ namespace CLI { std::string value = str; return (active_) ? func_(value) : std::string{}; - }; + } /// Specify the type string Validator& description(std::string validator_desc) @@ -2576,14 +2593,14 @@ namespace CLI { application_index_ = app_index; return *this; - }; + } /// Specify the application index of a validator Validator application_index(int app_index) const { Validator newval(*this); newval.application_index_ = app_index; return newval; - }; + } /// Get the current value of the application index int get_application_index() const { return application_index_; } /// Get a boolean if the validator is active @@ -2699,7 +2716,7 @@ namespace CLI /// CLI enumeration of different file types enum class path_type { - nonexistant, + nonexistent, file, directory }; @@ -2712,13 +2729,13 @@ namespace CLI auto stat = std::filesystem::status(file, ec); if (ec) { - return path_type::nonexistant; + return path_type::nonexistent; } switch (stat.type()) { case std::filesystem::file_type::none: case std::filesystem::file_type::not_found: - return path_type::nonexistant; + return path_type::nonexistent; case std::filesystem::file_type::directory: return path_type::directory; case std::filesystem::file_type::symlink: @@ -2749,7 +2766,7 @@ namespace CLI return ((buffer.st_mode & S_IFDIR) != 0) ? path_type::directory : path_type::file; } #endif - return path_type::nonexistant; + return path_type::nonexistent; } #endif /// Check for an existing file (returns error message if check fails) @@ -2761,7 +2778,7 @@ namespace CLI { func_ = [](std::string& filename) { auto path_result = check_path(filename.c_str()); - if (path_result == path_type::nonexistant) + if (path_result == path_type::nonexistent) { return "File does not exist: " + filename; } @@ -2783,7 +2800,7 @@ namespace CLI { func_ = [](std::string& filename) { auto path_result = check_path(filename.c_str()); - if (path_result == path_type::nonexistant) + if (path_result == path_type::nonexistent) { return "Directory does not exist: " + filename; } @@ -2805,7 +2822,7 @@ namespace CLI { func_ = [](std::string& filename) { auto path_result = check_path(filename.c_str()); - if (path_result == path_type::nonexistant) + if (path_result == path_type::nonexistent) { return "Path does not exist: " + filename; } @@ -2823,7 +2840,7 @@ namespace CLI { func_ = [](std::string& filename) { auto path_result = check_path(filename.c_str()); - if (path_result != path_type::nonexistant) + if (path_result != path_type::nonexistent) { return "Path already exists: " + filename; } @@ -3310,7 +3327,7 @@ namespace CLI // if the type does not have first_type and second_type, these are both value_type using element_t = typename detail::element_type::type; // Removes (smart) pointers if needed using item_t = typename detail::pair_adaptor::first_type; // Is value_type if not a map - using local_item_t = typename IsMemberType::type; // This will convert bad types to good ones + using local_item_t = typename IsMemberType::type; // Will convert bad types to good ones // (const char * to std::string) // Make a local copy of the filter function, using a std::function if not one already @@ -3381,10 +3398,9 @@ namespace CLI // if the type does not have first_type and second_type, these are both value_type using element_t = typename detail::element_type::type; // Removes (smart) pointers if needed using item_t = typename detail::pair_adaptor::first_type; // Is value_type if not a map - using local_item_t = typename IsMemberType::type; // This will convert bad types to good ones + using local_item_t = typename IsMemberType::type; // Will convert bad types to good ones // (const char * to std::string) - using iteration_type_t = typename detail::pair_adaptor::value_type; // the type of the object pair // - // the type of the object pair + using iteration_type_t = typename detail::pair_adaptor::value_type; // the type of the object pair // Make a local copy of the filter function, using a std::function if not one already std::function filter_fn = filter_function; @@ -3625,7 +3641,7 @@ namespace CLI class AsSizeValue : public AsNumberWithUnit { public: - using result_t = uint64_t; + using result_t = std::uint64_t; /// If kb_is_1000 is true, /// interpret 'kb', 'k' as 1000 and 'kib', 'ki' as 1024 @@ -3721,7 +3737,7 @@ namespace CLI } // namespace CLI -// From CLI/FormatterFwd.hpp: +// From FormatterFwd.hpp: namespace CLI { @@ -3735,9 +3751,9 @@ namespace CLI enum class AppFormatMode { - Normal, //< The normal, detailed help - All, //< A fully expanded help - Sub, //< Used when printed as part of expanded subcommand + Normal, ///< The normal, detailed help + All, ///< A fully expanded help + Sub, ///< Used when printed as part of expanded subcommand }; /// This is the minimum requirements to run a formatter. @@ -3897,7 +3913,7 @@ namespace CLI } // namespace CLI -// From CLI/Option.hpp: +// From Option.hpp: namespace CLI { @@ -4441,7 +4457,7 @@ namespace CLI template Option* needs(std::string opt_name) { - auto opt = dynamic_cast(parent_)->get_option_no_throw(opt_name); + auto opt = static_cast(parent_)->get_option_no_throw(opt_name); if (opt == nullptr) { throw IncorrectConstruction::MissingOption(opt_name); @@ -4492,7 +4508,7 @@ namespace CLI template Option* excludes(std::string opt_name) { - auto opt = dynamic_cast(parent_)->get_option_no_throw(opt_name); + auto opt = static_cast(parent_)->get_option_no_throw(opt_name); if (opt == nullptr) { throw IncorrectConstruction::MissingOption(opt_name); @@ -4538,7 +4554,7 @@ namespace CLI if (!ignore_case_ && value) { ignore_case_ = value; - auto* parent = dynamic_cast(parent_); + auto* parent = static_cast(parent_); for (const Option_p& opt : parent->options_) { if (opt.get() == this) @@ -4570,7 +4586,7 @@ namespace CLI if (!ignore_underscore_ && value) { ignore_underscore_ = value; - auto* parent = dynamic_cast(parent_); + auto* parent = static_cast(parent_); for (const Option_p& opt : parent->options_) { if (opt.get() == this) @@ -4698,9 +4714,9 @@ namespace CLI /// Will include / prefer the positional name if positional is true. /// If all_options is false, pick just the most descriptive name to show. /// Use `get_name(true)` to get the positional name (replaces `get_pname`) - std::string get_name(bool positional = false, //<[input] Show the positional name - bool all_options = false //<[input] Show every option - ) const + std::string get_name(bool positional = false, ///< Show the positional name + bool all_options = false ///< Show every option + ) const { if (get_group().empty()) return {}; // Hidden @@ -5000,7 +5016,7 @@ namespace CLI { if (!default_str_.empty()) { - //_add_results takes an rvalue only + // _add_results takes an rvalue only _add_result(std::string(default_str_), res); _validate_results(res); results_t extra; @@ -5379,7 +5395,7 @@ namespace CLI } // namespace CLI -// From CLI/App.hpp: +// From App.hpp: namespace CLI { @@ -6221,8 +6237,9 @@ namespace CLI } /// Vector version to capture multiple flags. - template, T>::value, detail::enabler> = detail::dummy> + template< + typename T, + enable_if_t, T>::value, detail::enabler> = detail::dummy> Option* add_flag(std::string flag_name, std::vector& flag_results, ///< A vector of values with the flag results std::string flag_description = "") @@ -6260,11 +6277,11 @@ namespace CLI /// Add option for callback with an integer value Option* add_flag_function(std::string flag_name, - std::function function, ///< A function to call, void(int) + std::function function, ///< A function to call, void(int) std::string flag_description = "") { CLI::callback_t fun = [function](const CLI::results_t& res) { - int64_t flag_count = 0; + std::int64_t flag_count = 0; detail::sum_flag_vector(res, flag_count); function(flag_count); return true; @@ -6276,7 +6293,7 @@ namespace CLI #ifdef CLI11_CPP14 /// Add option for callback (C++14 or better only) Option* add_flag(std::string flag_name, - std::function function, ///< A function to call, void(int64_t) + std::function function, ///< A function to call, void(std::int64_t) std::string flag_description = "") { return add_flag_function(std::move(flag_name), std::move(function), std::move(flag_description)); @@ -6452,7 +6469,7 @@ namespace CLI template T* add_option_group(std::string group_name, std::string group_description = "") { - auto option_group = std::make_shared(std::move(group_description), group_name, nullptr); + auto option_group = std::make_shared(std::move(group_description), group_name, this); auto ptr = option_group.get(); // move to App_p for overload resolution on older gcc versions App_p app_ptr = std::dynamic_pointer_cast(option_group); @@ -6461,7 +6478,7 @@ namespace CLI } ///@} - /// @name Subcommmands + /// @name Subcommands ///@{ /// Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag @@ -6837,16 +6854,16 @@ namespace CLI int exit(const Error& e, std::ostream& out = std::cout, std::ostream& err = std::cerr) const { /// Avoid printing anything if this is a CLI::RuntimeError - if (dynamic_cast(&e) != nullptr) + if (e.get_name() == "RuntimeError") return e.get_exit_code(); - if (dynamic_cast(&e) != nullptr) + if (e.get_name() == "CallForHelp") { out << help(); return e.get_exit_code(); } - if (dynamic_cast(&e) != nullptr) + if (e.get_name() == "CallForAllHelp") { out << help("", AppFormatMode::All); return e.get_exit_code(); @@ -7080,7 +7097,12 @@ namespace CLI /// Access the config formatter as a configBase pointer std::shared_ptr get_config_formatter_base() const { + // This is safer as a dynamic_cast if we have RTTI, as Config -> ConfigBase +#if defined(__cpp_rtti) || (defined(__GXX_RTTI) && __GXX_RTTI) || (defined(_HAS_STATIC_RTTI) && (_HAS_STATIC_RTTI == 0)) return std::dynamic_pointer_cast(config_formatter_); +#else + return std::static_pointer_cast(config_formatter_); +#endif } /// Get the app or subcommand description @@ -8908,6 +8930,21 @@ namespace CLI /// This class is simply to allow tests access to App's protected functions struct AppFriend { +#ifdef CLI11_CPP14 + /// Wrap _parse_short, perfectly forward arguments and return + template + static decltype(auto) parse_arg(App* app, Args&&... args) + { + return app->_parse_arg(std::forward(args)...); + } + + /// Wrap _parse_subcommand, perfectly forward arguments and return + template + static decltype(auto) parse_subcommand(App* app, Args&&... args) + { + return app->_parse_subcommand(std::forward(args)...); + } +#else /// Wrap _parse_short, perfectly forward arguments and return template static auto parse_arg(App* app, Args&&... args) -> @@ -8923,6 +8960,7 @@ namespace CLI { return app->_parse_subcommand(std::forward(args)...); } +#endif /// Wrap the fallthrough parent function to make sure that is working correctly static App* get_fallthrough_parent(App* app) { return app->_get_fallthrough_parent(); } }; @@ -8930,7 +8968,7 @@ namespace CLI } // namespace CLI -// From CLI/Config.hpp: +// From Config.hpp: namespace CLI { @@ -9360,7 +9398,7 @@ namespace CLI } // namespace CLI -// From CLI/Formatter.hpp: +// From Formatter.hpp: namespace CLI { diff --git a/dep/CLI11/README.md b/dep/CLI11/README.md index a6e04c1801..023ffc1e3b 100644 --- a/dep/CLI11/README.md +++ b/dep/CLI11/README.md @@ -1,5 +1,4 @@ # CLI11 -Taken from [release v1.9.0](https://github.com/CLIUtils/CLI11/releases/tag/v1.9.0), source commit -[dd0d8e4](https://github.com/CLIUtils/CLI11/commit/dd0d8e4fe729e5b1110232c7a5c9566dad884686) - +Taken from [release v1.9.1](https://github.com/CLIUtils/CLI11/releases/tag/v1.9.1), source commit +[5cb3efa](https://github.com/CLIUtils/CLI11/commit/5cb3efabce007c3a0230e4cc2e27da491c646b6c) diff --git a/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp b/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp index c13bcbdc8b..fac134c951 100644 --- a/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp +++ b/src/cascadia/LocalTests_SettingsModel/ColorSchemeTests.cpp @@ -84,7 +84,7 @@ namespace SettingsModelLocalTests for (size_t i = 0; i < expectedCampbellTable.size(); i++) { - const auto& expected = expectedCampbellTable.at(i); + const til::color expected{ expectedCampbellTable.at(i) }; const til::color actual{ scheme->Table().at(static_cast(i)) }; VERIFY_ARE_EQUAL(expected, actual); } diff --git a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp index ad2463bbb7..4f064a0e6c 100644 --- a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp +++ b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp @@ -795,11 +795,11 @@ namespace SettingsModelLocalTests const auto terminalSettings4 = createTerminalSettings(activeProfiles.GetAt(4), colorSchemes); const auto terminalSettings5 = createTerminalSettings(activeProfiles.GetAt(5), colorSchemes); - VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), terminalSettings0->CursorColor()); // from color scheme + VERIFY_ARE_EQUAL(til::color(0x12, 0x34, 0x56), terminalSettings0->CursorColor()); // from color scheme VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1->CursorColor()); // default - VERIFY_ARE_EQUAL(RGB(0x23, 0x45, 0x67), terminalSettings2->CursorColor()); // from profile (trumps color scheme) - VERIFY_ARE_EQUAL(RGB(0x34, 0x56, 0x78), terminalSettings3->CursorColor()); // from profile (not set in color scheme) - VERIFY_ARE_EQUAL(RGB(0x45, 0x67, 0x89), terminalSettings4->CursorColor()); // from profile (no color scheme) + VERIFY_ARE_EQUAL(til::color(0x23, 0x45, 0x67), terminalSettings2->CursorColor()); // from profile (trumps color scheme) + VERIFY_ARE_EQUAL(til::color(0x34, 0x56, 0x78), terminalSettings3->CursorColor()); // from profile (not set in color scheme) + VERIFY_ARE_EQUAL(til::color(0x45, 0x67, 0x89), terminalSettings4->CursorColor()); // from profile (no color scheme) VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings5->CursorColor()); // default } diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp index 0d8cb34fa2..fe6636a4f9 100644 --- a/src/cascadia/TerminalApp/AppLogic.cpp +++ b/src/cascadia/TerminalApp/AppLogic.cpp @@ -1007,7 +1007,7 @@ namespace winrt::TerminalApp::implementation const auto package{ GetCurrentPackageNoThrow() }; if (package == nullptr) { - return; + co_return; } const auto tryEnableStartupTask = _settings.GlobalSettings().StartOnUserLogin(); diff --git a/src/cascadia/TerminalApp/TabBase.cpp b/src/cascadia/TerminalApp/TabBase.cpp index 6cda2158ae..6667f760ea 100644 --- a/src/cascadia/TerminalApp/TabBase.cpp +++ b/src/cascadia/TerminalApp/TabBase.cpp @@ -176,7 +176,7 @@ namespace winrt::TerminalApp::implementation if (_keyChord == keyChordText) { - return; + co_return; } _keyChord = keyChordText; diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index bacba947c5..5dc5259617 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -274,7 +274,7 @@ namespace winrt::TerminalApp::implementation // Don't reload our icon if it hasn't changed. if (iconPath == _lastIconPath) { - return; + co_return; } _lastIconPath = iconPath; @@ -283,7 +283,7 @@ namespace winrt::TerminalApp::implementation // for when we show the icon again) if (_iconHidden) { - return; + co_return; } auto weakThis{ get_weak() }; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index b6bb9e6b98..d329f1132f 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -2274,7 +2274,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation { if (_IsClosing()) { - return; + co_return; } if (e.DataView().Contains(StandardDataFormats::ApplicationLink())) diff --git a/src/cascadia/TerminalSettingsModel/FileUtils.cpp b/src/cascadia/TerminalSettingsModel/FileUtils.cpp index 4535c23be0..30104ff28a 100644 --- a/src/cascadia/TerminalSettingsModel/FileUtils.cpp +++ b/src/cascadia/TerminalSettingsModel/FileUtils.cpp @@ -12,7 +12,7 @@ #include #include -static constexpr std::string_view Utf8Bom{ u8"\uFEFF" }; +static constexpr std::string_view Utf8Bom{ "\xEF\xBB\xBF", 3 }; static constexpr std::wstring_view UnpackagedSettingsFolderName{ L"Microsoft\\Windows Terminal\\" }; namespace winrt::Microsoft::Terminal::Settings::Model diff --git a/src/common.build.pre.props b/src/common.build.pre.props index 30d7fb285f..4d494f911a 100644 --- a/src/common.build.pre.props +++ b/src/common.build.pre.props @@ -118,7 +118,8 @@ false true true - stdcpp17 + stdcpp17 + stdcpp20 stdc17 %(AdditionalOptions) /utf-8 /Zc:externConstexpr /Zc:lambda /Zc:throwingNew Guard diff --git a/src/host/ft_host/InitTests.cpp b/src/host/ft_host/InitTests.cpp index ea738dd8fa..f3d062c887 100644 --- a/src/host/ft_host/InitTests.cpp +++ b/src/host/ft_host/InitTests.cpp @@ -25,7 +25,7 @@ static FILE* std_in = nullptr; // This will automatically try to terminate the job object (and all of the // binaries under test that are children) whenever this class gets shut down. // also closes the FILE pointers created by reopening stdin and stdout. -auto OnAppExitKillJob = wil::scope_exit([&] { +auto OnAppExitKillJob = wil::scope_exit([] { if (std_out != nullptr) { fclose(std_out); diff --git a/src/inc/til/bit.h b/src/inc/til/bit.h index fd8d9c44ff..dc15d4bce4 100644 --- a/src/inc/til/bit.h +++ b/src/inc/til/bit.h @@ -8,9 +8,7 @@ namespace til template, std::is_trivially_copyable, std::is_trivially_copyable>, int> = 0> [[nodiscard]] constexpr To bit_cast(const From& _Val) noexcept { -#ifdef __cpp_lib_bit_cast -#warning "Replace til::bit_cast and __builtin_bit_cast with std::bit_cast" -#endif + // TODO: Replace til::bit_cast and __builtin_bit_cast with std::bit_cast return __builtin_bit_cast(To, _Val); } } diff --git a/src/inc/til/enumset.h b/src/inc/til/enumset.h index dcb5e1a330..5ee47a7167 100644 --- a/src/inc/til/enumset.h +++ b/src/inc/til/enumset.h @@ -124,13 +124,14 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" template static constexpr UnderlyingType to_underlying(Args... positions) noexcept { - return ((UnderlyingType{ 1 } << static_cast(positions)) | ...); - } - - template<> - static constexpr UnderlyingType to_underlying() noexcept - { - return 0; + if constexpr (sizeof...(positions) == 0) + { + return 0; + } + else + { + return ((UnderlyingType{ 1 } << static_cast(positions)) | ...); + } } UnderlyingType _data{}; diff --git a/src/terminal/parser/ft_fuzzer/fuzzing_directed.h b/src/terminal/parser/ft_fuzzer/fuzzing_directed.h index aef4f3fb29..a48ed24733 100644 --- a/src/terminal/parser/ft_fuzzer/fuzzing_directed.h +++ b/src/terminal/parser/ft_fuzzer/fuzzing_directed.h @@ -253,25 +253,27 @@ namespace fuzz template static _Type GetRandom(__in _Type tMin, __in _Type tMax) { - std::mt19937 engine(m_rd()); // Mersenne twister MT19937 - std::uniform_int_distribution<_Type> distribution(tMin, tMax); - auto generator = std::bind(distribution, engine); - return generator(); + if constexpr (std::is_same_v<_Type, BYTE>) + { + // uniform_int_distribution only works with _Is_IntType types, which do not + // currently include char or unsigned char, so here is a specialization + // specifically for BYTE (unsigned char). + std::mt19937 engine(m_rd()); // Mersenne twister MT19937 + // BYTE is unsigned, so we want to also use an unsigned type to avoid sign + // extension of tMin and tMax. + std::uniform_int_distribution distribution(tMin, tMax); + auto generator = std::bind(distribution, engine); + return static_cast(generator()); + } + else + { + std::mt19937 engine(m_rd()); // Mersenne twister MT19937 + std::uniform_int_distribution<_Type> distribution(tMin, tMax); + auto generator = std::bind(distribution, engine); + return generator(); + } } - // uniform_int_distribution only works with _Is_IntType types, which do not - // currently include char or unsigned char, so here is a specialization - // specifically for BYTE (unsigned char). - template<> - static BYTE GetRandom(__in BYTE tMin, __in BYTE tMax) - { - std::mt19937 engine(m_rd()); // Mersenne twister MT19937 - // BYTE is unsigned, so we want to also use an unsigned type to avoid sign - // extension of tMin and tMax. - std::uniform_int_distribution distribution(tMin, tMax); - auto generator = std::bind(distribution, engine); - return static_cast(generator()); - } #ifdef __min_collision__ #undef __min_collision__ #define min(a, b) (((a) < (b)) ? (a) : (b))