Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/81978f7525e4c3f23214aa677431b53b6e23b0aa
>---------------------------------------------------------------
commit 81978f7525e4c3f23214aa677431b53b6e23b0aa
Author: Alex Alabuzhev <
alab...@gmail.com>
Date: Sat May 9 13:06:59 2026 +0100
Bump VS version to 2022, remove 2019 workarounds
>---------------------------------------------------------------
81978f7525e4c3f23214aa677431b53b6e23b0aa
far/color_picker_256.cpp | 6 ++----
far/common/compiler.hpp | 16 +++++++++++-----
far/common/enum_tokens.hpp | 2 +-
far/common/library.hpp | 6 +++---
far/common/polyfills.hpp | 33 ---------------------------------
far/common/string_utils.hpp | 34 ++--------------------------------
far/far.natjmc | 7 ++-----
far/farversion.cpp | 4 ++--
far/format.hpp | 8 ++------
far/headers.hpp | 10 +++-------
far/pathmix.hpp | 2 +-
far/platform.fs.cpp | 4 +---
far/preservestyle.cpp | 4 ++--
far/string_sort.cpp | 6 +++---
far/strmix.hpp | 2 +-
15 files changed, 36 insertions(+), 108 deletions(-)
diff --git a/far/color_picker_256.cpp b/far/color_picker_256.cpp
index 96f163655..0a84f586f 100644
--- a/far/color_picker_256.cpp
+++ b/far/color_picker_256.cpp
@@ -116,8 +116,7 @@ static constexpr auto distinct_cube_map = []
{
std::array<uint8_t, colors::index::cube_count> Result;
- // Not constexpr, VS2019 LTO crashes and burns
- const auto CubeInverseMapping = foreground_inverse_mapping<cube_size>();
+ constexpr auto CubeInverseMapping = foreground_inverse_mapping<cube_size>();
for (uint8_t i = 0; i != Result.size(); ++i)
{
@@ -137,8 +136,7 @@ static constexpr auto distinct_grey_map = []
{
std::array<uint8_t, colors::index::grey_count> Result;
- // Not constexpr, VS2019 LTO crashes and burns
- const auto GreyInverseMapping = foreground_inverse_mapping<colors::index::grey_count>();
+ constexpr auto GreyInverseMapping = foreground_inverse_mapping<colors::index::grey_count>();
for (uint8_t i = 0; i != Result.size(); ++i)
{
diff --git a/far/common/compiler.hpp b/far/common/compiler.hpp
index fa9e82867..3f0f02c66 100644
--- a/far/common/compiler.hpp
+++ b/far/common/compiler.hpp
@@ -110,27 +110,27 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//----------------------------------------------------------------------------
#if COMPILER(CL)
-#define COMPILER_NAME L"Microsoft Visual C++"
+#define COMPILER_NAME "Microsoft Visual C++"
#define COMPILER_VERSION_MAJOR (_MSC_FULL_VER / 10000000)
#define COMPILER_VERSION_MINOR (_MSC_FULL_VER % 10000000 / 100000)
#define COMPILER_VERSION_PATCH (_MSC_FULL_VER % 100000)
#elif COMPILER(GCC)
-#define COMPILER_NAME L"GCC"
+#define COMPILER_NAME "GCC"
#define COMPILER_VERSION_MAJOR __GNUC__
#define COMPILER_VERSION_MINOR __GNUC_MINOR__
#define COMPILER_VERSION_PATCH __GNUC_PATCHLEVEL__
#elif COMPILER(INTEL)
-#define COMPILER_NAME L"Intel C++ Compiler"
+#define COMPILER_NAME "Intel C++ Compiler"
#define COMPILER_VERSION_MAJOR (__INTEL_COMPILER / 100)
#define COMPILER_VERSION_MINOR (__INTEL_COMPILER % 100)
#define COMPILER_VERSION_PATCH __INTEL_COMPILER_UPDATE
#elif COMPILER(CLANG)
-#define COMPILER_NAME L"Clang"
+#define COMPILER_NAME "Clang"
#define COMPILER_VERSION_MAJOR __clang_major__
#define COMPILER_VERSION_MINOR __clang_minor__
#define COMPILER_VERSION_PATCH __clang_patchlevel__
#else
-#define COMPILER_NAME L"Unknown compiler"
+#define COMPILER_NAME "Unknown compiler"
#define COMPILER_VERSION_MAJOR 0
#define COMPILER_VERSION_MINOR 0
#define COMPILER_VERSION_PATCH 0
@@ -166,4 +166,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
) \
)
+#define REQUIRE_COMPILER(compiler, major, minor, patch, ...) \
+ static_assert( \
+ CHECK_COMPILER(compiler, major, minor, patch), \
+ COMPILER_NAME " " #major "." #minor "." #patch " (or higher) required" __VA_ARGS__ \
+ )
+
#endif // COMPILER_HPP_6A237B14_5BAA_4106_9D7F_7C7BA14A36B0
diff --git a/far/common/enum_tokens.hpp b/far/common/enum_tokens.hpp
index 5df66f2c2..9a5c8ab71 100644
--- a/far/common/enum_tokens.hpp
+++ b/far/common/enum_tokens.hpp
@@ -208,7 +208,7 @@ WARNING_POP()
const auto NewIterator = std::ranges::find_if(View, [&](wchar_t const i)
{
- return !m_Overrider.active(i) && contains(Separators, i);
+ return !m_Overrider.active(i) && Separators.contains(i);
});
Value = { View.cbegin(), NewIterator };
diff --git a/far/common/library.hpp b/far/common/library.hpp
index 3dbec8cf2..ae57cb987 100644
--- a/far/common/library.hpp
+++ b/far/common/library.hpp
@@ -49,19 +49,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if defined(_MSVC_STL_VERSION) && defined(_MSVC_STL_UPDATE)
#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_MSVC()
-#define STANDARD_LIBRARY_NAME L"Microsoft STL"
+#define STANDARD_LIBRARY_NAME "Microsoft STL"
#define STANDARD_LIBRARY_VERSION_MAJOR (_MSVC_STL_VERSION / 10)
#define STANDARD_LIBRARY_VERSION_MINOR (_MSVC_STL_VERSION % 10)
#define STANDARD_LIBRARY_VERSION_PATCH _MSVC_STL_UPDATE
#elif defined(_GLIBCXX_RELEASE) and defined(__GLIBCXX__)
#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_GNU()
-#define STANDARD_LIBRARY_NAME L"GNU libstdc++"
+#define STANDARD_LIBRARY_NAME "GNU libstdc++"
#define STANDARD_LIBRARY_VERSION_MAJOR _GLIBCXX_RELEASE
#define STANDARD_LIBRARY_VERSION_MINOR 0
#define STANDARD_LIBRARY_VERSION_PATCH __GLIBCXX__
#elif defined(_LIBCPP_VERSION)
#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_LLVM()
-#define STANDARD_LIBRARY_NAME L"LLVM libc++"
+#define STANDARD_LIBRARY_NAME "LLVM libc++"
#define STANDARD_LIBRARY_VERSION_MAJOR (_LIBCPP_VERSION / 10000)
#define STANDARD_LIBRARY_VERSION_MINOR ((_LIBCPP_VERSION % 10000) / 100)
#define STANDARD_LIBRARY_VERSION_PATCH (_LIBCPP_VERSION % 100)
diff --git a/far/common/polyfills.hpp b/far/common/polyfills.hpp
index 66354b091..861443095 100644
--- a/far/common/polyfills.hpp
+++ b/far/common/polyfills.hpp
@@ -55,39 +55,6 @@ namespace std::this_thread
//----------------------------------------------------------------------------
-#ifndef __cpp_lib_to_underlying
-#include <type_traits>
-
-namespace std
-{
- template<class enum_type>
- [[nodiscard]]
- constexpr auto to_underlying(enum_type const Enum) noexcept
- {
- return static_cast<std::underlying_type_t<enum_type>>(Enum);
- }
-}
-#endif
-
-#ifndef __cpp_lib_unreachable
-#include <cassert>
-
-namespace std
-{
- [[noreturn]]
- inline void unreachable()
- {
- assert(false);
-
-#if COMPILER(CL)
- __assume(0);
-#else
- __builtin_unreachable();
-#endif
- }
-}
-#endif
-
#ifndef __cpp_lib_ranges_fold
#include <algorithm>
#if !defined _LIBCPP___ALGORITHM_FOLD_H && !defined _LIBCPP___ALGORITHM_RANGES_FOLD_H // as of March 2025 libc++ doesn't define __cpp_lib_ranges_fold
diff --git a/far/common/string_utils.hpp b/far/common/string_utils.hpp
index 9ebbabda9..29cb672cc 100644
--- a/far/common/string_utils.hpp
+++ b/far/common/string_utils.hpp
@@ -166,9 +166,7 @@ namespace string_utils::detail
}
}
-// Don't "auto" it yet, ICE in VS2019
-template <typename... args>
-void append(std::wstring& Str, args const&... Args)
+void append(std::wstring& Str, auto const&... Args)
{
string_utils::detail::append_impl(Str, { string_utils::detail::append_arg(Args)... });
}
@@ -184,34 +182,6 @@ auto concat(auto const&... Args)
}
// uniform "contains"
-template<typename... traits>
-[[nodiscard]]
-bool contains(const std::basic_string<traits...>& Str, const auto& What) noexcept
-{
- if constexpr (requires { Str.contains(What); })
- {
- return Str.contains(What);
- }
- else
- {
- return Str.find(What) != Str.npos;
- }
-}
-
-template<typename... traits>
-[[nodiscard]]
-constexpr bool contains(const std::basic_string_view<traits...> Str, const auto& What) noexcept
-{
- if constexpr (requires { Str.contains(What); })
- {
- return Str.contains(What);
- }
- else
- {
- return Str.find(What) != Str.npos;
- }
-}
-
namespace detail
{
template<typename raw_string_type>
@@ -306,7 +276,7 @@ namespace inplace
inline void quote_space(std::wstring& Str)
{
- if (contains(Str, L' '))
+ if (Str.contains(L' '))
quote(Str);
}
diff --git a/far/far.natjmc b/far/far.natjmc
index a7e7ae510..a689b2b74 100644
--- a/far/far.natjmc
+++ b/far/far.natjmc
@@ -1,7 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copy to %USERPROFILE%\Documents\Visual Studio 2019\Visualizers
--->
+<?xml version="1.0" encoding="utf-8"?>
<NonUserCode>
-<File Name="*\thirdparty\*" />
+ <File Name="*\thirdparty\*" />
</NonUserCode>
diff --git a/far/farversion.cpp b/far/farversion.cpp
index c81a2e85e..8901b673a 100644
--- a/far/farversion.cpp
+++ b/far/farversion.cpp
@@ -72,7 +72,7 @@ namespace build
L""sv;
return far::format(L"{}, version {}.{}.{}{}"sv,
- COMPILER_NAME,
+ WIDE_SV(COMPILER_NAME),
COMPILER_VERSION_MAJOR,
COMPILER_VERSION_MINOR,
COMPILER_VERSION_PATCH,
@@ -83,7 +83,7 @@ namespace build
string library()
{
return far::format(L"{}, version {}.{}.{}"sv,
- STANDARD_LIBRARY_NAME,
+ WIDE_SV(STANDARD_LIBRARY_NAME),
STANDARD_LIBRARY_VERSION_MAJOR,
STANDARD_LIBRARY_VERSION_MINOR,
STANDARD_LIBRARY_VERSION_PATCH
diff --git a/far/format.hpp b/far/format.hpp
index 408eca45a..81e04e705 100644
--- a/far/format.hpp
+++ b/far/format.hpp
@@ -88,9 +88,7 @@ namespace far
return fmt::vformat(fmt::string_view(Format), fmt::make_format_args(Args...));
}
- // Don't "auto" it yet, ICE in VS2019
- template <typename... args>
- auto vformat(string_view const Format, args const&... Args)
+ auto vformat(string_view const Format, auto const&... Args)
{
return fmt::vformat(fmt::wstring_view(Format), fmt::make_wformat_args(Args...));
}
@@ -143,9 +141,7 @@ namespace format_helpers
template<typename object_type>
struct format_no_spec
{
- // Don't "auto" it yet, ICE in VS2019
- template<typename FormatContext>
- auto format(object_type const& Value, FormatContext& ctx) const
+ auto format(object_type const& Value, auto& ctx) const
{
return fmt::format_to(ctx.out(), L"{}"sv, fmt::formatter<object_type, wchar_t>::to_string(Value));
}
diff --git a/far/headers.hpp b/far/headers.hpp
index 838655b8a..a284103f3 100644
--- a/far/headers.hpp
+++ b/far/headers.hpp
@@ -37,13 +37,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "common/compiler.hpp"
-#if !CHECK_COMPILER(CL, 19, 29, 30148)
-#error Visual C++ 2019 Update 16.11.24 (or higher) required
-#elif !CHECK_COMPILER(GCC, 12, 0, 0)
-#error GCC 12.0.0 (or higher) required
-#elif !CHECK_COMPILER(CLANG, 16, 0, 0)
-#error Clang 16.0.0 (or higher) required
-#endif
+REQUIRE_COMPILER(CL, 19, 42, 34444, " (Visual Studio 2022 Fall 2024 LTSC 17.12)");
+REQUIRE_COMPILER(GCC, 12, 0, 0);
+REQUIRE_COMPILER(CLANG, 16, 0, 0);
#include "common/shims_pre.hpp"
diff --git a/far/pathmix.hpp b/far/pathmix.hpp
index 48f118391..20d65c02b 100644
--- a/far/pathmix.hpp
+++ b/far/pathmix.hpp
@@ -60,7 +60,7 @@ namespace path
static_assert(separators.front() == separator);
constexpr bool is_nt_separator(wchar_t x) noexcept { return x == separator; }
- constexpr bool is_separator(wchar_t x) noexcept { return contains(separators, x); }
+ constexpr bool is_separator(wchar_t x) noexcept { return separators.contains(x); }
decltype(is_separator)* get_is_separator(string_view Path);
diff --git a/far/platform.fs.cpp b/far/platform.fs.cpp
index d83286598..d454dc8db 100644
--- a/far/platform.fs.cpp
+++ b/far/platform.fs.cpp
@@ -2646,9 +2646,7 @@ WARNING_POP()
// It's good enough to read it once.
static const auto AllowedDrivesMask = []
{
- // Declared separately due to a VS19 bug
- const auto Where = { ®::key::local_machine, ®::key::current_user };
- for (const auto& i: Where)
+ for (const auto& i: { ®::key::local_machine, ®::key::current_user })
{
if (const auto NoDrives = i->get_dword(L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"sv, L"NoDrives"sv))
return ~*NoDrives;
diff --git a/far/preservestyle.cpp b/far/preservestyle.cpp
index a11ee4327..3a7f59247 100644
--- a/far/preservestyle.cpp
+++ b/far/preservestyle.cpp
@@ -61,7 +61,7 @@ enum PreserveStyleType
static bool IsPreserveStyleTokenSeparator(wchar_t C)
{
- return contains(L"_-."sv, C);
+ return L"_-."sv.contains(C);
}
static int GetPreserveCaseStyleMask(const string_view Str)
@@ -285,7 +285,7 @@ bool PreserveStyleReplaceString(
const auto BlankOrWordDiv = [&WordDiv](wchar_t Ch)
{
- return std::iswblank(Ch) || contains(WordDiv, Ch);
+ return std::iswblank(Ch) || WordDiv.contains(Ch);
};
for (int I=Position; (options.Reverse && I>=0) || (!options.Reverse && static_cast<size_t>(I) < Source.size()); options.Reverse? I-- : I++)
diff --git a/far/string_sort.cpp b/far/string_sort.cpp
index 0d783d211..30492d3db 100644
--- a/far/string_sort.cpp
+++ b/far/string_sort.cpp
@@ -49,9 +49,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static std::strong_ordering per_char_compare(const string_view Str1, const string_view Str2, const auto Comparer)
{
- // VS2019 bug - 'classic' CTAD breaks the compilation here
- auto Iterator = std::pair(Str1.cbegin(), Str2.cbegin());
- const auto End = std::pair(Str1.cend(), Str2.cend());
+ std::pair
+ Iterator{ Str1.cbegin(), Str2.cbegin() },
+ End{ Str1.cend(), Str2.cend() };
while (Iterator.first != End.first && Iterator.second != End.second)
{
diff --git a/far/strmix.hpp b/far/strmix.hpp
index 2cf0db791..915bf5b35 100644
--- a/far/strmix.hpp
+++ b/far/strmix.hpp
@@ -153,7 +153,7 @@ string GroupDigits(unsigned long long Value);
[[nodiscard]]
inline bool IsWordDiv(string_view const WordDiv, wchar_t const Chr)
{
- return !Chr || contains(WordDiv, Chr);
+ return !Chr || WordDiv.contains(Chr);
}
[[nodiscard]]