]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Require C++17 (#1212)
authorAlex Rousskov <rousskov@measurement-factory.com>
Tue, 13 Dec 2022 23:17:48 +0000 (23:17 +0000)
committerSquid Anubis <squid-anubis@squid-cache.org>
Thu, 15 Dec 2022 23:30:59 +0000 (23:30 +0000)
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.

64 files changed:
acinclude/ax_cxx_0x_types.m4 [deleted file]
acinclude/ax_cxx_compile_stdcxx.m4 [new file with mode: 0644]
acinclude/ax_cxx_compile_stdcxx_11.m4 [deleted file]
compat/types.h
configure.ac
lib/hash.cc
lib/ntlmauth/ntlmauth.cc
scripts/source-maintenance.sh
src/HttpHdrSc.cc
src/SquidMath.h
src/acl/Random.cc
src/acl/external/AD_group/ext_ad_group_acl.cc
src/acl/external/LM_group/ext_lm_group_acl.cc
src/acl/external/session/ext_session_acl.cc
src/acl/external/unix_group/check_group.cc
src/adaptation/icap/Xaction.cc
src/adaptation/icap/Xaction.h
src/auth/basic/RADIUS/basic_radius_auth.cc
src/auth/basic/SSPI/basic_sspi_auth.cc
src/auth/digest/Config.cc
src/auth/digest/UserRequest.cc
src/auth/negotiate/Config.cc
src/auth/negotiate/SSPI/negotiate_sspi_auth.cc
src/auth/negotiate/UserRequest.cc
src/auth/ntlm/Config.cc
src/auth/ntlm/SSPI/ntlm_sspi_auth.cc
src/auth/ntlm/UserRequest.cc
src/auth/ntlm/fake/ntlm_fake_auth.cc
src/auth/toUtf.cc
src/base/AsyncCallbacks.h
src/base/ClpMap.h
src/base/EnumIterator.h
src/base/IoManip.h
src/base/Makefile.am
src/base/Optional.h [deleted file]
src/base/SupportOrVeto.h
src/base/TypeTraits.h
src/base/forward.h
src/cf_gen.cc
src/client_side.cc
src/clients/FtpClient.cc
src/comm/Tcp.cc
src/debug/debug.cc
src/dns_internal.cc
src/errorpage.cc
src/event.cc
src/fs/ufs/UFSSwapDir.cc
src/http.cc
src/http/RegisteredHeadersHash.cci
src/http/StatusCode.cc
src/http/url_rewriters/fake/fake.cc
src/ipc/TypedMsgHdr.h
src/ipcache.cc
src/log/FormattedLog.cc
src/log/FormattedLog.h
src/mem/PoolingAllocator.h
src/sbuf/Stream.h
src/servers/Http1Server.cc
src/store/SwapMeta.h
src/tests/SBufFindTest.cc
src/tests/testMath.cc
src/tunnel.cc
test-suite/splay.cc
tools/cachemgr.cc

diff --git a/acinclude/ax_cxx_0x_types.m4 b/acinclude/ax_cxx_0x_types.m4
deleted file mode 100644 (file)
index cd2175b..0000000
+++ /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<T> is supported],
-                 [squid_cv_std_uniform_int_distribution_works],[
-    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <random>]],
-      [[std::uniform_int_distribution<int> 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<T> 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 <random>]],
-      [[std::uniform_real_distribution<double> 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<enumType>::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 <type_traits>
-enum class testEnum { one, two, three };
-        ],[
-        std::underlying_type<testEnum>::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 <type_traits>]],
-        [[return std::is_trivially_copyable<int>::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 (file)
index 0000000..483bf09
--- /dev/null
@@ -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 <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
+#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
+#   Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
+#   Copyright (c) 2020 Jason Merrill <jason@redhat.com>
+#   Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
+#
+#   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 <typename T>
+    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<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> 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<T, T>
+    {
+      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<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::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 <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::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<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(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<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::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 <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+  namespace test_constexpr_lambdas
+  {
+
+    constexpr int foo = [](){return 42;}();
+
+  }
+
+  namespace test::nested_namespace::definitions
+  {
+
+  }
+
+  namespace test_fold_expression
+  {
+
+    template<typename... Args>
+    int multiply(Args... args)
+    {
+      return (args * ... * 1);
+    }
+
+    template<typename... Args>
+    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<std::initializer_list<int>, decltype(foo)>::value);
+    static_assert(std::is_same<int, decltype(bar)>::value);
+  }
+
+  namespace test_typename_in_template_template_parameter
+  {
+
+    template<template<typename> 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 <bool cond>
+    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 <typename T1, typename T2>
+    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 <auto n>
+    struct B
+    {};
+
+    B<5> b1;
+    B<'a'> b2;
+
+  }
+
+  namespace test_structured_bindings
+  {
+
+    int arr[2] = { 1, 2 };
+    std::pair<int, int> pr = { 1, 2 };
+
+    auto f1() -> int(&)[2]
+    {
+      return arr;
+    }
+
+    auto f2() -> std::pair<int, int>&
+    {
+      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<typename T>
+    Bad
+    f(T*, T*);
+
+    template<typename T1, typename T2>
+    Good
+    f(T1*, T2*);
+
+    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+  }
+
+  namespace test_inline_variables
+  {
+
+    template<class T> void f(T)
+    {}
+
+    template<class T> 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 <version>
+
+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 (file)
index bc65be9..0000000
+++ /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 <bkoz@redhat.com>
-#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
-#   Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
-#
-#   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 <typename T>
-    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<check<bool>> right_angle_brackets; // GCC 4.3+
-
-    int a;
-    decltype(a) b; // GCC 4.3+
-
-    typedef check<int> check_type;
-    check_type c;
-    check_type&& cr = static_cast<check_type&&>(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
-])
index 360069d54b1f0d036e656d47f664d3e098843927..b125c91b7a2010576deb4bf6fa9fe47b403ba216 100644 (file)
 #include <netinet/in_systm.h>
 #endif
 
-#if __cplusplus && HAVE_TR1_RANDOM
-#if !HAVE_STD_UNIFORM_INT_DISTRIBUTION && !HAVE_STD_UNIFORM_REAL_DISTRIBUTION
-#include <tr1/random>
-#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 */
 
index 313373cf33329e0b8202c52b3fdc2489102504c5..ef3fa2284ec55ffd4b36f501dd95c6efd8256cca 100644 (file)
@@ -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
index 40d142fa9d62b9a1ad243d816361a45c7b13abd2..072d71710773ca13abfd65ce0ae85f6f39437b74 100644 (file)
@@ -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';
index 1039b5309b1525b581545652d812dc4439f9b4b6..6909d1ffd7081386f2e82afb3a30ca49b81805b6 100644 (file)
@@ -195,7 +195,7 @@ void
 ntlm_make_nonce(char *nonce)
 {
     static std::mt19937 mt(time(nullptr));
-    static xuniform_int_distribution<uint8_t> dist;
+    static std::uniform_int_distribution<uint8_t> dist;
 
     for (int i = 0; i < NTLM_NONCE_LEN; ++i)
         nonce[i] = static_cast<char>(dist(mt) & 0xFF);
index 99bb9096383c1b7c169b0f96d3322f184190bada..20ebba80d4010b5e8627b2ce0994799b63a7d674 100755 (executable)
@@ -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 ()
index ecb7aadf3dd0cac6b4feb9023f60bf370b0c1e7a..e4bf071c41b7fdc1cf7c0c58279ce20c07c4561d 100644 (file)
@@ -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);
index 225f80da5a26ac84c2de28babbd8ac7069d37f07..faf5b7e2f92f7446cfb51f7a4495c472eda0f9b3 100644 (file)
 #define _SQUID_SRC_SQUIDMATH_H
 
 #include "base/forward.h"
-#include "base/Optional.h"
 #include "base/TypeTraits.h"
 
 #include <limits>
+#include <optional>
 
 // 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<typename T>
-constexpr bool
+constexpr void
 AssertNaturalType()
 {
     static_assert(std::numeric_limits<T>::is_bounded, "std::numeric_limits<T>::max() is meaningful");
     static_assert(std::numeric_limits<T>::is_exact, "no silent loss of precision");
     static_assert(!std::is_enum<T>::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 <typename S, typename A, typename B, EnableIfType<AllUnsigned<A,B>::value, int> = 0>
-Optional<S>
+template <typename S, typename A, typename B, std::enable_if_t<AllUnsigned<A,B>::value, int> = 0>
+std::optional<S>
 IncreaseSumInternal(const A a, const B b) {
     // paranoid: AllUnsigned<A,B> precondition established that already
     static_assert(std::is_unsigned<A>::value, "AllUnsigned dispatch worked for A");
     static_assert(std::is_unsigned<B>::value, "AllUnsigned dispatch worked for B");
 
-    // TODO: Just call AssertNaturalType() after upgrading to C++14.
-    static_assert(AssertNaturalType<S>(), "S is a supported type");
-    static_assert(AssertNaturalType<A>(), "A is a supported type");
-    static_assert(AssertNaturalType<B>(), "B is a supported type");
+    AssertNaturalType<S>();
+    AssertNaturalType<A>();
+    AssertNaturalType<B>();
 
     // we should only be called by IncreaseSum(); it forces integer promotion
     static_assert(std::is_same<A, decltype(+a)>::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<S>::max()) ?
-           Optional<S>(sum) : Optional<S>();
+           std::optional<S>(sum) : std::optional<S>();
 }
 
 /// 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 <typename S, typename A, typename B, EnableIfType<!AllUnsigned<A,B>::value, int> = 0>
-Optional<S> constexpr
+template <typename S, typename A, typename B, std::enable_if_t<!AllUnsigned<A,B>::value, int> = 0>
+std::optional<S> constexpr
 IncreaseSumInternal(const A a, const B b) {
-    static_assert(AssertNaturalType<S>(), "S is a supported type");
-    static_assert(AssertNaturalType<A>(), "A is a supported type");
-    static_assert(AssertNaturalType<B>(), "B is a supported type");
+    AssertNaturalType<S>();
+    AssertNaturalType<A>();
+    AssertNaturalType<B>();
 
     // we should only be called by IncreaseSum() that does integer promotion
     static_assert(std::is_same<A, decltype(+a)>::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<S>() :
+        (a < 0 || b < 0) ? std::optional<S>() :
         // 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<S>::max() - a, b) ? Optional<S>() :
-        Optional<S>(a + b);
+        Less(std::numeric_limits<S>::max() - a, b) ? std::optional<S>() :
+        std::optional<S>(a + b);
 }
 
 /// argument pack expansion termination for IncreaseSum<S, T, Args...>()
 template <typename S, typename T>
-Optional<S>
+std::optional<S>
 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<AllUnsigned>(s,t)
     // but getting a _signed_ promoted value of s or t in s + t.
     return IncreaseSumInternal<S>(+s, +t);
@@ -153,18 +151,19 @@ IncreaseSum(const S s, const T t)
 
 /// \returns a non-overflowing sum of the arguments (or nothing)
 template <typename S, typename T, typename... Args>
-Optional<S>
+std::optional<S>
 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<S>();
+        // std::optional<S>() triggers bogus -Wmaybe-uninitialized warnings in GCC v10.3
+        return std::nullopt;
     }
 }
 
 /// \returns an exact, non-overflowing sum of the arguments (or nothing)
 template <typename SummationType, typename... Args>
-Optional<SummationType>
+std::optional<SummationType>
 NaturalSum(const Args... args) {
     return IncreaseSum<SummationType>(0, args...);
 }
index d0666c15e88b94fdb84efd688df334fca625b437..84f5376902376d6a905348f675320a4efa94cb2c 100644 (file)
@@ -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);
 
index 534d6292bec75e1d3f4adeee59e43319bbe1a23b..bc74e2cf9674a3258dc428b6b4ce928856444799 100644 (file)
@@ -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]);
index 50ef7aeb2cece0bebf3f9241834c78c33ed5fd2e..68b75afd6d0069fce272edefe2b7be052e36f2a0 100644 (file)
@@ -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]);
index 0e5481417006224e914de79e806b25540d24ec7c..4cb24f571b85f5f6ded5f54062ddbbdb2573c677 100644 (file)
@@ -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;
index 854ee8801aece2d824e284fd9dbff369545132af..4d7c655f1022009589271b2cb55e34a29a168978 100644 (file)
@@ -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);
index 47469d27871765b6239b599ea59bcd8abdba9de5..2fdabcb34dc90d5a35f7b43739edfabcd7199ace 100644 (file)
@@ -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 <optional>
+
 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<Adaptation::Icap::Xaction *>(data);
