build: raise minimum build requirements

 * Make gcc 7.4 and boost 1.65.1 hard dependencies, both are
   available out-of-the-box on Ubuntu 18.04
 * Require Xcode 10 on macOS but recommend 11.3 or later
 * If using clang on non-Apple platforms, the minimum supported
   version is now 6.0

Change-Id: I79c84a266741c9a66655da4fd467fe0d8218e8f0
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d9f98d8..47d9a6a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -22,8 +22,6 @@
         include:
           - compiler: g++-7
             os: ubuntu-18.04
-          - compiler: clang++-5.0
-            os: ubuntu-18.04
           - compiler: clang++-6.0
             os: ubuntu-18.04
     runs-on: ${{ matrix.os }}
@@ -37,7 +35,7 @@
           sudo apt-get -qy install ${CXX/clang++/clang}
           ${CXX} --version
       - name: Checkout
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
       - name: Build and test
         run: ./.jenkins
 
@@ -63,6 +61,6 @@
         with:
           xcode-version: ${{ matrix.xcode }}
       - name: Checkout
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
       - name: Build and test
         run: ./.jenkins
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 7e19491..f27285b 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -21,7 +21,7 @@
       WAF_JOBS: 3
     steps:
       - name: Checkout
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
       - name: Install dependencies
         run: |
           case ${RUNNER_OS} in
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index f3be6e7..f086c17 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -16,20 +16,21 @@
     errmsg = ''
     warnmsg = ''
     if cxx == 'gcc':
-        if ccver < (5, 3, 0):
+        if ccver < (7, 4, 0):
             errmsg = ('The version of gcc you are using is too old.\n'
-                      'The minimum supported gcc version is 7.4.0.')
-        elif ccver < (7, 4, 0):
-            warnmsg = ('Using a version of gcc older than 7.4.0 is not '
-                       'officially supported and may result in build failures.')
+                      'The minimum supported gcc version is 7.4.')
         conf.flags = GccFlags()
     elif cxx == 'clang':
-        if Utils.unversioned_sys_platform() == 'darwin' and ccver < (9, 0, 0):
-            errmsg = ('The version of Xcode you are using is too old.\n'
-                      'The minimum supported Xcode version is 9.0.')
-        elif ccver < (4, 0, 0):
+        if Utils.unversioned_sys_platform() == 'darwin':
+            if ccver < (10, 0, 0):
+                errmsg = ('The version of Xcode you are using is too old.\n'
+                          'The minimum supported Xcode version is 11.3.')
+            elif ccver < (11, 0, 0):
+                warnmsg = ('Using a version of Xcode older than 11.3 is not '
+                           'officially supported and may result in build failures.')
+        elif ccver < (6, 0, 0):
             errmsg = ('The version of clang you are using is too old.\n'
-                      'The minimum supported clang version is 4.0.')
+                      'The minimum supported clang version is 6.0.')
         conf.flags = ClangFlags()
     else:
         warnmsg = '%s compiler is unsupported' % cxx
@@ -181,7 +182,7 @@
         flags['CXXFLAGS'] += ['-fdiagnostics-color',
                               '-Wredundant-tags',
                               ]
-        if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
+        if platform.machine() == 'armv7l':
             flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
         return flags
 
@@ -190,7 +191,7 @@
         flags['CXXFLAGS'] += ['-fdiagnostics-color',
                               '-Wredundant-tags',
                               ]
-        if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
+        if platform.machine() == 'armv7l':
             flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
         return flags
 
@@ -212,8 +213,6 @@
                               '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        if self.getCompilerVersion(conf) < (6, 0, 0):
-            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
 
     def getOptimizedFlags(self, conf):
@@ -222,6 +221,4 @@
                               '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
-        if self.getCompilerVersion(conf) < (6, 0, 0):
-            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
         return flags
diff --git a/docs/INSTALL.rst b/docs/INSTALL.rst
index 3fb4e59..25438da 100644
--- a/docs/INSTALL.rst
+++ b/docs/INSTALL.rst
@@ -22,7 +22,7 @@
 -  Fedora >= 29
 -  Gentoo Linux
 -  Raspberry Pi OS (formerly Raspbian) >= 2019-06-20
