From 09835feb258c3058d028918e36d959dccb3f7496 Mon Sep 17 00:00:00 2001 From: Alex Rousskov Date: Tue, 13 Dec 2022 23:17:48 +0000 Subject: [PATCH] Require C++17 (#1212) Modern environments support C++17 well. We are wasting significant amounts of time on emulating such basic C++17 features as std::optional. We are writing worse code than we can because we lack access to such C++14 and C++17 features like std::make_unique and std::byte. The following language-standard-dependent TODOs were completed: * Switched to [[fallthrough]] attributes. * Replaced Optional with std::optional. * Replaced EnableIfType with std::enable_if_t. * Removed old C++11 type replacements (e.g., xuniform_int_distribution). * Removed std::allocator declarations deprecated in C++17. * Made ToSBuf() readable using a fold expression. * Simplified compile-time "natural type" assertions. * Used std::container::emplace*() return value where warranted. Moved BUILDCXX-setting code after AX_CXX_COMPILE_STDCXX adds -std=c++17 to CXX (rather than CXXFLAGS!). Our cf_gen was built with compiler's default C++ standard version! Ideally, BUILDCXX block should be lowered further -- other macros might alter CXX -- but its CXXFLAGS adjustment may affect subsequent code, warranting a careful/dedicated change. --- acinclude/ax_cxx_0x_types.m4 | 80 -- acinclude/ax_cxx_compile_stdcxx.m4 | 1016 +++++++++++++++++ acinclude/ax_cxx_compile_stdcxx_11.m4 | 153 --- compat/types.h | 21 - configure.ac | 35 +- lib/hash.cc | 14 +- lib/ntlmauth/ntlmauth.cc | 2 +- scripts/source-maintenance.sh | 3 +- src/HttpHdrSc.cc | 6 +- src/SquidMath.h | 45 +- src/acl/Random.cc | 2 +- src/acl/external/AD_group/ext_ad_group_acl.cc | 2 +- src/acl/external/LM_group/ext_lm_group_acl.cc | 2 +- src/acl/external/session/ext_session_acl.cc | 2 +- src/acl/external/unix_group/check_group.cc | 2 +- src/adaptation/icap/Xaction.cc | 8 +- src/adaptation/icap/Xaction.h | 2 +- src/auth/basic/RADIUS/basic_radius_auth.cc | 2 +- src/auth/basic/SSPI/basic_sspi_auth.cc | 2 +- src/auth/digest/Config.cc | 2 +- src/auth/digest/UserRequest.cc | 5 +- src/auth/negotiate/Config.cc | 2 +- .../negotiate/SSPI/negotiate_sspi_auth.cc | 2 +- src/auth/negotiate/UserRequest.cc | 2 +- src/auth/ntlm/Config.cc | 10 +- src/auth/ntlm/SSPI/ntlm_sspi_auth.cc | 2 +- src/auth/ntlm/UserRequest.cc | 2 +- src/auth/ntlm/fake/ntlm_fake_auth.cc | 2 +- src/auth/toUtf.cc | 10 +- src/base/AsyncCallbacks.h | 4 +- src/base/ClpMap.h | 10 +- src/base/EnumIterator.h | 4 - src/base/IoManip.h | 13 + src/base/Makefile.am | 1 - src/base/Optional.h | 184 --- src/base/SupportOrVeto.h | 4 +- src/base/TypeTraits.h | 4 - src/base/forward.h | 3 - src/cf_gen.cc | 10 +- src/client_side.cc | 3 +- src/clients/FtpClient.cc | 4 +- src/comm/Tcp.cc | 2 - src/debug/debug.cc | 8 +- src/dns_internal.cc | 6 +- src/errorpage.cc | 2 +- src/event.cc | 2 +- src/fs/ufs/UFSSwapDir.cc | 2 +- src/http.cc | 2 +- src/http/RegisteredHeadersHash.cci | 4 +- src/http/StatusCode.cc | 2 +- src/http/url_rewriters/fake/fake.cc | 2 +- src/ipc/TypedMsgHdr.h | 4 - src/ipcache.cc | 4 +- src/log/FormattedLog.cc | 4 +- src/log/FormattedLog.h | 4 +- src/mem/PoolingAllocator.h | 11 - src/sbuf/Stream.h | 4 +- src/servers/Http1Server.cc | 1 - src/store/SwapMeta.h | 12 +- src/tests/SBufFindTest.cc | 2 +- src/tests/testMath.cc | 1 - src/tunnel.cc | 2 +- test-suite/splay.cc | 2 +- tools/cachemgr.cc | 4 +- 64 files changed, 1161 insertions(+), 608 deletions(-) delete mode 100644 acinclude/ax_cxx_0x_types.m4 create mode 100644 acinclude/ax_cxx_compile_stdcxx.m4 delete mode 100644 acinclude/ax_cxx_compile_stdcxx_11.m4 delete mode 100644 src/base/Optional.h diff --git a/acinclude/ax_cxx_0x_types.m4 b/acinclude/ax_cxx_0x_types.m4 deleted file mode 100644 index cd2175b9c15..00000000000 --- a/acinclude/ax_cxx_0x_types.m4 +++ /dev/null @@ -1,80 +0,0 @@ -## Copyright (C) 1996-2022 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -## Hand crafted for Squid under GPL version 2 -AC_DEFUN([AX_CXX_TYPE_UNIFORM_DISTRIBUTIONS],[ - AC_REQUIRE([AC_PROG_CXX]) - AC_LANG_PUSH([C++]) - AC_CHECK_HEADERS(tr1/random) - AC_CACHE_CHECK([whether std::uniform_int_distribution is supported], - [squid_cv_std_uniform_int_distribution_works],[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[std::uniform_int_distribution c;]])], - [squid_cv_std_uniform_int_distribution_works=yes], - [squid_cv_std_uniform_int_distribution_works=no]) - ]) - SQUID_DEFINE_BOOL([HAVE_STD_UNIFORM_INT_DISTRIBUTION], - [$squid_cv_std_uniform_int_distribution_works], - [Define if c++11 std::uniform_int_distribution is supported]) - - AC_CACHE_CHECK([whether std::uniform_real_distribution is supported], - [squid_cv_std_uniform_real_distribution_works],[ - AC_REQUIRE([AC_PROG_CXX]) - AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[std::uniform_real_distribution c;]])], - [squid_cv_std_uniform_real_distribution_works=yes], - [squid_cv_std_uniform_real_distribution_works=no]) - ]) - SQUID_DEFINE_BOOL([HAVE_STD_UNIFORM_REAL_DISTRIBUTION], - [$squid_cv_std_uniform_real_distribution_works], - [Define if c++11 std::uniform_real_distribution is supported]) - - AC_LANG_POP -]) - -## SQUID_CXX_STD_UNDERLYING_TYPE -## checks whether the std::underlying_type::type trait exists -AC_DEFUN([SQUID_CXX_STD_UNDERLYING_TYPE],[ - AC_CACHE_CHECK([whether compiler supports std::underlying_type], - [squid_cv_have_std_underlying_type],[ - AC_REQUIRE([AC_PROG_CXX]) - AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([ -#include -enum class testEnum { one, two, three }; - ],[ - std::underlying_type::type testNum = 0; - ])], - [squid_cv_have_std_underlying_type=yes], - [squid_cv_have_std_underlying_type=no]) - AC_LANG_POP - ]) - SQUID_DEFINE_BOOL([HAVE_STD_UNDERLYING_TYPE], - [$squid_cv_have_std_underlying_type], - [Define if stdlibc support std::underlying_type for enums]) -]) - -## SQUID_CXX_STD_IS_TRIVIALLY_COPYABLE -## checks whether the std::is_trivially_copyable<> trait exists -## (known to be missing in GCC until version 5.1) -AC_DEFUN([SQUID_CXX_STD_IS_TRIVIALLY_COPYABLE],[ - AC_CACHE_CHECK([whether compiler supports std::is_trivially_copyable], - [squid_cv_have_std_is_trivially_copyable],[ - AC_REQUIRE([AC_PROG_CXX]) - AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[return std::is_trivially_copyable::value ? 1 : 0;]])], - [squid_cv_have_std_is_trivially_copyable=yes], - [squid_cv_have_std_is_trivially_copyable=no]) - AC_LANG_POP - ]) - SQUID_DEFINE_BOOL([HAVE_STD_IS_TRIVIALLY_COPYABLE], - [$squid_cv_have_std_is_trivially_copyable], - [Define if stdlibc support std::is_trivially_copyable]) -]) diff --git a/acinclude/ax_cxx_compile_stdcxx.m4 b/acinclude/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000000..483bf09710d --- /dev/null +++ b/acinclude/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,1016 @@ +## Copyright (C) 1996-2022 The Squid Software Foundation and contributors +## +## Squid software is distributed under GPLv2+ license and includes +## contributions from numerous individuals and organizations. +## Please see the COPYING and CONTRIBUTORS files for details. +## + +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 15 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +dnl Test body for checking C++17 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L && !defined _MSC_VER + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L && !defined _MSC_VER + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L && !defined _MSC_VER + +]]) + + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + +]]) diff --git a/acinclude/ax_cxx_compile_stdcxx_11.m4 b/acinclude/ax_cxx_compile_stdcxx_11.m4 deleted file mode 100644 index bc65be90238..00000000000 --- a/acinclude/ax_cxx_compile_stdcxx_11.m4 +++ /dev/null @@ -1,153 +0,0 @@ -## Copyright (C) 1996-2022 The Squid Software Foundation and contributors -## -## Squid software is distributed under GPLv2+ license and includes -## contributions from numerous individuals and organizations. -## Please see the COPYING and CONTRIBUTORS files for details. -## - -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++11 -# standard; if necessary, add switches to CXXFLAGS to enable support. -# -# The first argument, if specified, indicates whether you insist on an -# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -# -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. -# -# The second argument, if specified 'mandatory' or if left unspecified, -# indicates that baseline C++11 support is required and that the macro -# should error out if no mode with that support is found. If specified -# 'optional', then configuration proceeds regardless, after defining -# HAVE_CXX11 if and only if a supporting mode is found. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# Copyright (c) 2012 Zack Weinberg -# Copyright (c) 2013 Roy Stogner -# Copyright (c) 2014 Alexey Sokolov -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 4 - -m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); // GCC 4.3+ - }; - -#if WHEN_SQUID_HAS_MANDATORY_GCC_4_789_SUPPORT - struct Base { - virtual void f() {} - }; - struct Child : public Base { - virtual void f() override {} // GCC 4.7+ - }; -#endif - - typedef check> right_angle_brackets; // GCC 4.3+ - - int a; - decltype(a) b; // GCC 4.3+ - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c); // GCC 4.3+ - - auto d = a; // GCC 4.4+ -#if WHEN_SQUID_HAS_MANDATORY_GCC_4_789_SUPPORT - auto l = [](){}; // GCC 4.5+ (void lambda seems not to be documented) -#endif -]]) - -AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl - m4_if([$1], [], [], - [$1], [ext], [], - [$1], [noext], [], - [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl - m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], - [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], - [$2], [optional], [ax_cxx_compile_cxx11_required=false], - [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) - AC_LANG_PUSH([C++])dnl - ac_success=no - AC_CACHE_CHECK(whether $CXX supports C++11 features by default, - ax_cv_cxx_compile_cxx11, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [ax_cv_cxx_compile_cxx11=yes], - [ax_cv_cxx_compile_cxx11=no])]) - if test x$ax_cv_cxx_compile_cxx11 = xyes; then - ac_success=yes - fi - - m4_if([$1], [noext], [], [dnl - if test x$ac_success = xno; then - for switch in -std=gnu++11 -std=gnu++0x; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - - m4_if([$1], [ext], [], [dnl - if test x$ac_success = xno; then - for switch in -std=c++11 -std=c++0x; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - AC_LANG_POP([C++]) - if test x$ax_cxx_compile_cxx11_required = xtrue; then - if test x$ac_success = xno; then - AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) - fi - else - if test x$ac_success = xno; then - HAVE_CXX11=0 - AC_MSG_NOTICE([No compiler with C++11 support was found]) - else - HAVE_CXX11=1 - AC_DEFINE(HAVE_CXX11,1, - [define if the compiler supports basic C++11 syntax]) - fi - - AC_SUBST(HAVE_CXX11) - fi -]) diff --git a/compat/types.h b/compat/types.h index 360069d54b1..b125c91b7a2 100644 --- a/compat/types.h +++ b/compat/types.h @@ -45,12 +45,6 @@ #include #endif -#if __cplusplus && HAVE_TR1_RANDOM -#if !HAVE_STD_UNIFORM_INT_DISTRIBUTION && !HAVE_STD_UNIFORM_REAL_DISTRIBUTION -#include -#endif -#endif - /******************************************************/ /* Typedefs for missing entries on a system */ /******************************************************/ @@ -166,20 +160,5 @@ typedef long mtyp_t; #define NULL 0 #endif -/***********************************************************/ -/* uniform_int_distribution backward compatibility wrapper */ -/***********************************************************/ -#if HAVE_STD_UNIFORM_INT_DISTRIBUTION -#define xuniform_int_distribution std::uniform_int_distribution -#else -#define xuniform_int_distribution std::tr1::uniform_int -#endif - -#if HAVE_STD_UNIFORM_REAL_DISTRIBUTION -#define xuniform_real_distribution std::uniform_real_distribution -#else -#define xuniform_real_distribution std::tr1::uniform_real -#endif - #endif /* SQUID_TYPES_H */ diff --git a/configure.ac b/configure.ac index 313373cf333..ef3fa2284ec 100644 --- a/configure.ac +++ b/configure.ac @@ -27,8 +27,7 @@ m4_include([acinclude/pam.m4]) m4_include([acinclude/pkg.m4]) m4_include([acinclude/tdb.m4]) m4_include([acinclude/lib-checks.m4]) -m4_include([acinclude/ax_cxx_compile_stdcxx_11.m4]) -m4_include([acinclude/ax_cxx_0x_types.m4]) +m4_include([acinclude/ax_cxx_compile_stdcxx.m4]) PRESET_CFLAGS="$CFLAGS" PRESET_CXXFLAGS="$CXXFLAGS" @@ -75,8 +74,16 @@ AS_IF([test "x${enable_arch_native}" != "xno"],[ SQUID_CC_CHECK_ARGUMENT([squid_cv_check_marchnative],[-march=native]) ]) -# might be cross-compiling. -# NP: BUILDCXXFLAGS defined at the end of configure after CXXFLAGS fully known. +# If the user did not specify a C++ version. +user_cxx=`echo "$PRESET_CXXFLAGS" | grep -o -E "(-)std="` +AS_IF([test "x$user_cxx" = "x"],[ + # Check for C++17 compiler support + # May change CXX. + AX_CXX_COMPILE_STDCXX([17],[noext],[mandatory]) +]) + +# Prerequisite: CXX has been finalized. +# BUILDCXXFLAGS are defined later, after CXXFLAGS have been finalized. AC_ARG_VAR([BUILDCXX],[path to compiler for building compile-time tools. e.g. cf_gen]) AS_IF([test "x$HOSTCXX" != "x" -a "x$BUILDCXX" = "x"],[ AC_MSG_WARN([Cross-compiling with HOSTCXX is deprecated. Use BUILDCXX instead.]) @@ -90,13 +97,6 @@ AS_IF([test "x$BUILDCXX" = "x"],[ ]) AC_SUBST(BUILDCXX) -# If the user did not specify a C++ version. -user_cxx=`echo "$PRESET_CXXFLAGS" | grep -o -E "(-)std="` -AS_IF([test "x$user_cxx" = "x"],[ - # Check for C++11 compiler support - AX_CXX_COMPILE_STDCXX_11([noext],[mandatory]) -]) - # test for programs AC_PROG_RANLIB AC_PROG_CPP @@ -303,10 +303,9 @@ AS_IF([test "$squid_cv_cc_simplified" = "gcc-4"],[ # in unit tests. Disable that SQUID_CC_ADD_CXXFLAG_WARNING_IF_SUPPORTED([-Wno-unused-private-field]) - # ...=2: This flexibility level allows GCC to "understand" our fallthrough - # comments. TODO: Switch to [[fallthrough]] attributes with C++17. - SQUID_CC_ADD_CXXFLAG_WARNING_IF_SUPPORTED([-Wimplicit-fallthrough=2]) - AS_IF([test "x$squid_cv_cc_arg_wimplicit_fallthrough_2" != "xyes"], [ + # ...=5: Do not trust comments about fallthrough cases (GCC). + SQUID_CC_ADD_CXXFLAG_WARNING_IF_SUPPORTED([-Wimplicit-fallthrough=5]) + AS_IF([test "x$squid_cv_cc_arg_wimplicit_fallthrough_5" != "xyes"], [ SQUID_CC_ADD_CXXFLAG_WARNING_IF_SUPPORTED([-Wno-implicit-fallthrough]) ]) ]) @@ -2403,11 +2402,6 @@ AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(off_t) AC_CHECK_SIZEOF(size_t) -dnl Some C++11 types we try to use -AX_CXX_TYPE_UNIFORM_DISTRIBUTIONS -SQUID_CXX_STD_UNDERLYING_TYPE -SQUID_CXX_STD_IS_TRIVIALLY_COPYABLE - dnl On Solaris 9 x86, gcc may includes a "fixed" set of old system include files dnl that is incompatible with the updated Solaris header files. dnl For this reason, we must check if pad128_t and upad128_t are defined. @@ -3074,6 +3068,7 @@ AC_SUBST(XTRA_LIBS) AC_SUBST(SQUID_CFLAGS) AC_SUBST(SQUID_CXXFLAGS) +# Prerequisite: CXXFLAGS have been finalized. AC_ARG_VAR([BUILDCXXFLAGS],[C++ compiler flags for building compile-time tools. e.g. cf_gen]) AS_IF([test "x$BUILDCXXFLAGS" = "x"],[ # if we are NOT cross-compiling, use the default build flags for cf_gen and friends diff --git a/lib/hash.cc b/lib/hash.cc index 40d142fa9d6..072d7171077 100644 --- a/lib/hash.cc +++ b/lib/hash.cc @@ -66,22 +66,22 @@ hash4(const void *data, unsigned int size) break; case 7: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 6: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 5: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 4: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 3: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 2: HASH4; - /* [[fallthrough]] */ + [[fallthrough]]; case 1: HASH4; } @@ -340,7 +340,7 @@ main(void) printf("done creating hash table: %d\n", hid); std::mt19937 mt; - xuniform_int_distribution<> dist(0,16); + std::uniform_int_distribution<> dist(0,16); while (fgets(buf, BUFSIZ, stdin)) { buf[strlen(buf) - 1] = '\0'; diff --git a/lib/ntlmauth/ntlmauth.cc b/lib/ntlmauth/ntlmauth.cc index 1039b5309b1..6909d1ffd70 100644 --- a/lib/ntlmauth/ntlmauth.cc +++ b/lib/ntlmauth/ntlmauth.cc @@ -195,7 +195,7 @@ void ntlm_make_nonce(char *nonce) { static std::mt19937 mt(time(nullptr)); - static xuniform_int_distribution dist; + static std::uniform_int_distribution dist; for (int i = 0; i < NTLM_NONCE_LEN; ++i) nonce[i] = static_cast(dist(mt) & 0xFF); diff --git a/scripts/source-maintenance.sh b/scripts/source-maintenance.sh index 99bb9096383..20ebba80d40 100755 --- a/scripts/source-maintenance.sh +++ b/scripts/source-maintenance.sh @@ -519,7 +519,8 @@ generateRawGperfFile () echo "/* $GeneratedByMe */" echo - (cd `dirname $gperfFile` && gperf -m 100000 `basename $gperfFile`) + (cd `dirname $gperfFile` && gperf -m 100000 `basename $gperfFile`) | \ + sed 's@/[*]FALLTHROUGH[*]/@[[fallthrough]];@g' } generateGperfFile () diff --git a/src/HttpHdrSc.cc b/src/HttpHdrSc.cc index ecb7aadf3dd..e4bf071c41b 100644 --- a/src/HttpHdrSc.cc +++ b/src/HttpHdrSc.cc @@ -126,8 +126,7 @@ HttpHdrSc::parse(const String * str) if (!sct) { // XXX: if parse is left-to-right over field-value this should be emplace_back() // currently placing on the front reverses the order of headers passed on downstream. - targets.emplace_front(target); - sct = &targets.front(); + sct = &targets.emplace_front(target); } safe_free (temp); @@ -240,8 +239,7 @@ HttpHdrSc::setMaxAge(char const *target, int max_age) HttpHdrScTarget *sct = findTarget(target); if (!sct) { - targets.emplace_back(target); - sct = &targets.back(); + sct = &targets.emplace_back(target); } sct->maxAge(max_age); diff --git a/src/SquidMath.h b/src/SquidMath.h index 225f80da5a2..faf5b7e2f92 100644 --- a/src/SquidMath.h +++ b/src/SquidMath.h @@ -10,10 +10,10 @@ #define _SQUID_SRC_SQUIDMATH_H #include "base/forward.h" -#include "base/Optional.h" #include "base/TypeTraits.h" #include +#include // TODO: Move to src/base/Math.h and drop the Math namespace @@ -58,13 +58,12 @@ Less(const A a, const B b) { /// ensure that T is supported by NaturalSum() and friends template -constexpr bool +constexpr void AssertNaturalType() { static_assert(std::numeric_limits::is_bounded, "std::numeric_limits::max() is meaningful"); static_assert(std::numeric_limits::is_exact, "no silent loss of precision"); static_assert(!std::is_enum::value, "no silent creation of non-enumerated values"); - return true; // for static_assert convenience in C++11 constexpr callers } // TODO: Investigate whether this optimization can be expanded to [signed] types @@ -72,17 +71,16 @@ AssertNaturalType() /// This IncreaseSumInternal() overload is optimized for speed. /// \returns a non-overflowing sum of the two unsigned arguments (or nothing) /// \prec both argument types are unsigned -template ::value, int> = 0> -Optional +template ::value, int> = 0> +std::optional IncreaseSumInternal(const A a, const B b) { // paranoid: AllUnsigned precondition established that already static_assert(std::is_unsigned::value, "AllUnsigned dispatch worked for A"); static_assert(std::is_unsigned::value, "AllUnsigned dispatch worked for B"); - // TODO: Just call AssertNaturalType() after upgrading to C++14. - static_assert(AssertNaturalType(), "S is a supported type"); - static_assert(AssertNaturalType(), "A is a supported type"); - static_assert(AssertNaturalType(), "B is a supported type"); + AssertNaturalType(); + AssertNaturalType(); + AssertNaturalType(); // we should only be called by IncreaseSum(); it forces integer promotion static_assert(std::is_same::value, "a will not be promoted"); @@ -102,19 +100,19 @@ IncreaseSumInternal(const A a, const B b) { // 2. the sum may overflow S (i.e. the return base type) // We do not need Less() here because we compare promoted unsigned types. return (sum >= a && sum <= std::numeric_limits::max()) ? - Optional(sum) : Optional(); + std::optional(sum) : std::optional(); } /// This IncreaseSumInternal() overload supports a larger variety of types. /// \returns a non-overflowing sum of the two arguments (or nothing) /// \returns nothing if at least one of the arguments is negative /// \prec at least one of the argument types is signed -template ::value, int> = 0> -Optional constexpr +template ::value, int> = 0> +std::optional constexpr IncreaseSumInternal(const A a, const B b) { - static_assert(AssertNaturalType(), "S is a supported type"); - static_assert(AssertNaturalType(), "A is a supported type"); - static_assert(AssertNaturalType(), "B is a supported type"); + AssertNaturalType(); + AssertNaturalType(); + AssertNaturalType(); // we should only be called by IncreaseSum() that does integer promotion static_assert(std::is_same::value, "a will not be promoted"); @@ -124,7 +122,7 @@ IncreaseSumInternal(const A a, const B b) { // We could support a non-under/overflowing sum of negative numbers, but // our callers use negative values specially (e.g., for do-not-use or // do-not-limit settings) and are not supposed to do math with them. - (a < 0 || b < 0) ? Optional() : + (a < 0 || b < 0) ? std::optional() : // To avoid undefined behavior of signed overflow, we must not compute // the raw a+b sum if it may overflow. When A is not B, a or b undergoes // (safe for non-negatives) integer conversion in these expressions, so @@ -136,16 +134,16 @@ IncreaseSumInternal(const A a, const B b) { // which is the same as the overflow-safe condition here: maxS - a < b. // Finally, (maxS - a) cannot overflow because a is not negative and // cannot underflow because a is a promotion of s: 0 <= a <= maxS. - Less(std::numeric_limits::max() - a, b) ? Optional() : - Optional(a + b); + Less(std::numeric_limits::max() - a, b) ? std::optional() : + std::optional(a + b); } /// argument pack expansion termination for IncreaseSum() template -Optional +std::optional IncreaseSum(const S s, const T t) { - // Force (always safe) integer promotions now, to give EnableIfType<> + // Force (always safe) integer promotions now, to give std::enable_if_t<> // promoted types instead of entering IncreaseSumInternal(s,t) // but getting a _signed_ promoted value of s or t in s + t. return IncreaseSumInternal(+s, +t); @@ -153,18 +151,19 @@ IncreaseSum(const S s, const T t) /// \returns a non-overflowing sum of the arguments (or nothing) template -Optional +std::optional IncreaseSum(const S sum, const T t, const Args... args) { if (const auto head = IncreaseSum(sum, t)) { return IncreaseSum(head.value(), args...); } else { - return Optional(); + // std::optional() triggers bogus -Wmaybe-uninitialized warnings in GCC v10.3 + return std::nullopt; } } /// \returns an exact, non-overflowing sum of the arguments (or nothing) template -Optional +std::optional NaturalSum(const Args... args) { return IncreaseSum(0, args...); } diff --git a/src/acl/Random.cc b/src/acl/Random.cc index d0666c15e88..84f53769023 100644 --- a/src/acl/Random.cc +++ b/src/acl/Random.cc @@ -97,7 +97,7 @@ ACLRandom::match(ACLChecklist *) // actually matching whether the random value is above // or below the configured threshold ratio. static std::mt19937 mt; - static xuniform_real_distribution<> dist(0, 1); + static std::uniform_real_distribution<> dist(0, 1); const double random = dist(mt); diff --git a/src/acl/external/AD_group/ext_ad_group_acl.cc b/src/acl/external/AD_group/ext_ad_group_acl.cc index 534d6292bec..bc74e2cf967 100644 --- a/src/acl/external/AD_group/ext_ad_group_acl.cc +++ b/src/acl/external/AD_group/ext_ad_group_acl.cc @@ -756,7 +756,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "%s: FATAL: Unknown option: -%c. Exiting\n", program_name, opt); usage(argv[0]); diff --git a/src/acl/external/LM_group/ext_lm_group_acl.cc b/src/acl/external/LM_group/ext_lm_group_acl.cc index 50ef7aeb2ce..68b75afd6d0 100644 --- a/src/acl/external/LM_group/ext_lm_group_acl.cc +++ b/src/acl/external/LM_group/ext_lm_group_acl.cc @@ -495,7 +495,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "%s: FATAL: Unknown option: -%c. Exiting\n", program_name, opt); usage(argv[0]); diff --git a/src/acl/external/session/ext_session_acl.cc b/src/acl/external/session/ext_session_acl.cc index 0e548141700..4cb24f571b8 100644 --- a/src/acl/external/session/ext_session_acl.cc +++ b/src/acl/external/session/ext_session_acl.cc @@ -280,7 +280,7 @@ int main(int argc, char **argv) switch (opt) { case 'T': fixed_timeout = 1; - /* [[fallthrough]] */ + [[fallthrough]]; case 't': session_ttl = strtol(optarg, nullptr, 0); break; diff --git a/src/acl/external/unix_group/check_group.cc b/src/acl/external/unix_group/check_group.cc index 854ee8801ae..4d7c655f102 100644 --- a/src/acl/external/unix_group/check_group.cc +++ b/src/acl/external/unix_group/check_group.cc @@ -181,7 +181,7 @@ main(int argc, char *argv[]) } else { fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); } - /* [[fallthrough]] */ + [[fallthrough]]; default: usage(argv[0]); exit(EXIT_FAILURE); diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index 47469d27871..2fdabcb34dc 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -14,8 +14,8 @@ #include "adaptation/icap/Launcher.h" #include "adaptation/icap/Xaction.h" #include "base/AsyncCallbacks.h" +#include "base/IoManip.h" #include "base/JobWait.h" -#include "base/Optional.h" #include "base/TextException.h" #include "comm.h" #include "comm/Connection.h" @@ -34,6 +34,8 @@ #include "security/PeerConnector.h" #include "SquidConfig.h" +#include + namespace Ssl { /// A simple PeerConnector for Secure ICAP services. No SslBump capabilities. @@ -136,7 +138,7 @@ static void icapLookupDnsResults(const ipcache_addrs *ia, const Dns::LookupDetails &, void *data) { Adaptation::Icap::Xaction *xa = static_cast(data); - const auto &addr = ia ? Optional(ia->current()) : Optional(); + const auto &addr = ia ? std::optional(ia->current()) : std::optional(); CallJobHere1(93, 5, CbcPointer(xa), Adaptation::Icap::Xaction, dnsLookupDone, addr); } @@ -168,7 +170,7 @@ Adaptation::Icap::Xaction::openConnection() } void -Adaptation::Icap::Xaction::dnsLookupDone(Optional addr) +Adaptation::Icap::Xaction::dnsLookupDone(std::optional addr) { assert(waitingForDns); waitingForDns = false; diff --git a/src/adaptation/icap/Xaction.h b/src/adaptation/icap/Xaction.h index defdb8dd51a..c9444b19d8f 100644 --- a/src/adaptation/icap/Xaction.h +++ b/src/adaptation/icap/Xaction.h @@ -117,7 +117,7 @@ class Xaction: public Adaptation::Initiate /// clear stored error details, if any; used for retries/repeats virtual void clearError() {} virtual AccessLogEntry::Pointer masterLogEntry(); - void dnsLookupDone(Optional); + void dnsLookupDone(std::optional); protected: // logging diff --git a/src/auth/basic/RADIUS/basic_radius_auth.cc b/src/auth/basic/RADIUS/basic_radius_auth.cc index 8ecf07c1c68..6642c115ada 100644 --- a/src/auth/basic/RADIUS/basic_radius_auth.cc +++ b/src/auth/basic/RADIUS/basic_radius_auth.cc @@ -207,7 +207,7 @@ static void random_vector(char *aVector) { static std::mt19937 mt(RandomSeed32()); - static xuniform_int_distribution dist; + static std::uniform_int_distribution dist; for (int i = 0; i < AUTH_VECTOR_LEN; ++i) aVector[i] = static_cast(dist(mt) & 0xFF); diff --git a/src/auth/basic/SSPI/basic_sspi_auth.cc b/src/auth/basic/SSPI/basic_sspi_auth.cc index 21fd79e8fa0..1c0a429dc57 100644 --- a/src/auth/basic/SSPI/basic_sspi_auth.cc +++ b/src/auth/basic/SSPI/basic_sspi_auth.cc @@ -100,7 +100,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "FATAL: Unknown option: -%c\n", opt); usage(argv[0]); diff --git a/src/auth/digest/Config.cc b/src/auth/digest/Config.cc index 1b9aa4943d2..536fb3870a2 100644 --- a/src/auth/digest/Config.cc +++ b/src/auth/digest/Config.cc @@ -158,7 +158,7 @@ authenticateDigestNonceNew(void) * the hash function. */ static std::mt19937 mt(RandomSeed32()); - static xuniform_int_distribution newRandomData; + static std::uniform_int_distribution newRandomData; /* create a new nonce */ newnonce->nc = 0; diff --git a/src/auth/digest/UserRequest.cc b/src/auth/digest/UserRequest.cc index 3a3c8ffff9b..6f2a42bba28 100644 --- a/src/auth/digest/UserRequest.cc +++ b/src/auth/digest/UserRequest.cc @@ -356,11 +356,12 @@ Auth::Digest::UserRequest::HandleReply(void *data, const Helper::Reply &reply) case Helper::TT: debugs(29, DBG_IMPORTANT, "ERROR: Digest auth does not support the result code received. Using the wrong helper program? received: " << reply); - // [[fallthrough]] to handle this as an ERR response + [[fallthrough]]; // to handle this as an ERR response case Helper::TimedOut: case Helper::BrokenHelper: - // [[fallthrough]] to (silently) handle this as an ERR response + [[fallthrough]]; // to (silently) handle this as an ERR response + // TODO retry the broken lookup on another helper? case Helper::Error: { /* allow this because the digest_request pointer is purely local */ diff --git a/src/auth/negotiate/Config.cc b/src/auth/negotiate/Config.cc index 75a93d66e96..8443dcfc2b5 100644 --- a/src/auth/negotiate/Config.cc +++ b/src/auth/negotiate/Config.cc @@ -164,7 +164,7 @@ Auth::Negotiate::Config::fixHeader(Auth::UserRequest::Pointer auth_user_request, * tied to it, even if MAYBE the client could handle it - Kinkie */ rep->header.delByName("keep-alive"); request->flags.proxyKeepalive = false; - /* [[fallthrough]] */ + [[fallthrough]]; case Auth::Ok: /* Special case: authentication finished OK but disallowed by ACL. diff --git a/src/auth/negotiate/SSPI/negotiate_sspi_auth.cc b/src/auth/negotiate/SSPI/negotiate_sspi_auth.cc index 3f161b10b2b..36c7f55dd13 100644 --- a/src/auth/negotiate/SSPI/negotiate_sspi_auth.cc +++ b/src/auth/negotiate/SSPI/negotiate_sspi_auth.cc @@ -115,7 +115,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "ERROR: unknown option: -%c. Exiting\n", opt); usage(); diff --git a/src/auth/negotiate/UserRequest.cc b/src/auth/negotiate/UserRequest.cc index 088cf11e506..1303267e50c 100644 --- a/src/auth/negotiate/UserRequest.cc +++ b/src/auth/negotiate/UserRequest.cc @@ -368,7 +368,7 @@ Auth::Negotiate::UserRequest::HandleReply(void *data, const Helper::Reply &reply case Helper::Unknown: debugs(29, DBG_IMPORTANT, "ERROR: Negotiate Authentication Helper crashed (" << reply.reservationId << ")"); - /* [[fallthrough]] */ + [[fallthrough]]; case Helper::TimedOut: case Helper::BrokenHelper: diff --git a/src/auth/ntlm/Config.cc b/src/auth/ntlm/Config.cc index 13d087b4114..98c4d2b2317 100644 --- a/src/auth/ntlm/Config.cc +++ b/src/auth/ntlm/Config.cc @@ -163,13 +163,13 @@ Auth::Ntlm::Config::fixHeader(Auth::UserRequest::Pointer auth_user_request, Http /* here it makes sense to drop the connection, as auth is * tied to it, even if MAYBE the client could handle it - Kinkie */ request->flags.proxyKeepalive = false; - /* [[fallthrough]] */ + [[fallthrough]]; case Auth::Ok: - /* Special case: authentication finished OK but disallowed by ACL. - * Need to start over to give the client another chance. - */ - /* [[fallthrough]] */ + /* Special case: authentication finished OK but disallowed by ACL. + * Need to start over to give the client another chance. + */ + [[fallthrough]]; case Auth::Unchecked: /* semantic change: do not drop the connection. diff --git a/src/auth/ntlm/SSPI/ntlm_sspi_auth.cc b/src/auth/ntlm/SSPI/ntlm_sspi_auth.cc index ebf8bb3a0cc..98e3ab345b1 100644 --- a/src/auth/ntlm/SSPI/ntlm_sspi_auth.cc +++ b/src/auth/ntlm/SSPI/ntlm_sspi_auth.cc @@ -402,7 +402,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "unknown option: -%c. Exiting\n", opt); usage(); diff --git a/src/auth/ntlm/UserRequest.cc b/src/auth/ntlm/UserRequest.cc index 07e55af2a94..8eb6da08983 100644 --- a/src/auth/ntlm/UserRequest.cc +++ b/src/auth/ntlm/UserRequest.cc @@ -360,7 +360,7 @@ Auth::Ntlm::UserRequest::HandleReply(void *data, const Helper::Reply &reply) case Helper::Unknown: debugs(29, DBG_IMPORTANT, "ERROR: NTLM Authentication Helper crashed (" << reply.reservationId << ")"); - /* [[fallthrough]] */ + [[fallthrough]]; case Helper::TimedOut: case Helper::BrokenHelper: diff --git a/src/auth/ntlm/fake/ntlm_fake_auth.cc b/src/auth/ntlm/fake/ntlm_fake_auth.cc index a7309d01fe6..a7848f404c1 100644 --- a/src/auth/ntlm/fake/ntlm_fake_auth.cc +++ b/src/auth/ntlm/fake/ntlm_fake_auth.cc @@ -122,7 +122,7 @@ process_options(int argc, char *argv[]) exit(EXIT_SUCCESS); case '?': opt = optopt; - /* [[fallthrough]] */ + [[fallthrough]]; default: fprintf(stderr, "unknown option: -%c. Exiting\n", opt); usage(); diff --git a/src/auth/toUtf.cc b/src/auth/toUtf.cc index 0d4ffb8799a..d347fa732ff 100644 --- a/src/auth/toUtf.cc +++ b/src/auth/toUtf.cc @@ -78,11 +78,11 @@ Cp1251ToUtf8(const char *in) case 3: sequence[2] = static_cast(u & 0x3f) | 0x80; u >>= 6; - /* [[fallthrough]] */ + [[fallthrough]]; case 2: sequence[1] = static_cast(u & 0x3f) | 0x80; u >>= 6; - /* [[fallthrough]] */ + [[fallthrough]]; case 1: sequence[0] = static_cast(u) | firstByteMark[bytesToWrite]; } @@ -130,10 +130,10 @@ isValidUtf8CodePoint(const unsigned char* source, const size_t length) // Everything else falls through when "true"... case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - /* [[fallthrough]] */ + [[fallthrough]]; case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - /* [[fallthrough]] */ + [[fallthrough]]; case 2: if ((a = (*--srcptr)) > 0xBF) return false; @@ -155,7 +155,7 @@ isValidUtf8CodePoint(const unsigned char* source, const size_t length) if (a < 0x80) return false; break; } - /* [[fallthrough]] */ + [[fallthrough]]; case 1: if (*source >= 0x80 && *source < 0xC2) return false; diff --git a/src/base/AsyncCallbacks.h b/src/base/AsyncCallbacks.h index 68fce514b06..e978d8519c3 100644 --- a/src/base/AsyncCallbacks.h +++ b/src/base/AsyncCallbacks.h @@ -155,7 +155,7 @@ using IsAsyncJob = typename std::conditional< >::type; /// helper function to simplify UnaryCbcCallbackDialer creation -template ::value, int> = 0> +template ::value, int> = 0> UnaryCbcCallbackDialer callbackDialer(void (Destination::*method)(Argument1 &), Destination * const destination) { @@ -164,7 +164,7 @@ callbackDialer(void (Destination::*method)(Argument1 &), Destination * const des } /// helper function to simplify UnaryJobCallbackDialer creation -template ::value, int> = 0> +template ::value, int> = 0> UnaryJobCallbackDialer callbackDialer(void (Destination::*method)(Argument1 &), Destination * const destination) { diff --git a/src/base/ClpMap.h b/src/base/ClpMap.h index f8c6200b8c5..b8615136f13 100644 --- a/src/base/ClpMap.h +++ b/src/base/ClpMap.h @@ -9,7 +9,6 @@ #ifndef SQUID__SRC_BASE_CLPMAP_H #define SQUID__SRC_BASE_CLPMAP_H -#include "base/Optional.h" #include "mem/PoolingAllocator.h" #include "SquidMath.h" #include "time/gadgets.h" @@ -17,6 +16,7 @@ #include #include #include +#include #include template @@ -110,7 +110,7 @@ class ClpMap using Index = std::unordered_map, std::equal_to, PoolingAllocator >; using IndexIterator = typename Index::iterator; - static Optional MemoryCountedFor(const Key &, const Value &); + static std::optional MemoryCountedFor(const Key &, const Value &); void trim(uint64_t wantSpace); void erase(const IndexIterator &); @@ -183,7 +183,7 @@ ClpMap::get(const Key &key) } template -Optional +std::optional ClpMap::MemoryCountedFor(const Key &k, const Value &v) { // Both storage and index store keys, but we count keySz once, assuming that @@ -224,10 +224,10 @@ ClpMap::add(const Key &key, const Value &v, const Ttl return false; // will never fit trim(wantSpace); - entries_.emplace_front(key, v, ttl); // TODO: After C++17 migration, use the return value + auto &addedEntry = entries_.emplace_front(key, v, ttl); index_.emplace(key, entries_.begin()); - entries_.begin()->memCounted = wantSpace; + addedEntry.memCounted = wantSpace; memUsed_ += wantSpace; assert(memUsed_ >= wantSpace); // no overflows return true; diff --git a/src/base/EnumIterator.h b/src/base/EnumIterator.h index 96cb826f05c..c78d1792a0c 100644 --- a/src/base/EnumIterator.h +++ b/src/base/EnumIterator.h @@ -23,11 +23,7 @@ template class EnumIteratorBase { protected: -#if HAVE_STD_UNDERLYING_TYPE typedef typename std::underlying_type::type iterator_type; -#else - typedef int iterator_type; -#endif public: using iterator_category = std::bidirectional_iterator_tag; diff --git a/src/base/IoManip.h b/src/base/IoManip.h index bb60a8b6732..241d01bb1fe 100644 --- a/src/base/IoManip.h +++ b/src/base/IoManip.h @@ -13,6 +13,7 @@ #include #include +#include /// Safely prints an object pointed to by the given pointer: [label] /// Prints nothing at all if the pointer is nil. @@ -101,5 +102,17 @@ inline AsHex asHex(const Integer n) { return AsHex(n); } /// Prints the first n data bytes using hex notation. Does nothing if n is 0. void PrintHex(std::ostream &, const char *data, size_t n); +/// prints the value stored inside std::optional (if any) +template +inline std::ostream & +operator <<(std::ostream &os, const std::optional &optional) +{ + if (optional.has_value()) + os << optional.value(); + else + os << "[no value]"; + return os; +} + #endif /* SQUID_SRC_BASE_IO_MANIP_H */ diff --git a/src/base/Makefile.am b/src/base/Makefile.am index 776eadb44f0..2c828128036 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -49,7 +49,6 @@ libbase_la_SOURCES = \ JobWait.h \ Lock.h \ LookupTable.h \ - Optional.h \ Packable.h \ PackableStream.h \ Random.cc \ diff --git a/src/base/Optional.h b/src/base/Optional.h deleted file mode 100644 index 1c153b99c84..00000000000 --- a/src/base/Optional.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 1996-2022 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID__SRC_BASE_OPTIONAL_H -#define SQUID__SRC_BASE_OPTIONAL_H - -#include -#include -#include -#include - -/// std::bad_optional_access replacement (until we upgrade to C++17) -class BadOptionalAccess: public std::exception -{ -public: - BadOptionalAccess() {} - /* std::exception API */ - virtual const char* what() const noexcept override { return "bad-optional-access"; } - virtual ~BadOptionalAccess() noexcept = default; -}; - -/// (limited) std::optional replacement (until we upgrade to C++17) -template -class Optional -{ -public: - constexpr Optional() noexcept: dummy_() {} - constexpr explicit Optional(const Value &v): value_(v), hasValue_(true) {} - - ~Optional() - { - // XXX: This simplified implementation does not keep the destructor - // trivial for trivial Value types, but optimizing compilers still - // optimize such destruction away, and that is sufficient for our - // current needs. - reset(); - } - - Optional(const Optional &other): Optional() - { - if (other.hasValue_) - *this = other.value_; - } - - Optional &operator =(const Optional &other) - { - if (this != &other) { - if (other.hasValue_) - *this = other.value_; - else - reset(); - } - return *this; - } - - Optional(Optional &&other): Optional() - { - if (other.hasValue_) { - *this = std::move(other.value_); - // no other.reset() per std::optional move semantics - } - } - - Optional &operator =(Optional &&other) - { - if (this != &other) { - if (other.hasValue_) { - *this = std::move(other.value_); - // no other.reset() per std::optional move semantics - } else { - reset(); - } - } - return *this; - } - - constexpr explicit operator bool() const noexcept { return hasValue_; } - constexpr bool has_value() const noexcept { return hasValue_; } - - const Value &value() const & - { - if (!hasValue_) - throw BadOptionalAccess(); - return value_; - } - - template - constexpr Value value_or(Other &&defaultValue) const & - { - return hasValue_ ? value_ : static_cast(std::forward(defaultValue)); - } - - template - Optional &operator =(Other &&otherValue) - { - value_ = std::forward(otherValue); - hasValue_ = true; - return *this; - } - - void reset() { - if (hasValue_) { - hasValue_ = false; - value_.~Value(); - } - } - -private: - union { - /// unused member that helps satisfy various C++ union requirements - struct {} dummy_; - - /// stored value; inaccessible/uninitialized unless hasValue_ - Value value_; - }; - - bool hasValue_ = false; -}; - -/// Specialization to make Optional trivially-copyable. XXX: Keep this -/// temporary (until we switch to C++17 std::optional) hack in sync with the -/// generic Optional above, copying generic methods where possible. -template <> -class Optional -{ -public: - using Value = bool; - - constexpr Optional() noexcept = default; - constexpr explicit Optional(const Value &v): value_(v), hasValue_(true) {} - - constexpr explicit operator bool() const noexcept { return hasValue_; } - constexpr bool has_value() const noexcept { return hasValue_; } - - const Value &value() const & - { - if (!hasValue_) - throw BadOptionalAccess(); - return value_; - } - - template - constexpr Value value_or(Other &&defaultValue) const & - { - return hasValue_ ? value_ : static_cast(std::forward(defaultValue)); - } - - template - Optional &operator =(Other &&otherValue) - { - value_ = std::forward(otherValue); - hasValue_ = true; - return *this; - } - - void reset() { - if (hasValue_) { - hasValue_ = false; - } - } - -private: - Value value_ = false; - bool hasValue_ = false; -}; - -template -inline -std::ostream &operator <<(std::ostream &os, const Optional &opt) -{ - if (opt.has_value()) - os << opt.value(); - else - os << "[no value]"; - return os; -} - -#endif /* SQUID__SRC_BASE_OPTIONAL_H */ - diff --git a/src/base/SupportOrVeto.h b/src/base/SupportOrVeto.h index 68229cba3e4..62d43ba6d48 100644 --- a/src/base/SupportOrVeto.h +++ b/src/base/SupportOrVeto.h @@ -9,7 +9,7 @@ #ifndef SQUID_SRC_BASE_SUPPORTORVETO_H #define SQUID_SRC_BASE_SUPPORTORVETO_H -#include "base/Optional.h" +#include /// a boolean flag that is false by default and becomes permanently false if vetoed class SupportOrVeto @@ -30,7 +30,7 @@ class SupportOrVeto private: /// current decision (if any) - Optional decision_; + std::optional decision_; }; #endif /* SQUID_SRC_BASE_SUPPORTORVETO_H */ diff --git a/src/base/TypeTraits.h b/src/base/TypeTraits.h index 31cc9c2f445..bbcda9a6b45 100644 --- a/src/base/TypeTraits.h +++ b/src/base/TypeTraits.h @@ -39,9 +39,5 @@ class Interface using Interface = TypeTraits_::Interface; -/// std::enable_if_t replacement until C++14 -template -using EnableIfType = typename std::enable_if::type; - #endif /* SQUID_SRC_BASE_TYPETRAITS_H */ diff --git a/src/base/forward.h b/src/base/forward.h index a0ed6f47863..e595542fc7d 100644 --- a/src/base/forward.h +++ b/src/base/forward.h @@ -16,12 +16,9 @@ class CallDialer; class CodeContext; class DelayedAsyncCalls; class ScopedId; -class BadOptionalAccess; class Raw; class RegexPattern; -template class Optional; - template class CbcPointer; template class RefCount; template class JobWait; diff --git a/src/cf_gen.cc b/src/cf_gen.cc index 39d839db8eb..f35fbaee51c 100644 --- a/src/cf_gen.cc +++ b/src/cf_gen.cc @@ -265,17 +265,17 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } - entries.emplace_back(name); + auto &newEntry = entries.emplace_back(name); while ((aliasname = strtok(nullptr, WS)) != nullptr) - entries.back().alias.push_front(aliasname); + newEntry.alias.push_front(aliasname); state = s1; } else if (!strcmp(buff, "EOF")) { state = sEXIT; } else if (!strcmp(buff, "COMMENT_START")) { - entries.emplace_back("comment"); - entries.back().loc = "none"; + auto &newEntry = entries.emplace_back("comment"); + newEntry.loc = "none"; state = sDOC; } else { errorMsg(input_filename, linenum, buff); @@ -851,7 +851,7 @@ gen_quote_escape(const std::string &var) case '"': case '\\': esc += '\\'; - /* [[fallthrough]] */ + [[fallthrough]]; default: esc += c; } diff --git a/src/client_side.cc b/src/client_side.cc index 287d37636c4..00302fb352a 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3864,7 +3864,8 @@ ConnStateData::handleIdleClientPinnedTlsRead() switch(const int error = SSL_get_error(ssl, readResult)) { case SSL_ERROR_WANT_WRITE: debugs(83, DBG_IMPORTANT, pinning.serverConnection << " TLS SSL_ERROR_WANT_WRITE request for idle pinned connection"); - // fall through to restart monitoring, for now + [[fallthrough]]; // to restart monitoring, for now + case SSL_ERROR_NONE: case SSL_ERROR_WANT_READ: startPinnedConnectionMonitoring(); diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc index 14d618146b4..0be7f529b8b 100644 --- a/src/clients/FtpClient.cc +++ b/src/clients/FtpClient.cc @@ -696,7 +696,7 @@ Ftp::Client::sendPassive() state = SENT_EPSV_2; break; } - /* [[fallthrough]] to skip EPSV 2 */ + [[fallthrough]]; // to skip EPSV 2 case SENT_EPSV_2: /* EPSV IPv6 failed. Try EPSV IPv4 */ if (ctrl.conn->local.isIPv4()) { @@ -709,7 +709,7 @@ Ftp::Client::sendPassive() failed(ERR_FTP_FAILURE, 0); return false; } - /* [[fallthrough]] to skip EPSV 1 */ + [[fallthrough]]; // to skip EPSV 1 case SENT_EPSV_1: /* EPSV options exhausted. Try PASV now. */ debugs(9, 5, "FTP Channel (" << ctrl.conn->remote << ") rejects EPSV connection attempts. Trying PASV instead."); diff --git a/src/comm/Tcp.cc b/src/comm/Tcp.cc index 12a8180748c..4e159a00b4f 100644 --- a/src/comm/Tcp.cc +++ b/src/comm/Tcp.cc @@ -28,9 +28,7 @@ template static bool SetSocketOption(const int fd, const int level, const int optName, const Option &optValue) { -#if HAVE_STD_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_copyable