-    const auto &addr = ia ? Optional<Ip::Address>(ia->current()) : Optional<Ip::Address>();
+    const auto &addr = ia ? std::optional<Ip::Address>(ia->current()) : std::optional<Ip::Address>();
     CallJobHere1(93, 5, CbcPointer<Adaptation::Icap::Xaction>(xa), Adaptation::Icap::Xaction, dnsLookupDone, addr);
 }
 
@@ -168,7 +170,7 @@ Adaptation::Icap::Xaction::openConnection()
 }
 
 void
-Adaptation::Icap::Xaction::dnsLookupDone(Optional<Ip::Address> addr)
+Adaptation::Icap::Xaction::dnsLookupDone(std::optional<Ip::Address> addr)
 {
     assert(waitingForDns);
     waitingForDns = false;
index defdb8dd51a7cfd11af0952879f72e7696533d79..c9444b19d8ff69d83142533e870280efe9b9490b 100644 (file)
@@ -117,7 +117,7 @@ public:
     /// clear stored error details, if any; used for retries/repeats
     virtual void clearError() {}
     virtual AccessLogEntry::Pointer masterLogEntry();
-    void dnsLookupDone(Optional<Ip::Address>);
+    void dnsLookupDone(std::optional<Ip::Address>);
 
 protected:
     // logging
index 8ecf07c1c680f6bf3c3a80e6965ab7f83cd536f3..6642c115ada16d12af1d725db76e87f9b42405d8 100644 (file)
@@ -207,7 +207,7 @@ static void
 random_vector(char *aVector)
 {
     static std::mt19937 mt(RandomSeed32());
-    static xuniform_int_distribution<uint8_t> dist;
+    static std::uniform_int_distribution<uint8_t> dist;
 
     for (int i = 0; i < AUTH_VECTOR_LEN; ++i)
         aVector[i] = static_cast<char>(dist(mt) & 0xFF);
index 21fd79e8fa0ff367307699735180344f21f4a273..1c0a429dc57fedbe9fb2ff34226432e31c3fa126 100644 (file)
@@ -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]);
index 1b9aa4943d269ca6bca3052e23556b8cf7e82498..536fb3870a232631eb0d78ab83b56b82588b9f39 100644 (file)
@@ -158,7 +158,7 @@ authenticateDigestNonceNew(void)
      * the hash function.
      */
     static std::mt19937 mt(RandomSeed32());