--  FreeBSD >= 11.3
+-  FreeBSD >= 12.0
 -  macOS 10.14
 
 Prerequisites
@@ -31,8 +31,8 @@
 Required
 ~~~~~~~~
 
--  GCC >= 7.4 or clang >= 4.0 (on Linux and FreeBSD)
--  Xcode >= 9.0 (on macOS)
+-  GCC >= 7.4 or clang >= 6.0 (if you are on Linux or FreeBSD)
+-  Xcode >= 11.3 or corresponding version of Command Line Tools (if you are on macOS)
 -  Python >= 3.6
 -  pkg-config
 -  Boost >= 1.65.1
diff --git a/docs/conf.py b/docs/conf.py
index 22f4bc1..95639c1 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -18,7 +18,7 @@
 # -- Project information -----------------------------------------------------
 
 project = u'ndn-cxx: NDN C++ library with eXperimental eXtensions'
-copyright = u'Copyright © 2013-2021 Regents of the University of California.'
+copyright = u'Copyright © 2013-2022 Regents of the University of California.'
 author = u'Named Data Networking Project'
 
 # The short X.Y version.
diff --git a/docs/doxygen.conf.in b/docs/doxygen.conf.in
index 82513e4..5c857c5 100644
--- a/docs/doxygen.conf.in
+++ b/docs/doxygen.conf.in
@@ -774,7 +774,7 @@
 # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = ndn-cxx
