diff --git a/far/PluginA.cpp b/far/PluginA.cpp index a27c1799d0..1a5381fd36 100644 --- a/far/PluginA.cpp +++ b/far/PluginA.cpp @@ -60,6 +60,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.env.hpp" #include "platform.memory.hpp" +#include "common/function_ref.hpp" #include "common/null_iterator.hpp" #include "common/range.hpp" #include "common/scope_exit.hpp" @@ -724,7 +725,7 @@ static PluginPanelItem* ConvertAnsiPanelItemsToUnicode(range(Src.PackSize) + (static_cast(Src.PackSizeHigh) << 32); Dst.FileName = AnsiToUnicode(Src.FindData.cFileName); Dst.AlternateFileName = AnsiToUnicode(Src.FindData.cAlternateFileName); - }; + } return Result.release(); } @@ -925,7 +926,7 @@ static void AnsiVBufToUnicode(CHAR_INFO* VBufA, FAR_CHAR_INFO* VBuf, size_t Size AnsiToUnicodeBin({ &Src.Char.AsciiChar, 1 }, &Dst.Char); } Dst.Attributes = colors::ConsoleColorToFarColor(Src.Attributes); - }; + } } static FAR_CHAR_INFO* AnsiVBufToUnicode(const oldfar::FarDialogItem &diA) @@ -1341,10 +1342,10 @@ static void ConvertUnicodePanelInfoToAnsi(const PanelInfo* PIW, oldfar::PanelInf PIA->SelectedItems = nullptr; PIA->CurrentItem = static_cast(PIW->CurrentItem); PIA->TopPanelItem = static_cast(PIW->TopPanelItem); - PIA->Visible = (PIW->Flags&PFLAGS_VISIBLE) ? 1 : 0;; - PIA->Focus = (PIW->Flags&PFLAGS_FOCUS) ? 1 : 0;; + PIA->Visible = (PIW->Flags&PFLAGS_VISIBLE)? 1 : 0; + PIA->Focus = (PIW->Flags&PFLAGS_FOCUS)? 1 : 0; PIA->ViewMode = PIW->ViewMode; - PIA->ShortNames = (PIW->Flags&PFLAGS_ALTERNATIVENAMES) ? 1 : 0;; + PIA->ShortNames = (PIW->Flags&PFLAGS_ALTERNATIVENAMES)? 1 : 0; PIA->SortMode = 0; switch (PIW->SortMode) @@ -3597,7 +3598,7 @@ static void WINAPI FarRestoreScreenA(HANDLE Screen) noexcept CATCH_AND_SAVE_EXCEPTION_TO(GlobalExceptionPtr()) } -static int GetDirListGeneric(oldfar::PluginPanelItem*& PanelItems, int& ItemsSize, const std::function& Getter) +static int GetDirListGeneric(oldfar::PluginPanelItem*& PanelItems, int& ItemsSize, function_ref const Getter) { PanelItems = nullptr; ItemsSize = 0; @@ -5578,7 +5579,7 @@ class PluginA: public Plugin }; -#define CREATE_ITEMS(ItemsType) CreatePluginMenuItems(Src.ItemsType##Strings, Src.ItemsType##StringsNumber, PI.ItemsType); +#define CREATE_ITEMS(ItemsType) CreatePluginMenuItems(Src.ItemsType##Strings, Src.ItemsType##StringsNumber, PI.ItemsType) CREATE_ITEMS(DiskMenu); CREATE_ITEMS(PluginMenu); diff --git a/far/RegExp.cpp b/far/RegExp.cpp index db311da807..c968cdead9 100644 --- a/far/RegExp.cpp +++ b/far/RegExp.cpp @@ -37,6 +37,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "string_utils.hpp" #include "plugin.hpp" +#include "common/function_ref.hpp" + WARNING_DISABLE_GCC("-Wpragmas") WARNING_DISABLE_GCC("-Wimplicit-fallthrough") @@ -1801,7 +1803,7 @@ int RegExp::InnerMatch(const wchar_t* const start, const wchar_t* str, const wch if (str<=strend) { - const auto& MinSkip = [&](StateStackItem& st, const std::function& cmp) + const auto& MinSkip = [&](StateStackItem& st, function_ref const cmp) { int jj; switch (std::next(op)->op) diff --git a/far/changelog b/far/changelog index 3dc36db093..8539fad95c 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,11 @@ +drkns 26.12.2018 11:22:00 +0000 - build 5345 + +1. std::function заменена на function_ref, где возможно. Что-то (где-то, когда-то) будет работать быстрее. Наверное. + +2. Clang warnings. + +3. Новая версия fmt. + drkns 23.12.2018 16:09:53 +0000 - build 5344 1. ColorDialog использует более очевидный цвет (чёрный) в качестве базы предпросмотра, если не указано иное. diff --git a/far/changelog_eng b/far/changelog_eng index 5eaa382f60..51973a582b 100644 --- a/far/changelog_eng +++ b/far/changelog_eng @@ -3,6 +3,14 @@ This file is a translation of the main russian changelog and is provided by volu It might not always be as up to date as the main changelog. ======================================================================================= +drkns 26.12.2018 11:22:00 +0000 - build 5345 + +1. std::function replaced with function_ref where possible. Something (somewhere, sometime) will work faster. Probably. + +2. Clang warnings. + +3. New version of fmt. + drkns 23.12.2018 16:09:53 +0000 - build 5344 1. ColorDialog uses more obvious colour (black) as the base of the preview by default. diff --git a/far/cmdline.cpp b/far/cmdline.cpp index 8c38ff8273..17bcfa8d8e 100644 --- a/far/cmdline.cpp +++ b/far/cmdline.cpp @@ -893,7 +893,7 @@ void CommandLine::SetPromptSize(int NewSize) PromptSize = NewSize? std::clamp(NewSize, 5, 95) : DEFAULT_CMDLINE_WIDTH; } -static bool ProcessFarCommands(const string& Command, const std::function& ConsoleActivatior) +static bool ProcessFarCommands(const string& Command, function_ref const ConsoleActivatior) { if (equal_icase(Command, L"far:config"sv)) { @@ -1056,7 +1056,7 @@ void CommandLine::ExecString(execute_info& Info) IsUpdateNeeded = true; } -bool CommandLine::ProcessOSCommands(string_view const CmdLine, const std::function& ConsoleActivatior) +bool CommandLine::ProcessOSCommands(string_view const CmdLine, function_ref const ConsoleActivatior) { auto SetPanel = Global->CtrlObject->Cp()->ActivePanel(); @@ -1188,10 +1188,6 @@ bool CommandLine::ProcessOSCommands(string_view const CmdLine, const std::functi ppstack.push(PushDir); os::env::set(L"FARDIRSTACK"sv, PushDir); } - else - { - ; - } return true; } diff --git a/far/cmdline.hpp b/far/cmdline.hpp index 3aa614167a..67870bb957 100644 --- a/far/cmdline.hpp +++ b/far/cmdline.hpp @@ -38,6 +38,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "scrobj.hpp" #include "editcontrol.hpp" +#include "common/function_ref.hpp" + struct execute_info { enum class wait_mode { no_wait, wait_idle, wait_finish }; @@ -90,7 +92,7 @@ class CommandLine:public SimpleScreenObject private: void DisplayObject() override; size_t DrawPrompt(); - bool ProcessOSCommands(string_view CmdLine, const std::function& ConsoleActivatior); + bool ProcessOSCommands(string_view CmdLine, function_ref ConsoleActivatior); struct segment { string Text; diff --git a/far/common/enumerator.hpp b/far/common/enumerator.hpp index 9897c79c3c..633e3e355b 100644 --- a/far/common/enumerator.hpp +++ b/far/common/enumerator.hpp @@ -135,6 +135,9 @@ class inline_enumerator: public enumerator +class function_ref; + +template +class function_ref final +{ +public: + template, function_ref>)> + function_ref(const callable_type& Callable) noexcept: + m_Ptr(&Callable) + { + // TODO: use initializer list after dropping VS2015 + m_ErasedFn = [](const void* Ptr, args... Args) -> return_type + { + return std::invoke(*static_cast(Ptr), FWD(Args)...); + }; + } + + function_ref(std::nullptr_t) noexcept: + m_Ptr(), + m_ErasedFn() + { + } + + decltype(auto) operator()(args... Args) const + { + return m_ErasedFn(m_Ptr, FWD(Args)...); + } + + explicit operator bool() const noexcept + { + return m_Ptr != nullptr; + } + +private: + using signature_type = return_type(const void*, args...); + + const void* m_Ptr; + signature_type* m_ErasedFn; +}; + +#endif // FUNCTION_REF_HPP_0B2E3AF4_AB0A_4C89_9FC1_1A92AC2699A4 diff --git a/far/common/multifunction.hpp b/far/common/multifunction.hpp index 70da1c90cb..91ba1ad82a 100644 --- a/far/common/multifunction.hpp +++ b/far/common/multifunction.hpp @@ -120,7 +120,7 @@ class multifunction { public: MOVABLE(multifunction); - COPY_AND_MOVE(multifunction, const multifunction&); + COPY_AND_MOVE(multifunction, const multifunction&) multifunction() = default; diff --git a/far/config.cpp b/far/config.cpp index 2764d7b13d..6e5e689c51 100644 --- a/far/config.cpp +++ b/far/config.cpp @@ -2862,11 +2862,12 @@ void Options::ShellOptions(bool LastCommand, const MOUSE_EVENT_RECORD *MouseEven HMenuData MainMenu[] { - { msg(lng::MMenuLeftTitle), L"LeftRightMenu"sv, LeftMenu, true }, - { msg(lng::MMenuFilesTitle), L"FilesMenu"sv, FilesMenu }, - { msg(lng::MMenuCommandsTitle), L"CmdMenu"sv, CmdMenu }, - { msg(lng::MMenuOptionsTitle), L"OptMenu"sv, OptionsMenu }, - { msg(lng::MMenuRightTitle), L"LeftRightMenu"sv, RightMenu }, + // TODO: remove make_range after dropping VS2015 + { msg(lng::MMenuLeftTitle), L"LeftRightMenu"sv, make_range(LeftMenu), true }, + { msg(lng::MMenuFilesTitle), L"FilesMenu"sv, make_range(FilesMenu) }, + { msg(lng::MMenuCommandsTitle), L"CmdMenu"sv, make_range(CmdMenu) }, + { msg(lng::MMenuOptionsTitle), L"OptMenu"sv, make_range(OptionsMenu) }, + { msg(lng::MMenuRightTitle), L"LeftRightMenu"sv, make_range(RightMenu) }, }; static int LastHItem=-1,LastVItem=0; int HItem,VItem; diff --git a/far/configdb.cpp b/far/configdb.cpp index 7837f0ffe2..b5eea1cc26 100644 --- a/far/configdb.cpp +++ b/far/configdb.cpp @@ -48,6 +48,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.fs.hpp" #include "common/bytes_view.hpp" +#include "common/function_ref.hpp" #include "common/scope_exit.hpp" #include "format.hpp" @@ -1750,7 +1751,7 @@ class HistoryConfigCustom: public HistoryConfig, public sqlite_boilerplate ExecuteStatement(stmtDel, id); } - unsigned long long GetPrevImpl(const unsigned int TypeHistory, const string_view HistoryName, const unsigned long long id, string& Name, const std::function& Fallback) const + unsigned long long GetPrevImpl(const unsigned int TypeHistory, const string_view HistoryName, const unsigned long long id, string& Name, function_ref const Fallback) const { WaitAllAsync(); Name.clear(); diff --git a/far/console.cpp b/far/console.cpp index 39aab42671..fa30cf6a57 100644 --- a/far/console.cpp +++ b/far/console.cpp @@ -407,6 +407,11 @@ namespace console_detail return Result; } + static bool ReadOutputImpl(CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& ReadRegion) + { + return ReadConsoleOutput(::console.GetOutputHandle(), Buffer, BufferSize, {}, &ReadRegion) != FALSE; + } + bool console::ReadOutput(matrix& Buffer, COORD BufferCoord, const SMALL_RECT& ReadRegionRelative) const { if (ExternalConsole.Imports.pReadOutput) @@ -427,11 +432,6 @@ namespace console_detail const COORD BufferSize{ static_cast(SubRect.width()), static_cast(SubRect.height()) }; - const auto& ReadOutput = [](CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& ReadRegion) - { - return ReadConsoleOutput(::console.GetOutputHandle(), Buffer, BufferSize, {}, &ReadRegion) != FALSE; - }; - if (BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO) > MAXSIZE) { const auto HeightStep = std::max(MAXSIZE / (BufferSize.X * sizeof(CHAR_INFO)), size_t(1)); @@ -444,14 +444,14 @@ namespace console_detail PartialReadRegion.Top += static_cast(i); PartialReadRegion.Bottom = std::min(ReadRegion.Bottom, static_cast(PartialReadRegion.Top + HeightStep - 1)); const COORD PartialBufferSize{ BufferSize.X, static_cast(PartialReadRegion.Bottom - PartialReadRegion.Top + 1) }; - if (!ReadOutput(ConsoleBuffer.data() + i * PartialBufferSize.X, PartialBufferSize, PartialReadRegion)) + if (!ReadOutputImpl(ConsoleBuffer.data() + i * PartialBufferSize.X, PartialBufferSize, PartialReadRegion)) return false; } } else { auto ReadRegionCopy = ReadRegion; - if (!ReadOutput(ConsoleBuffer.data(), BufferSize, ReadRegionCopy)) + if (!ReadOutputImpl(ConsoleBuffer.data(), BufferSize, ReadRegionCopy)) return false; } @@ -540,7 +540,7 @@ namespace console_detail class console::implementation { public: - static bool WriteVT(const matrix& Buffer, rectangle const SubRect, const SMALL_RECT& WriteRegion) + static bool WriteOutputVT(const matrix& Buffer, rectangle const SubRect, const SMALL_RECT& WriteRegion) { const auto Out = ::console.GetOutputHandle(); @@ -609,44 +609,44 @@ namespace console_detail return ::console.Write(Str); } - static bool WriteNT(const matrix& Buffer, rectangle const SubRect, const SMALL_RECT& WriteRegion) + static bool WriteOutputNTImpl(CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& WriteRegion) { - std::vector ConsoleBuffer; - ConsoleBuffer.reserve(SubRect.width() * SubRect.height()); + return WriteConsoleOutput(::console.GetOutputHandle(), Buffer, BufferSize, {}, &WriteRegion) != FALSE; + } - for_submatrix(Buffer, SubRect, [&](const FAR_CHAR_INFO& i) - { - ConsoleBuffer.emplace_back(CHAR_INFO{ ReplaceControlCharacter(i.Char), colors::FarColorToConsoleColor(i.Attributes) }); - }); + static bool WriteOutputNTImplDebug(CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& WriteRegion) + { +#if 0 + assert(BufferSize.X == WriteRegion.Right - WriteRegion.Left + 1); + assert(BufferSize.Y == WriteRegion.Bottom - WriteRegion.Top + 1); - const COORD BufferSize{ static_cast(SubRect.width()), static_cast(SubRect.height()) }; - const auto& WriteOutputImpl = [](CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& WriteRegion) + for (auto&i: make_span(Buffer, BufferSize.X * BufferSize.Y)) { - return WriteConsoleOutput(::console.GetOutputHandle(), Buffer, BufferSize, {}, &WriteRegion) != FALSE; - }; + i.Attributes = (i.Attributes & FCF_RAWATTR_MASK) | LOBYTE(~i.Attributes); + } - const auto& WriteOutput = [WriteOutputImpl](CHAR_INFO* const Buffer, COORD const BufferSize, SMALL_RECT& WriteRegion) - { -#if 0 - assert(BufferSize.X == WriteRegion.Right - WriteRegion.Left + 1); - assert(BufferSize.Y == WriteRegion.Bottom - WriteRegion.Top + 1); + auto WriteRegionCopy = WriteRegion; + WriteOutputNTImpl(Buffer, BufferSize, WriteRegionCopy); + Sleep(50); + for (auto&i: make_span(Buffer, BufferSize.X * BufferSize.Y)) + i.Attributes = (i.Attributes & FCF_RAWATTR_MASK) | LOBYTE(~i.Attributes); +#endif + return WriteOutputNTImpl(Buffer, BufferSize, WriteRegion) != FALSE; + } - for (auto&i : make_span(Buffer, BufferSize.X * BufferSize.Y)) - { - i.Attributes = (i.Attributes & FCF_RAWATTR_MASK) | LOBYTE(~i.Attributes); - } + static bool WriteOutputNT(const matrix& Buffer, rectangle const SubRect, const SMALL_RECT& WriteRegion) + { + std::vector ConsoleBuffer; + ConsoleBuffer.reserve(SubRect.width() * SubRect.height()); - auto WriteRegionCopy = WriteRegion; - WriteOutputImpl(Buffer, BufferSize, WriteRegionCopy); - Sleep(50); + for_submatrix(Buffer, SubRect, [&](const FAR_CHAR_INFO& i) + { + ConsoleBuffer.emplace_back(CHAR_INFO{ ReplaceControlCharacter(i.Char), colors::FarColorToConsoleColor(i.Attributes) }); + }); - for (auto&i : make_span(Buffer, BufferSize.X * BufferSize.Y)) - i.Attributes = (i.Attributes & FCF_RAWATTR_MASK) | LOBYTE(~i.Attributes); -#endif - return WriteOutputImpl(Buffer, BufferSize, WriteRegion) != FALSE; - }; + const COORD BufferSize{ static_cast(SubRect.width()), static_cast(SubRect.height()) }; if (BufferSize.X * BufferSize.Y * sizeof(CHAR_INFO) > MAXSIZE) { @@ -660,14 +660,14 @@ namespace console_detail PartialWriteRegion.Top += static_cast(i); PartialWriteRegion.Bottom = std::min(WriteRegion.Bottom, static_cast(PartialWriteRegion.Top + HeightStep - 1)); const COORD PartialBufferSize{ BufferSize.X, static_cast(PartialWriteRegion.Bottom - PartialWriteRegion.Top + 1) }; - if (!WriteOutput(ConsoleBuffer.data() + i * PartialBufferSize.X, PartialBufferSize, PartialWriteRegion)) + if (!WriteOutputNTImplDebug(ConsoleBuffer.data() + i * PartialBufferSize.X, PartialBufferSize, PartialWriteRegion)) return false; } } else { auto WriteRegionCopy = WriteRegion; - if (!WriteOutput(ConsoleBuffer.data(), BufferSize, WriteRegionCopy)) + if (!WriteOutputNTImplDebug(ConsoleBuffer.data(), BufferSize, WriteRegionCopy)) return false; } @@ -710,7 +710,7 @@ namespace console_detail DWORD Mode = 0; const auto IsVT = sEnableVirtualTerminal && GetMode(GetOutputHandle(), Mode) && Mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING; - return (IsVT? implementation::WriteVT : implementation::WriteNT)(Buffer, SubRect, WriteRegion); + return (IsVT? implementation::WriteOutputVT : implementation::WriteOutputNT)(Buffer, SubRect, WriteRegion); } bool console::Read(std::vector& Buffer, size_t& Size) const diff --git a/far/delete.cpp b/far/delete.cpp index 13b83f5639..faefa0a848 100644 --- a/far/delete.cpp +++ b/far/delete.cpp @@ -321,7 +321,7 @@ static bool WipeFile(const string& Name, ShellDelete::progress Files, bool& Canc const auto strTempName = MakeTemp({}, false); if (!os::fs::move_file(Name, strTempName)) - return false;; + return false; return os::fs::delete_file(strTempName); } @@ -781,7 +781,7 @@ ShellDelete::ShellDelete(panel_ptr SrcPanel, bool Wipe): if (MsgCode==DELETE_CANCEL) { - Cancel=true;; + Cancel=true; break; } else if (MsgCode==DELETE_SKIP) diff --git a/far/dialog.hpp b/far/dialog.hpp index 5081651653..570bf4a604 100644 --- a/far/dialog.hpp +++ b/far/dialog.hpp @@ -312,4 +312,7 @@ class Dialog: public Modal string m_ConsoleTitle; }; +// BUGBUG +extern std::chrono::steady_clock::duration WaitUserTime; + #endif // DIALOG_HPP_7A9BE12B_EE5C_441F_84C9_64E9A63ABEFE diff --git a/far/dirinfo.cpp b/far/dirinfo.cpp index ed75638db4..1f598e4dae 100644 --- a/far/dirinfo.cpp +++ b/far/dirinfo.cpp @@ -111,7 +111,7 @@ static void PR_DrawGetDirInfoMsg() }); } -int GetDirInfo(const string& DirName, DirInfoData& Data, FileFilter *Filter, const dirinfo_callback& Callback, DWORD Flags) +int GetDirInfo(const string& DirName, DirInfoData& Data, FileFilter *Filter, dirinfo_callback const Callback, DWORD Flags) { SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique()); SCOPED_ACTION(IndeterminateTaskbar)(false); @@ -312,7 +312,7 @@ static void PushPluginDirItem(std::vector& PluginDirList, const PluginDirList.emplace_back(NewItem); } -static void ScanPluginDir(plugin_panel* hDirListPlugin, OPERATION_MODES OpMode, const string& BaseDir, const string& PluginSearchPath, std::vector& PluginDirList, bool& StopSearch, BasicDirInfoData& Data, const dirinfo_callback& Callback) +static void ScanPluginDir(plugin_panel* hDirListPlugin, OPERATION_MODES OpMode, const string& BaseDir, const string& PluginSearchPath, std::vector& PluginDirList, bool& StopSearch, BasicDirInfoData& Data, dirinfo_callback const Callback) { Callback(BaseDir, Data.DirCount + Data.FileCount, Data.FileSize); @@ -369,7 +369,7 @@ static void ScanPluginDir(plugin_panel* hDirListPlugin, OPERATION_MODES OpMode, Global->CtrlObject->Plugins->FreeFindData(hDirListPlugin,PanelData,ItemCount,true); } -static bool GetPluginDirListImpl(Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* const UserData, std::vector& Items, BasicDirInfoData& Data, const dirinfo_callback& Callback) +static bool GetPluginDirListImpl(Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* const UserData, std::vector& Items, BasicDirInfoData& Data, dirinfo_callback const Callback) { Items.clear(); @@ -441,7 +441,7 @@ static bool GetPluginDirListImpl(Plugin* PluginNumber, HANDLE hPlugin, const str return !StopSearch; } -bool GetPluginDirList(Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* const UserData, std::vector& Items, const dirinfo_callback& Callback) +bool GetPluginDirList(Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* const UserData, std::vector& Items, dirinfo_callback const Callback) { BasicDirInfoData Data{}; return GetPluginDirListImpl(PluginNumber, hPlugin, Dir, UserData, Items, Data, Callback); @@ -459,8 +459,13 @@ void FreePluginDirList(HANDLE hPlugin, std::vector& Items) Items.clear(); } -bool GetPluginDirInfo(const plugin_panel* ph, const string& DirName, const UserDataItem* const UserData, - BasicDirInfoData& Data, const dirinfo_callback& Callback) +bool GetPluginDirInfo( + const plugin_panel* ph, + const string& DirName, + const UserDataItem* const UserData, + BasicDirInfoData& Data, + dirinfo_callback const Callback +) { Data = {}; diff --git a/far/dirinfo.hpp b/far/dirinfo.hpp index 72d5b6bee3..6fedb2a6db 100644 --- a/far/dirinfo.hpp +++ b/far/dirinfo.hpp @@ -35,6 +35,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "common/function_ref.hpp" + class FileFilter; struct PluginPanelItem; struct UserDataItem; @@ -69,15 +71,15 @@ enum getdirinfo_message_delay getdirinfo_default_delay = 500, // ms }; -using dirinfo_callback = std::function; -int GetDirInfo(const string& DirName, DirInfoData& Data, FileFilter *Filter, const dirinfo_callback& Callback, DWORD Flags = GETDIRINFO_SCANSYMLINKDEF); +using dirinfo_callback = function_ref; +int GetDirInfo(const string& DirName, DirInfoData& Data, FileFilter *Filter, dirinfo_callback Callback, DWORD Flags = GETDIRINFO_SCANSYMLINKDEF); void DirInfoMsg(string_view Title, string_view Name, unsigned long long Items, unsigned long long Size); class plugin_panel; -bool GetPluginDirInfo(const plugin_panel* hPlugin, const string& DirName, const UserDataItem* UserData, BasicDirInfoData& Data, const dirinfo_callback& Callback); +bool GetPluginDirInfo(const plugin_panel* hPlugin, const string& DirName, const UserDataItem* UserData, BasicDirInfoData& Data, dirinfo_callback Callback); -bool GetPluginDirList(class Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* UserData, std::vector& Items, const dirinfo_callback& Callback); +bool GetPluginDirList(class Plugin* PluginNumber, HANDLE hPlugin, const string& Dir, const UserDataItem* UserData, std::vector& Items, dirinfo_callback Callback); void FreePluginDirList(HANDLE hPlugin, std::vector& Items); #endif // DIRINFO_HPP_DA86BD11_D517_4EC9_8324_44EDF0CC7C9A diff --git a/far/disabled_warnings.hpp b/far/disabled_warnings.hpp index 0a9f6bf9f9..56958599fe 100644 --- a/far/disabled_warnings.hpp +++ b/far/disabled_warnings.hpp @@ -92,10 +92,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wcovered-switch-default" +#pragma clang diagnostic ignored "-Wdeprecated-this-capture" #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" #pragma clang diagnostic ignored "-Wenum-compare" #pragma clang diagnostic ignored "-Wexit-time-destructors" -#pragma clang diagnostic ignored "-Wextra-semi" #pragma clang diagnostic ignored "-Wglobal-constructors" #pragma clang diagnostic ignored "-Wgnu-anonymous-struct" #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" @@ -109,6 +109,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma clang diagnostic ignored "-Wnonportable-system-include-path" #pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wrange-loop-analysis" +#pragma clang diagnostic ignored "-Wreturn-std-move-in-c++11" #pragma clang diagnostic ignored "-Wreserved-id-macro" #pragma clang diagnostic ignored "-Wshadow-field-in-constructor" #pragma clang diagnostic ignored "-Wshadow-field" diff --git a/far/edit.cpp b/far/edit.cpp index b39b13e3fc..ef74deacd4 100644 --- a/far/edit.cpp +++ b/far/edit.cpp @@ -1364,7 +1364,7 @@ bool Edit::InsertKey(int Key) else { // Здесь вариант для "ввели символ из маски", например для SetAttr - ввели '.' - ;// char *Ptr=strchr(Mask+CurPos,Key); + // char *Ptr=strchr(Mask+CurPos,Key); } } else if (m_CurPos; + using delete_color_condition = function_ref; explicit Edit(window_ptr Owner); @@ -192,7 +194,7 @@ class Edit: public SimpleScreenObject bool ReplaceTabs(); void InsertTab(); void AddColor(const ColorItem& col); - void DeleteColor(const delete_color_condition& Condition); + void DeleteColor(delete_color_condition Condition); bool GetColor(ColorItem& col, size_t Item) const; void Xlat(bool All=false); void SetDialogParent(DWORD Sets); diff --git a/far/editor.cpp b/far/editor.cpp index 968c7bb622..b7e6096a12 100644 --- a/far/editor.cpp +++ b/far/editor.cpp @@ -4797,7 +4797,7 @@ bool Editor::IsFileModified() const // используется в FileEditor long long Editor::GetCurPos(bool file_pos, bool add_bom) const { - enum { Unknown = -1 }; + enum { UnknownMultiplier = -1 }; int Multiplier = 1; unsigned long long bom = 0; @@ -4811,13 +4811,13 @@ long long Editor::GetCurPos(bool file_pos, bool add_bom) const } else if (m_codepage == CP_UTF8) { - Multiplier = Unknown; + Multiplier = UnknownMultiplier; if (add_bom) bom = 3; } else if (GetCodePageInfo(m_codepage).first > 1) { - Multiplier = Unknown; + Multiplier = UnknownMultiplier; } } diff --git a/far/eject.cpp b/far/eject.cpp index 6cd17f6a42..b88374ee9b 100644 --- a/far/eject.cpp +++ b/far/eject.cpp @@ -171,7 +171,7 @@ bool EjectVolume(wchar_t Letter, unsigned long long Flags) { //printf("Media in Drive %c can be safely removed.\n",cDriveLetter); //if(Flags&EJECT_NOTIFY_AFTERREMOVE) - ; + //; } } // END: while(Retry) diff --git a/far/encoding.cpp b/far/encoding.cpp index be27361f8f..293e977ca7 100644 --- a/far/encoding.cpp +++ b/far/encoding.cpp @@ -98,7 +98,7 @@ class system_codepages_enumerator return TRUE; } - CATCH_AND_SAVE_EXCEPTION_TO(context->m_ExceptionPtr); + CATCH_AND_SAVE_EXCEPTION_TO(context->m_ExceptionPtr) return FALSE; } diff --git a/far/exception_handler_test.cpp b/far/exception_handler_test.cpp index 09f9c7bafa..a9ec7e3f9e 100644 --- a/far/exception_handler_test.cpp +++ b/far/exception_handler_test.cpp @@ -48,11 +48,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace tests { + [[noreturn]] static void cpp_far() { throw MAKE_FAR_EXCEPTION(L"Test far error"sv); } + [[noreturn]] static void cpp_std() { throw std::runtime_error("Test std error"s); @@ -60,15 +62,13 @@ namespace tests static void cpp_std_nested() { + std::exception_ptr Ptr; + try { - std::exception_ptr Ptr; - try - { - throw std::runtime_error("Test nested std error"s); - } - CATCH_AND_SAVE_EXCEPTION_TO(Ptr); - rethrow_if(Ptr); + throw std::runtime_error("Test nested std error"s); } + CATCH_AND_SAVE_EXCEPTION_TO(Ptr) + rethrow_if(Ptr); } static void cpp_std_nested_thread() @@ -80,7 +80,7 @@ namespace tests { throw std::runtime_error("Test nested std error (thread)"s); } - CATCH_AND_SAVE_EXCEPTION_TO(Ptr); + CATCH_AND_SAVE_EXCEPTION_TO(Ptr) }); rethrow_if(Ptr); @@ -92,6 +92,7 @@ namespace tests const auto Ptr = std::make_unique(std::numeric_limits::max() - 1024 * 1024); } + [[noreturn]] static void cpp_unknown() { throw 42u; @@ -104,7 +105,7 @@ namespace tests { throw 69u; } - CATCH_AND_SAVE_EXCEPTION_TO(Ptr); + CATCH_AND_SAVE_EXCEPTION_TO(Ptr) rethrow_if(Ptr); } diff --git a/far/execute.cpp b/far/execute.cpp index ac794c65fe..d58a4e3e04 100644 --- a/far/execute.cpp +++ b/far/execute.cpp @@ -725,7 +725,7 @@ static bool GetProtocolType(string_view const Str, image_type& ImageType) return false; } -void Execute(execute_info& Info, bool FolderRun, bool Silent, const std::function& ConsoleActivator) +void Execute(execute_info& Info, bool FolderRun, bool Silent, function_ref const ConsoleActivator) { bool Result = false; string strNewCmdStr; diff --git a/far/execute.hpp b/far/execute.hpp index b02c909ed5..8890198e56 100644 --- a/far/execute.hpp +++ b/far/execute.hpp @@ -35,11 +35,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "common/function_ref.hpp" + bool GetShellType(string_view Ext, string& strType, ASSOCIATIONTYPE aType = AT_FILEEXTENSION); void OpenFolderInShell(const string& Folder); -void Execute(struct execute_info& Info, bool FolderRun, bool Silent, const std::function& ConsoleActivator = nullptr); +void Execute(struct execute_info& Info, bool FolderRun, bool Silent, function_ref ConsoleActivator = nullptr); bool IsExecutable(string_view Filename); diff --git a/far/far.vcxproj b/far/far.vcxproj index 4a00c783d4..99ca117a63 100644 --- a/far/far.vcxproj +++ b/far/far.vcxproj @@ -361,6 +361,7 @@ cl /nologo /c /Fo"$(IntDir)%(Filename)_c++.testobj" /TP api_test.c + diff --git a/far/far.vcxproj.filters b/far/far.vcxproj.filters index 8e29fe46d4..a8113a123b 100644 --- a/far/far.vcxproj.filters +++ b/far/far.vcxproj.filters @@ -538,6 +538,9 @@ Header Files\common + + Header Files\common + Header Files\common diff --git a/far/fastfind.cpp b/far/fastfind.cpp index c8d6cef180..ad17ee6546 100644 --- a/far/fastfind.cpp +++ b/far/fastfind.cpp @@ -210,7 +210,7 @@ bool FastFind::ProcessKey(const Manager::Key& Key) { //Global->CtrlObject->Macro.DropProcess(); // ... то дропнем макропроцесс //Global->CtrlObject->Macro.PopState(); - ; + // ; } m_FindEdit->SetString(strLastName); diff --git a/far/fileattr.cpp b/far/fileattr.cpp index d6c4156009..b9aa1ceba1 100644 --- a/far/fileattr.cpp +++ b/far/fileattr.cpp @@ -338,7 +338,7 @@ int EDeleteReparsePoint(const string& Name, DWORD FileAttr, int SkipMode) return SETATTR_RET_OK; } -void enum_attributes(const std::function& Pred) +void enum_attributes(function_ref const Pred) { static const std::pair AttrMap[] = { diff --git a/far/fileattr.hpp b/far/fileattr.hpp index c4f58f8259..cb72598def 100644 --- a/far/fileattr.hpp +++ b/far/fileattr.hpp @@ -37,6 +37,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.chrono.hpp" +#include "common/function_ref.hpp" + enum SETATTR_RET_CODES { SETATTR_RET_ERROR, @@ -53,7 +55,7 @@ int ESetFileTime(const string& Name, const os::chrono::time_point* LastWriteTime int ESetFileOwner(const string& Name, const string& Owner,int SkipMode=-1); int EDeleteReparsePoint(const string& Name, DWORD FileAttr, int SkipMode=-1); -void enum_attributes(const std::function& Pred); +void enum_attributes(function_ref Pred); #endif // FILEATTR_HPP_1920BF1F_BD95_4A22_B3D9_33F2544760D1 diff --git a/far/fileedit.cpp b/far/fileedit.cpp index b9819d1d90..6fc6338fd8 100644 --- a/far/fileedit.cpp +++ b/far/fileedit.cpp @@ -844,7 +844,7 @@ bool FileEditor::ReProcessKey(const Manager::Key& Key, bool CalledFromControl) */ if ((LocalKey >= KEY_MACRO_BASE && LocalKey <= KEY_MACRO_ENDBASE) || (LocalKey>=KEY_OP_BASE && LocalKey <=KEY_OP_ENDBASE)) // исключаем MACRO { - ; // + // ; // } switch (LocalKey) diff --git a/far/filefilterparams.cpp b/far/filefilterparams.cpp index a4510a7fcd..ba4df0696c 100644 --- a/far/filefilterparams.cpp +++ b/far/filefilterparams.cpp @@ -259,7 +259,7 @@ bool FileFilterParams::FileInFilter(const PluginPanelItem& Object, os::chrono::t return FileInFilter(FilterObject, CurrentTime, nullptr); } -bool FileFilterParams::FileInFilter(const filter_file_object& Object, os::chrono::time_point CurrentTime, const std::function& HardlinkGetter) const +bool FileFilterParams::FileInFilter(const filter_file_object& Object, os::chrono::time_point CurrentTime, function_ref const HardlinkGetter) const { // Режим проверки атрибутов файла включен? if (FAttr.Used) diff --git a/far/filefilterparams.hpp b/far/filefilterparams.hpp index d5c9c164f3..7c36454282 100644 --- a/far/filefilterparams.hpp +++ b/far/filefilterparams.hpp @@ -41,6 +41,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.chrono.hpp" #include "platform.fwd.hpp" +#include "common/function_ref.hpp" + enum { DEFAULT_SORT_GROUP = 10000, @@ -149,7 +151,7 @@ class FileFilterParams private: - bool FileInFilter(struct filter_file_object const& Object, os::chrono::time_point CurrentTime, const std::function& HardlinkGetter) const; + bool FileInFilter(struct filter_file_object const& Object, os::chrono::time_point CurrentTime, function_ref HardlinkGetter) const; string m_strTitle; diff --git a/far/filelist.cpp b/far/filelist.cpp index 1d1d70c67e..f309f7f036 100644 --- a/far/filelist.cpp +++ b/far/filelist.cpp @@ -4959,7 +4959,7 @@ void FileList::CountDirSize(bool IsRealNames) } } - const auto& GetPluginDirInfoOrParent = [this, &Total](const plugin_panel* const ph, const string& DirName, const UserDataItem* const UserData, BasicDirInfoData& Data, const dirinfo_callback& Callback) + const auto& GetPluginDirInfoOrParent = [this, &Total](const plugin_panel* const ph, const string& DirName, const UserDataItem* const UserData, BasicDirInfoData& BasicData, const dirinfo_callback& Callback) { if (!m_CurFile && IsParentDirectory(m_ListData[0])) { @@ -4973,7 +4973,7 @@ void FileList::CountDirSize(bool IsRealNames) { if (i.Attributes & FILE_ATTRIBUTE_DIRECTORY) { - ++Data.DirCount; + ++BasicData.DirCount; if (!IsParentDirectory(i)) { @@ -4981,10 +4981,10 @@ void FileList::CountDirSize(bool IsRealNames) if (!GetPluginDirInfo(GetPluginHandle(), i.FileName, &i.UserData, SubData, ParentDirInfoCallback)) return false; - Data.FileCount += SubData.FileCount; - Data.DirCount += SubData.DirCount; - Data.FileSize += SubData.FileSize; - Data.AllocationSize += SubData.AllocationSize; + BasicData.FileCount += SubData.FileCount; + BasicData.DirCount += SubData.DirCount; + BasicData.FileSize += SubData.FileSize; + BasicData.AllocationSize += SubData.AllocationSize; Total.Items += SubData.DirCount + SubData.FileCount; Total.Size += SubData.FileSize; @@ -4992,9 +4992,9 @@ void FileList::CountDirSize(bool IsRealNames) } else { - ++Data.FileCount; - Data.FileSize += i.FileSize; - Data.AllocationSize += i.AllocationSize; + ++BasicData.FileCount; + BasicData.FileSize += i.FileSize; + BasicData.AllocationSize += i.AllocationSize; ++Total.Items; Total.Size += i.FileSize; @@ -5005,7 +5005,7 @@ void FileList::CountDirSize(bool IsRealNames) } else { - return GetPluginDirInfo(ph, DirName, UserData, Data, Callback); + return GetPluginDirInfo(ph, DirName, UserData, BasicData, Callback); } }; @@ -8607,7 +8607,7 @@ bool FileList::IsDizDisplayed() const return IsColumnDisplayed(DIZ_COLUMN); } -bool FileList::IsColumnDisplayed(std::function Compare) const +bool FileList::IsColumnDisplayed(function_ref const Compare) const { return std::any_of(ALL_CONST_RANGE(m_ViewSettings.PanelColumns), Compare) || std::any_of(ALL_CONST_RANGE(m_ViewSettings.StatusColumns), Compare); diff --git a/far/filelist.hpp b/far/filelist.hpp index 1a4e8bb0d6..f2fd4bc6ed 100644 --- a/far/filelist.hpp +++ b/far/filelist.hpp @@ -40,6 +40,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "filesystemwatcher.hpp" #include "plugin.hpp" +#include "common/function_ref.hpp" + class FileFilter; class Plugin; class plugin_item_list; @@ -284,7 +286,7 @@ class FileList:public Panel int ProcessOneHostFile(const FileListItem* Item); void HighlightBorder(int Level, int ListPos) const; void InitFSWatcher(bool CheckTree); - bool IsColumnDisplayed(std::function Compare) const; + bool IsColumnDisplayed(function_ref Compare) const; void UpdateHeight(); enum direction { diff --git a/far/filetype.cpp b/far/filetype.cpp index 3268ba0c3a..35c25afcf3 100644 --- a/far/filetype.cpp +++ b/far/filetype.cpp @@ -68,7 +68,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - Убрал непонятный мне запрет на использование маски файлов типа "*.*" (был когда-то, вроде, такой баг-репорт) */ -bool ProcessLocalFileTypes(string_view const Name, string_view const ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish, bool AddToHistory, bool RunAs, const std::function& Launcher) +bool ProcessLocalFileTypes(string_view const Name, string_view const ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish, bool AddToHistory, bool RunAs, function_ref const Launcher) { string strCommand, strDescription; diff --git a/far/filetype.hpp b/far/filetype.hpp index 0404078307..eb3001641b 100644 --- a/far/filetype.hpp +++ b/far/filetype.hpp @@ -35,6 +35,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "common/function_ref.hpp" + // Работа с ассоциациями файлов enum FILETYPE_MODE { @@ -54,7 +56,7 @@ enum FILETYPE_MODE */ bool GetFiletypeOpenMode(int keyPressed, FILETYPE_MODE& mode, bool& shouldForceInternal); -bool ProcessLocalFileTypes(string_view Name, string_view ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish, bool AddToHistory = true, bool RunAs = false, const std::function& Launcher = nullptr); +bool ProcessLocalFileTypes(string_view Name, string_view ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish, bool AddToHistory = true, bool RunAs = false, function_ref Launcher = nullptr); void ProcessExternal(const string& Command, const string& Name, const string& ShortName, bool AlwaysWaitFinish); void EditFileTypes(); diff --git a/far/fnparce.cpp b/far/fnparce.cpp index 040faf15cd..063c1ee25b 100644 --- a/far/fnparce.cpp +++ b/far/fnparce.cpp @@ -269,17 +269,17 @@ static size_t SkipInputToken(string_view const Str, subst_strings* const Strings static string_view ProcessMetasymbol(string_view const CurStr, subst_data& SubstData, string& Out) { - const auto& append_with_escape = [EscapeAmpersands = SubstData.EscapeAmpersands](string& Out, string_view const Str) + const auto& append_with_escape = [EscapeAmpersands = SubstData.EscapeAmpersands](string& Destination, string_view const Str) { if (EscapeAmpersands && contains(Str, L"&"sv)) { string Escaped(Str); replace(Escaped, L"&"sv, L"&&"sv); - append(Out, Escaped); + append(Destination, Escaped); } else { - append(Out, Str); + append(Destination, Str); } }; diff --git a/far/headers.hpp b/far/headers.hpp index 15c15e21eb..db97200cd8 100644 --- a/far/headers.hpp +++ b/far/headers.hpp @@ -195,9 +195,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using string = std::wstring; using string_view = std::wstring_view; +WARNING_PUSH() +WARNING_DISABLE_CLANG("-Wheader-hygiene") using namespace std::string_literals; using namespace std::string_view_literals; using namespace std::chrono_literals; +WARNING_POP() #include "common.hpp" diff --git a/far/hmenu.hpp b/far/hmenu.hpp index e2b55db1ec..dff7a18ea6 100644 --- a/far/hmenu.hpp +++ b/far/hmenu.hpp @@ -45,7 +45,7 @@ struct HMenuData { string_view Name; string_view SubMenuHelp; - span SubMenu; + range SubMenu; bool Selected; int XPos; }; diff --git a/far/infolist.cpp b/far/infolist.cpp index eac655c9e0..b0cbc4cc2c 100644 --- a/far/infolist.cpp +++ b/far/infolist.cpp @@ -569,7 +569,7 @@ void InfoList::DisplayObject() { if (ShowPluginDescription(CurY)) { - ; + // ; } } } diff --git a/far/interf.cpp b/far/interf.cpp index ea8dccc7d7..551bf7c7b2 100644 --- a/far/interf.cpp +++ b/far/interf.cpp @@ -54,6 +54,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.concurrency.hpp" #include "platform.security.hpp" +#include "common/function_ref.hpp" + #include "format.hpp" static HICON load_icon(int IconId, bool Big) @@ -758,7 +760,7 @@ void VText(string_view const Str) } } -static void HiTextBase(const string& Str, const std::function& TextHandler, const std::function& HilightHandler) +static void HiTextBase(const string& Str, function_ref const TextHandler, function_ref const HilightHandler) { const auto AmpBegin = Str.find(L'&'); if (AmpBegin != string::npos) diff --git a/far/keyboard.cpp b/far/keyboard.cpp index df886ba95b..e0de19c713 100644 --- a/far/keyboard.cpp +++ b/far/keyboard.cpp @@ -486,7 +486,7 @@ DWORD IsMouseButtonPressed() return IntKeyState.MouseButtonState; } -bool while_mouse_button_pressed(const std::function& Action) +bool while_mouse_button_pressed(function_ref const Action) { DWORD RepeatSpeed; if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &RepeatSpeed, 0)) diff --git a/far/keyboard.hpp b/far/keyboard.hpp index 33ac57ac85..aeb5af5813 100644 --- a/far/keyboard.hpp +++ b/far/keyboard.hpp @@ -36,6 +36,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "common/2d/point.hpp" +#include "common/function_ref.hpp" struct FarKey; @@ -94,7 +95,7 @@ int KeyToKeyLayout(int Key); // возвращает: 1 - LeftPressed, 2 - Right Pressed, 3 - Middle Pressed, 0 - none DWORD IsMouseButtonPressed(); -bool while_mouse_button_pressed(const std::function& Action); +bool while_mouse_button_pressed(function_ref Action); int TranslateKeyToVK(int Key,int &VirtKey,int &ControlState,INPUT_RECORD *rec=nullptr); int KeyNameToKey(string_view Name); bool InputRecordToText(const INPUT_RECORD *Rec, string &strKeyText); diff --git a/far/main.cpp b/far/main.cpp index f26989a781..5b9cfdb921 100644 --- a/far/main.cpp +++ b/far/main.cpp @@ -551,7 +551,7 @@ static int mainImpl(range const Args) const wchar_t *ChPtr = wcschr(Arg + 2, L':'); if (ChPtr) - StartChar = static_cast(std::wcstol(ChPtr + 1, nullptr, 10));; + StartChar = static_cast(std::wcstol(ChPtr + 1, nullptr, 10)); } if (Iter + 1 != Args.end()) diff --git a/far/makefile_vc b/far/makefile_vc index be51cb5f11..ab908da3e0 100644 --- a/far/makefile_vc +++ b/far/makefile_vc @@ -288,6 +288,23 @@ LINKFLAGS=/nologo /subsystem:console /release /nxcompat /largeaddressaware /dyna ULINKFLAGS=-q -m- -ap -Gz -O- -o- -Gh -Gh- -GF:LARGEADDRESSAWARE -d*kernel32 RFLAGS=/nologo /l 0x409 /fo"$(RES_FILE)" /d $(USEDEBUG) +# compiler-specific +!if "$(VC)">="15" +CPPFLAGS=$(CPPFLAGS) /permissive- /Zc:__cplusplus,externConstexpr /diagnostics:caret +!endif + +!ifdef CLANG +CPP = clang-cl +CPPFLAGS = $(CPPFLAGS) -Qunused-arguments -Xclang -fno-char8_t +NOBATCH=1 +NO_RELEASE_LTCG=1 +OUTDIR=$(OUTDIR).clang +!elseifdef ICL +CPP = icl +LINK = xilink +CPPFLAGS = $(CPPFLAGS) /Qstd=c++11 /Qdiag-disable:672,869,2415,3280 +!endif + # config-specific !ifdef DEBUG CPPFLAGS=$(CPPFLAGS) /MTd /Od /ZI @@ -341,17 +358,6 @@ OS_VERSION=5.2 LINKFLAGS=$(LINKFLAGS) /machine:ARM !endif -# compiler-specific -!if "$(VC)">="15" -CPPFLAGS=$(CPPFLAGS) /permissive- /Zc:__cplusplus,externConstexpr /diagnostics:caret -!endif - -!ifdef ICL -CPP = icl -LINK = xilink -CPPFLAGS = $(CPPFLAGS) /Qstd=c++11 /Qdiag-disable:672,869,2415,3280 -!endif - CPPFLAGS = $(CPPFLAGS) /Fo"$(INTDIR)\\" ALL: AllDirs lng depfile include docs $(TEST_OBJS) @@ -434,12 +440,22 @@ $(INTDIR)\vc_crt_fix_impl.obj: vc_crt_fix_impl.cpp $(INTDIR)\vc_crt_fix_ulink.obj: vc_crt_fix_ulink.cpp $(CPP) $(CPPFLAGS) vc_crt_fix_ulink.cpp +!ifdef NOBATCH +.c{$(INTDIR)}.obj: + @echo $(@F) +!else .c{$(INTDIR)}.obj:: +!endif $(CPP) @<< $(CPPFLAGS) $< << +!ifdef NOBATCH +.cpp{$(INTDIR)}.obj: + @echo $(@F) +!else .cpp{$(INTDIR)}.obj:: +!endif $(CPP) @<< $(CPPFLAGS) /Yuheaders.hpp /Fp"$(PCH_FILE)" /FI headers.hpp /FI memcheck.hpp $< << diff --git a/far/manager.cpp b/far/manager.cpp index 29391992cb..fbee483db6 100644 --- a/far/manager.cpp +++ b/far/manager.cpp @@ -242,7 +242,7 @@ bool Manager::ExitAll() void Manager::RefreshAll() { - m_Queue.emplace([=]{ RefreshAllCommit(); }); + m_Queue.emplace([this]{ RefreshAllCommit(); }); } void Manager::CloseAll() @@ -1228,14 +1228,13 @@ Manager::sorted_windows Manager::GetSortedWindows() const return sorted_windows(m_windows.cbegin(),m_windows.cbegin() + m_NonModalSize); } -void* Manager::GetCurrent(const std::function& Check) const +void* Manager::GetCurrent(function_ref const Check) const { - const auto iterator = std::find_if(CONST_REVERSE_RANGE(m_windows, i) { return !std::dynamic_pointer_cast(i) || GetCurrentWindow()->GetCanLoseFocus(); }); - if (iterator!=m_windows.crend()) - { - return Check(iterator); - } - return nullptr; + const auto Iterator = std::find_if(CONST_REVERSE_RANGE(m_windows, i) { return !std::dynamic_pointer_cast(i) || GetCurrentWindow()->GetCanLoseFocus(); }); + if (Iterator==m_windows.crend()) + return nullptr; + + return Check(*Iterator); } desktop* Manager::Desktop() const @@ -1245,19 +1244,17 @@ desktop* Manager::Desktop() const Viewer* Manager::GetCurrentViewer() const { - return reinterpret_cast(GetCurrent([](windows::const_reverse_iterator Iterator) + return static_cast(GetCurrent([](window_ptr const& Window) { - const auto result = std::dynamic_pointer_cast(*Iterator); - return result?result->GetViewer():nullptr; - } - )); + const auto Result = std::dynamic_pointer_cast(Window); + return Result? Result->GetViewer() : nullptr; + })); } FileEditor* Manager::GetCurrentEditor() const { - return reinterpret_cast(GetCurrent([](windows::const_reverse_iterator Iterator) + return static_cast(GetCurrent([](window_ptr const& Window) { - return std::dynamic_pointer_cast(*Iterator).get(); - } - )); + return std::dynamic_pointer_cast(Window).get(); + })); } diff --git a/far/manager.hpp b/far/manager.hpp index 758b89369e..0319f1266d 100644 --- a/far/manager.hpp +++ b/far/manager.hpp @@ -35,10 +35,12 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -class Viewer; - #include "windowsfwd.hpp" +#include "common/function_ref.hpp" + +class Viewer; + class Manager: noncopyable { public: @@ -180,7 +182,7 @@ class Manager: noncopyable void WindowsChanged() { std::fill(m_windows_changed.begin(), m_windows_changed.end(), true); } using windows = std::vector; - void* GetCurrent(const std::function& Check) const; + void* GetCurrent(function_ref Check) const; windows m_windows; size_t m_NonModalSize; bool EndLoop; // Признак выхода из цикла diff --git a/far/panel.hpp b/far/panel.hpp index fe2ccdb9a4..c4df216aef 100644 --- a/far/panel.hpp +++ b/far/panel.hpp @@ -342,7 +342,7 @@ class dummy_panel : public Panel } private: - void Update(int Mode) override {}; + void Update(int Mode) override {} void UpdateKeyBar() override {} }; diff --git a/far/pathmix.cpp b/far/pathmix.cpp index 95dedf4296..b1df2a642a 100644 --- a/far/pathmix.cpp +++ b/far/pathmix.cpp @@ -82,7 +82,7 @@ string KernelPath(string&& NtPath) { NtPath[1] = L'?'; } - return NtPath; + return std::move(NtPath); } diff --git a/far/platform.concurrency.cpp b/far/platform.concurrency.cpp index 5b0f4526cf..63db0f46d7 100644 --- a/far/platform.concurrency.cpp +++ b/far/platform.concurrency.cpp @@ -137,7 +137,7 @@ namespace os::concurrency NONCOPYABLE(shared_mutex_legacy); shared_mutex_legacy() { imports.RtlInitializeResource(&m_Lock); m_Lock.Flags |= RTL_RESOURCE_FLAG_LONG_TERM; } - ~shared_mutex_legacy() { imports.RtlDeleteResource(&m_Lock); } + ~shared_mutex_legacy() override { imports.RtlDeleteResource(&m_Lock); } void lock() override { imports.RtlAcquireResourceExclusive(&m_Lock, TRUE); } bool try_lock() override { return imports.RtlAcquireResourceExclusive(&m_Lock, FALSE) != FALSE; } diff --git a/far/platform.fs.cpp b/far/platform.fs.cpp index 0ff7cf804c..da63d41170 100644 --- a/far/platform.fs.cpp +++ b/far/platform.fs.cpp @@ -177,7 +177,7 @@ namespace os::fs { DeleteEndSlash(PreparedObject); } - return PreparedObject; + return std::move(PreparedObject); } enum_files::enum_files(const string_view Object, const bool ScanSymlink): diff --git a/far/plugsettings.cpp b/far/plugsettings.cpp index 8032e3b235..cc5d9c04d9 100644 --- a/far/plugsettings.cpp +++ b/far/plugsettings.cpp @@ -44,6 +44,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "global.hpp" #include "common/bytes_view.hpp" +#include "common/function_ref.hpp" const wchar_t* AbstractSettings::Add(const string& String) { @@ -245,7 +246,7 @@ class FarSettings: public AbstractSettings class FarSettingsHistoryItems; private: - bool FillHistory(int Type, const string& HistoryName, FarSettingsEnum& Enum, const std::function& Filter); + bool FillHistory(int Type, const string& HistoryName, FarSettingsEnum& Enum, function_ref Filter); std::vector m_Enum; std::vector m_Keys; }; @@ -455,7 +456,7 @@ static const auto& HistoryRef(int Type) return IsSave()? ConfigProvider().HistoryCfg() : ConfigProvider().HistoryCfgMem(); } -bool FarSettings::FillHistory(int Type,const string& HistoryName,FarSettingsEnum& Enum, const std::function& Filter) +bool FarSettings::FillHistory(int Type,const string& HistoryName,FarSettingsEnum& Enum, function_ref const Filter) { FarSettingsHistory item = {}; FarSettingsHistoryItems NewEnumItem; diff --git a/far/scrobj.hpp b/far/scrobj.hpp index 2f387e710f..6d1655331f 100644 --- a/far/scrobj.hpp +++ b/far/scrobj.hpp @@ -55,6 +55,8 @@ class SimpleScreenObject { public: NONCOPYABLE(SimpleScreenObject); + MOVABLE(SimpleScreenObject); + virtual ~SimpleScreenObject() = default; virtual bool ProcessKey(const Manager::Key& Key) { return false; } diff --git a/far/scrsaver.cpp b/far/scrsaver.cpp index 2567f59ac8..2debb86593 100644 --- a/far/scrsaver.cpp +++ b/far/scrsaver.cpp @@ -44,6 +44,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.chrono.hpp" +#include "common/function_ref.hpp" + enum {STAR_NONE,STAR_NORMAL,STAR_PLANET}; struct star @@ -66,7 +68,7 @@ static const wchar_t StarSymbol[]= L'\x00B7', }; -static void ShowSaver(int Step, const std::function& Fill) +static void ShowSaver(int Step, function_ref const Fill) { std::for_each(RANGE(Star, i) { diff --git a/far/setattr.cpp b/far/setattr.cpp index eb26bd2b22..17a821f97f 100644 --- a/far/setattr.cpp +++ b/far/setattr.cpp @@ -947,7 +947,7 @@ bool ShellSetFileAttributes(Panel *SrcPanel, const string* Object) Item.Flags = ((Storage.State & DFS_STORAGE_STATE_ACTIVE)? (LIF_CHECKED | LIF_SELECTED) : LIF_NONE) | ((Storage.State & DFS_STORAGE_STATE_OFFLINE)? LIF_GRAYED : LIF_NONE); - }; + } NameList.Items = ListItems.data(); NameList.ItemsNumber = DfsInfo->NumberOfStorages; diff --git a/far/setcolor.cpp b/far/setcolor.cpp index a05ff864c4..cd0e972d68 100644 --- a/far/setcolor.cpp +++ b/far/setcolor.cpp @@ -521,7 +521,6 @@ static intptr_t GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Param1, void else return FALSE; } - break; case DN_BTNCLICK: { diff --git a/far/stddlg.cpp b/far/stddlg.cpp index ed6c845742..7f3390a290 100644 --- a/far/stddlg.cpp +++ b/far/stddlg.cpp @@ -52,6 +52,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.fs.hpp" +#include "common/function_ref.hpp" #include "common/function_traits.hpp" #include "common/scope_exit.hpp" @@ -73,7 +74,7 @@ int GetSearchReplaceString( const wchar_t *HelpTopic, bool HideAll, const GUID* Id, - const std::function& Picker) + function_ref const Picker) { int Result = 0; @@ -457,7 +458,7 @@ static os::com::ptr CreateIFileIsInUse(const string& File) } } -static size_t enumerate_rm_processes(const string& Filename, DWORD& Reasons, const std::function& Handler) +static size_t enumerate_rm_processes(const string& Filename, DWORD& Reasons, function_ref const Handler) { DWORD Session; WCHAR SessionKey[CCH_RM_SESSION_KEY + 1] = {}; diff --git a/far/stddlg.hpp b/far/stddlg.hpp index 4538d1e81d..b9f054bb61 100644 --- a/far/stddlg.hpp +++ b/far/stddlg.hpp @@ -35,6 +35,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "common/function_ref.hpp" + enum class lng : int; class RegExp; struct error_state_ex; @@ -102,22 +104,22 @@ struct error_state_ex; */ int GetSearchReplaceString( - bool IsReplaceMode, - const wchar_t *Title, - const wchar_t *SubTitle, - string& SearchStr, - string& ReplaceStr, - const wchar_t *TextHistoryName, - const wchar_t *ReplaceHistoryName, - bool* Case, - bool* WholeWords, - bool* Reverse, - bool* Regexp, - bool* PreserveStyle, - const wchar_t *HelpTopic=nullptr, - bool HideAll=false, - const GUID* Id = nullptr, - const std::function& Picker = nullptr + bool IsReplaceMode, + const wchar_t *Title, + const wchar_t *SubTitle, + string& SearchStr, + string& ReplaceStr, + const wchar_t *TextHistoryName, + const wchar_t *ReplaceHistoryName, + bool* Case, + bool* WholeWords, + bool* Reverse, + bool* Regexp, + bool* PreserveStyle, + const wchar_t *HelpTopic=nullptr, + bool HideAll=false, + const GUID* Id = nullptr, + function_ref Picker = nullptr ); bool GetString( diff --git a/far/strmix.cpp b/far/strmix.cpp index 5d0f8fd3af..56cc150073 100644 --- a/far/strmix.cpp +++ b/far/strmix.cpp @@ -399,14 +399,14 @@ string FileSizeToStr(unsigned long long FileSize, int WidthWithSign, unsigned lo const auto& FitToWidth = [&](string&& Str) { if (!Width) - return Str; + return std::move(Str); if (Str.size() <= Width) return (LeftAlign? inplace::pad_right : inplace::pad_left)(Str, Width, L' '); Str = (LeftAlign? inplace::cut_right : inplace::cut_left)(Str, Width - 1); Str.insert(LeftAlign? Str.end() : Str.begin(), L'\x2026'); - return Str; + return std::move(Str); }; if (!UnitIndex && !ShowUnit) diff --git a/far/strmix.hpp b/far/strmix.hpp index 30f4b63258..70347c2ac9 100644 --- a/far/strmix.hpp +++ b/far/strmix.hpp @@ -56,7 +56,7 @@ string InsertRegexpQuote(string strStr); string& RemoveUnprintableCharacters(string &strStr); string& QuoteSpaceOnly(string &strStr); string& QuoteOuterSpace(string &strStr); -inline string QuoteOuterSpace(string&& strStr) { QuoteOuterSpace(strStr); return strStr; } +inline string QuoteOuterSpace(string&& strStr) { QuoteOuterSpace(strStr); return std::move(strStr); } bool ReplaceStrings(string& strStr, string_view FindStr, string_view ReplStr, bool IgnoreCase = false, size_t Count = string::npos); diff --git a/far/thirdparty/fmt/fmt/core.h b/far/thirdparty/fmt/fmt/core.h index 36816d461c..33830eefae 100644 --- a/far/thirdparty/fmt/fmt/core.h +++ b/far/thirdparty/fmt/fmt/core.h @@ -112,11 +112,13 @@ #endif // Check if exceptions are disabled. -#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ - FMT_MSC_VER && !_HAS_EXCEPTIONS -# define FMT_EXCEPTIONS 0 -#else -# define FMT_EXCEPTIONS 1 +#ifndef FMT_EXCEPTIONS +# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ + FMT_MSC_VER && !_HAS_EXCEPTIONS +# define FMT_EXCEPTIONS 0 +# else +# define FMT_EXCEPTIONS 1 +# endif #endif // Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). @@ -765,6 +767,7 @@ FMT_CONSTEXPR11 typename std::enable_if< // Maximum number of arguments with packed types. enum { max_packed_args = 15 }; +enum : unsigned long long { is_unpacked_bit = 1ull << 63 }; template class arg_map; @@ -918,6 +921,10 @@ class basic_parse_context : private ErrorHandler { FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; } }; +typedef basic_parse_context format_parse_context; +typedef basic_parse_context wformat_parse_context; + +// DEPRECATED! typedef basic_parse_context parse_context; typedef basic_parse_context wparse_context; @@ -1013,7 +1020,8 @@ class context_base { public: basic_parse_context &parse_context() { return parse_context_; } - basic_format_args args() const { return args_; } + basic_format_args args() const { return args_; } // DEPRECATED! + basic_format_arg arg(unsigned id) const { return args_.get(id); } internal::error_handler error_handler() { return parse_context_.error_handler(); @@ -1145,17 +1153,17 @@ class format_arg_store { friend class basic_format_args; - static FMT_CONSTEXPR11 long long get_types() { + static FMT_CONSTEXPR11 unsigned long long get_types() { return IS_PACKED ? - static_cast(internal::get_types()) : - -static_cast(NUM_ARGS); + internal::get_types() : + internal::is_unpacked_bit | NUM_ARGS; } public: #if FMT_USE_CONSTEXPR11 - static FMT_CONSTEXPR11 long long TYPES = get_types(); + static FMT_CONSTEXPR11 unsigned long long TYPES = get_types(); #else - static const long long TYPES; + static const unsigned long long TYPES; #endif #if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \ @@ -1174,7 +1182,8 @@ class format_arg_store { #if !FMT_USE_CONSTEXPR11 template -const long long format_arg_store::TYPES = get_types(); +const unsigned long long format_arg_store::TYPES = + get_types(); #endif /** @@ -1209,11 +1218,12 @@ class basic_format_args { const format_arg *args_; }; + bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } + typename internal::type type(unsigned index) const { unsigned shift = index * 4; - unsigned long long mask = 0xf; return static_cast( - (types_ & (mask << shift)) >> shift); + (types_ & (0xfull << shift)) >> shift); } friend class internal::arg_map; @@ -1223,10 +1233,8 @@ class basic_format_args { format_arg do_get(size_type index) const { format_arg arg; - long long signed_types = static_cast(types_); - if (signed_types < 0) { - unsigned long long num_args = - static_cast(-signed_types); + if (!is_packed()) { + auto num_args = max_size(); if (index < num_args) arg = args_[index]; return arg; @@ -1261,7 +1269,7 @@ class basic_format_args { \endrst */ basic_format_args(const format_arg *args, size_type count) - : types_(-static_cast(count)) { + : types_(internal::is_unpacked_bit | count) { set_data(args); } @@ -1273,11 +1281,10 @@ class basic_format_args { return arg; } - unsigned max_size() const { - long long signed_types = static_cast(types_); - return static_cast( - signed_types < 0 ? - -signed_types : static_cast(internal::max_packed_args)); + size_type max_size() const { + unsigned long long max_packed = internal::max_packed_args; + return static_cast( + is_packed() ? max_packed : types_ & ~internal::is_unpacked_bit); } }; @@ -1294,28 +1301,22 @@ struct wformat_args : basic_format_args { : basic_format_args(std::forward(arg)...) {} }; +#define FMT_ENABLE_IF_T(B, T) typename std::enable_if::type + #ifndef FMT_USE_ALIAS_TEMPLATES # define FMT_USE_ALIAS_TEMPLATES FMT_HAS_FEATURE(cxx_alias_templates) #endif #if FMT_USE_ALIAS_TEMPLATES /** String's character type. */ template -using char_t = typename std::enable_if::value, - typename internal::char_t::type>::type; +using char_t = FMT_ENABLE_IF_T( + internal::is_string::value, typename internal::char_t::type); #define FMT_CHAR(S) fmt::char_t - -template -using enable_if_string_t = - typename std::enable_if::value, T>::type; -#define FMT_ENABLE_IF_STRING(S, T) enable_if_string_t #else template struct char_t : std::enable_if< internal::is_string::value, typename internal::char_t::type> {}; #define FMT_CHAR(S) typename char_t::type - -#define FMT_ENABLE_IF_STRING(S, T) \ - typename std::enable_if::value, T>::type #endif namespace internal { @@ -1471,7 +1472,7 @@ FMT_API void vprint(std::FILE *f, wstring_view format_str, wformat_args args); \endrst */ template -inline FMT_ENABLE_IF_STRING(S, void) +inline FMT_ENABLE_IF_T(internal::is_string::value, void) print(std::FILE *f, const S &format_str, const Args &... args) { vprint(f, to_string_view(format_str), internal::checked_args(format_str, args...)); @@ -1490,7 +1491,7 @@ FMT_API void vprint(wstring_view format_str, wformat_args args); \endrst */ template -inline FMT_ENABLE_IF_STRING(S, void) +inline FMT_ENABLE_IF_T(internal::is_string::value, void) print(const S &format_str, const Args &... args) { vprint(to_string_view(format_str), internal::checked_args(format_str, args...)); diff --git a/far/thirdparty/fmt/fmt/format-inl.h b/far/thirdparty/fmt/fmt/format-inl.h index 513834f6b8..552c943033 100644 --- a/far/thirdparty/fmt/fmt/format-inl.h +++ b/far/thirdparty/fmt/fmt/format-inl.h @@ -136,12 +136,14 @@ int safe_strerror( ERANGE : result; } +#if !FMT_MSC_VER // Fallback to strerror if strerror_r and strerror_s are not available. int fallback(internal::null<>) { errno = 0; buffer_ = strerror(error_code_); return errno; } +#endif public: dispatcher(int err_code, char *&buf, std::size_t buf_size) @@ -170,7 +172,7 @@ void format_error_code(internal::buffer &out, int error_code, abs_value = 0 - abs_value; ++error_code_size; } - error_code_size += internal::count_digits(abs_value); + error_code_size += internal::to_unsigned(internal::count_digits(abs_value)); writer w(out); if (message.size() <= inline_buffer_size - error_code_size) { w.write(message); @@ -224,7 +226,7 @@ FMT_FUNC Char thousands_sep_impl(locale_ref loc) { } #else template -FMT_FUNC Char internal::thousands_sep(locale_ref) { +FMT_FUNC Char internal::thousands_sep_impl(locale_ref) { return FMT_STATIC_THOUSANDS_SEPARATOR; } #endif @@ -241,19 +243,19 @@ FMT_FUNC void system_error::init( namespace internal { template int char_traits::format_float( - char *buffer, std::size_t size, const char *format, int precision, T value) { + char *buf, std::size_t size, const char *format, int precision, T value) { return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, value) : - FMT_SNPRINTF(buffer, size, format, precision, value); + FMT_SNPRINTF(buf, size, format, value) : + FMT_SNPRINTF(buf, size, format, precision, value); } template int char_traits::format_float( - wchar_t *buffer, std::size_t size, const wchar_t *format, int precision, + wchar_t *buf, std::size_t size, const wchar_t *format, int precision, T value) { return precision < 0 ? - FMT_SWPRINTF(buffer, size, format, value) : - FMT_SWPRINTF(buffer, size, format, precision, value); + FMT_SWPRINTF(buf, size, format, value) : + FMT_SWPRINTF(buf, size, format, precision, value); } template @@ -370,7 +372,7 @@ class fp { sizeof(significand_type) * char_size; fp(): f(0), e(0) {} - fp(uint64_t f, int e): f(f), e(e) {} + fp(uint64_t f_val, int e_val): f(f_val), e(e_val) {} // Constructs fp from an IEEE754 double. It is a template to prevent compile // errors on platforms where double is not IEEE754. @@ -462,17 +464,17 @@ FMT_FUNC fp get_cached_power(int min_exponent, int &pow10_exponent) { } FMT_FUNC bool grisu2_round( - char *buffer, size_t &size, size_t max_digits, uint64_t delta, + char *buf, int &size, int max_digits, uint64_t delta, uint64_t remainder, uint64_t exp, uint64_t diff, int &exp10) { while (remainder < diff && delta - remainder >= exp && (remainder + exp < diff || diff - remainder > remainder + exp - diff)) { - --buffer[size - 1]; + --buf[size - 1]; remainder += exp; } if (size > max_digits) { --size; ++exp10; - if (buffer[size] >= '5') + if (buf[size] >= '5') return false; } return true; @@ -480,8 +482,8 @@ FMT_FUNC bool grisu2_round( // Generates output using Grisu2 digit-gen algorithm. FMT_FUNC bool grisu2_gen_digits( - char *buffer, size_t &size, uint32_t hi, uint64_t lo, int &exp, - uint64_t delta, const fp &one, const fp &diff, size_t max_digits) { + char *buf, int &size, uint32_t hi, uint64_t lo, int &exp, + uint64_t delta, const fp &one, const fp &diff, int max_digits) { // Generate digits for the most significant part (hi). while (exp > 0) { uint32_t digit = 0; @@ -502,12 +504,12 @@ FMT_FUNC bool grisu2_gen_digits( FMT_ASSERT(false, "invalid number of digits"); } if (digit != 0 || size != 0) - buffer[size++] = static_cast('0' + digit); + buf[size++] = static_cast('0' + digit); --exp; uint64_t remainder = (static_cast(hi) << -one.e) + lo; if (remainder <= delta || size > max_digits) { return grisu2_round( - buffer, size, max_digits, delta, remainder, + buf, size, max_digits, delta, remainder, static_cast(data::POWERS_OF_10_32[exp]) << -one.e, diff.f, exp); } @@ -518,11 +520,11 @@ FMT_FUNC bool grisu2_gen_digits( delta *= 10; char digit = static_cast(lo >> -one.e); if (digit != 0 || size != 0) - buffer[size++] = static_cast('0' + digit); + buf[size++] = static_cast('0' + digit); lo &= one.f - 1; --exp; if (lo < delta || size > max_digits) { - return grisu2_round(buffer, size, max_digits, delta, lo, one.f, + return grisu2_round(buf, size, max_digits, delta, lo, one.f, diff.f * data::POWERS_OF_10_32[-exp], exp); } } @@ -537,7 +539,7 @@ FMT_FUNC bool grisu2_gen_digits( #endif struct gen_digits_params { - unsigned num_digits; + int num_digits; bool fixed; bool upper; bool trailing_zeros; @@ -545,30 +547,30 @@ struct gen_digits_params { struct prettify_handler { char *data; - size_t size; + ptrdiff_t size; buffer &buf; - explicit prettify_handler(buffer &b, size_t n) + explicit prettify_handler(buffer &b, ptrdiff_t n) : data(b.data()), size(n), buf(b) {} ~prettify_handler() { - assert(buf.size() >= size); - buf.resize(size); + assert(buf.size() >= to_unsigned(size)); + buf.resize(to_unsigned(size)); } template - void insert(size_t pos, size_t n, F f) { - std::memmove(data + pos + n, data + pos, size - pos); + void insert(ptrdiff_t pos, ptrdiff_t n, F f) { + std::memmove(data + pos + n, data + pos, to_unsigned(size - pos)); f(data + pos); size += n; } - void insert(size_t pos, char c) { - std::memmove(data + pos + 1, data + pos, size - pos); + void insert(ptrdiff_t pos, char c) { + std::memmove(data + pos + 1, data + pos, to_unsigned(size - pos)); data[pos] = c; ++size; } - void append(size_t n, char c) { + void append(ptrdiff_t n, char c) { std::uninitialized_fill_n(data + size, n, c); size += n; } @@ -605,21 +607,21 @@ FMT_FUNC void write_exponent(int exp, Handler &&h) { struct fill { size_t n; - void operator()(char *buffer) const { - buffer[0] = '0'; - buffer[1] = '.'; - std::uninitialized_fill_n(buffer + 2, n, '0'); + void operator()(char *buf) const { + buf[0] = '0'; + buf[1] = '.'; + std::uninitialized_fill_n(buf + 2, n, '0'); } }; // The number is given as v = f * pow(10, exp), where f has size digits. template FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms, - size_t size, int exp, Handler &&handler) { + int size, int exp, Handler &&handler) { if (!params.fixed) { // Insert a decimal point after the first digit and add an exponent. handler.insert(1, '.'); - exp += static_cast(size) - 1; + exp += size - 1; if (size < params.num_digits) handler.append(params.num_digits - size, '0'); handler.append(params.upper ? 'E' : 'e'); @@ -627,13 +629,12 @@ FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms, return; } // pow(10, full_exp - 1) <= v <= pow(10, full_exp). - int int_size = static_cast(size); - int full_exp = int_size + exp; + int full_exp = size + exp; const int exp_threshold = 21; - if (int_size <= full_exp && full_exp <= exp_threshold) { + if (size <= full_exp && full_exp <= exp_threshold) { // 1234e7 -> 12340000000[.0+] - handler.append(full_exp - int_size, '0'); - int num_zeros = static_cast(params.num_digits) - full_exp; + handler.append(full_exp - size, '0'); + int num_zeros = params.num_digits - full_exp; if (num_zeros > 0 && params.trailing_zeros) { handler.append('.'); handler.append(num_zeros, '0'); @@ -646,7 +647,7 @@ FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms, handler.remove_trailing('0'); } else if (params.num_digits > size) { // Add trailing zeros. - size_t num_zeros = params.num_digits - size; + ptrdiff_t num_zeros = params.num_digits - size; handler.append(num_zeros, '0'); } } else { @@ -656,12 +657,12 @@ FMT_FUNC void grisu2_prettify(const gen_digits_params ¶ms, } struct char_counter { - size_t size; + ptrdiff_t size; template - void insert(size_t, size_t n, F) { size += n; } - void insert(size_t, char) { ++size; } - void append(size_t n, char) { size += n; } + void insert(ptrdiff_t, ptrdiff_t n, F) { size += n; } + void insert(ptrdiff_t, char) { ++size; } + void append(ptrdiff_t n, char) { size += n; } void append(char) { ++size; } void remove_trailing(char) {} }; @@ -703,10 +704,10 @@ FMT_FUNC gen_digits_params process_specs(const core_format_specs &specs, ++num_digits; break; } - params.num_digits = to_unsigned(num_digits); - char_counter counter{params.num_digits}; + params.num_digits = num_digits; + char_counter counter{num_digits}; grisu2_prettify(params, params.num_digits, exp - num_digits, counter); - buf.resize(counter.size); + buf.resize(to_unsigned(counter.size)); return params; } @@ -738,7 +739,7 @@ FMT_FUNC typename std::enable_if::type // hi (p1 in Grisu) contains the most significant digits of scaled_upper. // hi = floor(upper / one). uint32_t hi = static_cast(upper.f >> -one.e); - int exp = static_cast(count_digits(hi)); // kappa in Grisu. + int exp = count_digits(hi); // kappa in Grisu. gen_digits_params params = process_specs(specs, cached_exp + exp, buf); fp_value.normalize(); fp scaled_value = fp_value * cached_pow; @@ -749,7 +750,7 @@ FMT_FUNC typename std::enable_if::type // lo (p2 in Grisu) contains the least significants digits of scaled_upper. // lo = supper % one. uint64_t lo = upper.f & (one.f - 1); - size_t size = 0; + int size = 0; if (!grisu2_gen_digits(buf.data(), size, hi, lo, exp, delta, one, diff, params.num_digits)) { buf.clear(); @@ -760,10 +761,10 @@ FMT_FUNC typename std::enable_if::type } template -void sprintf_format(Double value, internal::buffer &buffer, +void sprintf_format(Double value, internal::buffer &buf, core_format_specs spec) { // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. - FMT_ASSERT(buffer.capacity() != 0, "empty buffer"); + FMT_ASSERT(buf.capacity() != 0, "empty buffer"); // Build format string. enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg @@ -784,21 +785,21 @@ void sprintf_format(Double value, internal::buffer &buffer, // Format using snprintf. char *start = FMT_NULL; for (;;) { - std::size_t buffer_size = buffer.capacity(); - start = &buffer[0]; + std::size_t buffer_size = buf.capacity(); + start = &buf[0]; int result = internal::char_traits::format_float( start, buffer_size, format, spec.precision, value); if (result >= 0) { unsigned n = internal::to_unsigned(result); - if (n < buffer.capacity()) { - buffer.resize(n); + if (n < buf.capacity()) { + buf.resize(n); break; // The buffer is large enough - continue with formatting. } - buffer.reserve(n + 1); + buf.reserve(n + 1); } else { // If result is negative we ask to increase the capacity by at least 1, // but as std::vector, the buffer grows exponentially. - buffer.reserve(buffer.capacity() + 1); + buf.reserve(buf.capacity() + 1); } } } diff --git a/far/thirdparty/fmt/fmt/format.h b/far/thirdparty/fmt/fmt/format.h index f045b0c925..1bb24a5296 100644 --- a/far/thirdparty/fmt/fmt/format.h +++ b/far/thirdparty/fmt/fmt/format.h @@ -66,9 +66,9 @@ // many valid cases. # pragma GCC diagnostic ignored "-Wshadow" -// Disable the warning about implicit conversions that may change the sign of -// an integer; silencing it otherwise would require many explicit casts. -# pragma GCC diagnostic ignored "-Wsign-conversion" +// Disable the warning about nonliteral format strings because we construct +// them dynamically when falling back to snprintf for FP formatting. +# pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif # if FMT_CLANG_VERSION @@ -309,7 +309,7 @@ class numeric_limits : using namespace fmt::internal; // The resolution "priority" is: // isinf macro > std::isinf > ::isinf > fmt::internal::isinf - if (const_check(sizeof(isinf(x)) != sizeof(dummy_int))) + if (const_check(sizeof(isinf(x)) != sizeof(fmt::internal::dummy_int))) return isinf(x) != 0; return !_finite(static_cast(x)); } @@ -475,6 +475,9 @@ class basic_memory_buffer: private Allocator, public internal::basic_buffer { void grow(std::size_t size) FMT_OVERRIDE; public: + typedef T value_type; + typedef const T &const_reference; + explicit basic_memory_buffer(const Allocator &alloc = Allocator()) : Allocator(alloc) { this->set(store_, SIZE); @@ -606,98 +609,6 @@ class null_terminating_iterator; template FMT_CONSTEXPR_DECL const Char *pointer_from(null_terminating_iterator it); -// An iterator that produces a null terminator on *end. This simplifies parsing -// and allows comparing the performance of processing a null-terminated string -// vs string_view. -template -class null_terminating_iterator { - public: - typedef std::ptrdiff_t difference_type; - typedef Char value_type; - typedef const Char* pointer; - typedef const Char& reference; - typedef std::random_access_iterator_tag iterator_category; - - null_terminating_iterator() : ptr_(0), end_(0) {} - - FMT_CONSTEXPR null_terminating_iterator(const Char *ptr, const Char *end) - : ptr_(ptr), end_(end) {} - - template - FMT_CONSTEXPR explicit null_terminating_iterator(const Range &r) - : ptr_(r.begin()), end_(r.end()) {} - - FMT_CONSTEXPR null_terminating_iterator &operator=(const Char *ptr) { - assert(ptr <= end_); - ptr_ = ptr; - return *this; - } - - FMT_CONSTEXPR Char operator*() const { - return ptr_ != end_ ? *ptr_ : Char(); - } - - FMT_CONSTEXPR null_terminating_iterator operator++() { - ++ptr_; - return *this; - } - - FMT_CONSTEXPR null_terminating_iterator operator++(int) { - null_terminating_iterator result(*this); - ++ptr_; - return result; - } - - FMT_CONSTEXPR null_terminating_iterator operator--() { - --ptr_; - return *this; - } - - FMT_CONSTEXPR null_terminating_iterator operator+(difference_type n) { - return null_terminating_iterator(ptr_ + n, end_); - } - - FMT_CONSTEXPR null_terminating_iterator operator-(difference_type n) { - return null_terminating_iterator(ptr_ - n, end_); - } - - FMT_CONSTEXPR null_terminating_iterator operator+=(difference_type n) { - ptr_ += n; - return *this; - } - - FMT_CONSTEXPR difference_type operator-( - null_terminating_iterator other) const { - return ptr_ - other.ptr_; - } - - FMT_CONSTEXPR bool operator!=(null_terminating_iterator other) const { - return ptr_ != other.ptr_; - } - - bool operator>=(null_terminating_iterator other) const { - return ptr_ >= other.ptr_; - } - - // This should be a friend specialization pointer_from but the latter - // doesn't compile by gcc 5.1 due to a compiler bug. - template - friend FMT_CONSTEXPR_DECL const CharT *pointer_from( - null_terminating_iterator it); - - private: - const Char *ptr_; - const Char *end_; -}; - -template -FMT_CONSTEXPR const T *pointer_from(const T *p) { return p; } - -template -FMT_CONSTEXPR const Char *pointer_from(null_terminating_iterator it) { - return it.ptr_; -} - // An output iterator that counts the number of objects written to it and // discards them. template @@ -855,16 +766,16 @@ typedef basic_data<> data; #ifdef FMT_BUILTIN_CLZLL // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. -inline unsigned count_digits(uint64_t n) { +inline int count_digits(uint64_t n) { // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; - return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1; + return t - (n < data::ZERO_OR_POWERS_OF_10_64[t]) + 1; } #else // Fallback version of count_digits used when __builtin_clz is not available. -inline unsigned count_digits(uint64_t n) { - unsigned count = 1; +inline int count_digits(uint64_t n) { + int count = 1; for (;;) { // Integer division is slow so do it for a group of four digits instead // of for every digit. The idea comes from the talk by Alexandrescu @@ -985,9 +896,9 @@ class decimal_formatter_null : public decimal_formatter { #ifdef FMT_BUILTIN_CLZ // Optional version of count_digits for better performance on 32-bit platforms. -inline unsigned count_digits(uint32_t n) { +inline int count_digits(uint32_t n) { int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; - return to_unsigned(t) - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1; + return t - (n < data::ZERO_OR_POWERS_OF_10_32[t]) + 1; } #endif @@ -1044,8 +955,9 @@ inline wchar_t thousands_sep(locale_ref loc) { // thousands_sep is a functor that is called after writing each char to // add a thousands separator if necessary. template -inline Char *format_decimal(Char *buffer, UInt value, unsigned num_digits, +inline Char *format_decimal(Char *buffer, UInt value, int num_digits, ThousandsSep thousands_sep) { + FMT_ASSERT(num_digits >= 0, "invalid digit count"); buffer += num_digits; Char *end = buffer; while (value >= 100) { @@ -1073,7 +985,8 @@ inline Char *format_decimal(Char *buffer, UInt value, unsigned num_digits, template inline Iterator format_decimal( - Iterator out, UInt value, unsigned num_digits, ThousandsSep sep) { + Iterator out, UInt value, int num_digits, ThousandsSep sep) { + FMT_ASSERT(num_digits >= 0, "invalid digit count"); typedef typename ThousandsSep::char_type char_type; // Buffer should be large enough to hold all digits (<= digits10 + 1). enum { max_size = std::numeric_limits::digits10 + 1 }; @@ -1084,25 +997,26 @@ inline Iterator format_decimal( } template -inline It format_decimal(It out, UInt value, unsigned num_digits) { +inline It format_decimal(It out, UInt value, int num_digits) { return format_decimal(out, value, num_digits, no_thousands_sep()); } template -inline Char *format_uint(Char *buffer, UInt value, unsigned num_digits, +inline Char *format_uint(Char *buffer, UInt value, int num_digits, bool upper = false) { buffer += num_digits; Char *end = buffer; do { const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; unsigned digit = (value & ((1 << BASE_BITS) - 1)); - *--buffer = static_cast(BASE_BITS < 4 ? '0' + digit : digits[digit]); + *--buffer = static_cast(BASE_BITS < 4 ? static_cast('0' + digit) + : digits[digit]); } while ((value >>= BASE_BITS) != 0); return end; } template -inline It format_uint(It out, UInt value, unsigned num_digits, +inline It format_uint(It out, UInt value, int num_digits, bool upper = false) { // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1) // and null. @@ -1360,8 +1274,7 @@ void arg_map::init(const basic_format_args &args) { if (map_) return; map_ = new entry[args.max_size()]; - bool use_values = args.type(max_packed_args - 1) == internal::none_type; - if (use_values) { + if (args.is_packed()) { for (unsigned i = 0;/*nothing*/; ++i) { internal::type arg_type = args.type(i); switch (arg_type) { @@ -1431,7 +1344,7 @@ class arg_formatter_base { void write(bool value) { string_view sv(value ? "true" : "false"); - specs_ ? writer_.write_str(sv, *specs_) : writer_.write(sv); + specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); } void write(const char_type *value) { @@ -1439,7 +1352,7 @@ class arg_formatter_base { FMT_THROW(format_error("string pointer is null")); auto length = std::char_traits::length(value); basic_string_view sv(value, length); - specs_ ? writer_.write_str(sv, *specs_) : writer_.write(sv); + specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); } public: @@ -1515,7 +1428,7 @@ class arg_formatter_base { if (specs_) { internal::check_string_type_spec( specs_->type, internal::error_handler()); - writer_.write_str(value, *specs_); + writer_.write(value, *specs_); } else { writer_.write(value); } @@ -1535,38 +1448,6 @@ FMT_CONSTEXPR bool is_name_start(Char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; } -// DEPRECATED: Parses the input as an unsigned integer. This function assumes -// that the first character is a digit and presence of a non-digit character at -// the end. -// it: an iterator pointing to the beginning of the input range. -template -FMT_CONSTEXPR unsigned parse_nonnegative_int(Iterator &it, ErrorHandler &&eh) { - assert('0' <= *it && *it <= '9'); - if (*it == '0') { - ++it; - return 0; - } - unsigned value = 0; - // Convert to unsigned to prevent a warning. - unsigned max_int = (std::numeric_limits::max)(); - unsigned big = max_int / 10; - do { - // Check for overflow. - if (value > big) { - value = max_int + 1; - break; - } - value = value * 10 + unsigned(*it - '0'); - // Workaround for MSVC "setup_exception stack overflow" error: - auto next = it; - ++next; - it = next; - } while ('0' <= *it && *it <= '9'); - if (value > max_int) - eh.on_error("number is too big"); - return value; -} - // Parses the range [begin, end) as an unsigned integer. This function assumes // that the range is non-empty and the first character is a digit. template @@ -1901,36 +1782,6 @@ class dynamic_specs_handler : ParseContext &context_; }; -template -FMT_CONSTEXPR Iterator parse_arg_id(Iterator it, IDHandler &&handler) { - typedef typename std::iterator_traits::value_type char_type; - char_type c = *it; - if (c == '}' || c == ':') { - handler(); - return it; - } - if (c >= '0' && c <= '9') { - unsigned index = parse_nonnegative_int(it, handler); - if (*it != '}' && *it != ':') { - handler.on_error("invalid format string"); - return it; - } - handler(index); - return it; - } - if (!is_name_start(c)) { - handler.on_error("invalid format string"); - return it; - } - auto start = it; - do { - c = *++it; - } while (is_name_start(c) || ('0' <= c && c <= '9')); - handler(basic_string_view( - pointer_from(start), to_unsigned(it - start))); - return it; -} - template FMT_CONSTEXPR const Char *parse_arg_id( const Char *begin, const Char *end, IDHandler &&handler) { @@ -1949,8 +1800,8 @@ FMT_CONSTEXPR const Char *parse_arg_id( return handler.on_error("invalid format string"), begin; auto it = begin; do { - c = *++it; - } while (it != end && (is_name_start(c) || ('0' <= c && c <= '9'))); + ++it; + } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9'))); handler(basic_string_view(begin, to_unsigned(it - begin))); return it; } @@ -1991,24 +1842,16 @@ struct precision_adapter { SpecHandler &handler; }; -// Parses standard format specifiers and sends notifications about parsed -// components to handler. -// it: an iterator pointing to the beginning of a null-terminated range of -// characters, possibly emulated via null_terminating_iterator, representing -// format specifiers. -template -FMT_CONSTEXPR Iterator parse_format_specs(Iterator it, SpecHandler &&handler) { - typedef typename std::iterator_traits::value_type char_type; - char_type c = *it; - if (c == '}' || !c) - return it; - - // Parse fill and alignment. +// Parses fill and alignment. +template +FMT_CONSTEXPR const Char *parse_align( + const Char *begin, const Char *end, Handler &&handler) { + FMT_ASSERT(begin != end, ""); alignment align = ALIGN_DEFAULT; - int i = 1; + int i = 0; + if (begin + 1 != end) ++i; do { - auto p = it + i; - switch (static_cast(*p)) { + switch (static_cast(begin[i])) { case '<': align = ALIGN_LEFT; break; @@ -2023,80 +1866,103 @@ FMT_CONSTEXPR Iterator parse_format_specs(Iterator it, SpecHandler &&handler) { break; } if (align != ALIGN_DEFAULT) { - if (p != it) { - if (c == '{') { - handler.on_error("invalid fill character '{'"); - return it; - } - it += 2; + if (i > 0) { + auto c = *begin; + if (c == '{') + return handler.on_error("invalid fill character '{'"), begin; + begin += 2; handler.on_fill(c); - } else ++it; + } else ++begin; handler.on_align(align); break; } - } while (--i >= 0); + } while (i-- > 0); + return begin; +} + +template +FMT_CONSTEXPR const Char *parse_width( + const Char *begin, const Char *end, Handler &&handler) { + FMT_ASSERT(begin != end, ""); + if ('0' <= *begin && *begin <= '9') { + handler.on_width(parse_nonnegative_int(begin, end, handler)); + } else if (*begin == '{') { + ++begin; + if (begin != end) + begin = parse_arg_id(begin, end, width_adapter(handler)); + if (begin == end || *begin != '}') + return handler.on_error("invalid format string"), begin; + ++begin; + } + return begin; +} + +// Parses standard format specifiers and sends notifications about parsed +// components to handler. +template +FMT_CONSTEXPR const Char *parse_format_specs( + const Char *begin, const Char *end, SpecHandler &&handler) { + if (begin == end || *begin == '}') + return begin; + + begin = parse_align(begin, end, handler); + if (begin == end) return begin; // Parse sign. - switch (static_cast(*it)) { + switch (static_cast(*begin)) { case '+': handler.on_plus(); - ++it; + ++begin; break; case '-': handler.on_minus(); - ++it; + ++begin; break; case ' ': handler.on_space(); - ++it; + ++begin; break; } + if (begin == end) return begin; - if (*it == '#') { + if (*begin == '#') { handler.on_hash(); - ++it; + if (++begin == end) return begin; } // Parse zero flag. - if (*it == '0') { + if (*begin == '0') { handler.on_zero(); - ++it; + if (++begin == end) return begin; } - // Parse width. - if ('0' <= *it && *it <= '9') { - handler.on_width(parse_nonnegative_int(it, handler)); - } else if (*it == '{') { - it = parse_arg_id(it + 1, width_adapter(handler)); - if (*it++ != '}') { - handler.on_error("invalid format string"); - return it; - } - } + begin = parse_width(begin, end, handler); + if (begin == end) return begin; // Parse precision. - if (*it == '.') { - ++it; - if ('0' <= *it && *it <= '9') { - handler.on_precision(parse_nonnegative_int(it, handler)); - } else if (*it == '{') { - it = parse_arg_id( - it + 1, precision_adapter(handler)); - if (*it++ != '}') { - handler.on_error("invalid format string"); - return it; + if (*begin == '.') { + ++begin; + auto c = begin != end ? *begin : 0; + if ('0' <= c && c <= '9') { + handler.on_precision(parse_nonnegative_int(begin, end, handler)); + } else if (c == '{') { + ++begin; + if (begin != end) { + begin = parse_arg_id( + begin, end, precision_adapter(handler)); } + if (begin == end || *begin++ != '}') + return handler.on_error("invalid format string"), begin; } else { - handler.on_error("missing precision specifier"); - return it; + return handler.on_error("missing precision specifier"), begin; } handler.end_precision(); } // Parse type. - if (*it != '}' && *it) - handler.on_type(*it++); - return it; + if (begin != end && *begin != '}') + handler.on_type(*begin++); + return begin; } // Return the result via the out param to workaround gcc bug 77539. @@ -2112,7 +1978,7 @@ FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out) { template <> inline bool find( const char *first, const char *last, char value, const char *&out) { - out = static_cast(std::memchr(first, value, last - first)); + out = static_cast(std::memchr(first, value, internal::to_unsigned(last - first))); return out != FMT_NULL; } @@ -2171,11 +2037,9 @@ FMT_CONSTEXPR void parse_format_string( if (c == '}') { handler.on_replacement_field(p); } else if (c == ':') { - internal::null_terminating_iterator it(p + 1, end); - it = handler.on_format_specs(it); - if (*it != '}') + p = handler.on_format_specs(p + 1, end); + if (p == end || *p != '}') return handler.on_error("unknown format specifier"); - p = pointer_from(it); } else { return handler.on_error("missing '}' in format string"); } @@ -2197,11 +2061,9 @@ class format_string_checker { public: explicit FMT_CONSTEXPR format_string_checker( basic_string_view format_str, ErrorHandler eh) - : arg_id_(-1), context_(format_str, eh), + : arg_id_((std::numeric_limits::max)()), context_(format_str, eh), parse_funcs_{&parse_format_specs...} {} - typedef internal::null_terminating_iterator iterator; - FMT_CONSTEXPR void on_text(const Char *, const Char *) {} FMT_CONSTEXPR void on_arg_id() { @@ -2217,11 +2079,10 @@ class format_string_checker { FMT_CONSTEXPR void on_replacement_field(const Char *) {} - FMT_CONSTEXPR const Char *on_format_specs(iterator it) { - auto p = pointer_from(it); - context_.advance_to(p); - return to_unsigned(arg_id_) < NUM_ARGS ? - parse_funcs_[arg_id_](context_) : p; + FMT_CONSTEXPR const Char *on_format_specs(const Char *begin, const Char *) { + context_.advance_to(begin); + return arg_id_ < NUM_ARGS ? + parse_funcs_[arg_id_](context_) : begin; } FMT_CONSTEXPR void on_error(const char *message) { @@ -2233,14 +2094,14 @@ class format_string_checker { enum { NUM_ARGS = sizeof...(Args) }; FMT_CONSTEXPR void check_arg_id() { - if (internal::to_unsigned(arg_id_) >= NUM_ARGS) + if (arg_id_ >= NUM_ARGS) context_.on_error("argument index out of range"); } // Format specifier parsing function. typedef const Char *(*parse_func)(parse_context_type &); - int arg_id_; + unsigned arg_id_; parse_context_type context_; parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1]; }; @@ -2405,8 +2266,6 @@ class basic_writer { iterator out_; // Output iterator. internal::locale_ref locale_; - iterator out() const { return out_; } - // Attempts to reserve space for n extra characters in the output range. // Returns a pointer to the reserved range or a reference to out_. auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) { @@ -2417,7 +2276,28 @@ class basic_writer { // // where is written by f(it). template - void write_padded(const align_spec &spec, F &&f); + void write_padded(const align_spec &spec, F &&f) { + unsigned width = spec.width(); // User-perceived width (in code points). + size_t size = f.size(); // The number of code units. + size_t num_code_points = width != 0 ? f.width() : size; + if (width <= num_code_points) + return f(reserve(size)); + auto &&it = reserve(width + (size - num_code_points)); + char_type fill = static_cast(spec.fill()); + std::size_t padding = width - num_code_points; + if (spec.align() == ALIGN_RIGHT) { + it = std::fill_n(it, padding, fill); + f(it); + } else if (spec.align() == ALIGN_CENTER) { + std::size_t left_padding = padding / 2; + it = std::fill_n(it, left_padding, fill); + f(it); + it = std::fill_n(it, padding - left_padding, fill); + } else { + f(it); + it = std::fill_n(it, padding, fill); + } + } template struct padded_int_writer { @@ -2443,9 +2323,9 @@ class basic_writer { // // where are written by f(it). template - void write_int(unsigned num_digits, string_view prefix, + void write_int(int num_digits, string_view prefix, const Spec &spec, F f) { - std::size_t size = prefix.size() + num_digits; + std::size_t size = prefix.size() + internal::to_unsigned(num_digits); char_type fill = static_cast(spec.fill()); std::size_t padding = 0; if (spec.align() == ALIGN_NUMERIC) { @@ -2453,9 +2333,9 @@ class basic_writer { padding = spec.width() - size; size = spec.width(); } - } else if (spec.precision > static_cast(num_digits)) { + } else if (spec.precision > num_digits) { size = prefix.size() + internal::to_unsigned(spec.precision); - padding = internal::to_unsigned(spec.precision) - num_digits; + padding = internal::to_unsigned(spec.precision - num_digits); fill = static_cast('0'); } align_spec as = spec; @@ -2472,8 +2352,8 @@ class basic_writer { bool is_negative = internal::is_negative(value); if (is_negative) abs_value = 0 - abs_value; - unsigned num_digits = internal::count_digits(abs_value); - auto &&it = reserve((is_negative ? 1 : 0) + num_digits); + int num_digits = internal::count_digits(abs_value); + auto &&it = reserve((is_negative ? 1 : 0) + static_cast(num_digits)); if (is_negative) *it++ = static_cast('-'); it = internal::format_decimal(it, abs_value, num_digits); @@ -2494,9 +2374,9 @@ class basic_writer { // Counts the number of digits in abs_value. BITS = log2(radix). template - unsigned count_digits() const { + int count_digits() const { unsigned_type n = abs_value; - unsigned num_digits = 0; + int num_digits = 0; do { ++num_digits; } while ((n >>= BITS) != 0); @@ -2518,7 +2398,7 @@ class basic_writer { struct dec_writer { unsigned_type abs_value; - unsigned num_digits; + int num_digits; template void operator()(It &&it) const { @@ -2527,14 +2407,14 @@ class basic_writer { }; void on_dec() { - unsigned num_digits = internal::count_digits(abs_value); + int num_digits = internal::count_digits(abs_value); writer.write_int(num_digits, get_prefix(), spec, dec_writer{abs_value, num_digits}); } struct hex_writer { int_writer &self; - unsigned num_digits; + int num_digits; template void operator()(It &&it) const { @@ -2548,7 +2428,7 @@ class basic_writer { prefix[prefix_size++] = '0'; prefix[prefix_size++] = static_cast(spec.type); } - unsigned num_digits = count_digits<4>(); + int num_digits = count_digits<4>(); writer.write_int(num_digits, get_prefix(), spec, hex_writer{*this, num_digits}); } @@ -2556,7 +2436,7 @@ class basic_writer { template struct bin_writer { unsigned_type abs_value; - unsigned num_digits; + int num_digits; template void operator()(It &&it) const { @@ -2569,15 +2449,15 @@ class basic_writer { prefix[prefix_size++] = '0'; prefix[prefix_size++] = static_cast(spec.type); } - unsigned num_digits = count_digits<1>(); + int num_digits = count_digits<1>(); writer.write_int(num_digits, get_prefix(), spec, bin_writer<1>{abs_value, num_digits}); } void on_oct() { - unsigned num_digits = count_digits<3>(); + int num_digits = count_digits<3>(); if (spec.has(HASH_FLAG) && - spec.precision <= static_cast(num_digits)) { + spec.precision <= num_digits) { // Octal prefix '0' is counted as a digit, so only add it if precision // is not greater than the number of digits. prefix[prefix_size++] = '0'; @@ -2590,7 +2470,7 @@ class basic_writer { struct num_writer { unsigned_type abs_value; - unsigned size; + int size; char_type sep; template @@ -2602,9 +2482,9 @@ class basic_writer { }; void on_num() { - unsigned num_digits = internal::count_digits(abs_value); + int num_digits = internal::count_digits(abs_value); char_type sep = internal::thousands_sep(writer.locale_); - unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3); + int size = num_digits + SEP_SIZE * ((num_digits - 1) / 3); writer.write_int(size, get_prefix(), spec, num_writer{abs_value, size, sep}); } @@ -2679,15 +2559,6 @@ class basic_writer { } }; - // Writes a formatted string. - template - void write_str(const Char *s, std::size_t size, const align_spec &spec) { - write_padded(spec, str_writer{s, size}); - } - - template - void write_str(basic_string_view str, const format_specs &spec); - template friend class internal::arg_formatter_base; @@ -2697,6 +2568,8 @@ class basic_writer { Range out, internal::locale_ref loc = internal::locale_ref()) : out_(out.begin()), locale_(loc) {} + iterator out() const { return out_; } + void write(int value) { write_decimal(value); } void write(long value) { write_decimal(value); } void write(long long value) { write_decimal(value); } @@ -2756,9 +2629,20 @@ class basic_writer { it = std::copy(value.begin(), value.end(), it); } - template - void write(basic_string_view str, FormatSpecs... specs) { - write_str(str, format_specs(specs...)); + // Writes a formatted string. + template + void write(const Char *s, std::size_t size, const align_spec &spec) { + write_padded(spec, str_writer{s, size}); + } + + template + void write(basic_string_view s, + const format_specs &spec = format_specs()) { + const Char *data = s.data(); + std::size_t size = s.size(); + if (spec.precision >= 0 && internal::to_unsigned(spec.precision) < size) + size = internal::to_unsigned(spec.precision); + write(data, size, spec); } template @@ -2771,42 +2655,6 @@ class basic_writer { } }; -template -template -void basic_writer::write_padded(const align_spec &spec, F &&f) { - unsigned width = spec.width(); // User-perceived width (in code points). - size_t size = f.size(); // The number of code units. - size_t num_code_points = width != 0 ? f.width() : size; - if (width <= num_code_points) - return f(reserve(size)); - auto &&it = reserve(width + (size - num_code_points)); - char_type fill = static_cast(spec.fill()); - std::size_t padding = width - num_code_points; - if (spec.align() == ALIGN_RIGHT) { - it = std::fill_n(it, padding, fill); - f(it); - } else if (spec.align() == ALIGN_CENTER) { - std::size_t left_padding = padding / 2; - it = std::fill_n(it, left_padding, fill); - f(it); - it = std::fill_n(it, padding - left_padding, fill); - } else { - f(it); - it = std::fill_n(it, padding, fill); - } -} - -template -template -void basic_writer::write_str( - basic_string_view s, const format_specs &spec) { - const Char *data = s.data(); - std::size_t size = s.size(); - if (spec.precision >= 0 && internal::to_unsigned(spec.precision) < size) - size = internal::to_unsigned(spec.precision); - write_str(data, size, spec); -} - struct float_spec_handler { char type; bool upper; @@ -2972,7 +2820,7 @@ class format_int { // Formats value in reverse and returns a pointer to the beginning. char *format_decimal(unsigned long long value) { - char *ptr = buffer_ + BUFFER_SIZE - 1; + char *ptr = buffer_ + (BUFFER_SIZE - 1); // Parens to workaround MSVC bug. while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu @@ -3038,6 +2886,7 @@ class format_int { std::string str() const { return std::string(str_, size()); } }; +// DEPRECATED! // Formats a decimal integer value writing into buffer and returns // a pointer to the end of the formatted string. This function doesn't // write a terminating null character. @@ -3059,8 +2908,9 @@ inline void format_decimal(char *&buffer, T value) { *buffer++ = internal::data::DIGITS[index + 1]; return; } - unsigned num_digits = internal::count_digits(abs_value); - internal::format_decimal(buffer, abs_value, num_digits); + int num_digits = internal::count_digits(abs_value); + internal::format_decimal( + internal::make_checked(buffer, internal::to_unsigned(num_digits)), abs_value, num_digits); buffer += num_digits; } @@ -3075,13 +2925,12 @@ struct formatter< // terminating '}'. template FMT_CONSTEXPR typename ParseContext::iterator parse(ParseContext &ctx) { - auto it = internal::null_terminating_iterator(ctx); typedef internal::dynamic_specs_handler handler_type; auto type = internal::get_type< typename buffer_context::type, T>::value; internal::specs_checker handler(handler_type(specs_, ctx), type); - it = parse_format_specs(it, handler); + auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); auto type_spec = specs_.type; auto eh = ctx.error_handler(); switch (type) { @@ -3122,7 +2971,7 @@ struct formatter< // formatter specializations. break; } - return pointer_from(it); + return it; } template @@ -3165,11 +3014,9 @@ class dynamic_formatter { public: template auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { - auto it = internal::null_terminating_iterator(ctx); // Checks are deferred to formatting time when the argument type is known. internal::dynamic_specs_handler handler(specs_, ctx); - it = parse_format_specs(it, handler); - return pointer_from(it); + return parse_format_specs(ctx.begin(), ctx.end(), handler); } template @@ -3219,7 +3066,6 @@ typename basic_format_context::format_arg template struct format_handler : internal::error_handler { - typedef internal::null_terminating_iterator iterator; typedef typename ArgFormatter::range range; format_handler(range r, basic_string_view str, @@ -3251,22 +3097,22 @@ struct format_handler : internal::error_handler { context.advance_to(visit_format_arg(ArgFormatter(context), arg)); } - iterator on_format_specs(iterator it) { + const Char *on_format_specs(const Char *begin, const Char *end) { auto &parse_ctx = context.parse_context(); - parse_ctx.advance_to(pointer_from(it)); + parse_ctx.advance_to(begin); internal::custom_formatter f(context); if (visit_format_arg(f, arg)) - return iterator(parse_ctx); + return parse_ctx.begin(); basic_format_specs specs; using internal::specs_handler; internal::specs_checker> handler(specs_handler(specs, context), arg.type()); - it = parse_format_specs(it, handler); - if (*it != '}') + begin = parse_format_specs(begin, end, handler); + if (begin == end || *begin != '}') on_error("missing '}' in format string"); - parse_ctx.advance_to(pointer_from(it)); + parse_ctx.advance_to(begin); context.advance_to(visit_format_arg(ArgFormatter(context, &specs), arg)); - return it; + return begin; } Context context; @@ -3490,9 +3336,9 @@ inline typename std::enable_if::value, \endrst */ template -inline typename std::enable_if< +inline FMT_ENABLE_IF_T( internal::is_string::value && - internal::is_output_iterator::value, OutputIt>::type + internal::is_output_iterator::value, OutputIt) format_to(OutputIt out, const S &format_str, const Args &... args) { internal::check_format_string(format_str); typedef typename format_context_t::type context; @@ -3546,10 +3392,10 @@ inline typename std::enable_if< \endrst */ template -inline typename std::enable_if< +inline FMT_ENABLE_IF_T( internal::is_string::value && internal::is_output_iterator::value, - format_to_n_result>::type + format_to_n_result) format_to_n(OutputIt out, std::size_t n, const S &format_str, const Args &... args) { internal::check_format_string(format_str); diff --git a/far/thirdparty/fmt/format.cc b/far/thirdparty/fmt/format.cc index 33825818dd..dadfc8dd37 100644 --- a/far/thirdparty/fmt/format.cc +++ b/far/thirdparty/fmt/format.cc @@ -9,15 +9,16 @@ FMT_BEGIN_NAMESPACE template struct internal::basic_data; -template internal::locale_ref::locale_ref(const std::locale &loc); +template FMT_API internal::locale_ref::locale_ref(const std::locale &loc); +template FMT_API std::locale internal::locale_ref::get() const; // Explicit instantiations for char. template FMT_API char internal::thousands_sep_impl(locale_ref); -template void internal::basic_buffer::append(const char *, const char *); +template FMT_API void internal::basic_buffer::append(const char *, const char *); -template void internal::arg_map::init( +template FMT_API void internal::arg_map::init( const basic_format_args &args); template FMT_API int internal::char_traits::format_float( @@ -29,7 +30,7 @@ template FMT_API int internal::char_traits::format_float( template FMT_API std::string internal::vformat( string_view, basic_format_args); -template format_context::iterator internal::vformat_to( +template FMT_API format_context::iterator internal::vformat_to( internal::buffer &, string_view, basic_format_args); template FMT_API void internal::sprintf_format( @@ -41,10 +42,10 @@ template FMT_API void internal::sprintf_format( template FMT_API wchar_t internal::thousands_sep_impl(locale_ref); -template void internal::basic_buffer::append( +template FMT_API void internal::basic_buffer::append( const wchar_t *, const wchar_t *); -template void internal::arg_map::init( +template FMT_API void internal::arg_map::init( const basic_format_args &); template FMT_API int internal::char_traits::format_float( diff --git a/far/tracer.cpp b/far/tracer.cpp index 1369cc69ad..cfa35411e8 100644 --- a/far/tracer.cpp +++ b/far/tracer.cpp @@ -70,7 +70,7 @@ static auto GetBackTrace(CONTEXT ContextRecord, HANDLE ThreadHandle) return Result; } -static void GetSymbols(const std::vector& BackTrace, const std::function& Consumer) +static void GetSymbols(const std::vector& BackTrace, function_ref const Consumer) { SCOPED_ACTION(auto)(tracer::with_symbols()); @@ -112,11 +112,13 @@ static void GetSymbols(const std::vector& BackTrace, const std::fun } } +#ifdef _MSC_VER extern "C" void** __current_exception(); extern "C" void** __current_exception_context(); - +#else static EXCEPTION_RECORD DummyRecord; static CONTEXT DummyContext; +#endif EXCEPTION_POINTERS tracer::get_pointers() { @@ -139,7 +141,7 @@ std::vector tracer::get(const EXCEPTION_POINTERS& Pointers, HANDLE return GetBackTrace(*Pointers.ContextRecord, ThreadHandle); } -void tracer::get_symbols(const std::vector& Trace, const std::function& Consumer) +void tracer::get_symbols(const std::vector& Trace, function_ref const Consumer) { GetSymbols(Trace, Consumer); } diff --git a/far/tracer.hpp b/far/tracer.hpp index a6f35912f0..2b08b33c21 100644 --- a/far/tracer.hpp +++ b/far/tracer.hpp @@ -32,12 +32,14 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "common/function_ref.hpp" + class tracer: noncopyable { public: static EXCEPTION_POINTERS get_pointers(); static std::vector get(const EXCEPTION_POINTERS& Pointers, HANDLE ThreadHandle); - static void get_symbols(const std::vector& Trace, const std::function& Consumer); + static void get_symbols(const std::vector& Trace, function_ref Consumer); static void get_symbol(const void* Ptr, string& Address, string& Name, string& Source); static auto with_symbols() diff --git a/far/treelist.cpp b/far/treelist.cpp index 3408cf229c..1ec853ae93 100644 --- a/far/treelist.cpp +++ b/far/treelist.cpp @@ -83,6 +83,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "platform.fs.hpp" #include "common/enum_tokens.hpp" +#include "common/function_ref.hpp" #include "common/scope_exit.hpp" #include "format.hpp" @@ -719,7 +720,7 @@ static os::fs::file OpenCacheableTreeFile(const string& Root, string& Name, bool return Result; } -static void ReadLines(const os::fs::file& TreeFile, const std::function& Inserter) +static void ReadLines(const os::fs::file& TreeFile, function_ref const Inserter) { for (const auto& i: enum_file_lines(TreeFile, CP_UNICODE)) { diff --git a/far/tvar.hpp b/far/tvar.hpp index 19641225a1..2ab2852008 100644 --- a/far/tvar.hpp +++ b/far/tvar.hpp @@ -65,11 +65,11 @@ class TVar explicit TVar(const wchar_t*); explicit TVar(double); - COPY_AND_MOVE(TVar, long long); - COPY_AND_MOVE(TVar, string_view); - COPY_AND_MOVE(TVar, const wchar_t*); - COPY_AND_MOVE(TVar, int); - COPY_AND_MOVE(TVar, double); + COPY_AND_MOVE(TVar, long long) + COPY_AND_MOVE(TVar, string_view) + COPY_AND_MOVE(TVar, const wchar_t*) + COPY_AND_MOVE(TVar, int) + COPY_AND_MOVE(TVar, double) bool operator<(const TVar&) const; bool operator>(const TVar&) const; diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 4bed95d0ed..c0dc25b90f 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -m4_define(BUILD,5344)m4_dnl +m4_define(BUILD,5345)m4_dnl diff --git a/far/vmenu2.cpp b/far/vmenu2.cpp index fac1d9f5d8..2baa0f3353 100644 --- a/far/vmenu2.cpp +++ b/far/vmenu2.cpp @@ -651,7 +651,7 @@ void VMenu2::SortItems(bool Reverse, int Offset) ListBox().SortItems(Reverse, Offset); } -void VMenu2::SortItems(const std::function& Pred, bool Reverse, int Offset) +void VMenu2::SortItems(function_ref const Pred, bool Reverse, int Offset) { ListBox().SortItems(Pred, Reverse, Offset); } diff --git a/far/vmenu2.hpp b/far/vmenu2.hpp index 6e153ac10f..580d0e3474 100644 --- a/far/vmenu2.hpp +++ b/far/vmenu2.hpp @@ -36,6 +36,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "dialog.hpp" +#include "common/function_ref.hpp" #include "common/range.hpp" struct menu_item; @@ -109,7 +110,7 @@ class VMenu2 : public Dialog int SetSelectPos(const FarListPos* ListPos, int Direct = 0); void SortItems(bool Reverse, int Offset); - void SortItems(const std::function& Pred, bool Reverse = false, int Offset = 0); + void SortItems(function_ref Pred, bool Reverse = false, int Offset = 0); void Pack(); MenuItemEx& at(size_t n);