diff --git a/CMakeLists.txt b/CMakeLists.txt index 018e16916981..13f7c5250a60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,10 +75,10 @@ include(GitRepo) ## Libraries ## ############################## -# c++17 support +# c++20 support ############################## -#find_package(CXX17 REQUIRED COMPONENTS optional) -#find_package(Filesystem REQUIRED COMPONENTS ghc Final Experimental) + +find_package(format) find_package(Backtrace) if (Backtrace_FOUND) @@ -197,6 +197,7 @@ target_link_libraries(external_modules INTERFACE $<$:X11::Xi> $<$:X11::X11> $<$:Backtrace::backtrace> + $<$:fmt::fmt> ZLIB::ZLIB Threads::Threads ) @@ -372,7 +373,8 @@ Configuration: X11 support enabled: ${X11_FOUND} GTEST enabled: ${ENABLE_GTEST} GCOV enabled: ${DEV_ENABLE_GCOV} - Filesystem library: ${CXX_FILESYSTEM_NAMESPACE} + Filesystem library: std::filesystem + Format library: ${FORMAT_LIB} Profiling enabled: ${ENABLE_PROFILING} ") diff --git a/cmake/find/Find-format.cmake b/cmake/find/Find-format.cmake new file mode 100644 index 000000000000..5a949e3dd3d2 --- /dev/null +++ b/cmake/find/Find-format.cmake @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.14) + +enable_language(CXX) + +option(XOJ_USE_FMTLIB "Use fmtlib" OFF) +include(xoj_check_cxx_definition) +xoj_check_cxx_definition("__cpp_lib_format >= 202110L" "format" _XOJ_HAS_INCLUDE_FORMAT) + +if(_XOJ_HAS_INCLUDE_FORMAT AND NOT XOJ_USE_FMTLIB) + message(STATUS "Found ") + set(FORMAT_LIB "std::format") +else() + message(STATUS "Could not find , fetch {fmt}") + include(get_cpm) + CPMAddPackage("gh:fmtlib/fmt#7.1.3") + set(FORMAT_LIB "{fmt}") +endif() +set(format_FOUND TRUE) diff --git a/cmake/include/get_cpm.cmake b/cmake/include/get_cpm.cmake new file mode 100644 index 000000000000..d0fd0e8ea47f --- /dev/null +++ b/cmake/include/get_cpm.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.39.0) +set(CPM_HASH_SUM "66639bcac9dd2907b2918de466783554c1334446b9874e90d38e3778d404c2ef") + +if(CPM_SOURCE_CACHE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") +endif() + +# Expand relative path. This is important if the provided path contains a tilde (~) +get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) + +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) + +include(${CPM_DOWNLOAD_LOCATION}) diff --git a/cmake/include/xoj_check_cxx_definition.cmake b/cmake/include/xoj_check_cxx_definition.cmake new file mode 100644 index 000000000000..1396f305711d --- /dev/null +++ b/cmake/include/xoj_check_cxx_definition.cmake @@ -0,0 +1,20 @@ +# Define the function +function(xoj_check_cxx_definition definition header variable) + set(BINARY_DIR ${CMAKE_BINARY_DIR}/xoj_check_cxx_definition) + set(SOURCE_FILE ${CMAKE_BINARY_DIR}/xoj_check_cxx_definition/${variable}.cpp) + file(WRITE ${SOURCE_FILE} "#include <${header}> \n#if !(${definition}) \n#error \n#endif\nint main(){}") + try_compile(${variable} + ${BINARY_DIR} + ${SOURCE_FILE} + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED TRUE + OUTPUT_VARIABLE _OUT_ERROR + ) + if(${variable}) + message(STATUS "${header} defines ${definition}") + else() + message(STATUS "${header} does not define ${definition}") + message(STATUS "${_OUT_ERROR}") + endif() + file(REMOVE ${SOURCE_FILE}) +endfunction() diff --git a/src/core/control/Control.cpp b/src/core/control/Control.cpp index 5b24142ec7f8..706d21be0878 100644 --- a/src/core/control/Control.cpp +++ b/src/core/control/Control.cpp @@ -1,9 +1,8 @@ #include "Control.h" -#include // for max -#include // for size_t -#include // for exce... -#include +#include // for max +#include // for size_t +#include // for exce... #include // for bind #include // for end #include // for make... @@ -112,6 +111,7 @@ #include "UndoRedoController.h" // for Undo... #include "config-dev.h" // for SETT... #include "config.h" // for PROJ... +#include "format.h" // for fmt::format using std::string; @@ -1812,14 +1812,14 @@ void Control::updateWindowTitle() { title = _("Unsaved Document"); } else { if (settings->isPageNumberInTitlebarShown()) { - title += std::format("[{}/{}] ", getCurrentPageNo() + 1, doc->getPageCount()); + title += fmt::format("[{}/{}] ", getCurrentPageNo() + 1, doc->getPageCount()); } if (undoRedo->isChanged()) { title += "*"; } if (settings->isFilepathInTitlebarShown()) { - title += std::format("[{}] - {}", char_cast(doc->getPdfFilepath().parent_path().u8string()), + title += fmt::format("[{}] - {}", char_cast(doc->getPdfFilepath().parent_path().u8string()), char_cast(doc->getPdfFilepath().filename().u8string())); } else { title += char_cast(doc->getPdfFilepath().filename().u8string()); @@ -1827,14 +1827,14 @@ void Control::updateWindowTitle() { } } else { if (settings->isPageNumberInTitlebarShown()) { - title += ("[" + std::to_string(getCurrentPageNo() + 1) + "/" + std::to_string(doc->getPageCount()) + "] "); + title += fmt::format("[{}/{}] ", getCurrentPageNo() + 1 , doc->getPageCount()); } if (undoRedo->isChanged()) { title += "*"; } if (settings->isFilepathInTitlebarShown()) { - title += (std::format("[{}] - {}", char_cast(doc->getFilepath().parent_path().u8string()), + title += (fmt::format("[{}] - {}", char_cast(doc->getFilepath().parent_path().u8string()), char_cast(doc->getFilepath().filename().u8string()))); } else { title += char_cast(doc->getFilepath().filename().u8string()); diff --git a/src/util/include/format.h b/src/util/include/format.h new file mode 100644 index 000000000000..8fdfc7e56ed5 --- /dev/null +++ b/src/util/include/format.h @@ -0,0 +1,41 @@ +#pragma once + +// define XOJ_USE_STD_FORMAT if std::format should be forced + +#if !defined(XOJ_USE_STD_FORMAT) && __has_include() +#include // IWYU pragma: export +#if defined(__cpp_lib_format) && __cpp_lib_format >= 202110L +#define XOJ_USE_STD_FORMAT = 1 +#endif +#endif + +#if !defined(XOJ_USE_STD_FORMAT) +#include // IWYU pragma: export +#else // Include all the symbols from std::format into the fmt namespace +namespace fmt { +using std::basic_format_arg; +using std::basic_format_args; +using std::basic_format_context; +using std::basic_format_parse_context; +using std::basic_format_string; +using std::format; +using std::format_args; +using std::format_context; +using std::format_error; +using std::format_parse_context; +using std::format_string; +using std::format_to; +using std::format_to_n; +using std::formatted_size; +using std::formatter; +using std::make_format_args; +using std::make_wformat_args; +using std::vformat; +using std::vformat_to; +using std::visit_format_arg; +using std::wformat_args; +using std::wformat_context; +using std::wformat_parse_context; +using std::wformat_string; +} // namespace fmt +#endif