+INPUT                  = ndn-cxx build/ndn-cxx/version.hpp
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/ndn-cxx/face.hpp b/ndn-cxx/face.hpp
index e073ba0..45eaad2 100644
--- a/ndn-cxx/face.hpp
+++ b/ndn-cxx/face.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -517,11 +517,7 @@
 class RegisteredPrefixHandle : public detail::CancelHandle
 {
 public:
-  RegisteredPrefixHandle() noexcept
-  {
-    // This could have been '= default', but there's compiler bug in Apple clang 9.0.0,
-    // see https://stackoverflow.com/a/44693603
-  }
+  RegisteredPrefixHandle() noexcept = default;
 
   /** \brief Unregister the prefix.
    */
diff --git a/ndn-cxx/key-locator.cpp b/ndn-cxx/key-locator.cpp
index 61659b5..f29b623 100644
--- a/ndn-cxx/key-locator.cpp
+++ b/ndn-cxx/key-locator.cpp
@@ -21,9 +21,10 @@
 
 #include "ndn-cxx/key-locator.hpp"
 #include "ndn-cxx/encoding/block-helpers.hpp"
-#include "ndn-cxx/util/overload.hpp"
 #include "ndn-cxx/util/string-helper.hpp"
 
+#include <boost/hana/functional/overload.hpp>
+
 namespace ndn {
 
 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
@@ -56,7 +57,7 @@
 
   size_t totalLength = 0;
 
-  auto visitor = overload(
+  auto visitor = boost::hana::overload(
     []  (monostate)           {}, // nothing to encode, TLV-VALUE is empty
     [&] (const Name& name)    { totalLength += name.wireEncode(encoder); },
     [&] (const Block& digest) { totalLength += prependBlock(encoder, digest); },
@@ -192,7 +193,7 @@
 std::ostream&
 operator<<(std::ostream& os, const KeyLocator& keyLocator)
 {
-  auto visitor = overload(
+  auto visitor = boost::hana::overload(
     [&] (monostate) {
       os << "None";
     },
diff --git a/ndn-cxx/net/ethernet.cpp b/ndn-cxx/net/ethernet.cpp
index 28f6929..65cb118 100644
--- a/ndn-cxx/net/ethernet.cpp
+++ b/ndn-cxx/net/ethernet.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2018 Regents of the University of California,
+ * Copyright (c) 2014-2022 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -29,7 +29,7 @@
 
 #include <boost/functional/hash.hpp>
 
-#include <stdio.h>
+#include <cinttypes>
 #include <cstdio>
 #include <ostream>
 
@@ -65,7 +65,7 @@
 bool
 Address::isMulticast() const
 {
-  return (at(0) & 1) != 0;
+  return (front() & 1) != 0;
 }
 
 bool
@@ -77,43 +77,35 @@
 std::string
 Address::toString(char sep) const
 {
+  const auto& a = *this;
   char s[18]; // 12 digits + 5 separators + null terminator
 
-  // - apparently gcc-4.6 does not support the 'hh' type modifier
-  // - std::snprintf not found in some environments
-  //   https://redmine.named-data.net/issues/2299 for more information
-  snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
-           at(0), sep, at(1), sep, at(2), sep, at(3), sep, at(4), sep, at(5));
-
-  return std::string(s);
+  std::snprintf(s, sizeof(s),
+                "%02" PRIx8 "%c%02" PRIx8 "%c%02" PRIx8 "%c%02" PRIx8 "%c%02" PRIx8 "%c%02" PRIx8,
+                a[0], sep, a[1], sep, a[2], sep, a[3], sep, a[4], sep, a[5]);
+  return s;
 }
 
 Address
 Address::fromString(const std::string& str)
 {
   Address a;
-  unsigned short temp[a.size()];
   char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
   int n = 0; // num of chars read from the input string
 
-  // apparently gcc-4.6 does not support the 'hh' type modifier
-  int ret = std::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
-                        &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
-                        &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
+  int ret = std::sscanf(str.data(),
+                        "%2" SCNx8 "%1[:-]%2" SCNx8 "%1[:-]%2" SCNx8 "%1[:-]"
+                        "%2" SCNx8 "%1[:-]%2" SCNx8 "%1[:-]%2" SCNx8 "%n",
+                        &a[0], &sep[0][0], &a[1], &sep[1][0], &a[2], &sep[2][0],
+                        &a[3], &sep[3][0], &a[4], &sep[4][0], &a[5], &n);
 
   if (ret < 11 || static_cast<size_t>(n) != str.length())
-    return Address();
+    return {};
 
-  for (size_t i = 0; i < a.size(); ++i) {
-    // check that all separators are actually the same char (: or -)
-    if (i < 5 && sep[i][0] != sep[0][0])
-      return Address();
-
-    // check that each value fits into a uint8_t
-    if (temp[i] > 0xFF)
-      return Address();
-
-    a[i] = static_cast<uint8_t>(temp[i]);
+  // check that all separators are the same char (: or -)
+  for (size_t i = 1; i < 5; ++i) {
+    if (sep[i][0] != sep[0][0])
+      return {};
   }
 
   return a;
diff --git a/ndn-cxx/util/backports.hpp b/ndn-cxx/util/backports.hpp
index 6948f38..6015153 100644
--- a/ndn-cxx/util/backports.hpp
+++ b/ndn-cxx/util/backports.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,7 +41,7 @@
 #endif
 
 //
-// http://wg21.link/P0188
+// https://wg21.link/P0188
 // [[fallthrough]] attribute (C++17)
 //
 #if (__cplusplus > 201402L) && NDN_CXX_HAS_CPP_ATTRIBUTE(fallthrough)
@@ -57,7 +57,7 @@
 #endif
 
 //
-// http://wg21.link/P0189
+// https://wg21.link/P0189
 // [[nodiscard]] attribute (C++17)
 //
 #if (__cplusplus > 201402L) && NDN_CXX_HAS_CPP_ATTRIBUTE(nodiscard)
@@ -68,17 +68,6 @@
 #  define NDN_CXX_NODISCARD
 #endif
 
-#ifndef NDEBUG
-#  define NDN_CXX_UNREACHABLE BOOST_ASSERT(false)
-#elif BOOST_COMP_GNUC || BOOST_COMP_CLANG
-#  define NDN_CXX_UNREACHABLE __builtin_unreachable()
-#elif BOOST_COMP_MSVC
-#  define NDN_CXX_UNREACHABLE __assume(0)
-#else
-#  include <cstdlib>
-#  define NDN_CXX_UNREACHABLE std::abort()
-#endif
-
 #ifndef NDN_CXX_HAVE_STD_TO_STRING
 #include <boost/lexical_cast.hpp>
 #endif
@@ -93,7 +82,7 @@
 using std::to_string;
 #else
 template<typename T>
-inline std::string
+std::string
 to_string(const T& val)
 {
   return boost::lexical_cast<std::string>(val);
@@ -141,6 +130,29 @@
 }
 #endif // __cpp_lib_to_underlying
 
+//
+// https://wg21.link/P0627
+// std::unreachable() (C++23)
+//
+#ifndef NDEBUG
+#  define NDN_CXX_UNREACHABLE BOOST_ASSERT(false)
+#elif __cpp_lib_unreachable >= 202202L
+#  define NDN_CXX_UNREACHABLE std::unreachable()
+#else
+#  define NDN_CXX_UNREACHABLE ::ndn::detail::unreachable()
+namespace detail {
+[[noreturn]] inline void
+unreachable()
+{
+#if BOOST_COMP_GNUC || BOOST_COMP_CLANG
+  __builtin_unreachable();
+#elif BOOST_COMP_MSVC
+  __assume(0);
+#endif
+} // unreachable()
+} // namespace detail
+#endif
+
 } // namespace ndn
 
 #endif // NDN_CXX_UTIL_BACKPORTS_HPP
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index 4367042..ba20396 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -37,15 +37,10 @@
 #include <boost/range/iterator_range.hpp>
 
 #include <cinttypes> // for PRIdLEAST64
+#include <cstdio>    // for std::snprintf()
 #include <cstdlib>   // for std::abs()
 #include <iostream>
 #include <sstream>
-#include <stdio.h>   // for snprintf()
-
-// suppress warning caused by <boost/log/sinks/text_ostream_backend.hpp>
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wundefined-func-template"
-#endif
 
 namespace ndn {
 namespace util {
@@ -68,9 +63,8 @@
 
   static_assert(std::is_same<microseconds::rep, int_least64_t>::value,
                 "PRIdLEAST64 is incompatible with microseconds::rep");
-  // std::snprintf unavailable on some platforms, see #2299
-  ::snprintf(&buffer.front(), buffer.size(), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
-             usecs / usecsPerSec, usecs % usecsPerSec);
+  std::snprintf(&buffer.front(), buffer.size(), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
+                usecs / usecsPerSec, usecs % usecsPerSec);
 
   // need to remove extra 1 byte ('\0')
   buffer.pop_back();
diff --git a/ndn-cxx/util/overload.hpp b/ndn-cxx/util/overload.hpp
deleted file mode 100644
index b3af737..0000000
--- a/ndn-cxx/util/overload.hpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2021 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#ifndef NDN_CXX_UTIL_OVERLOAD_HPP
-#define NDN_CXX_UTIL_OVERLOAD_HPP
-
-#include <boost/predef/compiler/gcc.h>
-#include <boost/version.hpp>
-
-// Hana does not support GCC < 6.0.0
-#if (BOOST_VERSION >= 106100) && (!BOOST_COMP_GNUC || (BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(6,0,0)))
-
-#include <boost/hana/functional/overload.hpp>
-
-namespace ndn {
-constexpr boost::hana::make_overload_t overload{};
-} // namespace ndn
-
-#else
-
-#include <type_traits>
-
-namespace ndn {
-namespace detail {
-
-// The following code is copied from the Boost.Hana library.
-// Copyright Louis Dionne 2013-2017
-// Distributed under the Boost Software License, Version 1.0.
-// (See http://boost.org/LICENSE_1_0.txt)
-
-//! Pick one of several functions to call based on overload resolution.
-//!
-//! Specifically, `overload(f1, f2, ..., fn)` is a function object such
-//! that
-//! @code
-//!     overload(f1, f2, ..., fn)(x...) == fk(x...)
-//! @endcode
-//!
-//! where `fk` is the function of `f1, ..., fn` that would be called if
-//! overload resolution was performed amongst that set of functions only.
-//! If more than one function `fk` would be picked by overload resolution,
-//! then the call is ambiguous.
-#ifndef DOXYGEN
-template <typename F, typename ...G>
-struct overload_t
-    : overload_t<F>::type
-    , overload_t<G...>::type
-{
-  using type = overload_t;
-  using overload_t<F>::type::operator();
-  using overload_t<G...>::type::operator();
-
-  template <typename F_, typename ...G_>
-  constexpr explicit overload_t(F_&& f, G_&& ...g)
-    : overload_t<F>::type(static_cast<F_&&>(f))
-    , overload_t<G...>::type(static_cast<G_&&>(g)...)
-  { }
-};
-
-template <typename F>
-struct overload_t<F> { using type = F; };
-
-template <typename R, typename ...Args>
-struct overload_t<R(*)(Args...)> {
-  using type = overload_t;
-  R (*fptr_)(Args...);
-
-  explicit constexpr overload_t(R (*fp)(Args...))
-    : fptr_(fp)
-  { }
-
-  constexpr R operator()(Args ...args) const
-  { return fptr_(static_cast<Args&&>(args)...); }
-};
-
-struct make_overload_t {
-  template <typename ...F,
-    typename Overload = typename overload_t<
-      typename std::decay<F>::type...
-    >::type
-  >
-  constexpr Overload operator()(F&& ...f) const {
-    return Overload(static_cast<F&&>(f)...);
-  }
-};
-#endif // DOXYGEN
-
-} // namespace detail
-
-constexpr detail::make_overload_t overload{};
-
-} // namespace ndn
-
-#endif // BOOST_VERSION >= 106100
-#endif // NDN_CXX_UTIL_OVERLOAD_HPP
diff --git a/ndn-cxx/version.hpp.in b/ndn-cxx/version.hpp.in
index cbd5a63..6a972e0 100644
--- a/ndn-cxx/version.hpp.in
+++ b/ndn-cxx/version.hpp.in
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -19,50 +19,52 @@
  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
  */
 
-#ifndef NDN_VERSION_HPP
-#define NDN_VERSION_HPP
+#ifndef NDN_CXX_VERSION_HPP
+#define NDN_CXX_VERSION_HPP
 
-namespace ndn {
+// ndn-cxx version follows Semantic Versioning 2.0.0
+// https://semver.org/spec/v2.0.0.html
 
-/** ndn-cxx version follows Semantic Versioning 2.0.0 specification
- *  http://semver.org/
- */
-
-/** \brief ndn-cxx version represented as an integer
+/**
+ * \brief ndn-cxx version represented as an integer.
  *
- *  MAJOR*1000000 + MINOR*1000 + PATCH
+ * Equivalent to: #NDN_CXX_VERSION_MAJOR*1000000 + #NDN_CXX_VERSION_MINOR*1000 + #NDN_CXX_VERSION_PATCH
  */
 #define NDN_CXX_VERSION @VERSION@
 
-/** \brief ndn-cxx version represented as a string
+/// The major version of ndn-cxx
+#define NDN_CXX_VERSION_MAJOR @VERSION_MAJOR@
+/// The minor version of ndn-cxx
+#define NDN_CXX_VERSION_MINOR @VERSION_MINOR@
+/// The patch version of ndn-cxx
+#define NDN_CXX_VERSION_PATCH @VERSION_PATCH@
+
+/**
+ * \brief ndn-cxx version represented as a string.
  *
- *  MAJOR.MINOR.PATCH
+ * Format:
+ * @code
+ * MAJOR.MINOR.PATCH
+ * @endcode
  */
 #define NDN_CXX_VERSION_STRING "@VERSION_STRING@"
 
-/** \brief ndn-cxx version string, including git commit information, if ndn-cxx is build from
- *         specific git commit
+/**
+ * \brief ndn-cxx version string, including git commit information if ndn-cxx is built from a
+ *        specific git commit.
  *
- * NDN_CXX_VERSION_BUILD_STRING is obtained using the following command (`ndn-cxx-` prefix is
- * afterwards removed):
+ * #NDN_CXX_VERSION_BUILD_STRING is obtained using the following command (`ndn-cxx-` prefix is
+ * afterwards removed): ``git describe --match 'ndn-cxx-*'``
  *
- *    `git describe --match 'ndn-cxx-*'`
+ * When ndn-cxx is not built from git, #NDN_CXX_VERSION_BUILD_STRING equals #NDN_CXX_VERSION_STRING.
  *
- * When ndn-cxx is built not from git, NDN_CXX_VERSION_BUILD_STRING equals NDN_CXX_VERSION_STRING
- *
+ * Format:
+ * @code
  * MAJOR.MINOR.PATCH(-release-candidate-tag)(-(number-of-commits-since-tag)-COMMIT-HASH)
+ * @endcode
  *
- * Example, 0.1.0-rc1-1-g5c86570
+ * Example: 0.1.0-rc1-1-g5c86570
  */
 #define NDN_CXX_VERSION_BUILD_STRING "@VERSION_BUILD@"
 
-/// MAJOR version
-#define NDN_CXX_VERSION_MAJOR @VERSION_MAJOR@
-/// MINOR version
-#define NDN_CXX_VERSION_MINOR @VERSION_MINOR@
-/// PATCH version
-#define NDN_CXX_VERSION_PATCH @VERSION_PATCH@
-
-} // namespace ndn
-
-#endif // NDN_VERSION_HPP
+#endif // NDN_CXX_VERSION_HPP
diff --git a/tests/unit/util/indented-stream.t.cpp b/tests/unit/util/indented-stream.t.cpp
index f07990a..91da1e3 100644
--- a/tests/unit/util/indented-stream.t.cpp
+++ b/tests/unit/util/indented-stream.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,11 +23,7 @@
 
 #include "tests/boost-test.hpp"
 
-#if BOOST_VERSION >= 105900
 #include <boost/test/tools/output_test_stream.hpp>
-#else
-#include <boost/test/output_test_stream.hpp>
-#endif
 
 namespace ndn {
 namespace util {
diff --git a/tests/unit/util/logging.t.cpp b/tests/unit/util/logging.t.cpp
index 7daa1cd..821e11e 100644
--- a/tests/unit/util/logging.t.cpp
+++ b/tests/unit/util/logging.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -25,11 +25,7 @@
 #include "tests/boost-test.hpp"
 #include "tests/unit/clock-fixture.hpp"
 
-#if BOOST_VERSION >= 105900
 #include <boost/test/tools/output_test_stream.hpp>
-#else
-#include <boost/test/output_test_stream.hpp>
-#endif
 
 namespace ndn {
 namespace util {
diff --git a/tests/unit/util/ostream-joiner.t.cpp b/tests/unit/util/ostream-joiner.t.cpp
index 2eaf2f9..4c617fa 100644
--- a/tests/unit/util/ostream-joiner.t.cpp
+++ b/tests/unit/util/ostream-joiner.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,12 +24,7 @@
 #include "tests/boost-test.hpp"
 
 #include <numeric>
-
-#if BOOST_VERSION >= 105900
 #include <boost/test/tools/output_test_stream.hpp>
-#else
-#include <boost/test/output_test_stream.hpp>
-#endif
 
 namespace ndn {
 namespace tests {
diff --git a/tests/unit/util/string-helper.t.cpp b/tests/unit/util/string-helper.t.cpp
index a129c1a..e3229e5 100644
--- a/tests/unit/util/string-helper.t.cpp
+++ b/tests/unit/util/string-helper.t.cpp
@@ -26,12 +26,7 @@
 
 #include <cctype>
 #include <cstring>
-
-#if BOOST_VERSION >= 105900
 #include <boost/test/tools/output_test_stream.hpp>
-#else
-#include <boost/test/output_test_stream.hpp>
-#endif
 
 namespace ndn {
 namespace util {
diff --git a/tests/unit/version.t.cpp b/tests/unit/version.t.cpp
index a567695..ff3e32a 100644
--- a/tests/unit/version.t.cpp
+++ b/tests/unit/version.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -20,11 +20,10 @@
  */
 
 #include "ndn-cxx/version.hpp"
-#include "ndn-cxx/detail/common.hpp"
 
 #include "tests/boost-test.hpp"
 
-#include <stdio.h>
+#include <cstdio>
 
 namespace ndn {
 namespace tests {
@@ -33,25 +32,28 @@
 
 BOOST_AUTO_TEST_CASE(VersionNumber)
 {
-  BOOST_TEST_MESSAGE("NDN_CXX_VERSION = " + to_string(NDN_CXX_VERSION));
+  BOOST_TEST_MESSAGE("NDN_CXX_VERSION = " << NDN_CXX_VERSION);
 
-  BOOST_CHECK_EQUAL(NDN_CXX_VERSION, NDN_CXX_VERSION_MAJOR * 1000000 +
-                                     NDN_CXX_VERSION_MINOR * 1000 +
-                                     NDN_CXX_VERSION_PATCH);
+  BOOST_TEST(NDN_CXX_VERSION == NDN_CXX_VERSION_MAJOR * 1000000 +
+                                NDN_CXX_VERSION_MINOR * 1000 +
+                                NDN_CXX_VERSION_PATCH);
+
+  static_assert(NDN_CXX_VERSION_MAJOR < 1000, "");
+  static_assert(NDN_CXX_VERSION_MINOR < 1000, "");
+  static_assert(NDN_CXX_VERSION_PATCH < 1000, "");
 }
 
 BOOST_AUTO_TEST_CASE(VersionString)
 {
   BOOST_TEST_MESSAGE("NDN_CXX_VERSION_STRING = " NDN_CXX_VERSION_STRING);
+  BOOST_TEST_MESSAGE("NDN_CXX_VERSION_BUILD_STRING = " NDN_CXX_VERSION_BUILD_STRING);
 
-  BOOST_STATIC_ASSERT(NDN_CXX_VERSION_MAJOR < 1000);
-  BOOST_STATIC_ASSERT(NDN_CXX_VERSION_MINOR < 1000);
-  BOOST_STATIC_ASSERT(NDN_CXX_VERSION_PATCH < 1000);
-  char buf[12];
-  ::snprintf(buf, sizeof(buf), "%d.%d.%d",
-             NDN_CXX_VERSION_MAJOR, NDN_CXX_VERSION_MINOR, NDN_CXX_VERSION_PATCH);
+  char s[12];
+  std::snprintf(s, sizeof(s), "%d.%d.%d",
+                NDN_CXX_VERSION_MAJOR, NDN_CXX_VERSION_MINOR, NDN_CXX_VERSION_PATCH);
 
-  BOOST_CHECK_EQUAL(NDN_CXX_VERSION_STRING, buf);
+  BOOST_TEST(NDN_CXX_VERSION_STRING == s);
+  BOOST_TEST(NDN_CXX_VERSION_BUILD_STRING != "");
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestVersion
diff --git a/tools/ndnsec/accumulator.hpp b/tools/ndnsec/accumulator.hpp
index fb7f357..a696000 100644
--- a/tools/ndnsec/accumulator.hpp
+++ b/tools/ndnsec/accumulator.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,7 +69,7 @@
   std::string
   name() const final
   {
-    return std::string();
+    return {};
   }
 
   // There are no tokens for an AccumulatorType
@@ -134,14 +134,6 @@
       *m_store = *val;
   }
 
-#if (BOOST_VERSION >= 105900) && (BOOST_VERSION < 106500)
-  bool
-  adjacent_tokens_only() const final
-  {
-    return false;
-  }
-#endif // (BOOST_VERSION >= 105900) && (BOOST_VERSION < 106500)
-
 private:
   T* m_store;
   T m_interval;
diff --git a/wscript b/wscript
index f9213f2..e7146d8 100644
--- a/wscript
+++ b/wscript
@@ -126,14 +126,10 @@
         boost_libs.append('unit_test_framework')
 
     conf.check_boost(lib=boost_libs, mt=True)
-    if conf.env.BOOST_VERSION_NUMBER < 105800:
+    if conf.env.BOOST_VERSION_NUMBER < 106501:
         conf.fatal('The minimum supported version of Boost is 1.65.1.\n'
                    'Please upgrade your distribution or manually install a newer version of Boost.\n'
                    'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
-    elif conf.env.BOOST_VERSION_NUMBER < 106501:
-        Logs.warn('WARNING: Using a version of Boost older than 1.65.1 is not officially supported and may not work.\n'
-                  'If you encounter any problems, please upgrade your distribution or manually install a newer version of Boost.\n'
-                  'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
 
     # Workaround for bug 4860
     if conf.env.BOOST_VERSION_NUMBER < 106900 and conf.env.CXX_NAME == 'clang':