-    static xuniform_int_distribution<uint32_t> newRandomData;
+    static std::uniform_int_distribution<uint32_t> newRandomData;
 
     /* create a new nonce */
     newnonce->nc = 0;
index 3a3c8ffff9b5882e0909b1d0ea32f2ae0bccdad7..6f2a42bba2831cd2a480bbb678c5f9d2a8c6d452 100644 (file)
@@ -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 */
index 75a93d66e968a329be6c822ff6c9d3f1e81645fd..8443dcfc2b5ad5e7c80b9ddffd81edaf5122378e 100644 (file)
@@ -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.
index 3f161b10b2b221bd7f5ee93ba9c161e88601a063..36c7f55dd13262435f756d2622ad2517d20b19b8 100644 (file)
@@ -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();
index 088cf11e5063b76ce935ee8204692f1eff4feb10..1303267e50c04e9676de7d6079adb4ed8416eb36 100644 (file)
@@ -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:
index 13d087b4114a675c4c16f01e519ac6e8407b9519..98c4d2b2317892a77a260e214c787a7ba37e76ef 100644 (file)
@@ -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.
index ebf8bb3a0ccefde424bcd7b6ab49127ff1c05092..98e3ab345b16a7d8e23e6d257c69568ef09dc7f2 100644 (file)
@@ -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();
index 07e55af2a947450fb9ab37ee83f2a021efb228b1..8eb6da089832b36cc61b163c7a572011efe76797 100644 (file)
@@ -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:
index a7309d01fe6c8ce8ce807cd452ccc47d9c31d540..a7848f404c1e0b80c93f55e2721fc188970a9d40 100644 (file)
@@ -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();
index 0d4ffb8799ab48ec74617a6fd05bd10da7754b17..d347fa732ffb7e39555eae4ef3b90ac881ec7eca 100644 (file)
@@ -78,11 +78,11 @@ Cp1251ToUtf8(const char *in)
         case 3:
             sequence[2] = static_cast<char>(u & 0x3f) | 0x80;
             u >>= 6;
