From 01df04f3971c1d936f8728fab852a232c71d72ff Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 16 Aug 2022 11:24:02 -0700 Subject: [PATCH 01/13] Disable unused parts of wxWdigets --- meson.build | 275 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 258 insertions(+), 17 deletions(-) diff --git a/meson.build b/meson.build index 4834c8224d..e07e89fb8b 100644 --- a/meson.build +++ b/meson.build @@ -137,36 +137,277 @@ else opt_var = cmake.subproject_options() opt_var.add_cmake_defines({ + 'CMAKE_BUILD_TYPE': build_type, + 'wxBUILD_INSTALL': false, 'wxBUILD_PRECOMP': false, # otherwise breaks project generation w/ meson + 'wxBUILD_MONOLITHIC': true, # otherwise breaks project generation w/ meson 'wxBUILD_SHARED': build_shared, - 'wxUSE_WEBVIEW': false, # breaks build on linux - 'CMAKE_BUILD_TYPE': build_type, - 'wxUSE_IMAGE': true, - 'wxBUILD_MONOLITHIC': true # otherwise breaks project generation w/ meson + 'WXWIN_COMPATIBILITY_2_4': false, + 'WXWIN_COMPATIBILITY_2_6': false, + 'WXWIN_COMPATIBILITY_2_8': false, + 'wxDIALOG_UNIT_COMPATIBILITY': false, + 'wxUSE_ON_FATAL_EXCEPTION': 1, + 'wxUSE_STACKWALKER': 0, + 'wxUSE_DEBUGREPORT': 0, + 'wxUSE_DEBUG_CONTEXT': 0, + 'wxUSE_MEMORY_TRACING': 0, + 'wxUSE_GLOBAL_MEMORY_OPERATORS': 0, + 'wxUSE_DEBUG_NEW_ALWAYS': 0, + 'wxUSE_UNICODE': 1, + 'wxUSE_WCHAR_T': 1, + 'wxUSE_EXCEPTIONS': 1, + 'wxUSE_EXTENDED_RTTI': 0, + 'wxUSE_STL': 0, + 'wxUSE_LOG': 1, + 'wxUSE_LOGWINDOW': 1, + 'wxUSE_LOGGUI': 1, + 'wxUSE_LOG_DIALOG': 1, + 'wxUSE_CMDLINE_PARSER': 0, + 'wxUSE_THREADS': 1, + 'wxUSE_STREAMS': 1, + 'wxUSE_STD_IOSTREAM': 0, + 'wxUSE_STD_STRING': 1, + 'wxUSE_PRINTF_POS_PARAMS': 1, + 'wxUSE_LONGLONG': 1, + 'wxUSE_BASE64': 0, + 'wxUSE_CONSOLE_EVENTLOOP': 1, + 'wxUSE_FILE': 1, + 'wxUSE_FFILE': 1, + 'wxUSE_FSVOLUME': 0, + 'wxUSE_STDPATHS': 1, + 'wxUSE_TEXTBUFFER': 0, + 'wxUSE_TEXTFILE': 0, + 'wxUSE_INTL': 1, + 'wxUSE_XLOCALE': 1, + 'wxUSE_DATETIME': 1, + 'wxUSE_TIMER': 1, + 'wxUSE_STOPWATCH': 1, + 'wxUSE_FSWATCHER': 0, + 'wxUSE_CONFIG': 0, + 'wxUSE_CONFIG_NATIVE': 0, + 'wxUSE_DIALUP_MANAGER': 0, + 'wxUSE_DYNLIB_CLASS': 1, + 'wxUSE_DYNAMIC_LOADER': 1, + 'wxUSE_SOCKETS': 0, + 'wxUSE_IPV6': 0, + 'wxUSE_FILESYSTEM': 0, + 'wxUSE_FS_ZIP': 0, + 'wxUSE_FS_ARCHIVE': 0, + 'wxUSE_FS_INET': 0, + 'wxUSE_ARCHIVE_STREAMS': 1, + 'wxUSE_ZIPSTREAM': 1, + 'wxUSE_TARSTREAM': 0, + 'wxUSE_APPLE_IEEE': 0, + 'wxUSE_JOYSTICK': 0, + 'wxUSE_FONTENUM': 1, + 'wxUSE_FONTMAP': 1, + 'wxUSE_MIMETYPE': 0, + 'wxUSE_PROTOCOL': 0, + 'wxUSE_PROTOCOL_FILE': 0, + 'wxUSE_PROTOCOL_FTP': 0, + 'wxUSE_PROTOCOL_HTTP': 0, + 'wxUSE_URL': 0, + 'wxUSE_URL_NATIVE': 0, + 'wxUSE_VARIANT': 1, + 'wxUSE_ANY': 0, + 'wxUSE_REGEX': 'OFF', + 'wxUSE_SYSTEM_OPTIONS': 1, + 'wxUSE_SOUND': 0, + 'wxUSE_MEDIACTRL': 0, + 'wxUSE_GSTREAMER': 0, + 'wxUSE_XRC': 0, + 'wxUSE_XML': 0, + 'wxUSE_AUI': 0, + 'wxUSE_RIBBON': 0, + 'wxUSE_PROPGRID': 0, + 'wxUSE_STC': 1, + 'wxUSE_GRAPHICS_CONTEXT': 1, + 'wxUSE_GRAPHICS_GDIPLUS': 1, + 'wxUSE_CONTROLS': 1, + 'wxUSE_POPUPWIN': 1, + 'wxUSE_TIPWINDOW': 0, + 'wxUSE_ANIMATIONCTRL': 0, + 'wxUSE_BUTTON': 1, + 'wxUSE_BMPBUTTON': 1, + 'wxUSE_CALENDARCTRL': 1, + 'wxUSE_CHECKBOX': 1, + 'wxUSE_CHECKLISTBOX': 1, + 'wxUSE_CHOICE': 1, + 'wxUSE_COLLPANE': 0, + 'wxUSE_COLOURPICKERCTRL': 1, + 'wxUSE_COMBOBOX': 1, + 'wxUSE_DATAVIEWCTRL': 1, + 'wxUSE_DATEPICKCTRL': 1, + 'wxUSE_DIRPICKERCTRL': 1, + 'wxUSE_EDITABLELISTBOX': 1, + 'wxUSE_FILECTRL': 1, + 'wxUSE_FILEPICKERCTRL': 1, + 'wxUSE_FONTPICKERCTRL': 1, + 'wxUSE_GAUGE': 1, + 'wxUSE_HEADERCTRL': 1, + 'wxUSE_HYPERLINKCTRL': 1, + 'wxUSE_LISTBOX': 1, + 'wxUSE_LISTCTRL': 1, + 'wxUSE_RADIOBOX': 1, + 'wxUSE_RADIOBTN': 1, + 'wxUSE_SCROLLBAR': 1, + 'wxUSE_SEARCHCTRL': 1, + 'wxUSE_SLIDER': 1, + 'wxUSE_SPINBTN': 1, + 'wxUSE_SPINCTRL': 1, + 'wxUSE_STATBOX': 1, + 'wxUSE_STATLINE': 1, + 'wxUSE_STATTEXT': 1, + 'wxUSE_STATBMP': 1, + 'wxUSE_TEXTCTRL': 1, + 'wxUSE_TOGGLEBTN': 1, + 'wxUSE_TREECTRL': 1, + 'wxUSE_STATUSBAR': 1, + 'wxUSE_NATIVE_STATUSBAR': 1, + 'wxUSE_TOOLBAR': 1, + 'wxUSE_TOOLBAR_NATIVE': 1, + 'wxUSE_NOTEBOOK': 1, + 'wxUSE_LISTBOOK': 1, + 'wxUSE_CHOICEBOOK': 1, + 'wxUSE_TREEBOOK': 1, + 'wxUSE_TOOLBOOK': 1, + 'wxUSE_TASKBARICON': 0, + 'wxUSE_TAB_DIALOG': 0, + 'wxUSE_GRID': 0, + 'wxUSE_MINIFRAME': 0, + 'wxUSE_COMBOCTRL': 1, + 'wxUSE_ODCOMBOBOX': 1, + 'wxUSE_BITMAPCOMBOBOX': 0, + 'wxUSE_REARRANGECTRL': 1, + 'wxUSE_ACCEL': 1, + 'wxUSE_HOTKEY': 1, + 'wxUSE_CARET': 1, + 'wxUSE_DISPLAY': 1, + 'wxUSE_GEOMETRY': 1, + 'wxUSE_IMAGLIST': 1, + 'wxUSE_INFOBAR': 1, + 'wxUSE_MENUS': 1, + 'wxUSE_NOTIFICATION_MESSAGE': 0, + 'wxUSE_SASH': 1, + 'wxUSE_SPLITTER': 1, + 'wxUSE_TOOLTIPS': 1, + 'wxUSE_VALIDATORS': 1, + 'wxUSE_COMMON_DIALOGS': 1, + 'wxUSE_BUSYINFO': 0, + 'wxUSE_CHOICEDLG': 1, + 'wxUSE_COLOURDLG': 1, + 'wxUSE_DIRDLG': 1, + 'wxUSE_FILEDLG': 1, + 'wxUSE_FINDREPLDLG': 0, + 'wxUSE_FONTDLG': 1, + 'wxUSE_MSGDLG': 1, + 'wxUSE_PROGRESSDLG': 0, + 'wxUSE_STARTUP_TIPS': 0, + 'wxUSE_TEXTDLG': 1, + 'wxUSE_NUMBERDLG': 1, + 'wxUSE_SPLASH': 0, + 'wxUSE_WIZARDDLG': 0, + 'wxUSE_ABOUTDLG': 1, + 'wxUSE_METAFILE': 0, + 'wxUSE_ENH_METAFILE': 0, + 'wxUSE_WIN_METAFILES_ALWAYS': 0, + 'wxUSE_MDI': 0, + 'wxUSE_DOC_VIEW_ARCHITECTURE': 0, + 'wxUSE_MDI_ARCHITECTURE': 0, + 'wxUSE_PRINTING_ARCHITECTURE': 0, + 'wxUSE_HTML': 0, + 'wxUSE_GLCANVAS': 1, + 'wxUSE_RICHTEXT': 0, + 'wxUSE_CLIPBOARD': 1, + 'wxUSE_DATAOBJ': 1, + 'wxUSE_DRAG_AND_DROP': 1, + 'wxUSE_ACCESSIBILITY': 0, + 'wxUSE_SNGLINST_CHECKER': 1, + 'wxUSE_DRAGIMAGE': 1, + 'wxUSE_IPC': 0, + 'wxUSE_HELP': 0, + 'wxUSE_MS_HTML_HELP': 0, + 'wxUSE_WXHTML_HELP': 0, + 'wxUSE_RESOURCES': 0, + 'wxUSE_CONSTRAINTS': 0, + 'wxUSE_SPLINES': 0, + 'wxUSE_MOUSEWHEEL': 1, + 'wxUSE_POSTSCRIPT': 0, + 'wxUSE_AFM_FOR_POSTSCRIPT': 0, + 'wxUSE_SVG': 0, + 'wxODBC_FWD_ONLY_CURSORS': false, + 'wxODBC_BACKWARD_COMPATABILITY': false, + 'wxUSE_IOSTREAMH': 0, + 'wxUSE_IMAGE': 1, + 'wxUSE_LIBJPEG': 'OFF', + 'wxUSE_LIBTIFF': 'OFF', + 'wxUSE_TGA': 'OFF', + 'wxUSE_GIF': 'OFF', + 'wxUSE_PNM': 'OFF', + 'wxUSE_PCX': 'OFF', + 'wxUSE_IFF': 'OFF', + 'wxUSE_XPM': 'OFF', + 'wxUSE_ICO_CUR': 1, + 'wxUSE_PALETTE': 1, + 'wxUSE_ALL_THEMES': 1, + 'wxUSE_UNICODE_MSLU': 0, + 'wxUSE_MFC': 0, + 'wxUSE_OLE': 1, + 'wxUSE_OLE_AUTOMATION': 0, + 'wxUSE_ACTIVEX': 0, + 'wxUSE_DC_CACHEING': 1, + 'wxUSE_DIB_FOR_BITMAP': 0, + 'wxUSE_WXDIB': 1, + 'wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW': 0, + 'wxUSE_REGKEY': 1, + 'wxUSE_RICHEDIT': 0, + 'wxUSE_RICHEDIT2': 0, + 'wxUSE_OWNER_DRAWN': 1, + 'wxUSE_TASKBARICON_BALLOONS': 0, + 'wxUSE_UXTHEME': 1, + 'wxUSE_UXTHEME_AUTO': 1, + 'wxUSE_INKEDIT': 0, + 'wxUSE_INICONF': 0, + 'wxUSE_DATEPICKCTRL_GENERIC': 0, + 'wxUSE_CRASHREPORT': 1, + 'wxUSE_AUTOID_MANAGEMENT': 1, + 'wxUSE_FILE_HISTORY': 0, + 'wxUSE_UIACTIONSIMULATOR': 0, + 'wxUSE_CAIRO': 0, + 'wxUSE_COMMANDLINKBUTTON': 0, + 'wxUSE_RICHMSGDLG': 0, + 'wxUSE_STD_CONTAINERS': 1, + 'wxUSE_STD_STRING_CONV_IN_WXSTRING': 0, + 'wxUSE_ARTPROVIDER_STD': 0, + 'wxUSE_ARTPROVIDER_TANGO': 0, + 'wxUSE_DC_TRANSFORM_MATRIX': 0, + 'wxUSE_MARKUP': 0, + 'wxUSE_TREELISTCTRL': 1, + 'wxUSE_TIMEPICKCTRL': 1, + 'wxUSE_WEBVIEW': 0, + 'wxUSE_RICHTOOLTIP': 0, + 'wxUSE_COMPILER_TLS': 2, + 'wxUSE_PREFERENCES_EDITOR': 0, + 'wxUSE_STD_CONTAINERS_COMPATIBLY': 0, + 'wxUSE_TASKBARBUTTON': 0, + 'wxUSE_ADDREMOVECTRL': 0, + 'wxUSE_ACTIVITYINDICATOR': 0, + 'wxUSE_WINRT': 0, }) wx = cmake.subproject('wxWidgets', options: opt_var) deps += [ wx.dependency('wxmono'), - wx.dependency('wxregex'), - wx.dependency('wxscintilla') + wx.dependency('wxscintilla'), + # wx.dependency('wxpng'), + # wx.dependency('wxzlib'), + # wx.dependency('wxexpat'), ] - if host_machine.system() == 'windows' or host_machine.system() == 'darwin' - deps += [ - wx.dependency('wxpng'), - ] - endif - if host_machine.system() == 'windows' - deps += [ - wx.dependency('wxzlib'), - wx.dependency('wxexpat'), - ] - if cc.has_header('rpc.h') deps += cc.find_library('rpcrt4', required: true) else From 9ea01cede713b4ba08c966727328e46ed866df2b Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 16 Aug 2022 12:47:42 -0700 Subject: [PATCH 02/13] Update boost and wxWidgets versions --- libaegisub/common/parser.cpp | 15 +-- meson.build | 18 ++-- src/colour_button.cpp | 4 - src/dialog_colorpicker.cpp | 4 +- src/dialog_translation.cpp | 2 +- src/subs_edit_ctrl.cpp | 22 ++--- src/video_frame.cpp | 4 - subprojects/boost.wrap | 8 +- subprojects/fribidi.wrap | 2 +- subprojects/harfbuzz.wrap | 2 +- .../boost/libs/filesystem/meson.build | 1 + .../boost/libs/locale/meson.build | 93 +++++++------------ .../packagefiles/boost/libs/regex/meson.build | 18 +--- subprojects/packagefiles/boost/meson.build | 2 +- subprojects/wxWidgets.wrap | 2 +- 15 files changed, 73 insertions(+), 124 deletions(-) diff --git a/libaegisub/common/parser.cpp b/libaegisub/common/parser.cpp index ef53ed0d20..94c0486bcf 100644 --- a/libaegisub/common/parser.cpp +++ b/libaegisub/common/parser.cpp @@ -19,20 +19,15 @@ #include "libaegisub/color.h" #include "libaegisub/ass/dialogue_parser.h" +#include +#include +#include +#include + #include -#include -#include -#include #include #include -// We have to use the copy of pheonix within spirit if it exists, as the -// standalone copy has different header guards -#ifdef HAVE_BOOST_SPIRIT_HOME_PHOENIX_VERSION_HPP -#include -#else -#include -#endif BOOST_FUSION_ADAPT_STRUCT( agi::Color, diff --git a/meson.build b/meson.build index e07e89fb8b..e5fa0e3a76 100644 --- a/meson.build +++ b/meson.build @@ -94,7 +94,7 @@ deps += dependency('libass', version: '>=0.9.7', boost_modules = ['chrono', 'filesystem', 'thread', 'locale', 'regex'] if not get_option('local_boost') - boost_dep = dependency('boost', version: '>=1.50.0', + boost_dep = dependency('boost', version: '>=1.70.0', modules: boost_modules + ['system'], required: false, static: get_option('default_library') == 'static') @@ -117,7 +117,7 @@ deps += dependency('zlib') wx_minver = '>=' + get_option('wx_version') if host_machine.system() == 'darwin' - wx_minver = '>=3.1.0' + wx_minver = '>=3.2.0' endif wx_dep = dependency('wxWidgets', version: wx_minver, required: false, @@ -139,15 +139,13 @@ else opt_var.add_cmake_defines({ 'CMAKE_BUILD_TYPE': build_type, - 'wxBUILD_INSTALL': false, - 'wxBUILD_PRECOMP': false, # otherwise breaks project generation w/ meson - 'wxBUILD_MONOLITHIC': true, # otherwise breaks project generation w/ meson + 'wxBUILD_COMPATIBILITY': '3.1', + 'wxBUILD_INSTALL': 'OFF', + 'wxBUILD_PRECOMP': 'OFF', # otherwise breaks project generation w/ meson + 'wxBUILD_MONOLITHIC': 'ON', # otherwise breaks project generation w/ meson 'wxBUILD_SHARED': build_shared, - 'WXWIN_COMPATIBILITY_2_4': false, - 'WXWIN_COMPATIBILITY_2_6': false, - 'WXWIN_COMPATIBILITY_2_8': false, - 'wxDIALOG_UNIT_COMPATIBILITY': false, + 'wxDIALOG_UNIT_COMPATIBILITY': 0, 'wxUSE_ON_FATAL_EXCEPTION': 1, 'wxUSE_STACKWALKER': 0, 'wxUSE_DEBUGREPORT': 0, @@ -175,7 +173,7 @@ else 'wxUSE_CONSOLE_EVENTLOOP': 1, 'wxUSE_FILE': 1, 'wxUSE_FFILE': 1, - 'wxUSE_FSVOLUME': 0, + 'wxUSE_FSVOLUME': 1, 'wxUSE_STDPATHS': 1, 'wxUSE_TEXTBUFFER': 0, 'wxUSE_TEXTFILE': 0, diff --git a/src/colour_button.cpp b/src/colour_button.cpp index 83671ebf3a..48a87856cd 100644 --- a/src/colour_button.cpp +++ b/src/colour_button.cpp @@ -18,11 +18,7 @@ #include "dialogs.h" -#if BOOST_VERSION >= 106900 #include -#else -#include -#endif AGI_DEFINE_EVENT(EVT_COLOR, agi::Color); diff --git a/src/dialog_colorpicker.cpp b/src/dialog_colorpicker.cpp index 510d2a6cec..eccdd7e3aa 100644 --- a/src/dialog_colorpicker.cpp +++ b/src/dialog_colorpicker.cpp @@ -398,8 +398,8 @@ void ColorPickerScreenDropper::DropFromScreenXY(int x, int y) { CGGetDisplaysWithPoint(CGPointMake(x, y), 1, &display_id, &display_count); agi::scoped_holder img(CGDisplayCreateImageForRect(display_id, CGRectMake(x - resx / 2, y - resy / 2, resx, resy)), CGImageRelease); - NSUInteger width = CGImageGetWidth(img); - NSUInteger height = CGImageGetHeight(img); + auto width = CGImageGetWidth(img); + auto height = CGImageGetHeight(img); std::vector imgdata(height * width * 4); agi::scoped_holder colorspace(CGColorSpaceCreateDeviceRGB(), CGColorSpaceRelease); diff --git a/src/dialog_translation.cpp b/src/dialog_translation.cpp index b47d01b4c4..b836c8259f 100644 --- a/src/dialog_translation.cpp +++ b/src/dialog_translation.cpp @@ -97,7 +97,7 @@ DialogTranslation::DialogTranslation(agi::Context *c) translated_text->SetMarginWidth(1, 0); translated_text->SetFocus(); translated_text->Bind(wxEVT_CHAR_HOOK, &DialogTranslation::OnKeyDown, this); - translated_text->CmdKeyAssign(wxSTC_KEY_RETURN, wxSTC_SCMOD_SHIFT, wxSTC_CMD_NEWLINE); + translated_text->CmdKeyAssign(wxSTC_KEY_RETURN, wxSTC_KEYMOD_SHIFT, wxSTC_CMD_NEWLINE); wxSizer *translated_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Translation")); translated_box->Add(translated_text, 1, wxEXPAND, 0); diff --git a/src/subs_edit_ctrl.cpp b/src/subs_edit_ctrl.cpp index 9d1fc6a016..eab2147c62 100644 --- a/src/subs_edit_ctrl.cpp +++ b/src/subs_edit_ctrl.cpp @@ -94,17 +94,17 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, a SetStyles(); // Set hotkeys - CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_SCMOD_CTRL); - CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_SCMOD_SHIFT); - CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_SCMOD_NORM); - CmdKeyClear(wxSTC_KEY_TAB,wxSTC_SCMOD_NORM); - CmdKeyClear(wxSTC_KEY_TAB,wxSTC_SCMOD_SHIFT); - CmdKeyClear('D',wxSTC_SCMOD_CTRL); - CmdKeyClear('L',wxSTC_SCMOD_CTRL); - CmdKeyClear('L',wxSTC_SCMOD_CTRL | wxSTC_SCMOD_SHIFT); - CmdKeyClear('T',wxSTC_SCMOD_CTRL); - CmdKeyClear('T',wxSTC_SCMOD_CTRL | wxSTC_SCMOD_SHIFT); - CmdKeyClear('U',wxSTC_SCMOD_CTRL); + CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_KEYMOD_CTRL); + CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_KEYMOD_SHIFT); + CmdKeyClear(wxSTC_KEY_RETURN,wxSTC_KEYMOD_NORM); + CmdKeyClear(wxSTC_KEY_TAB,wxSTC_KEYMOD_NORM); + CmdKeyClear(wxSTC_KEY_TAB,wxSTC_KEYMOD_SHIFT); + CmdKeyClear('D',wxSTC_KEYMOD_CTRL); + CmdKeyClear('L',wxSTC_KEYMOD_CTRL); + CmdKeyClear('L',wxSTC_KEYMOD_CTRL | wxSTC_KEYMOD_SHIFT); + CmdKeyClear('T',wxSTC_KEYMOD_CTRL); + CmdKeyClear('T',wxSTC_KEYMOD_CTRL | wxSTC_KEYMOD_SHIFT); + CmdKeyClear('U',wxSTC_KEYMOD_CTRL); using std::bind; diff --git a/src/video_frame.cpp b/src/video_frame.cpp index c7957d9647..c51f929ac5 100644 --- a/src/video_frame.cpp +++ b/src/video_frame.cpp @@ -16,11 +16,7 @@ #include "video_frame.h" -#if BOOST_VERSION >= 106900 #include -#else -#include -#endif #include namespace { diff --git a/subprojects/boost.wrap b/subprojects/boost.wrap index 1b20199811..93616f4b42 100644 --- a/subprojects/boost.wrap +++ b/subprojects/boost.wrap @@ -1,6 +1,6 @@ [wrap-file] -directory = boost_1_74_0 -source_url = https://boostorg.jfrog.io/artifactory/main/release/1.74.0/source/boost_1_74_0.tar.gz -source_filename = boost_1_74_0.tar.gz -source_hash = afff36d392885120bcac079148c177d1f6f7730ec3d47233aa51b0afa4db94a5 +directory = boost_1_80_0 +source_url = https://boostorg.jfrog.io/artifactory/main/release/1.80.0/source/boost_1_80_0.tar.gz +source_filename = boost_1_80_0.tar.gz +source_hash = 4b2136f98bdd1f5857f1c3dea9ac2018effe65286cf251534b6ae20cc45e1847 patch_directory = boost diff --git a/subprojects/fribidi.wrap b/subprojects/fribidi.wrap index 55458fca97..cefe18c947 100644 --- a/subprojects/fribidi.wrap +++ b/subprojects/fribidi.wrap @@ -1,7 +1,7 @@ [wrap-git] directory = fribidi url = https://github.com/fribidi/fribidi.git -revision = master +revision = v1.0.12 [provide] fribidi = libfribidi_dep diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap index 10caa4b4af..0a8de9e8b4 100644 --- a/subprojects/harfbuzz.wrap +++ b/subprojects/harfbuzz.wrap @@ -1,7 +1,7 @@ [wrap-git] directory = harfbuzz url = https://github.com/harfbuzz/harfbuzz -revision = main +revision = v5.1.0 [provide] harfbuzz = libharfbuzz_dep diff --git a/subprojects/packagefiles/boost/libs/filesystem/meson.build b/subprojects/packagefiles/boost/libs/filesystem/meson.build index b255d4c974..4650fad3d4 100644 --- a/subprojects/packagefiles/boost/libs/filesystem/meson.build +++ b/subprojects/packagefiles/boost/libs/filesystem/meson.build @@ -12,6 +12,7 @@ filesystem_sources = files([ ]) filesystem_args = ['-DBOOST_FILESYSTEM_SOURCE', + '-DBOOST_FILESYSTEM_NO_CXX20_ATOMIC_REF=1', is_static ? '-DBOOST_FILESYSTEM_STATIC_LINK=1' : '-DBOOST_FILESYSTEM_DYN_LINK=1'] filesystem_deps = [] diff --git a/subprojects/packagefiles/boost/libs/locale/meson.build b/subprojects/packagefiles/boost/libs/locale/meson.build index c52b18f7af..bf924aac01 100644 --- a/subprojects/packagefiles/boost/libs/locale/meson.build +++ b/subprojects/packagefiles/boost/libs/locale/meson.build @@ -1,77 +1,52 @@ locale_sources = files([ - 'src/encoding/codepage.cpp', - 'src/shared/date_time.cpp', - 'src/shared/format.cpp', - 'src/shared/formatting.cpp', - 'src/shared/generator.cpp', - 'src/shared/ids.cpp', - 'src/shared/localization_backend.cpp', - 'src/shared/message.cpp', - 'src/shared/mo_lambda.cpp', - 'src/util/codecvt_converter.cpp', - 'src/util/default_locale.cpp', - 'src/util/info.cpp', - 'src/util/locale_data.cpp', + 'src/boost/locale/encoding/codepage.cpp', + 'src/boost/locale/shared/date_time.cpp', + 'src/boost/locale/shared/format.cpp', + 'src/boost/locale/shared/formatting.cpp', + 'src/boost/locale/shared/generator.cpp', + 'src/boost/locale/shared/ids.cpp', + 'src/boost/locale/shared/localization_backend.cpp', + 'src/boost/locale/shared/message.cpp', + 'src/boost/locale/shared/mo_lambda.cpp', + 'src/boost/locale/util/codecvt_converter.cpp', + 'src/boost/locale/util/default_locale.cpp', + 'src/boost/locale/util/gregorian.cpp', + 'src/boost/locale/util/info.cpp', + 'src/boost/locale/util/locale_data.cpp', + # icu - 'src/icu/boundary.cpp', - 'src/icu/codecvt.cpp', - 'src/icu/collator.cpp', - 'src/icu/conversion.cpp', - 'src/icu/date_time.cpp', - 'src/icu/formatter.cpp', - 'src/icu/icu_backend.cpp', - 'src/icu/numeric.cpp', - 'src/icu/time_zone.cpp', - # std - docs say disabled by default on windows and solaris, - # but jamfile seemingly only disables on solaris - 'src/std/codecvt.cpp', - 'src/std/collate.cpp', - 'src/std/converter.cpp', - 'src/std/numeric.cpp', - 'src/std/std_backend.cpp', - # included if using posix, win32 or std backend (ie always) - 'src/util/gregorian.cpp', + 'src/boost/locale/icu/boundary.cpp', + 'src/boost/locale/icu/codecvt.cpp', + 'src/boost/locale/icu/collator.cpp', + 'src/boost/locale/icu/conversion.cpp', + 'src/boost/locale/icu/date_time.cpp', + 'src/boost/locale/icu/formatter.cpp', + 'src/boost/locale/icu/icu_backend.cpp', + 'src/boost/locale/icu/numeric.cpp', + 'src/boost/locale/icu/time_zone.cpp' ]) -locale_args = ['-DBOOST_THREAD_NO_LIB=1'] -locale_deps = [] +locale_args = [ + '-DBOOST_THREAD_NO_LIB=1', + '-DBOOST_LOCALE_NO_POSIX_BACKEND=1', + '-DBOOST_LOCALE_NO_WINAPI_BACKEND=1', + '-DBOOST_LOCALE_NO_STD_BACKEND=1', + '-DBOOST_LOCALE_WITH_ICONV=1', + '-DBOOST_LOCALE_WITH_ICU=1', +] if not is_static locale_args += '-DBOOST_LOCALE_DYN_LINK=1' endif -if host_machine.system() == 'windows' - locale_sources += files([ - 'src/win32/collate.cpp', - 'src/win32/converter.cpp', - 'src/win32/numeric.cpp', - 'src/win32/win_backend.cpp', - # included on windows/cygwin if std *or* win32 included - 'src/win32/lcid.cpp', - ]) - locale_args += '-DBOOST_LOCALE_NO_POSIX_BACKEND=1' -else - locale_sources += files([ - 'src/posix/collate.cpp', - 'src/posix/converter.cpp', - 'src/posix/numeric.cpp', - 'src/posix/codecvt.cpp', - 'src/posix/posix_backend.cpp', - ]) - locale_args += '-DBOOST_LOCALE_NO_WINAPI_BACKEND=1' -endif - cxx = meson.get_compiler('cpp') iconv_dep = cxx.find_library('iconv', required: false) if not (iconv_dep.found() or cxx.has_function('iconv_open')) iconv_dep = dependency('iconv') endif -locale_deps += iconv_dep -locale_args += '-DBOOST_LOCALE_WITH_ICONV=1' - -locale_deps += icu_deps -locale_args += '-DBOOST_LOCALE_WITH_ICU=1' +locale_deps = [iconv_dep, icu_deps] +inc = 'src' boost_locale = library('boost_locale', locale_sources, include_directories: inc, cpp_args: locale_args, diff --git a/subprojects/packagefiles/boost/libs/regex/meson.build b/subprojects/packagefiles/boost/libs/regex/meson.build index f073f33d80..1538cfe176 100644 --- a/subprojects/packagefiles/boost/libs/regex/meson.build +++ b/subprojects/packagefiles/boost/libs/regex/meson.build @@ -1,21 +1,8 @@ regex_sources = files([ - 'src/c_regex_traits.cpp', - 'src/cpp_regex_traits.cpp', - 'src/cregex.cpp', - 'src/fileiter.cpp', - 'src/icu.cpp', - 'src/instances.cpp', - 'src/posix_api.cpp', + # 'src/posix_api.cpp', 'src/regex.cpp', - 'src/regex_debug.cpp', - 'src/regex_raw_buffer.cpp', - 'src/regex_traits_defaults.cpp', 'src/static_mutex.cpp', - 'src/w32_regex_traits.cpp', - 'src/wc_regex_traits.cpp', - 'src/wide_posix_api.cpp', - 'src/winstances.cpp', - 'src/usinstances.cpp', + # 'src/wide_posix_api.cpp', ]) regex_args = ['-DBOOST_HAS_ICU=1'] @@ -24,6 +11,7 @@ if not is_static regex_args += '-DBOOST_REGEX_DYN_LINK=1' endif +inc = '../..' boost_regex = library('boost_regex', regex_sources, include_directories: inc, cpp_args: regex_args, diff --git a/subprojects/packagefiles/boost/meson.build b/subprojects/packagefiles/boost/meson.build index a0a9881d8b..6d7caa0020 100644 --- a/subprojects/packagefiles/boost/meson.build +++ b/subprojects/packagefiles/boost/meson.build @@ -1,5 +1,5 @@ project('boost', 'cpp', - version: '1.74.0', + version: '1.80.0', meson_version: '>=0.55.0') cpp = meson.get_compiler('cpp') diff --git a/subprojects/wxWidgets.wrap b/subprojects/wxWidgets.wrap index 949a03927c..5404fea3f7 100644 --- a/subprojects/wxWidgets.wrap +++ b/subprojects/wxWidgets.wrap @@ -1,5 +1,5 @@ [wrap-git] directory = wxWidgets url = https://github.com/wxWidgets/wxWidgets.git -revision = v3.1.4 +revision = v3.2.0 clone-recursive = true From ad39a1ce3ca41f7463aa4d5f9656b6357048f740 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 16 Aug 2022 12:38:34 -0700 Subject: [PATCH 03/13] Switch to building as C++20 --- libaegisub/ass/dialogue_parser.cpp | 27 +- libaegisub/ass/time.cpp | 2 +- libaegisub/ass/uuencode.cpp | 4 +- libaegisub/audio/provider_convert.cpp | 11 +- libaegisub/audio/provider_dummy.cpp | 8 +- libaegisub/audio/provider_hd.cpp | 5 +- libaegisub/audio/provider_lock.cpp | 3 +- libaegisub/audio/provider_pcm.cpp | 10 +- libaegisub/audio/provider_ram.cpp | 5 +- libaegisub/common/cajun/elements.cpp | 72 +++-- libaegisub/common/charset_6937.cpp | 4 +- libaegisub/common/charset_conv.cpp | 9 +- libaegisub/common/color.cpp | 10 +- libaegisub/common/dispatch.cpp | 4 +- libaegisub/common/file_mapping.cpp | 7 +- libaegisub/common/hotkey.cpp | 76 +++-- libaegisub/common/io.cpp | 5 +- libaegisub/common/json.cpp | 4 +- libaegisub/common/keyframe.cpp | 15 +- libaegisub/common/log.cpp | 4 +- libaegisub/common/mru.cpp | 28 +- libaegisub/common/option.cpp | 67 ++-- libaegisub/common/parser.cpp | 31 +- libaegisub/common/parser.h | 4 +- libaegisub/common/path.cpp | 5 +- libaegisub/common/thesaurus.cpp | 7 +- libaegisub/common/vfr.cpp | 8 +- .../include/libaegisub/ass/dialogue_parser.h | 10 +- libaegisub/include/libaegisub/ass/time.h | 3 +- .../include/libaegisub/cajun/elements.h | 16 +- libaegisub/include/libaegisub/color.h | 6 +- libaegisub/include/libaegisub/fs.h | 291 +++++++++--------- libaegisub/include/libaegisub/hotkey.h | 35 +-- libaegisub/include/libaegisub/json.h | 2 +- libaegisub/include/libaegisub/line_iterator.h | 1 - libaegisub/include/libaegisub/lua/utils.h | 15 +- libaegisub/include/libaegisub/make_unique.h | 24 -- libaegisub/include/libaegisub/mru.h | 21 +- libaegisub/include/libaegisub/option.h | 15 +- libaegisub/include/libaegisub/option_value.h | 22 +- libaegisub/include/libaegisub/signal.h | 33 +- libaegisub/include/libaegisub/spellchecker.h | 14 +- libaegisub/include/libaegisub/split.h | 93 +++--- libaegisub/include/libaegisub/util.h | 9 +- libaegisub/include/libaegisub/util_osx.h | 21 +- libaegisub/lua/modules.cpp | 4 +- libaegisub/lua/modules/re.cpp | 5 +- libaegisub/lua/script_reader.cpp | 6 +- libaegisub/lua/utils.cpp | 19 +- libaegisub/osx/spellchecker.mm | 67 ++-- libaegisub/osx/util.mm | 11 +- libaegisub/unix/access.cpp | 2 +- libaegisub/unix/fs.cpp | 2 +- libaegisub/unix/log.cpp | 4 +- libaegisub/unix/util.cpp | 14 +- libaegisub/windows/charset_conv_win.cpp | 4 +- meson.build | 4 +- src/ass_dialogue.cpp | 46 ++- src/ass_override.cpp | 15 +- src/ass_parser.cpp | 16 +- src/ass_style.cpp | 20 +- src/ass_style.h | 2 +- src/ass_style_storage.cpp | 3 +- src/async_video_provider.cpp | 4 +- src/audio_display.cpp | 13 +- src/audio_karaoke.cpp | 4 +- src/audio_marker.cpp | 8 +- src/audio_player.cpp | 10 +- src/audio_player_openal.cpp | 3 +- src/audio_provider_factory.cpp | 8 +- src/audio_provider_ffmpegsource.cpp | 3 +- src/audio_renderer.cpp | 3 +- src/audio_renderer_spectrum.cpp | 3 +- src/audio_timing_dialogue.cpp | 3 +- src/audio_timing_karaoke.cpp | 4 +- src/auto4_base.cpp | 14 +- src/auto4_lua.cpp | 7 +- src/auto4_lua.h | 2 +- src/auto4_lua_assfile.cpp | 54 ++-- src/auto4_lua_dialog.cpp | 35 ++- src/base_grid.cpp | 3 +- src/command/app.cpp | 33 +- src/command/audio.cpp | 63 ++-- src/command/automation.cpp | 9 +- src/command/command.cpp | 135 ++++---- src/command/command.h | 8 +- src/command/edit.cpp | 65 ++-- src/command/grid.cpp | 45 ++- src/command/help.cpp | 11 +- src/command/keyframe.cpp | 7 +- src/command/recent.cpp | 21 +- src/command/subtitle.cpp | 39 ++- src/command/time.cpp | 37 ++- src/command/timecode.cpp | 7 +- src/command/tool.cpp | 35 +-- src/command/video.cpp | 77 +++-- src/command/vis_tool.cpp | 17 +- src/compat.cpp | 23 +- src/compat.h | 9 +- src/context.cpp | 25 +- src/crash_writer_minidump.cpp | 3 +- src/dialog_colorpicker.cpp | 3 +- src/dialog_detached_video.cpp | 3 +- src/dialog_export_ebu3264.cpp | 17 +- src/dialog_fonts_collector.cpp | 5 +- src/dialog_resample.cpp | 2 +- src/dialog_search_replace.cpp | 3 +- src/dialog_shift_times.cpp | 13 +- src/dialog_style_editor.cpp | 5 +- src/dialog_style_manager.cpp | 12 +- src/dialog_styling_assistant.cpp | 4 +- src/dialog_translation.cpp | 4 +- src/factory_manager.h | 6 +- src/frame_main.cpp | 3 +- src/hotkey.cpp | 14 +- src/hotkey_data_view_model.cpp | 16 +- src/include/aegisub/hotkey.h | 9 +- src/libresrc/libresrc.h | 4 +- src/main.cpp | 14 +- src/menu.cpp | 11 +- src/mkv_wrap.cpp | 21 +- src/osx/osx_utils.mm | 5 - src/osx/retina_helper.mm | 30 +- src/preferences_base.cpp | 3 +- src/project.cpp | 12 +- src/resolution_resampler.cpp | 4 +- src/spellchecker.cpp | 3 +- src/spellchecker_hunspell.cpp | 9 +- src/spline.cpp | 2 +- src/string_codec.cpp | 7 +- src/string_codec.h | 6 +- src/subs_edit_box.cpp | 3 +- src/subs_edit_ctrl.cpp | 3 +- src/subs_preview.cpp | 11 +- src/subtitle_format.cpp | 21 +- src/subtitle_format_srt.cpp | 5 +- src/subtitles_provider_libass.cpp | 3 +- src/text_file_reader.cpp | 5 +- src/text_file_writer.cpp | 3 +- src/thesaurus.cpp | 3 +- src/timeedit_ctrl.cpp | 6 +- src/utils.h | 2 + src/video_display.cpp | 7 +- src/video_provider_cache.cpp | 3 +- src/video_provider_dummy.cpp | 5 +- src/video_provider_ffmpegsource.cpp | 3 +- src/video_provider_manager.cpp | 8 +- src/video_provider_yuv4mpeg.cpp | 3 +- src/visual_tool_cross.cpp | 3 +- src/visual_tool_drag.cpp | 7 +- src/visual_tool_vector_clip.cpp | 8 +- tests/support/main.cpp | 8 +- tests/tests/audio.cpp | 17 +- tests/tests/split.cpp | 10 +- tests/tests/syntax_highlight.cpp | 12 +- tests/tests/word_split.cpp | 2 +- 156 files changed, 1205 insertions(+), 1366 deletions(-) delete mode 100644 libaegisub/include/libaegisub/make_unique.h diff --git a/libaegisub/ass/dialogue_parser.cpp b/libaegisub/ass/dialogue_parser.cpp index ea486dcf71..719b652f41 100644 --- a/libaegisub/ass/dialogue_parser.cpp +++ b/libaegisub/ass/dialogue_parser.cpp @@ -21,17 +21,18 @@ #include #include #include +#include namespace { -typedef std::vector TokenVec; +using TokenVec = std::vector; using namespace agi::ass; namespace dt = DialogueTokenType; namespace ss = SyntaxStyle; class SyntaxHighlighter { TokenVec ranges; - std::string const& text; + std::string_view text; agi::SpellChecker *spellchecker; void SetStyling(size_t len, int type) { @@ -42,7 +43,7 @@ class SyntaxHighlighter { } public: - SyntaxHighlighter(std::string const& text, agi::SpellChecker *spellchecker) + SyntaxHighlighter(std::string_view text, agi::SpellChecker *spellchecker) : text(text) , spellchecker(spellchecker) { } @@ -91,7 +92,7 @@ class SyntaxHighlighter { }; class WordSplitter { - std::string const& text; + std::string_view text; std::vector &tokens; size_t pos = 0; @@ -108,9 +109,9 @@ class WordSplitter { void SplitText(size_t &i) { using namespace boost::locale::boundary; - ssegment_index map(word, text.begin() + pos, text.begin() + pos + tokens[i].length); + segment_index map(word, text.begin() + pos, text.begin() + pos + tokens[i].length); for (auto const& segment : map) { - auto len = static_cast(distance(begin(segment), end(segment))); + auto len = static_cast(boost::distance(segment)); if (segment.rule() & word_letters) SwitchTo(i, dt::WORD, len); else @@ -119,7 +120,7 @@ class WordSplitter { } public: - WordSplitter(std::string const& text, std::vector &tokens) + WordSplitter(std::string_view text, std::vector &tokens) : text(text) , tokens(tokens) { } @@ -137,14 +138,15 @@ class WordSplitter { }; } -namespace agi { -namespace ass { +namespace agi::ass { -std::vector SyntaxHighlight(std::string const& text, std::vector const& tokens, SpellChecker *spellchecker) { +std::vector SyntaxHighlight(std::string_view text, + std::vector const& tokens, + SpellChecker *spellchecker) { return SyntaxHighlighter(text, spellchecker).Highlight(tokens); } -void MarkDrawings(std::string const& str, std::vector &tokens) { +void MarkDrawings(std::string_view str, std::vector &tokens) { if (tokens.empty()) return; size_t last_ovr_end = 0; @@ -209,10 +211,9 @@ void MarkDrawings(std::string const& str, std::vector &tokens) { } } -void SplitWords(std::string const& str, std::vector &tokens) { +void SplitWords(std::string_view str, std::vector &tokens) { MarkDrawings(str, tokens); WordSplitter(str, tokens).SplitWords(); } } -} diff --git a/libaegisub/ass/time.cpp b/libaegisub/ass/time.cpp index b85f48a1f6..07367d229c 100644 --- a/libaegisub/ass/time.cpp +++ b/libaegisub/ass/time.cpp @@ -26,7 +26,7 @@ namespace agi { Time::Time(int time) : time(util::mid(0, time, 10 * 60 * 60 * 1000 - 6)) { } -Time::Time(std::string const& text) { +Time::Time(std::string_view text) { int after_decimal = -1; int current = 0; for (char c : text) { diff --git a/libaegisub/ass/uuencode.cpp b/libaegisub/ass/uuencode.cpp index 182472926c..893268d077 100644 --- a/libaegisub/ass/uuencode.cpp +++ b/libaegisub/ass/uuencode.cpp @@ -24,7 +24,7 @@ // characters, and files with non-multiple-of-three lengths are padded with // zero. -namespace agi { namespace ass { +namespace agi::ass { std::string UUEncode(const char *begin, const char *end, bool insert_linebreaks) { size_t size = std::distance(begin, end); @@ -82,4 +82,4 @@ std::vector UUDecode(const char *begin, const char *end) { return ret; } -} } +} diff --git a/libaegisub/audio/provider_convert.cpp b/libaegisub/audio/provider_convert.cpp index b45d8a852a..0feb2377d7 100644 --- a/libaegisub/audio/provider_convert.cpp +++ b/libaegisub/audio/provider_convert.cpp @@ -17,7 +17,6 @@ #include "libaegisub/audio/provider.h" #include -#include #include @@ -178,25 +177,25 @@ std::unique_ptr CreateConvertAudioProvider(std::unique_ptrAreSamplesFloat()) { LOG_D("audio_provider") << "Converting float to S16"; if (provider->GetBytesPerSample() == sizeof(float)) - provider = agi::make_unique>(std::move(provider)); + provider = std::make_unique>(std::move(provider)); else - provider = agi::make_unique>(std::move(provider)); + provider = std::make_unique>(std::move(provider)); } if (provider->GetBytesPerSample() != 2) { LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16"; - provider = agi::make_unique>(std::move(provider)); + provider = std::make_unique>(std::move(provider)); } // We currently only support mono audio if (provider->GetChannels() != 1) { LOG_D("audio_provider") << "Downmixing to mono from " << provider->GetChannels() << " channels"; - provider = agi::make_unique(std::move(provider)); + provider = std::make_unique(std::move(provider)); } // Some players don't like low sample rate audio while (provider->GetSampleRate() < 32000) { LOG_D("audio_provider") << "Doubling sample rate"; - provider = agi::make_unique(std::move(provider)); + provider = std::make_unique(std::move(provider)); } return provider; diff --git a/libaegisub/audio/provider_dummy.cpp b/libaegisub/audio/provider_dummy.cpp index 3e81ffb57d..01a6ae5b47 100644 --- a/libaegisub/audio/provider_dummy.cpp +++ b/libaegisub/audio/provider_dummy.cpp @@ -17,9 +17,7 @@ #include "libaegisub/audio/provider.h" #include "libaegisub/fs.h" -#include "libaegisub/make_unique.h" -#include #include /* @@ -61,7 +59,7 @@ class DummyAudioProvider final : public AudioProvider { public: DummyAudioProvider(agi::fs::path const& uri) { - noise = boost::contains(uri.string(), ":noise?"); + noise = uri.string().find(":noise?") != std::string::npos; channels = 1; sample_rate = 44100; bytes_per_sample = 2; @@ -73,8 +71,8 @@ class DummyAudioProvider final : public AudioProvider { namespace agi { std::unique_ptr CreateDummyAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *) { - if (!boost::starts_with(file.string(), "dummy-audio:")) + if (!file.string().starts_with("dummy-audio:")) return {}; - return agi::make_unique(file); + return std::make_unique(file); } } diff --git a/libaegisub/audio/provider_hd.cpp b/libaegisub/audio/provider_hd.cpp index 19e33eeed6..e36f7adde2 100644 --- a/libaegisub/audio/provider_hd.cpp +++ b/libaegisub/audio/provider_hd.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -75,7 +74,7 @@ class HDAudioProvider final : public AudioProviderWrapper { }); } - ~HDAudioProvider() { + ~HDAudioProvider() override { cancelled = true; decoder.join(); } @@ -84,6 +83,6 @@ class HDAudioProvider final : public AudioProviderWrapper { namespace agi { std::unique_ptr CreateHDAudioProvider(std::unique_ptr src, agi::fs::path const& dir) { - return agi::make_unique(std::move(src), dir); + return std::make_unique(std::move(src), dir); } } diff --git a/libaegisub/audio/provider_lock.cpp b/libaegisub/audio/provider_lock.cpp index eb397e4103..927eea7673 100644 --- a/libaegisub/audio/provider_lock.cpp +++ b/libaegisub/audio/provider_lock.cpp @@ -16,7 +16,6 @@ #include "libaegisub/audio/provider.h" -#include #include @@ -39,6 +38,6 @@ class LockAudioProvider final : public agi::AudioProviderWrapper { namespace agi { std::unique_ptr CreateLockAudioProvider(std::unique_ptr src) { - return agi::make_unique(std::move(src)); + return std::make_unique(std::move(src)); } } diff --git a/libaegisub/audio/provider_pcm.cpp b/libaegisub/audio/provider_pcm.cpp index 4131ecd2d2..9ca26a8491 100644 --- a/libaegisub/audio/provider_pcm.cpp +++ b/libaegisub/audio/provider_pcm.cpp @@ -18,7 +18,6 @@ #include "libaegisub/file_mapping.h" #include "libaegisub/fs.h" -#include "libaegisub/make_unique.h" #include #include @@ -106,7 +105,7 @@ struct RiffWav { static uint32_t chunk_size(uint32_t size) { return size; } }; -typedef std::array GUID; +using GUID = std::array; static const GUID w64GuidRIFF = {{ // {66666972-912E-11CF-A5D6-28DB04C10000} @@ -219,7 +218,7 @@ std::unique_ptr CreatePCMAudioProvider(fs::path const& filename, std::string msg; try { - return make_unique>(filename); + return std::make_unique>(filename); } catch (AudioDataNotFound const& err) { msg = "RIFF PCM WAV audio provider: " + err.GetMessage(); @@ -230,7 +229,7 @@ std::unique_ptr CreatePCMAudioProvider(fs::path const& filename, } try { - return make_unique>(filename); + return std::make_unique>(filename); } catch (AudioDataNotFound const& err) { msg += "\nWave64 audio provider: " + err.GetMessage(); @@ -242,7 +241,6 @@ std::unique_ptr CreatePCMAudioProvider(fs::path const& filename, if (wrong_file_type) throw AudioDataNotFound(msg); - else - throw AudioProviderError(msg); + throw AudioProviderError(msg); } } diff --git a/libaegisub/audio/provider_ram.cpp b/libaegisub/audio/provider_ram.cpp index 0c1da546c1..cc3c06828e 100644 --- a/libaegisub/audio/provider_ram.cpp +++ b/libaegisub/audio/provider_ram.cpp @@ -16,7 +16,6 @@ #include "libaegisub/audio/provider.h" -#include "libaegisub/make_unique.h" #include #include @@ -63,7 +62,7 @@ class RAMAudioProvider final : public AudioProviderWrapper { }); } - ~RAMAudioProvider() { + ~RAMAudioProvider() override { cancelled = true; decoder.join(); } @@ -91,6 +90,6 @@ void RAMAudioProvider::FillBuffer(void *buf, int64_t start, int64_t count) const namespace agi { std::unique_ptr CreateRAMAudioProvider(std::unique_ptr src) { - return agi::make_unique(std::move(src)); + return std::make_unique(std::move(src)); } } diff --git a/libaegisub/common/cajun/elements.cpp b/libaegisub/common/cajun/elements.cpp index b8f5a01744..a6d41f8d20 100644 --- a/libaegisub/common/cajun/elements.cpp +++ b/libaegisub/common/cajun/elements.cpp @@ -36,7 +36,7 @@ struct CastVisitor final : public CastVisitorBase { namespace json { class UnknownElement::Imp { public: - virtual ~Imp() {} + virtual ~Imp() = default; virtual void Accept(ConstVisitor& visitor) const = 0; virtual void Accept(Visitor& visitor) = 0; }; @@ -50,18 +50,20 @@ class Imp_T final : public UnknownElement::Imp { public: Imp_T(ElementTypeT element) : m_Element(std::move(element)) { } - void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); } - void Accept(Visitor& visitor) { visitor.Visit(m_Element); } + void Accept(ConstVisitor& visitor) const override { visitor.Visit(m_Element); } + void Accept(Visitor& visitor) override { visitor.Visit(m_Element); } }; } namespace json { -UnknownElement::UnknownElement() : m_pImp(new Imp_T(Null())) {} -UnknownElement::UnknownElement(UnknownElement&& unknown) : m_pImp(std::move(unknown.m_pImp)) {} +UnknownElement::UnknownElement() noexcept = default; UnknownElement::UnknownElement(int number) : m_pImp(new Imp_T(number)) {} UnknownElement::UnknownElement(const char *string) : m_pImp(new Imp_T(string)) {} +UnknownElement::UnknownElement(std::string_view string) : m_pImp(new Imp_T(String(string))) {} -UnknownElement::~UnknownElement() { } +UnknownElement::UnknownElement(UnknownElement&& unknown) noexcept = default; +UnknownElement& UnknownElement::operator=(UnknownElement&& unknown) noexcept = default; +UnknownElement::~UnknownElement() = default; #define DEFINE_UE_TYPE(Type) \ UnknownElement::UnknownElement(Type val) : m_pImp(new Imp_T(std::move(val))) { } \ @@ -76,37 +78,45 @@ DEFINE_UE_TYPE(Boolean) DEFINE_UE_TYPE(String) DEFINE_UE_TYPE(Null) -UnknownElement& UnknownElement::operator=(UnknownElement&& unknown) { - m_pImp = std::move(unknown.m_pImp); - return *this; -} - template ElementTypeT const& UnknownElement::CastTo() const { - CastVisitor castVisitor; - const_cast(this)->Accept(castVisitor); - if (!castVisitor.element) - throw Exception("Bad cast"); - return *castVisitor.element; + CastVisitor castVisitor; + const_cast(this)->Accept(castVisitor); + if (!castVisitor.element) + throw Exception("Bad cast"); + return *castVisitor.element; } template ElementTypeT& UnknownElement::CastTo() { - CastVisitor castVisitor; - Accept(castVisitor); - - // If this element is uninitialized, implicitly convert it to the desired type - if (castVisitor.is_null) { - *this = ElementTypeT(); - return *this; - } - - // Otherwise throw an exception - if (!castVisitor.element) - throw Exception("Bad cast"); - return *castVisitor.element; + CastVisitor castVisitor; + Accept(castVisitor); + + // If this element is uninitialized, implicitly convert it to the desired type + if (castVisitor.is_null) { + *this = ElementTypeT(); + return *this; + } + + // Otherwise throw an exception + if (!castVisitor.element) + throw Exception("Bad cast"); + return *castVisitor.element; } -void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } -void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } +void UnknownElement::Accept(ConstVisitor& visitor) const { + if (m_pImp) + m_pImp->Accept(visitor); + else + visitor.Visit(Null()); +} + +void UnknownElement::Accept(Visitor& visitor) { + if (m_pImp) + m_pImp->Accept(visitor); + else { + Null null; + visitor.Visit(null); + } +} } diff --git a/libaegisub/common/charset_6937.cpp b/libaegisub/common/charset_6937.cpp index c0e446a14e..b09372b422 100644 --- a/libaegisub/common/charset_6937.cpp +++ b/libaegisub/common/charset_6937.cpp @@ -167,7 +167,7 @@ int get_iso6937(int codepoint) { } // namespace { -namespace agi { namespace charset { +namespace agi::charset { #ifdef _LIBICONV_VERSION #define INTERNAL_CHARSET "UCS-4-INTERNAL" @@ -243,4 +243,4 @@ size_t Converter6937::Convert(const char **inbuf, size_t *inbytesleft, char **ou return bytes_written; } -} } // namespace agi::charset +} // namespace agi::charset diff --git a/libaegisub/common/charset_conv.cpp b/libaegisub/common/charset_conv.cpp index 47644eb1c9..ada87c8326 100644 --- a/libaegisub/common/charset_conv.cpp +++ b/libaegisub/common/charset_conv.cpp @@ -16,7 +16,7 @@ /// @brief Wrapper for libiconv to present a more C++-friendly API /// @ingroup libaegisub -#include +#include #include #include @@ -189,7 +189,7 @@ namespace { if (code == 0xFEFF) return; if (code == 0x5C) callback("\\", 1, callback_arg); else { - ConverterImpl *self = static_cast(convPtr); + auto *self = static_cast(convPtr); callback(self->invalidRep, self->invalidRepSize, callback_arg); } } @@ -271,7 +271,7 @@ namespace { } } // namespace { -namespace agi { namespace charset { +namespace agi::charset { Iconv::Iconv() : cd(iconv_invalid) { } Iconv::Iconv(const char *source, const char *dest) @@ -298,7 +298,7 @@ IconvWrapper::IconvWrapper(const char* sourceEncoding, const char* destEncoding, fromNulLen = nul_size(sourceEncoding); } -IconvWrapper::~IconvWrapper() { } +IconvWrapper::~IconvWrapper() = default; std::string IconvWrapper::Convert(const char *source, size_t len) { std::string dest; @@ -425,4 +425,3 @@ bool IsConversionSupported(const char *src, const char *dst) { } } -} diff --git a/libaegisub/common/color.cpp b/libaegisub/common/color.cpp index 7381e92ffc..e46a6cbdf1 100644 --- a/libaegisub/common/color.cpp +++ b/libaegisub/common/color.cpp @@ -24,7 +24,7 @@ Color::Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) : r(r), g(g), b(b), a(a) { } -Color::Color(std::string const& str) { +Color::Color(std::string_view str) { parser::parse(*this, str); } @@ -50,12 +50,4 @@ std::string Color::GetRgbFormatted() const { return agi::format("rgb(%d, %d, %d)", r, g, b); } -bool Color::operator==(Color const& col) const { - return r == col.r && g == col.g && b == col.b && a == col.a; -} - -bool Color::operator!=(Color const& col) const { - return !(*this == col); -} - } diff --git a/libaegisub/common/dispatch.cpp b/libaegisub/common/dispatch.cpp index 434195836e..98dfe0800a 100644 --- a/libaegisub/common/dispatch.cpp +++ b/libaegisub/common/dispatch.cpp @@ -72,7 +72,7 @@ namespace { }; } -namespace agi { namespace dispatch { +namespace agi::dispatch { void Init(std::function invoke_main) { static IOServiceThreadPool thread_pool; @@ -137,4 +137,4 @@ std::unique_ptr Create() { return std::unique_ptr(new SerialQueue); } -} } +} diff --git a/libaegisub/common/file_mapping.cpp b/libaegisub/common/file_mapping.cpp index 5102694963..3c11aabe2a 100644 --- a/libaegisub/common/file_mapping.cpp +++ b/libaegisub/common/file_mapping.cpp @@ -17,7 +17,6 @@ #include "libaegisub/file_mapping.h" #include "libaegisub/fs.h" -#include "libaegisub/make_unique.h" #include "libaegisub/util.h" #include @@ -62,7 +61,7 @@ char *map(int64_t s_offset, uint64_t length, boost::interprocess::mode_t mode, throw std::bad_alloc(); try { - region = agi::make_unique(file, mode, mapping_start, static_cast(length)); + region = std::make_unique(file, mode, mapping_start, static_cast(length)); } catch (interprocess_exception const&) { throw agi::fs::FileSystemUnknownError("Failed mapping a view of the file"); @@ -126,7 +125,7 @@ read_file_mapping::read_file_mapping(fs::path const& filename) file_size = static_cast(size); } -read_file_mapping::~read_file_mapping() { } +read_file_mapping::~read_file_mapping() = default; const char *read_file_mapping::read() { return read(0, size()); @@ -160,7 +159,7 @@ temp_file_mapping::temp_file_mapping(fs::path const& filename, uint64_t size) #endif } -temp_file_mapping::~temp_file_mapping() { } +temp_file_mapping::~temp_file_mapping() = default; const char *temp_file_mapping::read(int64_t offset, uint64_t length) { return map(offset, length, read_only, file_size, file, read_region, read_mapping_start); diff --git a/libaegisub/common/hotkey.cpp b/libaegisub/common/hotkey.cpp index a2cebeef93..48f9f776fb 100644 --- a/libaegisub/common/hotkey.cpp +++ b/libaegisub/common/hotkey.cpp @@ -23,30 +23,31 @@ #include #include #include +#include -namespace agi { namespace hotkey { +namespace agi::hotkey { namespace { struct combo_cmp { bool operator()(const Combo *a, const Combo *b) { return a->Str() < b->Str(); } - bool operator()(const Combo *a, std::string const& b) { + bool operator()(const Combo *a, std::string_view b) { return a->Str() < b; } - bool operator()(std::string const& a, const Combo *b) { + bool operator()(std::string_view a, const Combo *b) { return a < b->Str(); } }; struct hotkey_visitor : json::ConstVisitor { - std::string const& context; - std::string const& command; + std::string_view context; + std::string_view command; Hotkey::HotkeyMap& map; bool needs_backup = false; - hotkey_visitor(std::string const& context, std::string const& command, Hotkey::HotkeyMap& map) + hotkey_visitor(std::string_view context, std::string_view command, Hotkey::HotkeyMap& map) : context(context), command(command), map(map) { } void Visit(std::string const& string) override { @@ -85,7 +86,7 @@ struct hotkey_visitor : json::ConstVisitor { }; } -Hotkey::Hotkey(fs::path const& file, std::pair default_config) +Hotkey::Hotkey(fs::path const& file, std::string_view default_config) : config_file(file) { LOG_D("hotkey/init") << "Generating hotkeys."; @@ -96,7 +97,7 @@ Hotkey::Hotkey(fs::path const& file, std::pair default_con UpdateStrMap(); } -void Hotkey::BuildHotkey(std::string const& context, json::Object const& hotkeys) { +void Hotkey::BuildHotkey(std::string_view context, json::Object const& hotkeys) { for (auto const& command : hotkeys) { json::Array const& command_hotkeys = command.second; @@ -107,50 +108,48 @@ void Hotkey::BuildHotkey(std::string const& context, json::Object const& hotkeys } } -std::string Hotkey::Scan(std::string const& context, std::string const& str, bool always) const { - const std::string *local = nullptr, *dfault = nullptr; +std::string_view Hotkey::Scan(std::string_view context, std::string_view str, bool always) const { + std::string_view local, dfault; - std::vector::const_iterator index, end; - for (std::tie(index, end) = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) { - std::string const& ctext = (*index)->Context(); + for (auto [index, end] = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) { + std::string_view ctext = (*index)->Context(); if (always && ctext == "Always") { LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Always Command: " << (*index)->CmdName(); return (*index)->CmdName(); } if (ctext == "Default") - dfault = &(*index)->CmdName(); + dfault = (*index)->CmdName(); else if (ctext == context) - local = &(*index)->CmdName(); + local = (*index)->CmdName(); } - if (local) { - LOG_D("agi/hotkey/found") << "Found: " << str << " Context: " << context << " Command: " << *local; - return *local; + if (local.data()) { + LOG_D("agi/hotkey/found") << "Found: " << str << " Context: " << context << " Command: " << local; + return local; } - if (dfault) { - LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Default Command: " << *dfault; - return *dfault; + if (dfault.data()) { + LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Default Command: " << dfault; + return dfault; } return ""; } -bool Hotkey::HasHotkey(std::string const& context, std::string const& str) const { - std::vector::const_iterator index, end; - for (std::tie(index, end) = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) { +bool Hotkey::HasHotkey(std::string_view context, std::string_view str) const { + for (auto [index, end] = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) { if (context == (*index)->Context()) return true; } return false; } -std::vector Hotkey::GetHotkeys(std::string const& context, std::string const& command) const { +std::vector Hotkey::GetHotkeys(std::string_view context, std::string_view command) const { std::vector ret; HotkeyMap::const_iterator it, end; - for (std::tie(it, end) = cmd_map.equal_range(command); it != end; ++it) { - std::string const& ctext = it->second.Context(); + for (auto [it, end] = cmd_map.equal_range(command); it != end; ++it) { + std::string_view ctext = it->second.Context(); if (ctext == "Always" || ctext == "Default" || ctext == context) ret.emplace_back(it->second.Str()); } @@ -161,11 +160,10 @@ std::vector Hotkey::GetHotkeys(std::string const& context, std::str return ret; } -std::string Hotkey::GetHotkey(std::string const& context, std::string const& command) const { - std::string ret; - HotkeyMap::const_iterator it, end; - for (std::tie(it, end) = cmd_map.equal_range(command); it != end; ++it) { - std::string const& ctext = it->second.Context(); +std::string_view Hotkey::GetHotkey(std::string_view context, std::string_view command) const { + std::string_view ret; + for (auto [it, end] = cmd_map.equal_range(command); it != end; ++it) { + std::string_view ctext = it->second.Context(); if (ctext == context) return it->second.Str(); if (ctext == "Default") ret = it->second.Str(); @@ -178,13 +176,13 @@ std::string Hotkey::GetHotkey(std::string const& context, std::string const& com void Hotkey::Flush() { json::Object root; - for (auto const& combo : str_map) { - auto const& keys = combo->Str(); - if (keys.empty()) continue; + auto get = [](json::Object& obj, std::string_view key) -> json::UnknownElement& { + return obj.emplace(key, json::UnknownElement()).first->second; + }; - json::Object& context = root[combo->Context()]; - json::Array& combo_array = context[combo->CmdName()]; - combo_array.push_back(keys); + for (auto const& combo : str_map) { + json::Object& context = get(root, combo->Context()); + static_cast(get(context, combo->CmdName())).push_back(combo->Str()); } if (backup_config_file && fs::FileExists(config_file) && !fs::FileExists(config_file.string() + ".3_1")) @@ -210,4 +208,4 @@ void Hotkey::SetHotkeyMap(HotkeyMap new_map) { HotkeysChanged(); } -} } +} diff --git a/libaegisub/common/io.cpp b/libaegisub/common/io.cpp index e133a71abb..f1825d745b 100644 --- a/libaegisub/common/io.cpp +++ b/libaegisub/common/io.cpp @@ -21,7 +21,6 @@ #include #include "libaegisub/fs.h" #include "libaegisub/log.h" -#include "libaegisub/make_unique.h" #include "libaegisub/util.h" #include @@ -33,7 +32,7 @@ namespace agi { std::unique_ptr Open(fs::path const& file, bool binary) { LOG_D("agi/io/open/file") << file; - auto stream = agi::make_unique(file, (binary ? std::ios::binary : std::ios::in)); + auto stream = std::make_unique(file, (binary ? std::ios::binary : std::ios::in)); if (stream->fail()) { acs::CheckFileRead(file); throw IOFatal("Unknown fatal error occurred opening " + file.string()); @@ -48,7 +47,7 @@ Save::Save(fs::path const& file, bool binary) { LOG_D("agi/io/save/file") << file; - fp = agi::make_unique(tmp_name, binary ? std::ios::binary : std::ios::out); + fp = std::make_unique(tmp_name, binary ? std::ios::binary : std::ios::out); if (!fp->good()) { acs::CheckDirWrite(file.parent_path()); acs::CheckFileWrite(file); diff --git a/libaegisub/common/json.cpp b/libaegisub/common/json.cpp index 493ca2f5d8..52fdcdbaff 100644 --- a/libaegisub/common/json.cpp +++ b/libaegisub/common/json.cpp @@ -41,7 +41,7 @@ json::UnknownElement parse(std::istream &stream) { } } -json::UnknownElement file(agi::fs::path const& file, std::pair default_config) { +json::UnknownElement file(agi::fs::path const& file, std::string_view default_config) { try { if (fs::FileExists(file)) return parse(*io::Open(file)); @@ -55,7 +55,7 @@ json::UnknownElement file(agi::fs::path const& file, std::pair #include namespace { @@ -34,7 +33,7 @@ std::vector agi_keyframes(std::istream &file) { file >> fps_str; file >> fps; - return std::vector(agi::line_iterator(file), agi::line_iterator()); + return {agi::line_iterator(file), agi::line_iterator()}; } std::vector enumerated_keyframes(std::istream &file, char (*func)(std::string const&)) { @@ -112,12 +111,12 @@ std::vector Load(agi::fs::path const& filename) { getline(is, header); if (header == "# keyframe format v1") return agi_keyframes(is); - if (boost::starts_with(header, "# XviD 2pass stat file")) return enumerated_keyframes(is, xvid); - if (boost::starts_with(header, "# ffmpeg 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid); - if (boost::starts_with(header, "# avconv 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid); - if (boost::starts_with(header, "##map version")) return enumerated_keyframes(is, divx); - if (boost::starts_with(header, "#options:")) return enumerated_keyframes(is, x264); - if (boost::starts_with(header, "# WWXD log file, using qpfile format")) return indexed_keyframes(is, wwxd); + if (header.starts_with("# XviD 2pass stat file")) return enumerated_keyframes(is, xvid); + if (header.starts_with("# ffmpeg 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid); + if (header.starts_with("# avconv 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid); + if (header.starts_with("##map version")) return enumerated_keyframes(is, divx); + if (header.starts_with("#options:")) return enumerated_keyframes(is, x264); + if (header.starts_with("# WWXD log file, using qpfile format")) return indexed_keyframes(is, wwxd); throw UnknownKeyframeFormatError("File header does not match any known formats"); } diff --git a/libaegisub/common/log.cpp b/libaegisub/common/log.cpp index 5750330218..dd2a49382b 100644 --- a/libaegisub/common/log.cpp +++ b/libaegisub/common/log.cpp @@ -25,7 +25,7 @@ #include #include -namespace agi { namespace log { +namespace agi::log { /// Global log sink. LogSink *log; @@ -117,4 +117,4 @@ void JsonEmitter::log(SinkMessage const& sm) { fp->flush(); } -} } +} diff --git a/libaegisub/common/mru.cpp b/libaegisub/common/mru.cpp index dd7cfde92b..b92e827062 100644 --- a/libaegisub/common/mru.cpp +++ b/libaegisub/common/mru.cpp @@ -23,7 +23,7 @@ #include "libaegisub/option_value.h" namespace { -const char *mru_names[] = { +std::string_view mru_names[] = { "Audio", "Find", "Keyframes", @@ -33,7 +33,7 @@ const char *mru_names[] = { "Video", }; -const char *option_names[] = { +std::string_view option_names[] = { "Limits/MRU", "Limits/Find Replace", "Limits/MRU", @@ -43,9 +43,9 @@ const char *option_names[] = { "Limits/MRU", }; -int mru_index(const char *key) { +int mru_index(std::string_view key) { int i; - switch (*key) { + switch (key[0]) { case 'A': i = 0; break; case 'F': i = 1; break; case 'K': i = 2; break; @@ -55,12 +55,12 @@ int mru_index(const char *key) { case 'V': i = 6; break; default: return -1; } - return strcmp(key, mru_names[i]) == 0 ? i : -1; + return key == mru_names[i] ? i : -1; } } namespace agi { -MRUManager::MRUManager(agi::fs::path const& config, std::pair default_config, agi::Options *options) +MRUManager::MRUManager(agi::fs::path const& config, std::string_view default_config, agi::Options *options) : config_name(config) , options(options) { @@ -71,14 +71,14 @@ MRUManager::MRUManager(agi::fs::path const& config, std::pair= map->size()) throw MRUError("Requested element index is out of range."); @@ -115,7 +115,7 @@ void MRUManager::Flush() { json::Object out; for (size_t i = 0; i < mru.size(); ++i) { - json::Array &array = out[mru_names[i]]; + json::Array &array = out.emplace(mru_names[i], json::Array()).first->second; for (auto const& p : mru[i]) array.push_back(p.string()); } @@ -123,7 +123,7 @@ void MRUManager::Flush() { agi::JsonWriter::Write(out, io::Save(config_name).Get()); } -void MRUManager::Prune(const char *key, MRUListMap& map) const { +void MRUManager::Prune(std::string_view key, MRUListMap& map) const { size_t limit = 16u; if (options) { int idx = mru_index(key); @@ -133,7 +133,7 @@ void MRUManager::Prune(const char *key, MRUListMap& map) const { map.resize(std::min(limit, map.size())); } -void MRUManager::Load(const char *key, const json::Array& array) { +void MRUManager::Load(std::string_view key, const json::Array& array) { int idx = mru_index(key); if (idx == -1) return; diff --git a/libaegisub/common/option.cpp b/libaegisub/common/option.cpp index cdf5a07b89..f41e987238 100644 --- a/libaegisub/common/option.cpp +++ b/libaegisub/common/option.cpp @@ -12,10 +12,6 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file option.cpp -/// @brief Option interface. -/// @ingroup libaegisub - #include "libaegisub/option.h" #include "libaegisub/cajun/reader.h" @@ -28,9 +24,7 @@ #include "libaegisub/io.h" #include "libaegisub/log.h" #include "libaegisub/option_value.h" -#include "libaegisub/make_unique.h" -#include #include #include #include @@ -51,23 +45,22 @@ class ConfigVisitor final : public json::ConstVisitor { bool ignore_errors; void Error(const char *message) { - if (ignore_errors) - LOG_E("option/load/config_visitor") << "Error loading option from user configuration: " << message; - else + if (!ignore_errors) throw OptionJsonValueError(message); + LOG_E("option/load/config_visitor") << "Error loading option from user configuration: " << message; } template - void ReadArray(json::Array const& src, std::string const& array_type) { + void ReadArray(json::Array const& src) { typename OptionValueType::value_type arr; arr.reserve(src.size()); for (json::Object const& obj : src) - arr.push_back((typename OptionValueType::value_type::value_type)(obj.begin()->second)); + arr.emplace_back(static_cast((obj.begin()->second))); - values.push_back(agi::make_unique(name, std::move(arr))); + values.push_back(std::make_unique(name, std::move(arr))); } - void Visit(const json::Object& object) { + void Visit(const json::Object& object) override { auto old_name = name; for (auto const& obj : object) { name = old_name + (old_name.empty() ? "" : "/") + obj.first; @@ -76,7 +69,7 @@ class ConfigVisitor final : public json::ConstVisitor { name = old_name; } - void Visit(const json::Array& array) { + void Visit(const json::Array& array) override { if (array.empty()) return Error("Cannot infer the type of an empty array"); @@ -93,45 +86,45 @@ class ConfigVisitor final : public json::ConstVisitor { } if (array_type == "string") - ReadArray(array, array_type); + ReadArray(array); else if (array_type == "int") - ReadArray(array, array_type); + ReadArray(array); else if (array_type == "double") - ReadArray(array, array_type); + ReadArray(array); else if (array_type == "bool") - ReadArray(array, array_type); + ReadArray(array); else if (array_type == "color") - ReadArray(array, array_type); + ReadArray(array); else Error("Array type not handled"); } - void Visit(int64_t number) { - values.push_back(agi::make_unique(name, number)); + void Visit(int64_t number) override { + values.push_back(std::make_unique(name, number)); } - void Visit(double number) { - values.push_back(agi::make_unique(name, number)); + void Visit(double number) override { + values.push_back(std::make_unique(name, number)); } - void Visit(const json::String& string) { + void Visit(const json::String& string) override { size_t size = string.size(); if ((size == 4 && string[0] == '#') || (size == 7 && string[0] == '#') || - (size >= 10 && boost::starts_with(string, "rgb(")) || - ((size == 9 || size == 10) && boost::starts_with(string, "&H"))) + (size >= 10 && string.starts_with("rgb(")) || + ((size == 9 || size == 10) && string.starts_with("&H"))) { - values.push_back(agi::make_unique(name, string)); + values.push_back(std::make_unique(name, agi::Color(string))); } else { - values.push_back(agi::make_unique(name, string)); + values.push_back(std::make_unique(name, string)); } } - void Visit(bool boolean) { - values.push_back(agi::make_unique(name, boolean)); + void Visit(bool boolean) override { + values.push_back(std::make_unique(name, boolean)); } - void Visit(const json::Null& null) { + void Visit(const json::Null& null) override { Error("Attempt to read null value"); } @@ -169,11 +162,7 @@ struct option_name_cmp { return a->GetName() < b->GetName(); } - bool operator()(std::unique_ptr const& a, std::string const& b) const { - return a->GetName() < b; - } - - bool operator()(std::unique_ptr const& a, const char *b) const { + bool operator()(std::unique_ptr const& a, std::string_view b) const { return a->GetName() < b; } }; @@ -182,12 +171,12 @@ struct option_name_cmp { namespace agi { -Options::Options(agi::fs::path const& file, std::pair default_config, const OptionSetting setting) +Options::Options(agi::fs::path const& file, std::string_view default_config, const OptionSetting setting) : config_file(file) , setting(setting) { LOG_D("agi/options") << "New Options object"; - boost::interprocess::ibufferstream stream(default_config.first, default_config.second); + boost::interprocess::ibufferstream stream(default_config.data(), default_config.size()); LoadConfig(stream); } @@ -258,7 +247,7 @@ void Options::LoadConfig(std::istream& stream, bool ignore_errors) { } } -OptionValue *Options::Get(const char *name) { +OptionValue *Options::Get(std::string_view name) { auto index = lower_bound(begin(values), end(values), name, option_name_cmp()); if (index != end(values) && (*index)->GetName() == name) return index->get(); diff --git a/libaegisub/common/parser.cpp b/libaegisub/common/parser.cpp index 94c0486bcf..90b4734c07 100644 --- a/libaegisub/common/parser.cpp +++ b/libaegisub/common/parser.cpp @@ -42,7 +42,7 @@ using namespace boost::spirit; /// Convert a abgr value in an int or unsigned int to an agi::Color struct unpack_colors : public boost::static_visitor { - template struct result { typedef agi::Color type; }; + template struct result { using type = agi::Color; }; template agi::Color operator()(T arg) const { return boost::apply_visitor(*this, arg); @@ -103,7 +103,7 @@ struct color_grammar : qi::grammar { template struct dialogue_tokens final : lex::lexer { - int paren_depth; + int paren_depth = 0; template void init(KT &&kara_templater) { @@ -162,7 +162,7 @@ struct dialogue_tokens final : lex::lexer { ; } - dialogue_tokens(bool karaoke_templater) : paren_depth(0) { + dialogue_tokens(bool karaoke_templater) { using lex::string; using namespace agi::ass::DialogueTokenType; @@ -174,13 +174,13 @@ struct dialogue_tokens final : lex::lexer { }; template -bool do_try_parse(std::string const& str, Parser parser, T *out) { +bool do_try_parse(std::string_view str, Parser parser, T *out) { using namespace boost::spirit::qi; T res; - char const* cstr = str.c_str(); + auto cstr = str.data(), end = str.data() + str.size(); - bool parsed = parse(cstr, cstr + str.size(), parser, res); - if (parsed && cstr == &str[str.size()]) { + bool parsed = parse(cstr, end, parser, res); + if (parsed && cstr == end) { *out = res; return true; } @@ -192,20 +192,21 @@ bool do_try_parse(std::string const& str, Parser parser, T *out) { namespace agi { namespace parser { - bool parse(Color &dst, std::string const& str) { - std::string::const_iterator begin = str.begin(); - bool parsed = parse(begin, str.end(), color_grammar(), dst); - return parsed && begin == str.end(); + bool parse(Color &dst, std::string_view str) { + if (str.empty()) return false; + auto begin = str.data(), end = str.data() + str.size(); + bool parsed = parse(begin, end, color_grammar(), dst); + return parsed && begin == end; } } namespace ass { - std::vector TokenizeDialogueBody(std::string const& str, bool karaoke_templater) { + std::vector TokenizeDialogueBody(std::string_view str, bool karaoke_templater) { static const dialogue_tokens> kt(true); static const dialogue_tokens> not_kt(false); auto const& tokenizer = karaoke_templater ? kt : not_kt; - char const *first = str.c_str(); + char const *first = str.data(); char const *last = first + str.size(); std::vector data; auto it = tokenizer.begin(first, last), end = tokenizer.end(); @@ -226,11 +227,11 @@ namespace ass { namespace util { // from util.h - bool try_parse(std::string const& str, double *out) { + bool try_parse(std::string_view str, double *out) { return do_try_parse(str, boost::spirit::qi::double_, out); } - bool try_parse(std::string const& str, int *out) { + bool try_parse(std::string_view str, int *out) { return do_try_parse(str, boost::spirit::qi::int_, out); } } diff --git a/libaegisub/common/parser.h b/libaegisub/common/parser.h index d83ffb0bd6..49cae2ed2d 100644 --- a/libaegisub/common/parser.h +++ b/libaegisub/common/parser.h @@ -12,7 +12,7 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -#include +#include namespace agi { struct Color; @@ -34,6 +34,6 @@ namespace agi { /// * CSS-style rgb(r,g,b) /// /// CSS's rgb(r%,g%,b%) format is not currently supported. - bool parse(Color &dst, std::string const& str); + bool parse(Color &dst, std::string_view str); } } diff --git a/libaegisub/common/path.cpp b/libaegisub/common/path.cpp index cca7302cc5..610cbdebe6 100644 --- a/libaegisub/common/path.cpp +++ b/libaegisub/common/path.cpp @@ -18,7 +18,6 @@ #include "libaegisub/fs.h" -#include #include namespace { @@ -78,7 +77,7 @@ fs::path Path::MakeRelative(fs::path const& path, fs::path const& base) const { if (path.empty() || base.empty()) return path; const auto str = path.string(); - if (boost::starts_with(str, "?dummy") || boost::starts_with(str, "dummy-audio:")) + if (str.starts_with("?dummy") || str.starts_with("dummy-audio:")) return path; // Paths on different volumes can't be made relative to each other @@ -105,7 +104,7 @@ fs::path Path::MakeAbsolute(fs::path path, std::string const& token) const { path.make_preferred(); const auto str = path.string(); - if (boost::starts_with(str, "?dummy") || boost::starts_with(str, "dummy-audio:")) + if (str.starts_with("?dummy") || str.starts_with("dummy-audio:")) return path; return (paths[idx].empty() || path.is_absolute()) ? path : paths[idx]/path; } diff --git a/libaegisub/common/thesaurus.cpp b/libaegisub/common/thesaurus.cpp index 9d914be773..7f21d64e04 100644 --- a/libaegisub/common/thesaurus.cpp +++ b/libaegisub/common/thesaurus.cpp @@ -21,7 +21,6 @@ #include "libaegisub/charset_conv.h" #include "libaegisub/file_mapping.h" #include "libaegisub/line_iterator.h" -#include "libaegisub/make_unique.h" #include "libaegisub/split.h" #include @@ -29,7 +28,7 @@ namespace agi { Thesaurus::Thesaurus(agi::fs::path const& dat_path, agi::fs::path const& idx_path) -: dat(make_unique(dat_path)) +: dat(std::make_unique(dat_path)) { read_file_mapping idx_file(idx_path); boost::interprocess::ibufferstream idx(idx_file.read(), static_cast(idx_file.size())); @@ -39,7 +38,7 @@ Thesaurus::Thesaurus(agi::fs::path const& dat_path, agi::fs::path const& idx_pat std::string unused_entry_count; getline(idx, unused_entry_count); - conv = make_unique(encoding_name.c_str(), "utf-8"); + conv = std::make_unique(encoding_name.c_str(), "utf-8"); // Read the list of words and file offsets for those words for (auto const& line : line_iterator(idx, encoding_name)) { @@ -49,7 +48,7 @@ Thesaurus::Thesaurus(agi::fs::path const& dat_path, agi::fs::path const& idx_pat } } -Thesaurus::~Thesaurus() { } +Thesaurus::~Thesaurus() = default; std::vector Thesaurus::Lookup(std::string const& word) { std::vector out; diff --git a/libaegisub/common/vfr.cpp b/libaegisub/common/vfr.cpp index c82fcdbeed..44bb1cf4fc 100644 --- a/libaegisub/common/vfr.cpp +++ b/libaegisub/common/vfr.cpp @@ -57,14 +57,14 @@ struct TimecodeRange { int start; int end; double fps; - bool operator<(TimecodeRange const& cmp) const { return start < cmp.start; } + auto operator<=>(TimecodeRange const& cmp) const { return start <=> cmp.start; } }; /// @brief Parse a single line of a v1 timecode file /// @param str Line to parse /// @return The line in TimecodeRange form, or TimecodeRange() if it's a comment TimecodeRange v1_parse_line(std::string const& str) { - if (str.empty() || str[0] == '#') return TimecodeRange(); + if (str.empty() || str[0] == '#') return {}; boost::interprocess::ibufferstream ss(str.data(), str.size()); TimecodeRange range; @@ -130,7 +130,7 @@ int64_t v1_parse(line_iterator file, std::string line, std::vector< } } -namespace agi { namespace vfr { +namespace agi::vfr { Framerate::Framerate(double fps) : denominator(default_denominator) , numerator(int64_t(fps * denominator)) @@ -321,4 +321,4 @@ int Framerate::TimeAtSmpte(int h, int m, int s, int f) const { return TimeAtFrame(FrameAtSmpte(h, m, s, f)); } -} } +} diff --git a/libaegisub/include/libaegisub/ass/dialogue_parser.h b/libaegisub/include/libaegisub/ass/dialogue_parser.h index 0aa3f9962b..19c3f61b77 100644 --- a/libaegisub/include/libaegisub/ass/dialogue_parser.h +++ b/libaegisub/include/libaegisub/ass/dialogue_parser.h @@ -69,15 +69,17 @@ namespace agi { }; /// Tokenize the passed string as the body of a dialogue line - std::vector TokenizeDialogueBody(std::string const& str, bool karaoke_templater=false); + std::vector TokenizeDialogueBody(std::string_view str, bool karaoke_templater=false); /// Convert the body of drawings to DRAWING tokens - void MarkDrawings(std::string const& str, std::vector &tokens); + void MarkDrawings(std::string_view str, std::vector &tokens); /// Split the words in the TEXT tokens of the lexed line into their /// own tokens and convert the body of drawings to DRAWING tokens - void SplitWords(std::string const& str, std::vector &tokens); + void SplitWords(std::string_view str, std::vector &tokens); - std::vector SyntaxHighlight(std::string const& text, std::vector const& tokens, SpellChecker *spellchecker); + std::vector SyntaxHighlight(std::string_view text, + std::vector const& tokens, + SpellChecker *spellchecker); } } diff --git a/libaegisub/include/libaegisub/ass/time.h b/libaegisub/include/libaegisub/ass/time.h index 622052ceae..ef0a6c26fd 100644 --- a/libaegisub/include/libaegisub/ass/time.h +++ b/libaegisub/include/libaegisub/ass/time.h @@ -17,6 +17,7 @@ #pragma once #include +#include namespace agi { class Time { @@ -25,7 +26,7 @@ class Time { public: Time(int ms = 0); - Time(std::string const& text); + Time(std::string_view text); /// Get millisecond, rounded to centisecond precision // Always round up for 5ms because the range is [start, stop) diff --git a/libaegisub/include/libaegisub/cajun/elements.h b/libaegisub/include/libaegisub/cajun/elements.h index 1ba4b06960..392a26feda 100644 --- a/libaegisub/include/libaegisub/cajun/elements.h +++ b/libaegisub/include/libaegisub/cajun/elements.h @@ -11,8 +11,9 @@ Author: Terry Caton #include #include #include -#include #include +#include +#include #include namespace json { @@ -28,16 +29,15 @@ typedef double Double; typedef bool Boolean; typedef std::string String; typedef std::vector Array; -typedef std::map Object; +typedef std::map> Object; struct Null; - ///////////////////////////////////////////////////////////////////////// // Exception - base class for all JSON-related runtime errors class Exception : public std::runtime_error { public: - Exception(const std::string& sMessage) : std::runtime_error(sMessage) { } + Exception(const std::string& sMessage) : std::runtime_error(sMessage) { } }; ///////////////////////////////////////////////////////////////////////// @@ -55,8 +55,8 @@ class Exception : public std::runtime_error { // String str = objInvoices[1]["Customer"]["Company"]; class UnknownElement { public: - UnknownElement(); - UnknownElement(UnknownElement&& unknown); + UnknownElement() noexcept; + UnknownElement(UnknownElement&& unknown) noexcept; UnknownElement(Object object); UnknownElement(Array array); UnknownElement(double number); @@ -65,11 +65,12 @@ class UnknownElement { UnknownElement(bool boolean); UnknownElement(const char *string); UnknownElement(String string); + UnknownElement(std::string_view string); UnknownElement(Null null); ~UnknownElement(); - UnknownElement& operator=(UnknownElement&& unknown); + UnknownElement& operator=(UnknownElement&& unknown) noexcept; // implicit cast to actual element type. throws on failure operator Object const&() const; @@ -86,6 +87,7 @@ class UnknownElement { operator Boolean&(); operator String&(); operator Null&(); + operator std::string_view(); // implements visitor pattern void Accept(ConstVisitor& visitor) const; diff --git a/libaegisub/include/libaegisub/color.h b/libaegisub/include/libaegisub/color.h index b61b39f209..193976a5ae 100644 --- a/libaegisub/include/libaegisub/color.h +++ b/libaegisub/include/libaegisub/color.h @@ -15,6 +15,7 @@ #pragma once #include +#include namespace agi { struct Color { @@ -25,10 +26,9 @@ namespace agi { Color() = default; Color(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 0); - Color(std::string const& str); + Color(std::string_view str); - bool operator==(Color const& col) const; - bool operator!=(Color const& col) const; + bool operator==(Color const&) const noexcept = default; std::string GetAssStyleFormatted() const; std::string GetAssOverrideFormatted() const; diff --git a/libaegisub/include/libaegisub/fs.h b/libaegisub/include/libaegisub/fs.h index 6b3e212ceb..295a01d5a4 100644 --- a/libaegisub/include/libaegisub/fs.h +++ b/libaegisub/include/libaegisub/fs.h @@ -26,152 +26,149 @@ #undef CreateDirectory -namespace agi { - namespace fs { - /// Define a filesystem error which takes a path or a string -#define DEFINE_FS_EXCEPTION(type, base, message) \ - struct type : public base { \ - type(path const& p) : base(message + p.string()) { } \ - type(std::string const& s) : base(s) { } \ - const char *GetName() const { return ""; } \ - Exception *Copy() const { return new type(*this); } \ - } - - /// @class agi::FileSystemError - /// @extends agi::Exception - /// @brief Base class for errors related to the file system - /// - /// This base class can not be instantiated. - /// File system errors do not support inner exceptions, as they - /// are always originating causes for errors. - DEFINE_EXCEPTION(FileSystemError, Exception); - - /// A file can't be accessed for some reason - DEFINE_FS_EXCEPTION(FileNotAccessible, FileSystemError, "File is not accessible: "); - - /// A file can't be accessed because there's no file by the given name - DEFINE_FS_EXCEPTION(FileNotFound, FileNotAccessible, "File not found: "); - - /// An error of some unknown type has occured - DEFINE_EXCEPTION(FileSystemUnknownError, FileSystemError); - - /// The path exists, but isn't a file - DEFINE_FS_EXCEPTION(NotAFile, FileNotAccessible, "Path is not a file (and should be): "); - - /// The path exists, but isn't a directory - DEFINE_FS_EXCEPTION(NotADirectory, FileNotAccessible, "Path is not a directory (and should be): "); - - /// The given path is too long for the filesystem - DEFINE_FS_EXCEPTION(PathTooLog, FileSystemError, "Path is too long: "); - - /// Insufficient free space to complete operation - DEFINE_FS_EXCEPTION(DriveFull, FileSystemError, "Insufficient free space to write file: "); - - /// Base class for access denied errors - DEFINE_FS_EXCEPTION(AccessDenied, FileNotAccessible, "Access denied to path: "); - - /// Trying to read the file gave an access denied error - DEFINE_FS_EXCEPTION(ReadDenied, AccessDenied, "Access denied when trying to read: "); - - /// Trying to write the file gave an access denied error - DEFINE_FS_EXCEPTION(WriteDenied, AccessDenied, "Access denied when trying to write: "); - - /// File exists and cannot be overwritten due to being read-only - DEFINE_FS_EXCEPTION(ReadOnlyFile, WriteDenied, "File is read-only: "); - - bool Exists(path const& p); - bool FileExists(path const& file); - bool DirectoryExists(path const& dir); - - /// Get the local-charset encoded shortname for a file - /// - /// This is purely for compatibility with external libraries which do - /// not support unicode filenames on Windows. On all other platforms, - /// it is a no-op. - std::string ShortName(path const& file_path); - - /// Check for amount of free space on a path - uintmax_t FreeSpace(path const& dir_path); - - /// Get the size in bytes of the file at path - /// - /// @throws agi::FileNotFound if path does not exist - /// @throws agi::acs::NotAFile if path is a directory - /// @throws agi::acs::Read if path exists but could not be read - uintmax_t Size(path const& file_path); - - /// Get the modification time of the file at path - /// - /// @throws agi::FileNotFound if path does not exist - /// @throws agi::acs::NotAFile if path is a directory - /// @throws agi::acs::Read if path exists but could not be read - time_t ModifiedTime(path const& file_path); - - /// Create a directory and all required intermediate directories - /// @throws agi::acs::Write if the directory could not be created. - /// - /// Trying to create a directory which already exists is not an error. - bool CreateDirectory(path const& dir_path); - - /// Touch the given path - /// - /// Creates the file if it does not exist, or updates the modified - /// time if it does - void Touch(path const& file_path); - - /// Rename a file or directory - /// @param from Source path - /// @param to Destination path - void Rename(path const& from, path const& to); - - /// Copy a file - /// @param from Source path - /// @param to Destination path - /// - /// The destination path will be created if it does not exist. - void Copy(path const& from, path const& to); - - /// Delete a file - /// @param path Path to file to delete - /// @throws agi::FileNotAccessibleError if file exists but could not be deleted - bool Remove(path const& file); - - /// Check if the file has the given extension - /// @param p Path to check - /// @param ext Case-insensitive extension, without leading dot - bool HasExtension(path const& p, std::string const& ext); - - agi::fs::path Canonicalize(agi::fs::path const& path); - - class DirectoryIterator { - struct PrivData; - std::shared_ptr privdata; - std::string value; - public: - typedef path value_type; - typedef path* pointer; - typedef path& reference; - typedef size_t difference_type; - typedef std::forward_iterator_tag iterator_category; - - bool operator==(DirectoryIterator const&) const; - bool operator!=(DirectoryIterator const& rhs) const { return !(*this == rhs); } - DirectoryIterator& operator++(); - std::string const& operator*() const { return value; } - - DirectoryIterator(path const& p, std::string const& filter); - DirectoryIterator(); - ~DirectoryIterator(); - - template void GetAll(T& cont); - }; - - static inline DirectoryIterator& begin(DirectoryIterator &it) { return it; } - static inline DirectoryIterator end(DirectoryIterator &) { return DirectoryIterator(); } - - template - inline void DirectoryIterator::GetAll(T& cont) { - copy(*this, end(*this), std::back_inserter(cont)); - } +namespace agi::fs { +/// Define a filesystem error which takes a path or a string + #define DEFINE_FS_EXCEPTION(type, base, message) \ + struct type : public base { \ + type(path const& p) : base(message + p.string()) { } \ + type(std::string const& s) : base(s) { } \ + const char *GetName() const { return ""; } \ + Exception *Copy() const { return new type(*this); } \ } + +/// @class agi::FileSystemError +/// @extends agi::Exception +/// @brief Base class for errors related to the file system +/// +/// This base class can not be instantiated. +/// File system errors do not support inner exceptions, as they +/// are always originating causes for errors. +DEFINE_EXCEPTION(FileSystemError, Exception); + +/// A file can't be accessed for some reason +DEFINE_FS_EXCEPTION(FileNotAccessible, FileSystemError, "File is not accessible: "); + +/// A file can't be accessed because there's no file by the given name +DEFINE_FS_EXCEPTION(FileNotFound, FileNotAccessible, "File not found: "); + +/// An error of some unknown type has occured +DEFINE_EXCEPTION(FileSystemUnknownError, FileSystemError); + +/// The path exists, but isn't a file +DEFINE_FS_EXCEPTION(NotAFile, FileNotAccessible, "Path is not a file (and should be): "); + +/// The path exists, but isn't a directory +DEFINE_FS_EXCEPTION(NotADirectory, FileNotAccessible, "Path is not a directory (and should be): "); + +/// The given path is too long for the filesystem +DEFINE_FS_EXCEPTION(PathTooLog, FileSystemError, "Path is too long: "); + +/// Insufficient free space to complete operation +DEFINE_FS_EXCEPTION(DriveFull, FileSystemError, "Insufficient free space to write file: "); + +/// Base class for access denied errors +DEFINE_FS_EXCEPTION(AccessDenied, FileNotAccessible, "Access denied to path: "); + +/// Trying to read the file gave an access denied error +DEFINE_FS_EXCEPTION(ReadDenied, AccessDenied, "Access denied when trying to read: "); + +/// Trying to write the file gave an access denied error +DEFINE_FS_EXCEPTION(WriteDenied, AccessDenied, "Access denied when trying to write: "); + +/// File exists and cannot be overwritten due to being read-only +DEFINE_FS_EXCEPTION(ReadOnlyFile, WriteDenied, "File is read-only: "); + +bool Exists(path const& p); +bool FileExists(path const& file); +bool DirectoryExists(path const& dir); + +/// Get the local-charset encoded shortname for a file +/// +/// This is purely for compatibility with external libraries which do +/// not support unicode filenames on Windows. On all other platforms, +/// it is a no-op. +std::string ShortName(path const& file_path); + +/// Check for amount of free space on a path +uintmax_t FreeSpace(path const& dir_path); + +/// Get the size in bytes of the file at path +/// +/// @throws agi::FileNotFound if path does not exist +/// @throws agi::acs::NotAFile if path is a directory +/// @throws agi::acs::Read if path exists but could not be read +uintmax_t Size(path const& file_path); + +/// Get the modification time of the file at path +/// +/// @throws agi::FileNotFound if path does not exist +/// @throws agi::acs::NotAFile if path is a directory +/// @throws agi::acs::Read if path exists but could not be read +time_t ModifiedTime(path const& file_path); + +/// Create a directory and all required intermediate directories +/// @throws agi::acs::Write if the directory could not be created. +/// +/// Trying to create a directory which already exists is not an error. +bool CreateDirectory(path const& dir_path); + +/// Touch the given path +/// +/// Creates the file if it does not exist, or updates the modified +/// time if it does +void Touch(path const& file_path); + +/// Rename a file or directory +/// @param from Source path +/// @param to Destination path +void Rename(path const& from, path const& to); + +/// Copy a file +/// @param from Source path +/// @param to Destination path +/// +/// The destination path will be created if it does not exist. +void Copy(path const& from, path const& to); + +/// Delete a file +/// @param path Path to file to delete +/// @throws agi::FileNotAccessibleError if file exists but could not be deleted +bool Remove(path const& file); + +/// Check if the file has the given extension +/// @param p Path to check +/// @param ext Case-insensitive extension, without leading dot +bool HasExtension(path const& p, std::string const& ext); + +agi::fs::path Canonicalize(agi::fs::path const& path); + +class DirectoryIterator { + struct PrivData; + std::shared_ptr privdata; + std::string value; +public: + typedef path value_type; + typedef path* pointer; + typedef path& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + bool operator==(DirectoryIterator const&) const; + DirectoryIterator& operator++(); + std::string const& operator*() const { return value; } + + DirectoryIterator(path const& p, std::string const& filter); + DirectoryIterator(); + ~DirectoryIterator(); + + template void GetAll(T& cont); +}; + +static inline DirectoryIterator& begin(DirectoryIterator &it) { return it; } +static inline DirectoryIterator end(DirectoryIterator &) { return DirectoryIterator(); } + +template +inline void DirectoryIterator::GetAll(T& cont) { + copy(*this, end(*this), std::back_inserter(cont)); +} } diff --git a/libaegisub/include/libaegisub/hotkey.h b/libaegisub/include/libaegisub/hotkey.h index 81cae91fb4..ebec4a7021 100644 --- a/libaegisub/include/libaegisub/hotkey.h +++ b/libaegisub/include/libaegisub/hotkey.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,7 @@ namespace json { class UnknownElement; - typedef std::map Object; + typedef std::map> Object; } namespace agi { @@ -39,22 +40,22 @@ class Combo { /// Constructor /// @param ctx Context /// @param cmd Command name - Combo(std::string ctx, std::string cmd, std::string keys) - : keys(std::move(keys)) - , cmd_name(std::move(cmd)) - , context(std::move(ctx)) + Combo(std::string_view ctx, std::string_view cmd, std::string_view keys) + : keys(keys) + , cmd_name(cmd) + , context(ctx) { } /// String representation of the Combo - std::string const& Str() const { return keys; } + std::string_view Str() const { return keys; } /// Command name triggered by the combination. /// @return Command name - std::string const& CmdName() const { return cmd_name; } + std::string_view CmdName() const { return cmd_name; } /// Context this Combo is triggered in. - std::string const& Context() const { return context; } + std::string_view Context() const { return context; } }; /// @class Hotkey @@ -62,7 +63,7 @@ class Combo { class Hotkey { public: /// Map to hold Combo instances - typedef std::multimap HotkeyMap; + typedef std::multimap> HotkeyMap; private: HotkeyMap cmd_map; ///< Command name -> Combo std::vector str_map; ///< Sorted by string representation @@ -72,7 +73,7 @@ class Hotkey { /// Build hotkey map. /// @param context Context being parsed. /// @param object json::Object holding items for context being parsed. - void BuildHotkey(std::string const& context, const json::Object& object); + void BuildHotkey(std::string_view context, const json::Object& object); /// Write active Hotkey configuration to disk. void Flush(); @@ -85,32 +86,28 @@ class Hotkey { /// Constructor /// @param file Location of user config file. /// @param default_config Default config. - Hotkey(agi::fs::path const& file, std::pair default_config); - - template - Hotkey(agi::fs::path const& file, const char (&default_config)[N]) - : Hotkey(file, {default_config, N - 1}) { } + Hotkey(agi::fs::path const& file, std::string_view default_config); /// Scan for a matching key. /// @param context Context requested. /// @param str Hyphen separated key sequence. /// @param always Enable the "Always" override context /// @return Name of command or "" if none match - std::string Scan(const std::string &context, const std::string &str, bool always) const; + std::string_view Scan(std::string_view context, std::string_view str, bool always) const; - bool HasHotkey(const std::string &context, const std::string &str) const; + bool HasHotkey(std::string_view context, std::string_view str) const; /// Get the string representation of the hotkeys for the given command /// @param context Context requested /// @param command Command name /// @return A vector of all hotkeys for that command in the context - std::vector GetHotkeys(const std::string &context, const std::string &command) const; + std::vector GetHotkeys(std::string_view context, std::string_view command) const; /// Get a string representation of a hotkeys for the given command /// @param context Context requested /// @param command Command name /// @return A hotkey for the given command or "" if there are none - std::string GetHotkey(const std::string &context, const std::string &command) const; + std::string_view GetHotkey(std::string_view context, std::string_view command) const; /// Get the raw command name -> combo map for all registered hotkeys HotkeyMap const& GetHotkeyMap() const { return cmd_map; } diff --git a/libaegisub/include/libaegisub/json.h b/libaegisub/include/libaegisub/json.h index 4862cd0c15..962ed3f6ea 100644 --- a/libaegisub/include/libaegisub/json.h +++ b/libaegisub/include/libaegisub/json.h @@ -30,6 +30,6 @@ json::UnknownElement parse(std::istream &stream); /// @param file Path to JSON file. /// @param Default config file to load incase of nonexistent file /// @return json::UnknownElement -json::UnknownElement file(agi::fs::path const& file, std::pair default_config); +json::UnknownElement file(agi::fs::path const& file, std::string_view default_config); } } diff --git a/libaegisub/include/libaegisub/line_iterator.h b/libaegisub/include/libaegisub/line_iterator.h index 1e4fee9b15..bb8ffe6a2c 100644 --- a/libaegisub/include/libaegisub/line_iterator.h +++ b/libaegisub/include/libaegisub/line_iterator.h @@ -49,7 +49,6 @@ class line_iterator_base { line_iterator_base& operator=(line_iterator_base&&) = default; bool operator==(line_iterator_base const& rgt) const { return stream == rgt.stream; } - bool operator!=(line_iterator_base const& rgt) const { return !operator==(rgt); } }; /// @class line_iterator diff --git a/libaegisub/include/libaegisub/lua/utils.h b/libaegisub/include/libaegisub/lua/utils.h index c5a65d6e44..1333aa1a50 100644 --- a/libaegisub/include/libaegisub/lua/utils.h +++ b/libaegisub/include/libaegisub/lua/utils.h @@ -23,20 +23,15 @@ #include -#ifndef BOOST_NORETURN -#include -#define BOOST_NORETURN BOOST_ATTRIBUTE_NORETURN -#endif - -namespace agi { namespace lua { +namespace agi::lua { // Exception type for errors where the error details are on the lua stack struct error_tag {}; // Below are functionally equivalent to the luaL_ functions, but using a C++ // exception for stack unwinding -int BOOST_NORETURN error(lua_State *L, const char *fmt, ...); -int BOOST_NORETURN argerror(lua_State *L, int narg, const char *extramsg); -int BOOST_NORETURN typerror(lua_State *L, int narg, const char *tname); +[[noreturn]] int error(lua_State *L, const char *fmt, ...); +[[noreturn]] int argerror(lua_State *L, int narg, const char *extramsg); +[[noreturn]] int typerror(lua_State *L, int narg, const char *tname); void argcheck(lua_State *L, bool cond, int narg, const char *msg); inline void push_value(lua_State *L, bool value) { lua_pushboolean(L, value); } @@ -165,4 +160,4 @@ void lua_for_each(lua_State *L, Func&& func) { /// moonscript line rewriting support int add_stack_trace(lua_State *L); -} } +} diff --git a/libaegisub/include/libaegisub/make_unique.h b/libaegisub/include/libaegisub/make_unique.h deleted file mode 100644 index 3af862e97b..0000000000 --- a/libaegisub/include/libaegisub/make_unique.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2014, Thomas Goyne -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// Aegisub Project http://www.aegisub.org/ - -#include - -namespace agi { - template - std::unique_ptr make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); - } -} diff --git a/libaegisub/include/libaegisub/mru.h b/libaegisub/include/libaegisub/mru.h index 9ce3dd43f2..0fac24b469 100644 --- a/libaegisub/include/libaegisub/mru.h +++ b/libaegisub/include/libaegisub/mru.h @@ -14,6 +14,8 @@ #include #include +#include +#include #include #include @@ -43,34 +45,31 @@ class MRUManager { /// @brief Constructor /// @param config File to load MRU values from - MRUManager(agi::fs::path const& config, std::pair default_config, agi::Options *options = nullptr); + MRUManager(agi::fs::path const& config, std::string_view default_config, agi::Options *options = nullptr); - template - MRUManager(agi::fs::path const& file, const char (&default_config)[N]) - : MRUManager(file, {default_config, N - 1}) { } /// @brief Add entry to the list. /// @param key List name /// @param entry Entry to add /// @exception MRUError thrown when an invalid key is used. - void Add(const char *key, agi::fs::path const& entry); + void Add(std::string_view key, agi::fs::path const& entry); /// @brief Remove entry from the list. /// @param key List name /// @param entry Entry to add /// @exception MRUError thrown when an invalid key is used. - void Remove(const char *key, agi::fs::path const& entry); + void Remove(std::string_view key, agi::fs::path const& entry); /// @brief Return list /// @param key List name /// @exception MRUError thrown when an invalid key is used. - const MRUListMap* Get(const char *key); + const MRUListMap* Get(std::string_view key); /// @brief Return A single entry in a list. /// @param key List name /// @param entry 0-base position of entry /// @exception MRUError thrown when an invalid key is used. - agi::fs::path const& GetEntry(const char *key, const size_t entry); + agi::fs::path const& GetEntry(std::string_view key, const size_t entry); /// Write MRU lists to disk. void Flush(); @@ -88,11 +87,11 @@ class MRUManager { /// @brief Load MRU Lists. /// @param key List name. /// @param array json::Array of values. - void Load(const char *key, ::json::Array const& array); + void Load(std::string_view key, ::json::Array const& array); /// @brief Prune MRUListMap to the desired length. /// This uses the user-set values for MRU list length. - void Prune(const char *key, MRUListMap& map) const; - MRUListMap &Find(const char *key); + void Prune(std::string_view key, MRUListMap& map) const; + MRUListMap &Find(std::string_view key); }; } // namespace agi diff --git a/libaegisub/include/libaegisub/option.h b/libaegisub/include/libaegisub/option.h index eb94ef670b..b16d87be95 100644 --- a/libaegisub/include/libaegisub/option.h +++ b/libaegisub/include/libaegisub/option.h @@ -12,10 +12,6 @@ // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -/// @file option.h -/// @brief Public interface for option values. -/// @ingroup libaegisub - #pragma once #include @@ -28,7 +24,7 @@ namespace json { class UnknownElement; - typedef std::map Object; + typedef std::map> Object; } namespace agi { @@ -60,11 +56,7 @@ class Options { /// @brief Constructor /// @param file User config that will be loaded from and written back to. /// @param default_config Default configuration. - Options(agi::fs::path const& file, std::pair default_config, const OptionSetting setting = NONE); - - template - Options(agi::fs::path const& file, const char (&default_config)[N], const OptionSetting setting = NONE) - : Options(file, {default_config, N - 1}, setting) { } + Options(agi::fs::path const& file, std::string_view default_config, OptionSetting setting = NONE); /// Destructor ~Options(); @@ -72,8 +64,7 @@ class Options { /// @brief Get an option by name. /// @param name Option to get. /// Get an option value object by name throw an internal exception if the option is not found. - OptionValue *Get(const char *name); - OptionValue *Get(std::string const& name) { return Get(name.c_str()); } + OptionValue *Get(std::string_view name); /// @brief Next configuration file to load. /// @param[in] src Stream to load from. diff --git a/libaegisub/include/libaegisub/option_value.h b/libaegisub/include/libaegisub/option_value.h index 63870419cc..1090e0bd9f 100644 --- a/libaegisub/include/libaegisub/option_value.h +++ b/libaegisub/include/libaegisub/option_value.h @@ -68,7 +68,7 @@ class OptionValue { protected: void NotifyChanged() { ValueChanged(*this); } - OptionValue(std::string name) BOOST_NOEXCEPT : name(std::move(name)) { } + OptionValue(std::string name) noexcept : name(std::move(name)) { } public: virtual ~OptionValue() = default; @@ -130,16 +130,16 @@ CONFIG_OPTIONVALUE(Double, double) CONFIG_OPTIONVALUE(Color, Color) CONFIG_OPTIONVALUE(Bool, bool) -#define CONFIG_OPTIONVALUE_LIST(type_name, type) \ +#define CONFIG_OPTIONVALUE_LIST(type_name, type, rt) \ class OptionValueList##type_name final : public OptionValue { \ std::vector array; \ std::vector array_default; \ std::string name; \ public: \ - typedef std::vector value_type; \ - OptionValueList##type_name(std::string name, std::vector const& value = std::vector()) \ - : OptionValue(std::move(name)) \ - , array(value), array_default(value) { } \ + using value_type = std::vector; \ + using raw_type = rt; \ + OptionValueList##type_name(std::string name, std::vector const& value = {}) \ + : OptionValue(std::move(name)), array(value), array_default(value) { } \ std::vector const& GetValue() const { return array; } \ void SetValue(std::vector val) { array = std::move(val); NotifyChanged(); } \ OptionType GetType() const { return OptionType::List##type_name; } \ @@ -148,11 +148,11 @@ CONFIG_OPTIONVALUE(Bool, bool) void Set(const OptionValue *nv); \ }; -CONFIG_OPTIONVALUE_LIST(String, std::string) -CONFIG_OPTIONVALUE_LIST(Int, int64_t) -CONFIG_OPTIONVALUE_LIST(Double, double) -CONFIG_OPTIONVALUE_LIST(Color, Color) -CONFIG_OPTIONVALUE_LIST(Bool, bool) +CONFIG_OPTIONVALUE_LIST(String, std::string, std::string) +CONFIG_OPTIONVALUE_LIST(Int, int64_t, int64_t) +CONFIG_OPTIONVALUE_LIST(Double, double, double) +CONFIG_OPTIONVALUE_LIST(Color, Color, std::string) +CONFIG_OPTIONVALUE_LIST(Bool, bool, bool) #define CONFIG_OPTIONVALUE_ACCESSORS(ReturnType, Type) \ inline ReturnType const& OptionValue::Get##Type() const { return As(OptionType::Type)->GetValue(); } \ diff --git a/libaegisub/include/libaegisub/signal.h b/libaegisub/include/libaegisub/signal.h index 091cc78737..fd8ea936aa 100644 --- a/libaegisub/include/libaegisub/signal.h +++ b/libaegisub/include/libaegisub/signal.h @@ -19,7 +19,7 @@ #include #include -namespace agi { namespace signal { +namespace agi::signal { class Connection; /// Implementation details; nothing outside this file should directly touch @@ -63,10 +63,10 @@ class Connection { std::unique_ptr token; public: Connection() = default; - Connection(UnscopedConnection src) BOOST_NOEXCEPT : token(src.token) { token->claimed = true; } - Connection(Connection&& that) BOOST_NOEXCEPT : token(std::move(that.token)) { } - Connection(detail::ConnectionToken *token) BOOST_NOEXCEPT : token(token) { token->claimed = true; } - Connection& operator=(Connection&& that) BOOST_NOEXCEPT { token = std::move(that.token); return *this; } + Connection(UnscopedConnection src) noexcept : token(src.token) { token->claimed = true; } + Connection(Connection&& that) noexcept = default; + Connection(detail::ConnectionToken *token) noexcept : token(token) { token->claimed = true; } + Connection& operator=(Connection&& that) noexcept = default; /// @brief End this connection /// @@ -100,7 +100,7 @@ namespace detail { SignalBase& operator=(SignalBase const&) = delete; protected: SignalBase() = default; - virtual ~SignalBase() {}; + virtual ~SignalBase() = default; /// @brief Notify a slot that it has been disconnected /// @param tok Token to disconnect /// @@ -131,18 +131,13 @@ class Signal final : private detail::SignalBase { std::vector> slots; /// Signals currently connected to this slot void Disconnect(detail::ConnectionToken *tok) override { - for (auto it = begin(slots), e = end(slots); it != e; ++it) { - if (tok == it->first) { - slots.erase(it); - return; - } - } + std::erase_if(slots, [=](auto& slot) { return slot.first == tok; }); } - UnscopedConnection DoConnect(Slot sig) { - auto token = MakeToken(); - slots.emplace_back(token, sig); - return UnscopedConnection(token); + UnscopedConnection DoConnect(Slot&& sig) { + std::unique_ptr token(MakeToken()); + slots.emplace_back(token.get(), std::move(sig)); + return UnscopedConnection(token.release()); } public: @@ -167,8 +162,8 @@ class Signal final : private detail::SignalBase { /// @brief Connect a signal to this slot /// @param sig Signal to connect /// @return The connection object - UnscopedConnection Connect(Slot sig) { - return DoConnect(sig); + UnscopedConnection Connect(Slot&& sig) { + return DoConnect(std::move(sig)); } // Convenience wrapper for a member function which matches the signal's signature @@ -208,7 +203,7 @@ inline std::vector make_vector(std::initializer_list(std::begin(connections), std::end(connections)); } -} } +} /// @brief Define functions which forward their arguments to the connect method /// of the named signal diff --git a/libaegisub/include/libaegisub/spellchecker.h b/libaegisub/include/libaegisub/spellchecker.h index 450a39407c..8844774133 100644 --- a/libaegisub/include/libaegisub/spellchecker.h +++ b/libaegisub/include/libaegisub/spellchecker.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include namespace agi { @@ -26,31 +26,31 @@ class SpellChecker { /// Add word to the dictionary /// @param word Word to add - virtual void AddWord(std::string const& word)=0; + virtual void AddWord(std::string_view word)=0; /// Remove word from the dictionary /// @param word Word to remove - virtual void RemoveWord(std::string const& word)=0; + virtual void RemoveWord(std::string_view word)=0; /// Can the word be added to the current dictionary? /// @param word Word to check /// @return Whether or not word can be added - virtual bool CanAddWord(std::string const& word)=0; + virtual bool CanAddWord(std::string_view word)=0; /// Can the word be removed from the current dictionary? /// @param word Word to check /// @return Whether or not word can be removed - virtual bool CanRemoveWord(std::string const& word)=0; + virtual bool CanRemoveWord(std::string_view word)=0; /// Check if the given word is spelled correctly /// @param word Word to check /// @return Whether or not the word is valid - virtual bool CheckWord(std::string const& word)=0; + virtual bool CheckWord(std::string_view word)=0; /// Get possible corrections for a misspelled word /// @param word Word to get suggestions for /// @return List of suggestions, if any - virtual std::vector GetSuggestions(std::string const& word)=0; + virtual std::vector GetSuggestions(std::string_view word)=0; /// Get a list of languages which dictionaries are present for virtual std::vector GetLanguageList()=0; diff --git a/libaegisub/include/libaegisub/split.h b/libaegisub/include/libaegisub/split.h index 0b152b2245..48f951a770 100644 --- a/libaegisub/include/libaegisub/split.h +++ b/libaegisub/include/libaegisub/split.h @@ -14,63 +14,48 @@ // // Aegisub Project http://www.aegisub.org/ -#include +#include +#include namespace agi { - typedef boost::iterator_range StringRange; - - template + template class split_iterator { - bool is_end = false; - Iterator b; - Iterator cur; - Iterator e; - typename Iterator::value_type c; + std::basic_string_view str; + size_t pos = 0; + Char delim; public: using iterator_category = std::forward_iterator_tag; - using value_type = boost::iterator_range; + using value_type = std::string_view; using pointer = value_type*; using reference = value_type&; using difference_type = ptrdiff_t; - split_iterator(Iterator begin, Iterator end, typename Iterator::value_type c) - : b(begin), cur(begin), e(end), c(c) + split_iterator(std::basic_string_view str, Char c) + : str(str), delim(c) { - if (b != e) - cur = std::find(b, e, c); - else - is_end = true; + pos = str.find(delim); } - split_iterator() : is_end(true) { } + split_iterator() = default; - bool eof() const { return is_end; } + bool eof() const { return str.size() == 0; } - boost::iterator_range operator*() const { - return boost::make_iterator_range(b, cur); + std::basic_string_view operator*() const { + return str.substr(0, pos); } bool operator==(split_iterator const& it) const { - if (is_end || it.is_end) - return is_end && it.is_end; - return b == it.b && cur == it.cur && e == it.e && c == it.c; - } - - bool operator!=(split_iterator const& it) const { - return !(*this == it); + return str == it.str && (str.size() == 0 || delim == it.delim); } split_iterator& operator++() { - if (cur != e) { - b = cur + 1; - cur = std::find(b, e, c); + if (pos == str.npos) { + str = str.substr(str.size()); + } else { + str = str.substr(pos + 1); + pos = str.find(delim); } - else { - b = e; - is_end = true; - } - return *this; } @@ -81,29 +66,43 @@ namespace agi { } }; - template - split_iterator begin(split_iterator const& it) { + template + split_iterator begin(split_iterator const& it) { return it; } - template - split_iterator end(split_iterator const&) { - return split_iterator(); + template + split_iterator end(split_iterator const&) { + return split_iterator(); } - static inline std::string str(StringRange const& r) { - return std::string(r.begin(), r.end()); + template + split_iterator Split(std::basic_string_view str, Char delim) { + return split_iterator(str, delim); } - template - split_iterator Split(Str const& str, Char delim) { - return split_iterator(begin(str), end(str), delim); + inline split_iterator Split(std::basic_string_view str, char delim) { + return split_iterator(str, delim); } - template - void Split(Cont& out, Str const& str, Char delim) { + template + void Split(Cont& out, std::basic_string_view str, Char delim) { out.clear(); for (auto const& tok : Split(str, delim)) out.emplace_back(begin(tok), end(tok)); } + + template + void Split(Cont& out, std::basic_string_view str, char delim) { + Split(out, str, delim); + } + + inline std::string_view Trim(std::string_view str) { + std::locale loc; + while (str.size() && std::isspace(str.front(), loc)) + str.remove_prefix(1); + while (str.size() && std::isspace(str.back(), loc)) + str.remove_suffix(1); + return str; + } } diff --git a/libaegisub/include/libaegisub/util.h b/libaegisub/include/libaegisub/util.h index 4aa34619f0..ac7c40905e 100644 --- a/libaegisub/include/libaegisub/util.h +++ b/libaegisub/include/libaegisub/util.h @@ -15,19 +15,20 @@ #include #include #include +#include #include struct tm; -namespace agi { namespace util { +namespace agi::util { /// Clamp `b` to the range [`a`,`c`] template static inline T mid(T a, T b, T c) { return std::max(a, std::min(b, c)); } - bool try_parse(std::string const& str, double *out); - bool try_parse(std::string const& str, int *out); + bool try_parse(std::string_view str, double *out); + bool try_parse(std::string_view str, int *out); /// strftime, but on std::string rather than a fixed buffer /// @param fmt strftime format string @@ -80,4 +81,4 @@ namespace agi { namespace util { auto range(Integer end) -> decltype(boost::irange(0, end)) { return boost::irange(0, end); } -} } // namespace agi::util +} // namespace agi::util diff --git a/libaegisub/include/libaegisub/util_osx.h b/libaegisub/include/libaegisub/util_osx.h index 3e4ce599e7..537d7e68df 100644 --- a/libaegisub/include/libaegisub/util_osx.h +++ b/libaegisub/include/libaegisub/util_osx.h @@ -31,15 +31,16 @@ #include namespace agi { - namespace osx { - class AppNapDisabler { - void *handle; - public: - AppNapDisabler(std::string reason); - ~AppNapDisabler(); - }; - } - namespace util { +namespace osx { +class AppNapDisabler { + void *handle; +public: + AppNapDisabler(std::string reason); + ~AppNapDisabler(); +}; +} + +namespace util { /// @brief Get the esources directory. /// @return Resources directory. /// @@ -54,5 +55,5 @@ std::string GetBundleResourcesDirectory(); std::string GetBundleSharedSupportDirectory(); std::string GetApplicationSupportDirectory(); - } // namespace util +} // namespace util } // namespace agi diff --git a/libaegisub/lua/modules.cpp b/libaegisub/lua/modules.cpp index 061c0b8c05..61f32999fd 100644 --- a/libaegisub/lua/modules.cpp +++ b/libaegisub/lua/modules.cpp @@ -25,7 +25,7 @@ extern "C" int luaopen_unicode_impl(lua_State *L); extern "C" int luaopen_lfs_impl(lua_State *L); extern "C" int luaopen_lpeg(lua_State *L); -namespace agi { namespace lua { +namespace agi::lua { int regex_init(lua_State *L); void preload_modules(lua_State *L) { @@ -70,4 +70,4 @@ void do_register_lib_table(lua_State *L, std::initializer_list typ // leaves ffi.cast on the stack } -} } +} diff --git a/libaegisub/lua/modules/re.cpp b/libaegisub/lua/modules/re.cpp index 66efe0f89d..7671f9dcc9 100644 --- a/libaegisub/lua/modules/re.cpp +++ b/libaegisub/lua/modules/re.cpp @@ -15,7 +15,6 @@ // Aegisub Project http://www.aegisub.org/ #include "libaegisub/lua/ffi.h" -#include "libaegisub/make_unique.h" #include @@ -49,7 +48,7 @@ bool search(u32regex& re, const char *str, size_t len, int start, boost::cmatch& } match *regex_match(u32regex& re, const char *str, size_t len, int start) { - auto result = agi::make_unique(); + auto result = std::make_unique(); if (!search(re, str, len, start, result->m)) return nullptr; return result.release(); @@ -96,7 +95,7 @@ char *regex_replace(u32regex& re, const char *replacement, const char *str, size } u32regex *regex_compile(const char *pattern, int flags, char **err) { - auto re = agi::make_unique(); + auto re = std::make_unique(); try { *re = boost::make_u32regex(pattern, boost::u32regex::perl | flags); return re.release(); diff --git a/libaegisub/lua/script_reader.cpp b/libaegisub/lua/script_reader.cpp index 6beb9813b6..07d4dbd7e7 100644 --- a/libaegisub/lua/script_reader.cpp +++ b/libaegisub/lua/script_reader.cpp @@ -24,7 +24,7 @@ #include #include -namespace agi { namespace lua { +namespace agi::lua { bool LoadFile(lua_State *L, agi::fs::path const& raw_filename) { auto filename = raw_filename; try { @@ -36,7 +36,7 @@ namespace agi { namespace lua { agi::read_file_mapping file(filename); auto buff = file.read(); - size_t size = static_cast(file.size()); + auto size = static_cast(file.size()); // Discard the BOM if present if (size >= 3 && buff[0] == -17 && buff[1] == -69 && buff[2] == -65) { @@ -162,4 +162,4 @@ namespace agi { namespace lua { return true; } -} } +} diff --git a/libaegisub/lua/utils.cpp b/libaegisub/lua/utils.cpp index 2cde75f463..2efc7f68a0 100644 --- a/libaegisub/lua/utils.cpp +++ b/libaegisub/lua/utils.cpp @@ -20,16 +20,16 @@ #include "libaegisub/log.h" #include -#include #include -#include + +#include #ifdef _MSC_VER // Disable warnings for noreturn functions having return types #pragma warning(disable: 4645 4646) #endif -namespace agi { namespace lua { +namespace agi::lua { std::string get_string_or_default(lua_State *L, int idx) { size_t len = 0; const char *str = lua_tolstring(L, idx, &len); @@ -140,8 +140,8 @@ int add_stack_trace(lua_State *L) { // Strip the location from the error message since it's redundant with // the stack trace - boost::regex location(R"(^\[string ".*"\]:[0-9]+: )"); - message = regex_replace(message, location, "", boost::format_first_only); + std::regex location(R"(^\[string ".*"\]:[0-9]+: )"); + message = regex_replace(message, location, "", std::regex_constants::format_first_only); std::vector frames; frames.emplace_back(std::move(message)); @@ -157,7 +157,7 @@ int add_stack_trace(lua_State *L) { std::string file = ar.source; if (file == "=[C]") file = ""; - else if (boost::ends_with(file, ".moon")) + else if (file.ends_with(".moon")) is_moon = true; auto real_line = [&](int line) { @@ -181,7 +181,7 @@ int add_stack_trace(lua_State *L) { return 1; } -int BOOST_NORETURN error(lua_State *L, const char *fmt, ...) { +[[noreturn]] int error(lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); luaL_where(L, 1); @@ -191,7 +191,7 @@ int BOOST_NORETURN error(lua_State *L, const char *fmt, ...) { throw error_tag(); } -int BOOST_NORETURN argerror(lua_State *L, int narg, const char *extramsg) { +[[noreturn]] int argerror(lua_State *L, int narg, const char *extramsg) { lua_Debug ar; if (!lua_getstack(L, 0, &ar)) error(L, "bad argument #%d (%s)", narg, extramsg); @@ -203,7 +203,7 @@ int BOOST_NORETURN argerror(lua_State *L, int narg, const char *extramsg) { narg, ar.name, extramsg); } -int BOOST_NORETURN typerror(lua_State *L, int narg, const char *tname) { +[[noreturn]] int typerror(lua_State *L, int narg, const char *tname) { const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, luaL_typename(L, narg)); argerror(L, narg, msg); @@ -261,4 +261,3 @@ void LuaStackcheck::dump() { #endif } -} diff --git a/libaegisub/osx/spellchecker.mm b/libaegisub/osx/spellchecker.mm index ea7cb3d871..67405c6ea1 100644 --- a/libaegisub/osx/spellchecker.mm +++ b/libaegisub/osx/spellchecker.mm @@ -37,13 +37,17 @@ template using objc_ptr = std::unique_ptr; +NSString *ns_str(std::string_view str) { + return [[[NSString alloc] initWithBytes:str.data() length:str.length() encoding:NSUTF8StringEncoding] autorelease]; +} + class CocoaSpellChecker final : public agi::SpellChecker { + NSSpellChecker *spellChecker = NSSpellChecker.sharedSpellChecker; objc_ptr language; agi::signal::Connection lang_listener; void OnLanguageChanged(agi::OptionValue const& opt) { - language.reset([[NSString alloc] initWithCString:opt.GetString().c_str() - encoding:NSUTF8StringEncoding]); + language.reset(ns_str(opt.GetString()).retain); } public: @@ -54,50 +58,49 @@ void OnLanguageChanged(agi::OptionValue const& opt) { } std::vector GetLanguageList() override { - return array_to_vector([[NSSpellChecker sharedSpellChecker] availableLanguages]); + return array_to_vector(NSSpellChecker.sharedSpellChecker.availableLanguages); } - bool CheckWord(std::string const& word) override { - auto str = [NSString stringWithUTF8String:word.c_str()]; - auto range = [NSSpellChecker.sharedSpellChecker checkSpellingOfString:str - startingAt:0 - language:language.get() - wrap:NO - inSpellDocumentWithTag:0 - wordCount:nullptr]; + bool CheckWord(std::string_view word) override { + auto range = [spellChecker checkSpellingOfString:ns_str(word) + startingAt:0 + language:language.get() + wrap:NO + inSpellDocumentWithTag:0 + wordCount:nullptr]; return range.location == NSNotFound; } - std::vector GetSuggestions(std::string const& word) override { - auto str = [NSString stringWithUTF8String:word.c_str()]; - auto range = [NSSpellChecker.sharedSpellChecker checkSpellingOfString:str - startingAt:0 - language:language.get() - wrap:NO - inSpellDocumentWithTag:0 - wordCount:nullptr]; - return array_to_vector([NSSpellChecker.sharedSpellChecker guessesForWordRange:range - inString:str - language:language.get() - inSpellDocumentWithTag:0]); + std::vector GetSuggestions(std::string_view word) override { + auto str = ns_str(word); + auto range = [spellChecker checkSpellingOfString:str + startingAt:0 + language:language.get() + wrap:NO + inSpellDocumentWithTag:0 + wordCount:nullptr]; + return array_to_vector([spellChecker guessesForWordRange:range + inString:str + language:language.get() + inSpellDocumentWithTag:0]); } - bool CanAddWord(std::string const&) override { + bool CanAddWord(std::string_view) override { return true; } - bool CanRemoveWord(std::string const& str) override { - return [NSSpellChecker.sharedSpellChecker hasLearnedWord:[NSString stringWithUTF8String:str.c_str()]]; + bool CanRemoveWord(std::string_view str) override { + return [spellChecker hasLearnedWord:ns_str(str)]; } - void AddWord(std::string const& word) override { - NSSpellChecker.sharedSpellChecker.language = language.get(); - [NSSpellChecker.sharedSpellChecker learnWord:[NSString stringWithUTF8String:word.c_str()]]; + void AddWord(std::string_view word) override { + spellChecker.language = language.get(); + [spellChecker learnWord:ns_str(word)]; } - void RemoveWord(std::string const& word) override { - NSSpellChecker.sharedSpellChecker.language = language.get(); - [NSSpellChecker.sharedSpellChecker unlearnWord:[NSString stringWithUTF8String:word.c_str()]]; + void RemoveWord(std::string_view word) override { + spellChecker.language = language.get(); + [spellChecker unlearnWord:ns_str(word)]; } }; } diff --git a/libaegisub/osx/util.mm b/libaegisub/osx/util.mm index f211d6f464..e6b77dbc4a 100644 --- a/libaegisub/osx/util.mm +++ b/libaegisub/osx/util.mm @@ -22,10 +22,10 @@ #import static std::string EmptyIfNil(NSString *string) { - return string ? [string UTF8String] : ""; + return [string UTF8String] ?: ""; } -namespace agi { namespace osx { +namespace agi::osx { AppNapDisabler::AppNapDisabler(std::string reason) : handle(nullptr) { if (reason.empty()) reason = "Loading"; auto processInfo = [NSProcessInfo processInfo]; @@ -41,10 +41,9 @@ [processInfo endActivity:(id)handle]; [(id)handle release]; } +} // namespace agi::osx -} -namespace util { - +namespace agi::util { std::string GetBundleResourcesDirectory() { @autoreleasepool { return EmptyIfNil([[[NSBundle mainBundle] resourceURL] path]); @@ -63,4 +62,4 @@ } } -} } +} // namespace agi::util diff --git a/libaegisub/unix/access.cpp b/libaegisub/unix/access.cpp index 73da19d224..aa60e2abbd 100644 --- a/libaegisub/unix/access.cpp +++ b/libaegisub/unix/access.cpp @@ -21,7 +21,7 @@ #include "libaegisub/fs.h" #include -#include +#include #include #include diff --git a/libaegisub/unix/fs.cpp b/libaegisub/unix/fs.cpp index 8f6ead6a89..ffed42304e 100644 --- a/libaegisub/unix/fs.cpp +++ b/libaegisub/unix/fs.cpp @@ -64,7 +64,7 @@ struct DirectoryIterator::PrivData { } }; -DirectoryIterator::DirectoryIterator() { } +DirectoryIterator::DirectoryIterator() = default; DirectoryIterator::DirectoryIterator(path const& p, std::string const& filter) : privdata(new PrivData(p, filter)) { diff --git a/libaegisub/unix/log.cpp b/libaegisub/unix/log.cpp index 82109dd2b6..b53e1d2617 100644 --- a/libaegisub/unix/log.cpp +++ b/libaegisub/unix/log.cpp @@ -18,7 +18,7 @@ #include #include -namespace agi { namespace log { +namespace agi::log { void EmitSTDOUT::log(SinkMessage const& sm) { time_t time = sm.time / 1000000000; tm tmtime; @@ -40,4 +40,4 @@ void EmitSTDOUT::log(SinkMessage const& sm) { if (!isatty(fileno(stdout))) fflush(stdout); } -} } +} diff --git a/libaegisub/unix/util.cpp b/libaegisub/unix/util.cpp index 4cf6721198..e1b9bea604 100644 --- a/libaegisub/unix/util.cpp +++ b/libaegisub/unix/util.cpp @@ -15,22 +15,12 @@ #include #include - -#ifdef _LIBCPP_VERSION #include -#else -#include -#endif -namespace agi { namespace util { +namespace agi::util { void SetThreadName(const char *) { } void sleep_for(int ms) { -#ifdef __clang__ std::this_thread::sleep_for(std::chrono::milliseconds(ms)); -#else - boost::this_thread::sleep_for(boost::chrono::milliseconds(ms)); -#endif } - -} } +} diff --git a/libaegisub/windows/charset_conv_win.cpp b/libaegisub/windows/charset_conv_win.cpp index 67385001a2..c0e397fcf4 100644 --- a/libaegisub/windows/charset_conv_win.cpp +++ b/libaegisub/windows/charset_conv_win.cpp @@ -30,8 +30,7 @@ std::string from_w(agi::charset::IconvWrapper &w32Conv, std::wstring const& sour } } -namespace agi { - namespace charset { +namespace agi::charset { std::wstring ConvertW(std::string const& source) { static IconvWrapper w32Conv("utf-8", "utf-16le", false); @@ -54,4 +53,3 @@ std::string ConvertLocal(std::wstring const& source) { } } -} diff --git a/meson.build b/meson.build index e5fa0e3a76..f451019626 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project('Aegisub', ['c', 'cpp'], license: 'BSD-3-Clause', meson_version: '>=0.56.1', - default_options: ['cpp_std=c++14', 'buildtype=debugoptimized'], + default_options: ['cpp_std=c++20', 'buildtype=debugoptimized'], version: '3.2.2') cmake = import('cmake') @@ -67,7 +67,7 @@ if host_machine.system() == 'darwin' add_languages('objc', 'objcpp') add_project_arguments('-DGL_SILENCE_DEPRECATION', language: 'cpp') # meson neither supports objcpp_std nor inherits cpp_std https://github.com/mesonbuild/meson/issues/5495 - add_project_arguments('-std=c++11', language: 'objcpp') + add_project_arguments('-std=c++20', language: 'objcpp') elif host_machine.system() != 'windows' conf.set('WITH_FONTCONFIG', 1) deps += dependency('fontconfig') diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index 518e4d4fea..95073111ce 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -37,15 +37,14 @@ #include #include -#include #include #include -#include #include #include #include #include +#include using namespace boost::adaptors; @@ -72,31 +71,31 @@ AssDialogue::AssDialogue(std::string const& data) { AssDialogue::~AssDialogue () { } class tokenizer { - agi::StringRange str; - agi::split_iterator pos; + std::string_view str; + agi::split_iterator pos; public: - tokenizer(agi::StringRange const& str) : str(str) , pos(agi::Split(str, ',')) { } + tokenizer(std::string_view str) : str(str), pos(agi::Split(str, ',')) { } - agi::StringRange next_tok() { + std::string_view next_tok() { if (pos.eof()) - throw SubtitleFormatParseError("Failed parsing line: " + std::string(str.begin(), str.end())); + throw SubtitleFormatParseError("Failed parsing line: " + std::string(str)); return *pos++; } - std::string next_str() { return agi::str(next_tok()); } - std::string next_str_trim() { return agi::str(boost::trim_copy(next_tok())); } + std::string next_str() { return std::string(next_tok()); } + std::string next_str_trim() { return std::string(agi::Trim(next_tok())); } }; void AssDialogue::Parse(std::string const& raw) { - agi::StringRange str; + std::string_view str = raw; if (boost::starts_with(raw, "Dialogue:")) { Comment = false; - str = agi::StringRange(raw.begin() + 10, raw.end()); + str.remove_prefix(10); } else if (boost::starts_with(raw, "Comment:")) { Comment = true; - str = agi::StringRange(raw.begin() + 9, raw.end()); + str.remove_prefix(9); } else throw SubtitleFormatParseError("Failed parsing line: " + raw); @@ -108,20 +107,17 @@ void AssDialogue::Parse(std::string const& raw) { bool ssa = boost::istarts_with(tmp, "marked="); // Get layer number - if (ssa) - Layer = 0; - else - Layer = boost::lexical_cast(tmp); + Layer = ssa ? 0 : boost::lexical_cast(tmp); - Start = tkn.next_str_trim(); - End = tkn.next_str_trim(); + Start = agi::Trim(tkn.next_tok()); + End = agi::Trim(tkn.next_tok()); Style = tkn.next_str_trim(); Actor = tkn.next_str_trim(); for (int& margin : Margin) - margin = mid(-9999, boost::lexical_cast(tkn.next_str()), 99999); + margin = mid(-9999, boost::lexical_cast(tkn.next_tok()), 99999); Effect = tkn.next_str_trim(); - std::string text{tkn.next_tok().begin(), str.end()}; + std::string text{tkn.next_tok()}; if (text.size() > 1 && text[0] == '{' && text[1] == '=') { static const boost::regex extradata_test("^\\{(=\\d+)+\\}"); @@ -201,7 +197,7 @@ std::vector> AssDialogue::ParseTags() const { // Empty line, make an empty block if (Text.get().empty()) { - Blocks.push_back(agi::make_unique()); + Blocks.push_back(std::make_unique()); return Blocks; } @@ -226,11 +222,11 @@ std::vector> AssDialogue::ParseTags() const { if (work.size() && work.find('\\') == std::string::npos) { //We've found an override block with no backslashes //We're going to assume it's a comment and not consider it an override block - Blocks.push_back(agi::make_unique(work)); + Blocks.push_back(std::make_unique(work)); } else { // Create block - auto block = agi::make_unique(work); + auto block = std::make_unique(work); block->ParseTags(); // Look for \p in block @@ -258,9 +254,9 @@ std::vector> AssDialogue::ParseTags() const { } if (drawingLevel == 0) - Blocks.push_back(agi::make_unique(work)); + Blocks.push_back(std::make_unique(work)); else - Blocks.push_back(agi::make_unique(work, drawingLevel)); + Blocks.push_back(std::make_unique(work, drawingLevel)); } return Blocks; diff --git a/src/ass_override.cpp b/src/ass_override.cpp index fc8758c089..035662c6df 100644 --- a/src/ass_override.cpp +++ b/src/ass_override.cpp @@ -35,11 +35,10 @@ #include #include #include -#include +#include #include #include -#include #include #include #include @@ -85,12 +84,12 @@ template<> bool AssOverrideParameter::Get() const { } template<> agi::Color AssOverrideParameter::Get() const { - return Get(); + return std::string_view(Get()); } template<> AssDialogueBlockOverride *AssOverrideParameter::Get() const { if (!block) { - block = agi::make_unique(Get()); + block = std::make_unique(Get()); block->ParseTags(); } return block.get(); @@ -307,7 +306,7 @@ static void load_protos() { proto[i].AddParam(VariableDataType::BLOCK); } -std::vector tokenize(const std::string &text) { +std::vector tokenize(std::string_view text) { std::vector paramList; paramList.reserve(6); @@ -317,7 +316,7 @@ std::vector tokenize(const std::string &text) { if (text[0] != '(') { // There's just one parameter (because there's no parentheses) // This means text is all our parameters - paramList.emplace_back(boost::trim_copy(text)); + paramList.emplace_back(agi::Trim(text)); return paramList; } @@ -344,7 +343,7 @@ std::vector tokenize(const std::string &text) { i++; } // i now points to the first character not member of this parameter - paramList.emplace_back(boost::trim_copy(text.substr(start, i - start))); + paramList.emplace_back(agi::Trim(text.substr(start, i - start))); } if (i+1 < textlen) { @@ -355,7 +354,7 @@ std::vector tokenize(const std::string &text) { return paramList; } -void parse_parameters(AssOverrideTag *tag, const std::string &text, AssOverrideTagProto::iterator proto_it) { +void parse_parameters(AssOverrideTag *tag, std::string_view text, AssOverrideTagProto::iterator proto_it) { tag->Clear(); // Tokenize text, attempting to find all parameters diff --git a/src/ass_parser.cpp b/src/ass_parser.cpp index f55fc3567f..ebbd6211b2 100644 --- a/src/ass_parser.cpp +++ b/src/ass_parser.cpp @@ -23,7 +23,6 @@ #include "subtitle_format.h" #include -#include #include #include @@ -32,11 +31,11 @@ #include #include #include -#include #include +#include class AssParser::HeaderToProperty { - using field = boost::variant< + using field = std::variant< std::string ProjectProperties::*, int ProjectProperties::*, double ProjectProperties::* @@ -81,7 +80,7 @@ class AssParser::HeaderToProperty { void operator()(int ProjectProperties::*f) const { try_parse(value, &(obj.*f)); } void operator()(double ProjectProperties::*f) const { try_parse(value, &(obj.*f)); } } visitor {target->Properties, value}; - boost::apply_visitor(visitor, it->second); + std::visit(visitor, it->second); return true; } @@ -95,15 +94,14 @@ class AssParser::HeaderToProperty { }; AssParser::AssParser(AssFile *target, int version) -: property_handler(agi::make_unique()) +: property_handler(std::make_unique()) , target(target) , version(version) , state(&AssParser::ParseScriptInfoLine) { } -AssParser::~AssParser() { -} +AssParser::~AssParser() = default; void AssParser::ParseAttachmentLine(std::string const& data) { bool is_filename = boost::starts_with(data, "fontname: ") || boost::starts_with(data, "filename: "); @@ -188,12 +186,12 @@ void AssParser::ParseStyleLine(std::string const& data) { void AssParser::ParseFontLine(std::string const& data) { if (boost::starts_with(data, "fontname: ")) - attach = agi::make_unique(data, AssEntryGroup::FONT); + attach = std::make_unique(data, AssEntryGroup::FONT); } void AssParser::ParseGraphicsLine(std::string const& data) { if (boost::starts_with(data, "filename: ")) - attach = agi::make_unique(data, AssEntryGroup::GRAPHIC); + attach = std::make_unique(data, AssEntryGroup::GRAPHIC); } void AssParser::ParseExtradataLine(std::string const &data) { diff --git a/src/ass_style.cpp b/src/ass_style.cpp index 0b778b328f..fcdbbdaa5d 100644 --- a/src/ass_style.cpp +++ b/src/ass_style.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -54,19 +53,20 @@ AssEntryGroup AssStyle::Group() const { return AssEntryGroup::STYLE; } namespace { class parser { - agi::split_iterator pos; + agi::split_iterator pos; - std::string next_tok() { + std::string_view next_tok() { if (pos.eof()) throw SubtitleFormatParseError("Malformed style: not enough fields"); - return agi::str(trim_copy(*pos++)); + return agi::Trim(*pos++); } public: - parser(std::string const& str) { - auto colon = find(str.begin(), str.end(), ':'); - if (colon != str.end()) - pos = agi::Split(agi::StringRange(colon + 1, str.end()), ','); + parser(std::string_view str) { + if (auto colon = str.find(':'); colon != str.npos) { + str.remove_prefix(colon); + pos = agi::Split(str, ','); + } } void check_done() const { @@ -74,7 +74,7 @@ class parser { throw SubtitleFormatParseError("Malformed style: too many fields"); } - std::string next_str() { return next_tok(); } + std::string next_str() { return std::string(next_tok()); } agi::Color next_color() { return next_tok(); } int next_int() { @@ -102,7 +102,7 @@ class parser { }; } -AssStyle::AssStyle(std::string const& str, int version) { +AssStyle::AssStyle(std::string_view str, int version) { parser p(str); name = p.next_str(); diff --git a/src/ass_style.h b/src/ass_style.h index d366880d4e..60e028bb9c 100644 --- a/src/ass_style.h +++ b/src/ass_style.h @@ -71,7 +71,7 @@ class AssStyle final : public AssEntry, public AssEntryListHook { static void GetEncodings(wxArrayString &encodingStrings); AssStyle(); - AssStyle(std::string const& data, int version=1); + AssStyle(std::string_view data, int version=1); std::string const& GetEntryData() const { return data; } AssEntryGroup Group() const override; diff --git a/src/ass_style_storage.cpp b/src/ass_style_storage.cpp index d6dc6d8354..0b540624d7 100644 --- a/src/ass_style_storage.cpp +++ b/src/ass_style_storage.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -70,7 +69,7 @@ void AssStyleStorage::Load(agi::fs::path const& filename) { auto in = agi::io::Open(file); for (auto const& line : agi::line_iterator(*in)) { try { - style.emplace_back(agi::make_unique(line)); + style.emplace_back(std::make_unique(line)); } catch(...) { /* just ignore invalid lines for now */ } diff --git a/src/async_video_provider.cpp b/src/async_video_provider.cpp index 33dbe4bca1..3f8a5fc9f5 100644 --- a/src/async_video_provider.cpp +++ b/src/async_video_provider.cpp @@ -217,12 +217,12 @@ wxDEFINE_EVENT(EVT_VIDEO_ERROR, VideoProviderErrorEvent); wxDEFINE_EVENT(EVT_SUBTITLES_ERROR, SubtitlesProviderErrorEvent); VideoProviderErrorEvent::VideoProviderErrorEvent(VideoProviderError const& err) -: agi::Exception(err.GetMessage()) +: agi::Exception(std::string(err.GetMessage())) { SetEventType(EVT_VIDEO_ERROR); } SubtitlesProviderErrorEvent::SubtitlesProviderErrorEvent(std::string const& err) -: agi::Exception(err) +: agi::Exception(std::string(err)) { SetEventType(EVT_SUBTITLES_ERROR); } diff --git a/src/audio_display.cpp b/src/audio_display.cpp index 2041715fd6..44ea1ab5c8 100644 --- a/src/audio_display.cpp +++ b/src/audio_display.cpp @@ -46,7 +46,6 @@ #include #include -#include #include @@ -573,10 +572,10 @@ AudioDisplay::AudioDisplay(wxWindow *parent, AudioController *controller, agi::C : wxWindow(parent, -1, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS|wxBORDER_SIMPLE) , audio_open_connection(context->project->AddAudioProviderListener(&AudioDisplay::OnAudioOpen, this)) , context(context) -, audio_renderer(agi::make_unique()) +, audio_renderer(std::make_unique()) , controller(controller) -, scrollbar(agi::make_unique(this)) -, timeline(agi::make_unique(this)) +, scrollbar(std::make_unique(this)) +, timeline(std::make_unique(this)) , style_ranges({{0, 0}}) { audio_renderer->SetAmplitudeScale(scale_amplitude); @@ -743,7 +742,7 @@ void AudioDisplay::ReloadRenderingSettings() if (OPT_GET("Audio/Spectrum")->GetBool()) { colour_scheme_name = OPT_GET("Colour/Audio Display/Spectrum")->GetString(); - auto audio_spectrum_renderer = agi::make_unique(colour_scheme_name); + auto audio_spectrum_renderer = std::make_unique(colour_scheme_name); int64_t spectrum_quality = OPT_GET("Audio/Renderer/Spectrum/Quality")->GetInt(); #ifdef WITH_FFTW3 @@ -765,7 +764,7 @@ void AudioDisplay::ReloadRenderingSettings() else { colour_scheme_name = OPT_GET("Colour/Audio Display/Waveform")->GetString(); - audio_renderer_provider = agi::make_unique(colour_scheme_name); + audio_renderer_provider = std::make_unique(colour_scheme_name); } audio_renderer->SetRenderer(audio_renderer_provider.get()); @@ -1106,7 +1105,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) if (markers.size()) { RemoveTrackCursor(); - audio_marker = agi::make_unique(markers, timing, this, (wxMouseButton)event.GetButton()); + audio_marker = std::make_unique(markers, timing, this, (wxMouseButton)event.GetButton()); SetDraggedObject(audio_marker.get()); return; } diff --git a/src/audio_karaoke.cpp b/src/audio_karaoke.cpp index 2abeb79d80..02aac5f615 100644 --- a/src/audio_karaoke.cpp +++ b/src/audio_karaoke.cpp @@ -36,8 +36,6 @@ #include "selection_controller.h" #include "utils.h" -#include - #include #include #include @@ -64,7 +62,7 @@ AudioKaraoke::AudioKaraoke(wxWindow *parent, agi::Context *c) , file_changed(c->ass->AddCommitListener(&AudioKaraoke::OnFileChanged, this)) , audio_opened(c->project->AddAudioProviderListener(&AudioKaraoke::OnAudioOpened, this)) , active_line_changed(c->selectionController->AddActiveLineListener(&AudioKaraoke::OnActiveLineChanged, this)) -, kara(agi::make_unique()) +, kara(std::make_unique()) { using std::bind; diff --git a/src/audio_marker.cpp b/src/audio_marker.cpp index c627d5b964..fe584891b8 100644 --- a/src/audio_marker.cpp +++ b/src/audio_marker.cpp @@ -27,8 +27,6 @@ #include "project.h" #include "video_controller.h" -#include - #include class AudioMarkerKeyframe final : public AudioMarker { @@ -48,7 +46,7 @@ AudioMarkerProviderKeyframes::AudioMarkerProviderKeyframes(agi::Context *c, cons , timecode_slot(p->AddTimecodesListener(&AudioMarkerProviderKeyframes::Update, this)) , enabled_slot(OPT_SUB(opt_name, &AudioMarkerProviderKeyframes::Update, this)) , enabled_opt(OPT_GET(opt_name)) -, style(agi::make_unique("Colour/Audio Display/Keyframe")) +, style(std::make_unique("Colour/Audio Display/Keyframe")) { Update(); } @@ -115,7 +113,7 @@ void VideoPositionMarkerProvider::Update(int frame_number) { void VideoPositionMarkerProvider::OptChanged(agi::OptionValue const& opt) { if (opt.GetBool()) { video_seek_slot.Unblock(); - marker = agi::make_unique(); + marker = std::make_unique(); marker->SetPosition(vc->GetFrameN()); } else { @@ -130,7 +128,7 @@ void VideoPositionMarkerProvider::GetMarkers(const TimeRange &range, AudioMarker } SecondsMarkerProvider::SecondsMarkerProvider() -: pen(agi::make_unique("Colour/Audio Display/Seconds Line", 1, wxPENSTYLE_DOT)) +: pen(std::make_unique("Colour/Audio Display/Seconds Line", 1, wxPENSTYLE_DOT)) , enabled(OPT_GET("Audio/Display/Draw/Seconds")) , enabled_opt_changed(OPT_SUB("Audio/Display/Draw/Seconds", &SecondsMarkerProvider::EnabledOptChanged, this)) { diff --git a/src/audio_player.cpp b/src/audio_player.cpp index f5a8327ca0..fb0a974cf8 100644 --- a/src/audio_player.cpp +++ b/src/audio_player.cpp @@ -38,8 +38,6 @@ #include "factory_manager.h" #include "options.h" -#include - std::unique_ptr CreateAlsaPlayer(agi::AudioProvider *providers, wxWindow *window); std::unique_ptr CreateDirectSoundPlayer(agi::AudioProvider *providers, wxWindow *window); std::unique_ptr CreateDirectSound2Player(agi::AudioProvider *providers, wxWindow *window); @@ -55,7 +53,7 @@ namespace { bool hidden; }; - const factory factories[] = { + const std::initializer_list factories = { #ifdef WITH_ALSA {"ALSA", CreateAlsaPlayer, false}, #endif @@ -79,15 +77,15 @@ namespace { } std::vector AudioPlayerFactory::GetClasses() { - return ::GetClasses(boost::make_iterator_range(std::begin(factories), std::end(factories))); + return ::GetClasses(factories); } std::unique_ptr AudioPlayerFactory::GetAudioPlayer(agi::AudioProvider *provider, wxWindow *window) { - if (std::begin(factories) == std::end(factories)) + if (factories.size() == 0) throw AudioPlayerOpenError("No audio players are available."); auto preferred = OPT_GET("Audio/Player")->GetString(); - auto sorted = GetSorted(boost::make_iterator_range(std::begin(factories), std::end(factories)), preferred); + auto sorted = GetSorted(factories, preferred); std::string error; for (auto factory : sorted) { diff --git a/src/audio_player_openal.cpp b/src/audio_player_openal.cpp index b0f8372bdc..ca39dcb779 100644 --- a/src/audio_player_openal.cpp +++ b/src/audio_player_openal.cpp @@ -40,7 +40,6 @@ #include #include -#include #ifdef __WINDOWS__ #include @@ -305,7 +304,7 @@ int64_t OpenALPlayer::GetCurrentPosition() std::unique_ptr CreateOpenALPlayer(agi::AudioProvider *provider, wxWindow *) { - return agi::make_unique(provider); + return std::make_unique(provider); } #endif // WITH_OPENAL diff --git a/src/audio_provider_factory.cpp b/src/audio_provider_factory.cpp index 887783644d..d0d0e41d4f 100644 --- a/src/audio_provider_factory.cpp +++ b/src/audio_provider_factory.cpp @@ -25,8 +25,6 @@ #include #include -#include - using namespace agi; std::unique_ptr CreateAvisynthAudioProvider(fs::path const& filename, BackgroundRunner *); @@ -39,7 +37,7 @@ struct factory { bool hidden; }; -const factory providers[] = { +const std::initializer_list providers = { {"Dummy", CreateDummyAudioProvider, true}, {"PCM", CreatePCMAudioProvider, true}, #ifdef WITH_FFMS2 @@ -52,14 +50,14 @@ const factory providers[] = { } std::vector GetAudioProviderNames() { - return ::GetClasses(boost::make_iterator_range(std::begin(providers), std::end(providers))); + return ::GetClasses(providers); } std::unique_ptr GetAudioProvider(fs::path const& filename, Path const& path_helper, BackgroundRunner *br) { auto preferred = OPT_GET("Audio/Provider")->GetString(); - auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); + auto sorted = GetSorted(providers, preferred); std::unique_ptr provider; bool found_file = false; diff --git a/src/audio_provider_ffmpegsource.cpp b/src/audio_provider_ffmpegsource.cpp index 0a201855ac..7788ea34aa 100644 --- a/src/audio_provider_ffmpegsource.cpp +++ b/src/audio_provider_ffmpegsource.cpp @@ -39,7 +39,6 @@ #include "options.h" #include -#include #include @@ -183,7 +182,7 @@ void FFmpegSourceAudioProvider::LoadAudio(agi::fs::path const& filename) { } std::unique_ptr CreateFFmpegSourceAudioProvider(agi::fs::path const& file, agi::BackgroundRunner *br) { - return agi::make_unique(file, br); + return std::make_unique(file, br); } #endif /* WITH_FFMS2 */ diff --git a/src/audio_renderer.cpp b/src/audio_renderer.cpp index e90586b026..4befd15be1 100644 --- a/src/audio_renderer.cpp +++ b/src/audio_renderer.cpp @@ -34,7 +34,6 @@ #include "audio_renderer.h" #include -#include #include #include @@ -57,7 +56,7 @@ AudioRendererBitmapCacheBitmapFactory::AudioRendererBitmapCacheBitmapFactory(Aud std::unique_ptr AudioRendererBitmapCacheBitmapFactory::ProduceBlock(int /* i */) { - return agi::make_unique(renderer->cache_bitmap_width, renderer->pixel_height, 24); + return std::make_unique(renderer->cache_bitmap_width, renderer->pixel_height, 24); } size_t AudioRendererBitmapCacheBitmapFactory::GetBlockSize() const diff --git a/src/audio_renderer_spectrum.cpp b/src/audio_renderer_spectrum.cpp index 4331febfc3..4e818afb00 100644 --- a/src/audio_renderer_spectrum.cpp +++ b/src/audio_renderer_spectrum.cpp @@ -40,7 +40,6 @@ #endif #include -#include #include @@ -115,7 +114,7 @@ void AudioSpectrumRenderer::RecreateCache() if (provider) { size_t block_count = (size_t)((provider->GetNumSamples() + ((size_t)1<> derivation_dist); - cache = agi::make_unique(block_count, this); + cache = std::make_unique(block_count, this); #ifdef WITH_FFTW3 dft_input = fftw_alloc_real(2< -#include #include #include @@ -924,5 +923,5 @@ int AudioTimingControllerDialogue::SnapMarkers(int snap_range, std::vector