diff --git a/CMakeLists.txt b/CMakeLists.txt index e18bf3fe5..4060d21c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,18 +36,48 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # Setup C/C++ compiler options ################################################################################# -# C++17 compiler flags +# Detect if compiler supports at least C++17 standard include(CXX1x) check_for_cxx17_compiler(CXX17_COMPILER) -# If a C++17 compiler is available, then set the appropriate flags -if(CXX17_COMPILER) - set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -else() +if(NOT CXX17_COMPILER) message(FATAL_ERROR "Compiler does not support C++17.") endif() +# If a C++17 compiler is available, then set the appropriate flags + +option(POCO_ENABLE_CPP20 "Build Poco with C++20 standard" ON) + +if (EMSCRIPTEN) + set(POCO_ENABLE_CPP20 OFF CACHE BOOL "Build Poco with C++20 standard" FORCE) +else() + +# https://libcxx.llvm.org/Status/Cxx20.html +# https://en.wikipedia.org/wiki/Xcode#Toolchain_versions + + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0) + # Does not fully support C++20 yet + set(POCO_ENABLE_CPP20 OFF CACHE BOOL "Build Poco with C++20 standard" FORCE) + endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0) + # Does not fully support C++20 yet + set(POCO_ENABLE_CPP20 OFF CACHE BOOL "Build Poco with C++20 standard" FORCE) + endif () + endif() +endif() + +if (POCO_ENABLE_CPP20) + set(CMAKE_CXX_STANDARD 20) + message(STATUS "Building Poco with C++20 standard") +else() + set(CMAKE_CXX_STANDARD 17) + message(STATUS "Building Poco with C++17 standard") +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() diff --git a/Foundation/CMakeLists.txt b/Foundation/CMakeLists.txt index cc81a2496..a8175768e 100644 --- a/Foundation/CMakeLists.txt +++ b/Foundation/CMakeLists.txt @@ -128,17 +128,33 @@ target_include_directories(Foundation target_compile_definitions(Foundation PUBLIC $<$:_DEBUG> - $<$:POCO_DISABLE_CPP14> - $<$>:POCO_ENABLE_CPP14> - $<$:POCO_DISABLE_CPP11> - $<$>:POCO_ENABLE_CPP11> + $<$:POCO_ENABLE_CPP20> ) target_compile_features(Foundation PUBLIC $<$>:cxx_defaulted_move_initializers> ) -if(NOT DISABLE_CPP14 AND CMAKE_VERSION VERSION_GREATER "3.8") - target_compile_features(Foundation PUBLIC cxx_std_14) + +# +# Set target C++ standard compile features for exported target. +# +target_compile_features(Foundation PUBLIC cxx_std_17) +if (POCO_ENABLE_CPP20) + target_compile_features(Foundation PUBLIC cxx_std_20) +endif() + +if (POCO_ENABLE_CPP20 AND NOT EMSCRIPTEN) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 20.0) + # Some C++20 features must be enabled explicitly in clang + target_compile_options(Foundation PUBLIC -fexperimental-library) + endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0) + # Some C++20 features must be enabled explicitly in clang + target_compile_options(Foundation PUBLIC -fexperimental-library) + endif () + endif() endif() if(NOT BUILD_SHARED_LIBS) diff --git a/Foundation/include/Poco/Config.h b/Foundation/include/Poco/Config.h index ade3a848f..8d1ff8634 100644 --- a/Foundation/include/Poco/Config.h +++ b/Foundation/include/Poco/Config.h @@ -186,6 +186,8 @@ #endif #define POCO_HAVE_CPP17_COMPILER (__cplusplus >= 201703L) +#define POCO_HAVE_CPP20_COMPILER (__cplusplus >= 202002L) +#define POCO_HAVE_CPP23_COMPILER (__cplusplus >= 202302L) // Option to silence deprecation warnings. #ifndef POCO_SILENCE_DEPRECATED diff --git a/Foundation/include/Poco/UTFString.h b/Foundation/include/Poco/UTFString.h index db9dc1010..74170ea35 100644 --- a/Foundation/include/Poco/UTFString.h +++ b/Foundation/include/Poco/UTFString.h @@ -260,12 +260,6 @@ struct UTF32CharTraits }; -//#if defined(POCO_ENABLE_CPP11) //TODO - // using char16_t UTF16Char; - // using std::u16string UTF16String; - // using char32_t UTF32Char; - // using std::u32string UTF32String; -//#else #ifdef POCO_NO_WSTRING using UTF16Char = Poco::UInt16; using UTF16String = std::basic_string; @@ -301,7 +295,6 @@ struct UTF32CharTraits #define POCO_USE_STRING16 #endif //POCO_OS_FAMILY_WINDOWS #endif //POCO_NO_WSTRING -//#endif // POCO_ENABLE_CPP11 } // namespace Poco diff --git a/Foundation/src/Format.cpp b/Foundation/src/Format.cpp index 1b7cc2bc6..c1ced26b9 100644 --- a/Foundation/src/Format.cpp +++ b/Foundation/src/Format.cpp @@ -252,23 +252,23 @@ namespace std::string format(const std::string& fmt, const Any& value) { std::string result; - format(result, fmt, value); + Poco::format(result, fmt, value); return result; } void format(std::string& result, const char *fmt, const std::vector& values) { - format(result, std::string(fmt), values); + Poco::format(result, std::string(fmt), values); } void format(std::string& result, const std::string& fmt, const std::vector& values) { - std::string::const_iterator itFmt = fmt.begin(); - std::string::const_iterator endFmt = fmt.end(); - std::vector::const_iterator itVal = values.begin(); - std::vector::const_iterator endVal = values.end(); + auto itFmt = fmt.begin(); + const auto endFmt = fmt.end(); + auto itVal = values.begin(); + const auto endVal = values.end(); while (itFmt != endFmt) { switch (*itFmt) @@ -283,7 +283,7 @@ void format(std::string& result, const std::string& fmt, const std::vector& std::size_t index = parseIndex(itFmt, endFmt); if (index < values.size()) { - std::vector::const_iterator it = values.begin() + index; + auto it = values.begin() + index; formatOne(result, itFmt, endFmt, it); } else throw InvalidArgumentException("format argument index out of range", fmt); diff --git a/Foundation/testsuite/src/AnyTest.cpp b/Foundation/testsuite/src/AnyTest.cpp index f1e3e00c6..4f862bb9d 100644 --- a/Foundation/testsuite/src/AnyTest.cpp +++ b/Foundation/testsuite/src/AnyTest.cpp @@ -233,7 +233,7 @@ void AnyTest::testAnySwap() Poco::UInt64 eight = 8; Poco::UInt64 nine = 9; - bool operator==(const BigObject& other) + bool operator==(const BigObject& other) const { return one == other.one && two == other.two && diff --git a/Foundation/testsuite/src/FormatTest.cpp b/Foundation/testsuite/src/FormatTest.cpp index b91962d97..402122de2 100644 --- a/Foundation/testsuite/src/FormatTest.cpp +++ b/Foundation/testsuite/src/FormatTest.cpp @@ -29,9 +29,7 @@ FormatTest::FormatTest(const std::string& name): CppUnit::TestCase(name) } -FormatTest::~FormatTest() -{ -} +FormatTest::~FormatTest() = default; void FormatTest::testChar() @@ -256,7 +254,7 @@ void FormatTest::testBool() bv.push_back(true); s.clear(); - format(s, "%b%b%b%b%b%b%b%b%b%b", bv); + Poco::format(s, "%b%b%b%b%b%b%b%b%b%b", bv); assertTrue (s == "0101010101"); } @@ -571,7 +569,7 @@ void FormatTest::testAny() s.clear(); std::vector av{ 42, std::string("42"), 42. }; - format(s, "%d '%s' %f", av); + Poco::format(s, "%d '%s' %f", av); assertTrue (s.find("42 '42' 42.0") == 0); } diff --git a/Net/src/SSPINTLMCredentials.cpp b/Net/src/SSPINTLMCredentials.cpp index 849b62fe5..ebb57fecc 100644 --- a/Net/src/SSPINTLMCredentials.cpp +++ b/Net/src/SSPINTLMCredentials.cpp @@ -69,7 +69,8 @@ public: bool available() { PSecPkgInfoW pSecPkgInfo; - SECURITY_STATUS status = _pSecFunTable->QuerySecurityPackageInfoW(L"NTLM", &pSecPkgInfo); + ::SEC_WCHAR package[] = L"NTLM"; + SECURITY_STATUS status = _pSecFunTable->QuerySecurityPackageInfoW(package, &pSecPkgInfo); if (status == SEC_E_OK) { _pSecFunTable->FreeContextBuffer(pSecPkgInfo); @@ -81,7 +82,8 @@ public: Poco::SharedPtr createNTLMContext(const std::string& host, const std::string& service) { PSecPkgInfoW pSecPkgInfo; - SECURITY_STATUS status = _pSecFunTable->QuerySecurityPackageInfoW(L"NTLM", &pSecPkgInfo); + ::SEC_WCHAR package[] = L"NTLM"; + SECURITY_STATUS status = _pSecFunTable->QuerySecurityPackageInfoW(package, &pSecPkgInfo); if (status != SEC_E_OK) throw Poco::SystemException("NTLM SSPI not available", status); std::size_t maxTokenSize = pSecPkgInfo->cbMaxToken; @@ -93,7 +95,7 @@ public: TimeStamp expiry; status = _pSecFunTable->AcquireCredentialsHandleW( NULL, - L"NTLM", + package, SECPKG_CRED_OUTBOUND, NULL, NULL, diff --git a/NetSSL_Win/src/Context.cpp b/NetSSL_Win/src/Context.cpp index 3c5272634..71f7197d0 100644 --- a/NetSSL_Win/src/Context.cpp +++ b/NetSSL_Win/src/Context.cpp @@ -174,8 +174,10 @@ void Context::loadCertificate() } if (!_hCertStore) throw CertificateException("Failed to open certificate store", _certStoreName, GetLastError()); + CERT_RDN_ATTR cert_rdn_attr; - cert_rdn_attr.pszObjId = szOID_COMMON_NAME; + char cmnName[] = szOID_COMMON_NAME; + cert_rdn_attr.pszObjId = cmnName; cert_rdn_attr.dwValueType = CERT_RDN_ANY_TYPE; cert_rdn_attr.Value.cbData = (DWORD) _certNameOrPath.size(); cert_rdn_attr.Value.pbData = (BYTE *) _certNameOrPath.c_str(); @@ -270,7 +272,7 @@ void Context::acquireSchannelCredentials(CredHandle& credHandle) const if (_pCert) { schannelCred.cCreds = 1; // how many cred are stored in &pCertContext - schannelCred.paCred = &const_cast(_pCert); + schannelCred.paCred = const_cast(&_pCert); } schannelCred.grbitEnabledProtocols = proto(); @@ -312,9 +314,10 @@ void Context::acquireSchannelCredentials(CredHandle& credHandle) const TimeStamp tsExpiry; tsExpiry.LowPart = tsExpiry.HighPart = 0; + ::SEC_WCHAR name[] = UNISP_NAME_W; SECURITY_STATUS status = _securityFunctions.AcquireCredentialsHandleW( NULL, - UNISP_NAME_W, + name, isForServerUse() ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &schannelCred, diff --git a/NetSSL_Win/src/X509Certificate.cpp b/NetSSL_Win/src/X509Certificate.cpp index 1e0a32278..301f57dab 100644 --- a/NetSSL_Win/src/X509Certificate.cpp +++ b/NetSSL_Win/src/X509Certificate.cpp @@ -396,7 +396,8 @@ void X509Certificate::loadCertificate(const std::string& certName, const std::st if (!hCertStore) throw CertificateException("Failed to open certificate store", certStoreName, GetLastError()); CERT_RDN_ATTR cert_rdn_attr; - cert_rdn_attr.pszObjId = szOID_COMMON_NAME; + char cmnName[] = szOID_COMMON_NAME; + cert_rdn_attr.pszObjId = cmnName; cert_rdn_attr.dwValueType = CERT_RDN_ANY_TYPE; cert_rdn_attr.Value.cbData = static_cast(certName.size()); cert_rdn_attr.Value.pbData = reinterpret_cast(const_cast(certName.c_str())); diff --git a/Util/src/ServerApplication.cpp b/Util/src/ServerApplication.cpp index b9560d219..c11fff60c 100644 --- a/Util/src/ServerApplication.cpp +++ b/Util/src/ServerApplication.cpp @@ -333,7 +333,8 @@ int ServerApplication::run(int argc, wchar_t** argv) bool ServerApplication::isService() { SERVICE_TABLE_ENTRYW svcDispatchTable[2]; - svcDispatchTable[0].lpServiceName = L""; + wchar_t name[] = L""; + svcDispatchTable[0].lpServiceName = name; svcDispatchTable[0].lpServiceProc = ServiceMain; svcDispatchTable[1].lpServiceName = NULL; svcDispatchTable[1].lpServiceProc = NULL; diff --git a/cmake/CXX1x.cmake b/cmake/CXX1x.cmake index 608fd8f27..64a2b5ab1 100644 --- a/cmake/CXX1x.cmake +++ b/cmake/CXX1x.cmake @@ -20,25 +20,31 @@ # Determines whether the compiler supports C++17 macro(check_for_cxx17_compiler _VAR) - message(STATUS "Checking for C++17 compiler") - set(${_VAR}) - try_compile(_COMPILER_TEST_RESULT ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/test_compiler.cpp CMAKE_FLAGS -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON) - if(NOT _COMPILER_TEST_RESULT AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - try_compile(_COMPILER_TEST_RESULT ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/test_compiler.cpp CMAKE_FLAGS -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON) - if(_COMPILER_TEST_RESULT) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - else() - message(STATUS "To enable C++17 install libc++ standard library from https://libcxx.llvm.org/") - endif() - endif() - if(_COMPILER_TEST_RESULT AND ((MSVC AND (MSVC14)) OR - (CMAKE_COMPILER_IS_GNUCXX AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.9.2) OR - (CMAKE_CXX_COMPILER_ID STREQUAL "QCC" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.9.2) OR - (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.4) OR - (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))) - set(${_VAR} 1) - message(STATUS "Checking for C++17 compiler - available") - else() - message(STATUS "Checking for C++17 compiler - unavailable") - endif() + message(STATUS "Checking for C++17 compiler") + set(${_VAR}) + try_compile( + _COMPILER_TEST_RESULT ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/test_compiler.cpp + CMAKE_FLAGS -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON + ) + if(NOT _COMPILER_TEST_RESULT AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + try_compile( + _COMPILER_TEST_RESULT ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/test_compiler.cpp + CMAKE_FLAGS -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON + ) + if(_COMPILER_TEST_RESULT) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + else() + message(STATUS "To enable C++17 install libc++ standard library from https://libcxx.llvm.org/") + endif() + endif() + if(_COMPILER_TEST_RESULT AND ((MSVC AND (MSVC14)) OR + (CMAKE_COMPILER_IS_GNUCXX AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.9.2) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "QCC" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.9.2) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.4) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))) + set(${_VAR} 1) + message(STATUS "Checking for C++17 compiler - available") + else() + message(STATUS "Checking for C++17 compiler - unavailable") + endif() endmacro()