-        /* [[fallthrough]] */
+            [[fallthrough]];
         case 2:
             sequence[1] = static_cast<char>(u & 0x3f) | 0x80;
             u >>= 6;
-        /* [[fallthrough]] */
+            [[fallthrough]];
         case 1:
             sequence[0] = static_cast<char>(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;
index 68fce514b06ed71cd3853398272ffe9848be21b9..e978d8519c37fa0579c9382c2fa61fbe02a07073 100644 (file)
@@ -155,7 +155,7 @@ using IsAsyncJob = typename std::conditional<
                    >::type;
 
 /// helper function to simplify UnaryCbcCallbackDialer creation
-template <class Destination, typename Argument1, EnableIfType<!IsAsyncJob<Destination>::value, int> = 0>
+template <class Destination, typename Argument1, std::enable_if_t<!IsAsyncJob<Destination>::value, int> = 0>
 UnaryCbcCallbackDialer<Destination, Argument1>
 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 <class Destination, typename Argument1, EnableIfType<IsAsyncJob<Destination>::value, int> = 0>
+template <class Destination, typename Argument1, std::enable_if_t<IsAsyncJob<Destination>::value, int> = 0>
 UnaryJobCallbackDialer<Destination, Argument1>
 callbackDialer(void (Destination::*method)(Argument1 &), Destination * const destination)
 {
index f8c6200b8c514600d3b38969dee7a08a436a1912..b8615136f131e89c8d53b065adf78338e59d2d17 100644 (file)
@@ -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 <functional>
 #include <limits>
 #include <list>
+#include <optional>
 #include <unordered_map>
 
 template<class Value>
@@ -110,7 +110,7 @@ private:
     using Index = std::unordered_map<Key, EntriesIterator, std::hash<Key>, std::equal_to<Key>, PoolingAllocator<IndexItem> >;
     using IndexIterator = typename Index::iterator;
 
-    static Optional<uint64_t> MemoryCountedFor(const Key &, const Value &);
+    static std::optional<uint64_t> MemoryCountedFor(const Key &, const Value &);
 
     void trim(uint64_t wantSpace);
     void erase(const IndexIterator &);
@@ -183,7 +183,7 @@ ClpMap<Key, Value, MemoryUsedBy>::get(const Key &key)
 }
 
 template <class Key, class Value, uint64_t MemoryUsedBy(const Value &)>
-Optional<uint64_t>
+std::optional<uint64_t>
 ClpMap<Key, Value, MemoryUsedBy>::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<Key, Value, MemoryUsedBy>::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;
index 96cb826f05cc9188896a85411428566186ad74bf..c78d1792a0c7b93d0e8942a8a2a18ea393d29661 100644 (file)
@@ -23,11 +23,7 @@ template <typename EnumType>
 class EnumIteratorBase
 {
 protected:
-#if HAVE_STD_UNDERLYING_TYPE
     typedef typename std::underlying_type<EnumType>::type iterator_type;
-#else
-    typedef int iterator_type;
-#endif
 
 public:
     using iterator_category = std::bidirectional_iterator_tag;
index bb60a8b67323a9821d3a08bd094afa5156662733..241d01bb1fe2331fe6163099befe1107ca726b41 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <iostream>
 #include <iomanip>
+#include <optional>
 
 /// Safely prints an object pointed to by the given pointer: [label]<object>
 /// Prints nothing at all if the pointer is nil.
@@ -101,5 +102,17 @@ inline AsHex<Integer> asHex(const Integer n) { return AsHex<Integer>(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 <typename Value>
+inline std::ostream &
+operator <<(std::ostream &os, const std::optional<Value> &optional)
+{
+    if (optional.has_value())
+        os << optional.value();
+    else
+        os << "[no value]";
+    return os;
+}
+
 #endif /* SQUID_SRC_BASE_IO_MANIP_H */
 
index 776eadb44f0e1e3ad488000026cbc80903788cdf..2c828128036cb446f1fba674720bbe91cce67df0 100644 (file)
@@ -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 (file)
index 1c153b9..0000000
+++ /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 <exception>
-#include <ostream>
-#include <type_traits>
-#include <utility>
-
-/// 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 <typename Value>
-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<Value> &&other): Optional()
-    {
-        if (other.hasValue_) {
-            *this = std::move(other.value_);
-            // no other.reset() per std::optional move semantics
-        }
-    }
-
-    Optional &operator =(Optional<Value> &&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 <class Other>
-    constexpr Value value_or(Other &&defaultValue) const &
-    {
-        return hasValue_ ? value_ : static_cast<Value>(std::forward<Other>(defaultValue));
-    }
-
-    template <class Other = Value>
-    Optional &operator =(Other &&otherValue)
-    {
-        value_ = std::forward<Other>(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<bool> 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<bool>
-{
-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 <class Other>
-    constexpr Value value_or(Other &&defaultValue) const &
-    {
-        return hasValue_ ? value_ : static_cast<Value>(std::forward<Other>(defaultValue));
-    }
-
-    template <class Other = Value>
-    Optional &operator =(Other &&otherValue)
-    {
-        value_ = std::forward<Other>(otherValue);
-        hasValue_ = true;
-        return *this;
-    }
-
-    void reset() {
-        if (hasValue_) {
-            hasValue_ = false;
-        }
-    }
-
-private:
-    Value value_ = false;
-    bool hasValue_ = false;
-};
-
-template <typename Value>
-inline
-std::ostream &operator <<(std::ostream &os, const Optional<Value> &opt)
-{
-    if (opt.has_value())
-        os << opt.value();
-    else
-        os << "[no value]";
-    return os;
-}
-
-#endif /* SQUID__SRC_BASE_OPTIONAL_H */
-
index 68229cba3e41148fff7743230f4322f10ae87c82..62d43ba6d484933f8eb0368a7e1d48f45a94f449 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef SQUID_SRC_BASE_SUPPORTORVETO_H
 #define SQUID_SRC_BASE_SUPPORTORVETO_H
 
-#include "base/Optional.h"
+#include <optional>
 
 /// a boolean flag that is false by default and becomes permanently false if vetoed
 class SupportOrVeto
@@ -30,7 +30,7 @@ public:
 
 private:
     /// current decision (if any)
-    Optional<bool> decision_;
+    std::optional<bool> decision_;
 };
 
 #endif /* SQUID_SRC_BASE_SUPPORTORVETO_H */
index 31cc9c2f4451ca6a9ee584be7ef6c9f2104cde7e..bbcda9a6b45a9403b236f874e5b6019da529fb1d 100644 (file)
@@ -39,9 +39,5 @@ protected: // prevents accidental creation of Interface instances
 
 using Interface = TypeTraits_::Interface;
 
-/// std::enable_if_t replacement until C++14
-template <bool B, class T = void>
-using EnableIfType = typename std::enable_if<B,T>::type;
-
 #endif /* SQUID_SRC_BASE_TYPETRAITS_H */
 
index a0ed6f478631ba5e9b0ea6dc8a53d94ea0773511..e595542fc7d198c190da43e4690ffd5c9df29085 100644 (file)
@@ -16,12 +16,9 @@ class CallDialer;
 class CodeContext;
 class DelayedAsyncCalls;
 class ScopedId;
-class BadOptionalAccess;
 class Raw;
 class RegexPattern;
 
-template <typename Value> class Optional;
-
 template<class Cbc> class CbcPointer;
 template<class RefCountableKid> class RefCount;
 template<class Job> class JobWait;
index 39d839db8ebf8cb1a834221b11f33f004559ffe6..f35fbaee51c1a8db3d3569f24483e02074b1c8df 100644 (file)
@@ -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;
         }
index 287d37636c49a88ce36d5780806909ec01577b5d..00302fb352a407feb1a848fed73a1b21445eb0e1 100644 (file)
@@ -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();
index 14d618146b4a860fc4bc69fea25a682f6389c098..0be7f529b8bd5f13e7b8bb1b9c9568d3e3342803 100644 (file)
@@ -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.");
index 12a8180748c0f5bb978e48cd821770a58b871de0..4e159a00b4f0ca4aa6af70ea354cc42874563d50 100644 (file)
@@ -28,9 +28,7 @@ template <typename Option>
 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<Option>::value, "setsockopt() expects POD-like options");
-#endif
     static_assert(!std::is_same<Option, bool>::value, "setsockopt() uses int to represent boolean options");
     if (setsockopt(fd, level, optName, &optValue, sizeof(optValue)) < 0) {
         const auto xerrno = errno;
index c59e9ae135a2d7d8ec8d45f9afe3d19b8dfe0bd7..909afd53852ce886e8fc614989f950ee27b574ba 100644 (file)
@@ -9,7 +9,6 @@
 /* DEBUG: section 00    Debug Routines */
 
 #include "squid.h"
-#include "base/Optional.h"
 #include "base/TextException.h"
 #include "debug/Stream.h"
 #include "fd.h"
@@ -21,6 +20,7 @@
 #include <deque>
 #include <functional>
 #include <memory>
+#include <optional>
 
 char *Debug::debugOptions = nullptr;
 int Debug::override_X = 0;
@@ -40,7 +40,7 @@ static DebugModule *Module_ = nullptr;
 /// Explicitly configured maximum level for debugs() messages written to stderr.
 /// debugs() messages with this (or lower) level will be written to stderr (and
 /// possibly other channels).
-static Optional<int> ExplicitStderrLevel;
+static std::optional<int> ExplicitStderrLevel;
 
 /// ExplicitStderrLevel preference or default: Just like with
 /// ExplicitStderrLevel, debugs() messages with this (or lower) level will be
@@ -365,7 +365,7 @@ ResetSections(const int level)
 
 /// optimization: formats ProcessLabel once for frequent debugs() reuse
 static void
-LabelThisProcess(const char * const name, const Optional<int> id = Optional<int>())
+LabelThisProcess(const char * const name, const std::optional<int> id = std::optional<int>())
 {
     assert(name);
     assert(strlen(name));
@@ -407,7 +407,7 @@ Debug::NameThisKid(const int kidIdentifier)
     // to reduce noise and for backward compatibility, do not label kid messages
     // in non-SMP mode
     if (kidIdentifier)
-        LabelThisProcess("kid", Optional<int>(kidIdentifier));
+        LabelThisProcess("kid", std::optional<int>(kidIdentifier));
     else
         ProcessLabel.clear(); // probably already empty
 }
index 85de50adfc1e822b106cb2e1e3c703228813f470..60358c834eda16a878c4beb317f16dc5c9390790 100644 (file)
@@ -345,11 +345,11 @@ idnsAddNameserver(const char *buf)
         return;
     }
 
-    nameservers.emplace_back(ns());
+    auto &nameserver = nameservers.emplace_back(ns());
     A.port(NS_DEFAULTPORT);
-    nameservers.back().S = A;
+    nameserver.S = A;
 #if WHEN_EDNS_RESPONSES_ARE_PARSED
-    nameservers.back().last_seen_edns = RFC1035_DEFAULT_PACKET_SZ;
+    nameserver.last_seen_edns = RFC1035_DEFAULT_PACKET_SZ;
     // TODO generate a test packet to probe this NS from EDNS size and ability.
 #endif
     debugs(78, 3, "Added nameserver #" << nameservers.size()-1 << " (" << A << ")");
index 6d888abfe2ad53092622a2ae96bde46cded0dda9..48df95bf40777fac730f30b0b02203d8e6e0bb39 100644 (file)
@@ -1076,7 +1076,7 @@ ErrorState::compileLegacyCode(Build &build)
     case 'O':
         if (!building_deny_info_url)
             do_quote = 0;
-    /* [[fallthrough]] */
+        [[fallthrough]];
     case 'o':
         p = request ? request->extacl_message.termedBuf() : external_acl_message;
         if (!p && !building_deny_info_url)
index 00c68d995d187b342b4371c8413931b68407a647..4ee4df1766e5b20db9130d88f4be31077f0d2728 100644 (file)
@@ -116,7 +116,7 @@ eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int weigh
     if (delta_ish >= 3.0) {
         static std::mt19937 rng(RandomSeed32());
         auto third = (delta_ish/3.0);
-        xuniform_real_distribution<> thirdIsh(delta_ish - third, delta_ish + third);
+        std::uniform_real_distribution<> thirdIsh(delta_ish - third, delta_ish + third);
         delta_ish = thirdIsh(rng);
     }
 
index d9cd08b230337ad9c383a57cb8d75eee3cfc29af..65301a42f27816bb88a0b5eded17894543e27905 100644 (file)
@@ -1079,7 +1079,7 @@ Fs::Ufs::UFSSwapDir::HandleCleanEvent()
          * swap directories
          */
         static std::mt19937 mt(RandomSeed32());
-        xuniform_int_distribution<> dist(0, j);
+        std::uniform_int_distribution<> dist(0, j);
         swap_index = dist(mt);
     }
 
index cef4ea08ac469a2b03f2a9ae4aa17e53e0a749b5..8623917a6210467afc43ef2499219ca0639c091c 100644 (file)
@@ -497,7 +497,7 @@ HttpStateData::reusableReply(HttpStateData::ReuseDecision &decision)
     case Http::scMisdirectedRequest:
         statusAnswer = ReuseDecision::doNotCacheButShare;
         statusReason = shareableError;
-    /* [[fallthrough]] to the actual decision making below */
+        [[fallthrough]]; // to the actual decision making below
 
     case Http::scBadRequest: // no sharing; perhaps the server did not like something specific to this request
 #if USE_HTTP_VIOLATIONS
index 233c4f6d2feedbb2d70f4f3e05ba9e1f6eccd1c5..e87c7c7a02c75c4409a14848fdba1613089c25bf 100644 (file)
@@ -144,7 +144,7 @@ HttpHeaderHashTable::HttpHeaderHash (const char *str, size_t len)
     {
     default:
         hval += asso_values[static_cast<unsigned char>(str[8])];
-    /*FALLTHROUGH*/
+        [[fallthrough]];
     case 8:
     case 7:
     case 6:
@@ -152,7 +152,7 @@ HttpHeaderHashTable::HttpHeaderHash (const char *str, size_t len)
     case 4:
     case 3:
         hval += asso_values[static_cast<unsigned char>(str[2])];
-    /*FALLTHROUGH*/
+        [[fallthrough]];
     case 2:
         break;
     }
index 24fb2942340262a6bb287ae8a87f104eb28b0c42..2cd0bd77eea85937a164408f2f5d861d9eabbcca 100644 (file)
@@ -269,7 +269,7 @@ Http::StatusCodeString(const Http::StatusCode status)
     // 600+
     case Http::scInvalidHeader:
     case Http::scHeaderTooLarge:
-    // fall through to default.
+        [[fallthrough]];
 
     default:
         debugs(57, 3, "Unassigned HTTP status code: " << status);
index b5cbbd5065b6889be5b0c4e9f16161c19c7dc511..f3deaa643527bd31f5a9473a543f484f6bb96c8f 100644 (file)
@@ -80,7 +80,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();
index ba61dbb94eb84cc00043256f93d94ab35d953c1c..e4bd55d566a652d13310ac1ac74d55c4f5235b2c 100644 (file)
@@ -117,9 +117,7 @@ template <class Pod>
 void
 Ipc::TypedMsgHdr::getPod(Pod &pod) const
 {
-#if HAVE_STD_IS_TRIVIALLY_COPYABLE
     static_assert(std::is_trivially_copyable<Pod>::value, "getPod() used for a POD");
-#endif
     getFixed(&pod, sizeof(pod));
 }
 
@@ -127,9 +125,7 @@ template <class Pod>
 void
 Ipc::TypedMsgHdr::putPod(const Pod &pod)
 {
-#if HAVE_STD_IS_TRIVIALLY_COPYABLE
     static_assert(std::is_trivially_copyable<Pod>::value, "putPod() used for a POD");
-#endif
     putFixed(&pod, sizeof(pod));
 }
 
index e9b9811c707ea31f983e79ae9abfd4769debd784..0fd922679044d66ff17b56c82968e39587912b3f 100644 (file)
@@ -991,8 +991,8 @@ void
 Dns::CachedIps::pushUnique(const Ip::Address &ip)
 {
     assert(!have(ip));
-    ips.emplace_back(ip);
-    assert(!raw().back().bad());
+    [[maybe_unused]] auto &cachedIp = ips.emplace_back(ip);
+    assert(!cachedIp.bad());
 }
 
 void
index a48cba6a6302b858ee1bd98bcf669c71ffa2be6f..fcb5b0221f881409bac2b61e836de84f0f47baa7 100644 (file)
@@ -58,7 +58,7 @@ FormattedLog::parseOptions(ConfigParser &parser, const char *defaultFormatName)
         }
 
         if (strcmp(key, "rotate") == 0) {
-            rotationsToKeep = Optional<unsigned int>(xatoui(value));
+            rotationsToKeep = std::optional<unsigned int>(xatoui(value));
             continue;
         }
 
@@ -86,7 +86,7 @@ FormattedLog::dumpOptions(std::ostream &os) const
 
     // TODO: Here and elsewhere, report both explicitly configured settings and
     // various defaults. Properly excluding defaults requires wrapping most
-    // non-pointer members in Optional _and_ adding methods to compute the final
+    // non-pointer members in std::optional and adding methods to compute the final
     // option value after accounting for defaults (and those may change with
     // reconfiguration!). And all that effort may still not result in a faithful
     // reproduction of the original squid.conf because of size unit changes,
index eabb892dc0cf9e828d6f028bb3212ea279795360..ae1385b8224c21fdf75ebc46032fe3f0d36c319a 100644 (file)
 #define SQUID_LOG_FORMATTEDLOG_H_
 
 #include "acl/forward.h"
-#include "base/Optional.h"
 #include "log/Formats.h"
 #include "log/forward.h"
 
 #include <iosfwd>
+#include <optional>
 
 class ConfigParser;
 
@@ -70,7 +70,7 @@ public:
     size_t bufferSize = 8*MAX_URL;
 
     /// how many log files to retain when rotating. Default: obey logfile_rotate
-    Optional<unsigned int> rotationsToKeep;
+    std::optional<unsigned int> rotationsToKeep;
 
     /// whether unrecoverable errors (e.g., dropping a log record) kill worker
     bool fatal = true;
index ffef9772e42640d74874c44988bcba5bc9195015..831ffadcb73bea80fff0a57142a1a0d76e189a78 100644 (file)
@@ -23,17 +23,6 @@ public:
     value_type *allocate(std::size_t n) { return static_cast<value_type*>(memAllocRigid(n*sizeof(value_type))); }
     void deallocate(value_type *vp, std::size_t n) noexcept { memFreeRigid(vp, n*sizeof(value_type)); }
 
-    // The following declarations are only necessary for compilers that do not
-    // fully support C++11 Allocator-related APIs, such as GCC v4.8.
-    // The corresponding std::allocator declarations are deprecated in C++17.
-    // TODO: Remove after dropping support for deficient compilers.
-
-    using size_type = size_t;
-    using pointer = Value*;
-    using const_pointer = const Value*;
-    using reference = Value&;
-    using const_reference = const Value&;
-
     template <class OtherValue>
     struct rebind {
         typedef PoolingAllocator<OtherValue> other;
index 5d550980f1a59a61d8409117e5a0edf238ae88cf..14c2591e226d633250af1e5fda12ffa308bf6d84 100644 (file)
@@ -62,10 +62,8 @@ template <typename... Args>
 inline
 SBuf ToSBuf(Args&&... args)
 {
-    // TODO: Make this code readable after requiring C++17.
     SBufStream out;
-    using expander = int[];
-    (void)expander {0, (void(out << std::forward<Args>(args)),0)...};
+    (out << ... << args);
     return out.buf();
 }
 
index b7d8d3161b3af513e60a2de692e04da30fff9966..98b1c0e9cdb9009c59721816364b89f821670b11 100644 (file)
@@ -101,7 +101,6 @@ Http::One::Server::buildHttpRequest(Http::StreamPointer &context)
         err_type errPage = ERR_INVALID_REQ;
         switch (parser_->parseStatusCode) {
         case Http::scRequestHeaderFieldsTooLarge:
-        // fall through to next case
         case Http::scUriTooLong:
             errPage = ERR_TOO_BIG;
             break;
index ee9982802ef2aa7d1fdb82556ae1e7e2656dca37..631f3e81083eef2f9047ea78433615a080a6b511 100644 (file)
@@ -125,10 +125,9 @@ const auto SwapMetaPrefixSize = sizeof(SwapMetaMagic) + sizeof(RawSwapMetaPrefix
 /// This is not the smallest RawSwapMetaType value (that is usually -128).
 const RawSwapMetaType RawSwapMetaTypeBottom = 0;
 
-// TODO: Use "inline constexpr ..." with C++17.
 /// Maximum value of a serialized SwapMetaType ID.
 /// This is not the largest RawSwapMetaType value (that is usually +127).
-inline RawSwapMetaType
+inline constexpr RawSwapMetaType
 RawSwapMetaTypeTop()
 {
     // This "constant" switch forces developers to update this function when
@@ -155,7 +154,7 @@ RawSwapMetaTypeTop()
 
 /// Whether the given raw swap meta field type represents a type that we should
 /// inform the admin about (if found in a store) but can otherwise ignore.
-inline bool
+inline constexpr bool
 DeprecatedSwapMetaType(const RawSwapMetaType type)
 {
     enum class DeprecatedMetas {
@@ -169,7 +168,6 @@ DeprecatedSwapMetaType(const RawSwapMetaType type)
         STORE_META_VALID = 7
     };
     return
-        // TODO: simplify with std::underlying_type_t when switching to C++14
         type == static_cast<RawSwapMetaType>(DeprecatedMetas::STORE_META_KEY_URL) ||
         type == static_cast<RawSwapMetaType>(DeprecatedMetas::STORE_META_KEY_SHA) ||
         type == static_cast<RawSwapMetaType>(DeprecatedMetas::STORE_META_HITMETERING) ||
@@ -178,7 +176,7 @@ DeprecatedSwapMetaType(const RawSwapMetaType type)
 
 /// Whether the given raw swap meta field type represents a type that we should
 /// ignore without informing the admin.
-inline bool
+inline constexpr bool
 ReservedSwapMetaType(const RawSwapMetaType type)
 {
     enum class ReservedMetas {
@@ -195,7 +193,7 @@ ReservedSwapMetaType(const RawSwapMetaType type)
 /// Whether we store the given swap meta field type (and also interpret the
 /// corresponding swap meta field when the Store loads it). Matches all
 /// SwapMetaType enum values except for the never-stored STORE_META_VOID.
-inline bool
+inline constexpr bool
 HonoredSwapMetaType(const RawSwapMetaType type)
 {
     switch (type) {
@@ -217,7 +215,7 @@ HonoredSwapMetaType(const RawSwapMetaType type)
 
 /// Whether the given raw swap meta field type can be safely ignored.
 /// \sa HonoredSwapMetaType()
-inline bool
+inline constexpr bool
 IgnoredSwapMetaType(const RawSwapMetaType type)
 {
     return DeprecatedSwapMetaType(type) || ReservedSwapMetaType(type);
index 4a523bf2f93e97594da7a2463c9a5546db38a8a3..a63faf5bf256b2f8fa421cd329d8aa2238418d28 100644 (file)
@@ -375,7 +375,7 @@ SBufFindTest::RandomSBuf(const int length)
     // sizeof() counts the terminating zero at the end of characters
     // and the distribution is an 'inclusive' value range, so -2
     // TODO: add \0 character (needs reporting adjustments to print it as \0)
-    static xuniform_int_distribution<uint8_t> dist(0, sizeof(characters)-2);
+    static std::uniform_int_distribution<uint8_t> dist(0, sizeof(characters)-2);
 
     SBuf buf;
     buf.reserveCapacity(length);
index 6883dc5454ac7681038d97a8e3f920f18ebc6974..b7ddaa5d2b7ffcc0c41f6afd353b8c3c62f33802 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include "squid.h"
-#include "base/Optional.h"
 #include "compat/cppunit.h"
 #include "SquidMath.h"
 #include "unitTestMain.h"
index b93be36cbcda252ccd3784ab55509508be9d0e9d..4b202ce64393dad704d40d3be1f8d865e4d2fd40 100644 (file)
@@ -407,7 +407,7 @@ TunnelStateData::checkRetry()
     if (noConnections())
         return "no connections";
 
-    // TODO: Use Optional for peer_reply_status to avoid treating zero value specially.
+    // TODO: Use std::optional for peer_reply_status to avoid treating zero value specially.
     if (request->hier.peer_reply_status != Http::scNone && !Http::IsReforwardableStatus(request->hier.peer_reply_status))
         return "received HTTP status code is not reforwardable";
 
index e95d388cf087cc85527d825761d4619617d09135..0225852e41286a57dde81d65875389584c787c9d 100644 (file)
@@ -131,7 +131,7 @@ int
 main(int, char *[])
 {
     std::mt19937 generator;
-    xuniform_int_distribution<int> distribution;
+    std::uniform_int_distribution<int> distribution;
     auto nextRandom = std::bind (distribution, generator);
 
     {
index 63a2e66d38178e3df4864bc33bfe523d7df2a7c3..c4d7fee0d0b1c2e5fa6fb8cef240c85f6b888f97 100644 (file)
@@ -693,7 +693,7 @@ read_reply(int s, cachemgr_request * req)
             }
 
             istate = isActions;
-        /* [[fallthrough]] we do not want to lose the first line */
+            [[fallthrough]]; // we do not want to lose the first line
 
         case isActions:
             if (strncmp(buf, "action:", 7) == 0) {
@@ -709,7 +709,7 @@ read_reply(int s, cachemgr_request * req)
             }
 
             istate = isBody;
-        /* [[fallthrough]] we do not want to lose the first line */
+            [[fallthrough]]; // we do not want to lose the first line
 
         case isBody:
         {