Adopt more C++17 features throughout the codebase

Change-Id: I31af421d8a977ba2aae23afcda289ff53230897f
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index 3c55384..60a4aaa 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -28,7 +28,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<Data>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Data>));
 BOOST_CONCEPT_ASSERT((WireDecodable<Data>));
-static_assert(std::is_base_of<tlv::Error, Data::Error>::value,
+static_assert(std::is_convertible_v<Data::Error*, tlv::Error*>,
               "Data::Error must inherit from tlv::Error");
 
 Data::Data(const Name& name)
diff --git a/ndn-cxx/detail/cancel-handle.hpp b/ndn-cxx/detail/cancel-handle.hpp
index ed6629b..a7207a7 100644
--- a/ndn-cxx/detail/cancel-handle.hpp
+++ b/ndn-cxx/detail/cancel-handle.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -57,7 +57,7 @@
 template<typename HandleT>
 class ScopedCancelHandle
 {
-  static_assert(std::is_convertible<HandleT*, CancelHandle*>::value,
+  static_assert(std::is_convertible_v<HandleT*, CancelHandle*>,
                 "HandleT must publicly derive from CancelHandle");
 
 public:
diff --git a/ndn-cxx/detail/tag-host.hpp b/ndn-cxx/detail/tag-host.hpp
index 4e4805f..4bf59a3 100644
--- a/ndn-cxx/detail/tag-host.hpp
+++ b/ndn-cxx/detail/tag-host.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -35,24 +35,28 @@
 class TagHost
 {
 public:
-  /** \brief Get a tag item.
-   *  \tparam T type of the tag, which must be a subclass of ndn::Tag
-   *  \retval nullptr if no Tag of type T is stored
+  /**
+   * \brief Get a tag item.
+   * \tparam T type of the tag, which must be a subclass of ndn::Tag
+   * \retval nullptr if no Tag of type T is stored
    */
   template<typename T>
   shared_ptr<T>
   getTag() const;
 
-  /** \brief Set (add or replace) a tag item.
-   *  \tparam T type of the tag, which must be a subclass of ndn::Tag
-   *  \note Tag can be set even on a const tag host instance
+  /**
+   * \brief Set (add or replace) a tag item.
+   * \tparam T type of the tag, which must be a subclass of ndn::Tag
+   * \note Tag can be set even on a const tag host instance
    */
   template<typename T>
   void
   setTag(shared_ptr<T> tag) const;
 
-  /** \brief Remove a tag item.
-   *  \note Tag can be removed even on a const tag host instance
+  /**
+   * \brief Remove a tag item.
+   * \tparam T type of the tag, which must be a subclass of ndn::Tag
+   * \note Tag can be removed even on a const tag host instance
    */
   template<typename T>
   void
@@ -66,20 +70,19 @@
 shared_ptr<T>
 TagHost::getTag() const
 {
-  static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
+  static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
 
-  auto it = m_tags.find(T::getTypeId());
-  if (it == m_tags.end()) {
-    return nullptr;
+  if (auto it = m_tags.find(T::getTypeId()); it != m_tags.end()) {
+    return static_pointer_cast<T>(it->second);
   }
-  return static_pointer_cast<T>(it->second);
+  return nullptr;
 }
 
 template<typename T>
 void
 TagHost::setTag(shared_ptr<T> tag) const
 {
-  static_assert(std::is_base_of<Tag, T>::value, "T must inherit from Tag");
+  static_assert(std::is_convertible_v<T*, Tag*>, "T must inherit from ndn::Tag");
 
   if (tag == nullptr) {
     m_tags.erase(T::getTypeId());
diff --git a/ndn-cxx/encoding/block-helpers.hpp b/ndn-cxx/encoding/block-helpers.hpp
index 3cda2b1..232c2b3 100644
--- a/ndn-cxx/encoding/block-helpers.hpp
+++ b/ndn-cxx/encoding/block-helpers.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -68,7 +68,7 @@
  *                    represented in R
  */
 template<typename R>
-std::enable_if_t<std::is_integral<R>::value, R>
+std::enable_if_t<std::is_integral_v<R>, R>
 readNonNegativeIntegerAs(const Block& block)
 {
   uint64_t value = readNonNegativeInteger(block);
@@ -87,7 +87,7 @@
  *           function may trigger unspecified behavior.
  */
 template<typename R>
-std::enable_if_t<std::is_enum<R>::value, R>
+std::enable_if_t<std::is_enum_v<R>, R>
 readNonNegativeIntegerAs(const Block& block)
 {
   return static_cast<R>(readNonNegativeIntegerAs<std::underlying_type_t<R>>(block));
@@ -286,8 +286,8 @@
 makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
 {
   using BinaryBlockHelper = std::conditional_t<
-    std::is_base_of<std::random_access_iterator_tag,
-                    typename std::iterator_traits<Iterator>::iterator_category>::value,
+    std::is_base_of_v<std::random_access_iterator_tag,
+                      typename std::iterator_traits<Iterator>::iterator_category>,
     detail::BinaryBlockFast<Iterator>,
     detail::BinaryBlockSlow<Iterator>>;
 
diff --git a/ndn-cxx/encoding/block.cpp b/ndn-cxx/encoding/block.cpp
index 6c525c5..d2a4161 100644
--- a/ndn-cxx/encoding/block.cpp
+++ b/ndn-cxx/encoding/block.cpp
@@ -170,22 +170,22 @@
   uint32_t type = 0;
   bool isOk = tlv::readType(pos, end, type);
   if (!isOk) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
 
   uint64_t length = 0;
   isOk = tlv::readVarNumber(pos, end, length);
   if (!isOk) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
   // pos now points to TLV-VALUE
 
   BOOST_ASSERT(pos <= end);
   if (length > static_cast<uint64_t>(std::distance(pos, end))) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
 
-  return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
+  return {true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length)};
 }
 
 std::tuple<bool, Block>
@@ -197,25 +197,24 @@
   uint32_t type = 0;
   bool isOk = tlv::readType(pos, end, type);
   if (!isOk) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
   uint64_t length = 0;
   isOk = tlv::readVarNumber(pos, end, length);
   if (!isOk) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
   // pos now points to TLV-VALUE
 
   BOOST_ASSERT(pos <= end);
   if (length > static_cast<uint64_t>(std::distance(pos, end))) {
-    return std::make_tuple(false, Block());
+    return {false, {}};
   }
   std::advance(pos, length);
   // pos now points to the end of the TLV
 
   auto b = std::make_shared<Buffer>(buffer.begin(), pos);
-  return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
-                                     std::prev(b->end(), length), b->end()));
+  return {true, Block(b, type, b->begin(), b->end(), std::prev(b->end(), length), b->end())};
 }
 
 Block
@@ -413,13 +412,12 @@
 const Block&
 Block::get(uint32_t type) const
 {
-  auto it = this->find(type);
-  if (it != m_elements.end()) {
+  if (auto it = find(type); it != m_elements.end()) {
     return *it;
   }
 
-  NDN_THROW(Error("No sub-element of type " + to_string(type) +
-                  " found in block of type " + to_string(m_type)));
+  NDN_THROW(Error("No sub-element of type " + std::to_string(type) +
+                  " found in block of type " + std::to_string(m_type)));
 }
 
 Block::element_const_iterator
diff --git a/ndn-cxx/encoding/encoder.hpp b/ndn-cxx/encoding/encoder.hpp
index 82b5ea3..7b4e2d8 100644
--- a/ndn-cxx/encoding/encoder.hpp
+++ b/ndn-cxx/encoding/encoder.hpp
@@ -253,7 +253,7 @@
 Encoder::prependRange(Iterator first, Iterator last)
 {
   using ValueType = typename std::iterator_traits<Iterator>::value_type;
-  static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
+  static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>, "");
 
   size_t length = std::distance(first, last);
   reserveFront(length);
@@ -268,7 +268,7 @@
 Encoder::appendRange(Iterator first, Iterator last)
 {
   using ValueType = typename std::iterator_traits<Iterator>::value_type;
-  static_assert(sizeof(ValueType) == 1 && !std::is_same<ValueType, bool>::value, "");
+  static_assert(sizeof(ValueType) == 1 && !std::is_same_v<ValueType, bool>, "");
 
   size_t length = std::distance(first, last);
   reserveBack(length);
diff --git a/ndn-cxx/encoding/nfd-constants.cpp b/ndn-cxx/encoding/nfd-constants.cpp
index 43770a9..1840c36 100644
--- a/ndn-cxx/encoding/nfd-constants.cpp
+++ b/ndn-cxx/encoding/nfd-constants.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -182,11 +182,7 @@
   };
 
   auto join = make_ostream_joiner(os, '|');
-  for (const auto& pair : knownBits) {
-    RouteFlags bit = ROUTE_FLAGS_NONE;
-    std::string token;
-    std::tie(bit, token) = pair;
-
+  for (const auto& [bit, token] : knownBits) {
     if ((routeFlags & bit) != 0) {
       join = token;
       routeFlags = static_cast<RouteFlags>(routeFlags & ~bit);
diff --git a/ndn-cxx/encoding/tlv.hpp b/ndn-cxx/encoding/tlv.hpp
index be0fbfa..6480538 100644
--- a/ndn-cxx/encoding/tlv.hpp
+++ b/ndn-cxx/encoding/tlv.hpp
@@ -358,11 +358,11 @@
 constexpr bool
 shouldSelectContiguousReadNumber()
 {
-  return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
-          std::is_convertible<DecayedIterator, typename std::basic_string<ValueType>::const_iterator>::value ||
-          std::is_convertible<DecayedIterator, typename std::vector<ValueType>::const_iterator>::value) &&
+  return (std::is_convertible_v<DecayedIterator, const ValueType*> ||
+          std::is_convertible_v<DecayedIterator, typename std::basic_string<ValueType>::const_iterator> ||
+          std::is_convertible_v<DecayedIterator, typename std::vector<ValueType>::const_iterator>) &&
          sizeof(ValueType) == 1 &&
-         !std::is_same<ValueType, bool>::value;
+         !std::is_same_v<ValueType, bool>;
 }
 
 template<typename Iterator>
diff --git a/ndn-cxx/impl/name-component-types.hpp b/ndn-cxx/impl/name-component-types.hpp
index 8f88a97..ca2a0ac 100644
--- a/ndn-cxx/impl/name-component-types.hpp
+++ b/ndn-cxx/impl/name-component-types.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -33,7 +33,8 @@
 namespace name {
 namespace {
 
-/** \brief Declare rules for a NameComponent type.
+/**
+ * \brief Declare rules for a NameComponent type.
  */
 class ComponentType : noncopyable
 {
@@ -43,7 +44,8 @@
   virtual
   ~ComponentType() = default;
 
-  /** \brief Throw Component::Error if \p comp is invalid.
+  /**
+   * \brief Throw Component::Error if \p comp is invalid.
    */
   virtual void
   check(const Component& comp) const
@@ -91,7 +93,7 @@
    *  \pre getAltUriPrefix() != nullptr
    */
   virtual Component
-  parseAltUriValue(const std::string&) const
+  parseAltUriValue(const std::string& input) const
   {
     NDN_CXX_UNREACHABLE;
   }
@@ -153,10 +155,11 @@
   }
 };
 
-/** \brief Rules for GenericNameComponent.
+/**
+ * \brief Rules for GenericNameComponent.
  *
- *  GenericNameComponent has an alternate URI representation that omits the `<type-number>` prefix.
- *  This must be special-cased in the caller, and is not handled by this class.
+ * GenericNameComponent has an alternate URI representation that omits the `<type-number>` prefix.
+ * This must be special-cased in the caller, and is not handled by this class.
  */
 class GenericNameComponentType final : public ComponentType
 {
@@ -168,8 +171,9 @@
   }
 };
 
-/** \brief Rules for a component type holding a SHA256 digest value, written as
- *         a hex string in URI representation.
+/**
+ * \brief Rules for a component type holding a SHA256 digest value, written as
+ *        a hex string in URI representation.
  */
 class Sha256ComponentType final : public ComponentType
 {
@@ -193,9 +197,7 @@
   std::tuple<bool, Component>
   getSuccessor(const Component& comp) const final
   {
-    bool isExtended = false;
-    Block successor;
-    std::tie(isExtended, successor) = getSuccessorImpl(comp);
+    auto [isExtended, successor] = getSuccessorImpl(comp);
     return {isExtended, isExtended ? comp : Component(successor)};
   }
 
@@ -238,8 +240,9 @@
   const std::string m_uriPrefix;
 };
 
-/** \brief Rules for a component type holding a NonNegativeInteger value, written as
- *         a decimal number in URI representation.
+/**
+ * \brief Rules for a component type holding a NonNegativeInteger value, written as
+ *        a decimal number in URI representation.
  */
 class DecimalComponentType final : public ComponentType
 {
@@ -324,11 +327,10 @@
   const ComponentType*
   findByUriPrefix(const std::string& prefix) const
   {
-    auto it = m_uriPrefixes.find(prefix);
-    if (it == m_uriPrefixes.end()) {
-      return nullptr;
+    if (auto it = m_uriPrefixes.find(prefix); it != m_uriPrefixes.end()) {
+      return it->second;
     }
-    return it->second;
+    return nullptr;
   }
 
 private:
diff --git a/ndn-cxx/impl/record-container.hpp b/ndn-cxx/impl/record-container.hpp
index 12fff0d..791b0a2 100644
--- a/ndn-cxx/impl/record-container.hpp
+++ b/ndn-cxx/impl/record-container.hpp
@@ -23,7 +23,7 @@
 #define NDN_CXX_IMPL_RECORD_CONTAINER_HPP
 
 #include "ndn-cxx/detail/common.hpp"
-#include "ndn-cxx/util/signal.hpp"
+#include "ndn-cxx/util/signal/signal.hpp"
 
 #include <atomic>
 
@@ -77,30 +77,30 @@
   using Record = T;
   using Container = std::map<RecordId, Record>;
 
-  /** \brief Retrieve record by ID.
+  /**
+   * \brief Retrieve record by ID.
    */
   Record*
   get(RecordId id)
   {
-    auto i = m_container.find(id);
-    if (i == m_container.end()) {
-      return nullptr;
+    if (auto it = m_container.find(id); it != m_container.end()) {
+      return &it->second;
     }
-    return &i->second;
+    return nullptr;
   }
 
-  /** \brief Insert a record with given ID.
+  /**
+   * \brief Insert a record with given ID.
    */
   template<typename ...TArgs>
   Record&
   put(RecordId id, TArgs&&... args)
   {
     BOOST_ASSERT(id != 0);
-    auto it = m_container.emplace(std::piecewise_construct, std::forward_as_tuple(id),
-                                  std::forward_as_tuple(std::forward<decltype(args)>(args)...));
-    BOOST_ASSERT(it.second);
+    auto [it, isNew] = m_container.try_emplace(id, std::forward<decltype(args)>(args)...);
+    BOOST_VERIFY(isNew);
 
-    Record& record = it.first->second;
+    Record& record = it->second;
     record.m_container = this;
     record.m_id = id;
     return record;
@@ -112,7 +112,8 @@
     return ++m_lastId;
   }
 
-  /** \brief Insert a record with newly assigned ID.
+  /**
+   * \brief Insert a record with newly assigned ID.
    */
   template<typename ...TArgs>
   Record&
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index ad6c5c0..a7f919a 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -38,7 +38,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<Interest>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Interest>));
 BOOST_CONCEPT_ASSERT((WireDecodable<Interest>));
-static_assert(std::is_base_of<tlv::Error, Interest::Error>::value,
+static_assert(std::is_convertible_v<Interest::Error*, tlv::Error*>,
               "Interest::Error must inherit from tlv::Error");
 
 bool Interest::s_autoCheckParametersDigest = true;
diff --git a/ndn-cxx/key-locator.cpp b/ndn-cxx/key-locator.cpp
index 28ca7fe..c094c0c 100644
--- a/ndn-cxx/key-locator.cpp
+++ b/ndn-cxx/key-locator.cpp
@@ -31,7 +31,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
 BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
-static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
+static_assert(std::is_convertible_v<KeyLocator::Error*, tlv::Error*>,
               "KeyLocator::Error must inherit from tlv::Error");
 
 constexpr size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW = 8;
diff --git a/ndn-cxx/link.cpp b/ndn-cxx/link.cpp
index c1ac3fb..568f0fd 100644
--- a/ndn-cxx/link.cpp
+++ b/ndn-cxx/link.cpp
@@ -29,7 +29,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<Link>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Link>));
 BOOST_CONCEPT_ASSERT((WireDecodable<Link>));
-static_assert(std::is_base_of<Data::Error, Link::Error>::value,
+static_assert(std::is_convertible_v<Link::Error*, Data::Error*>,
               "Link::Error should inherit from Data::Error");
 
 Link::Link() = default;
diff --git a/ndn-cxx/lp/field-decl.hpp b/ndn-cxx/lp/field-decl.hpp
index 245859f..3cbdb09 100644
--- a/ndn-cxx/lp/field-decl.hpp
+++ b/ndn-cxx/lp/field-decl.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -35,7 +35,8 @@
 namespace ndn {
 namespace lp {
 
-/** \brief Indicate a uint64_t field shall be decoded and encoded as a non-negative integer.
+/**
+ * \brief Indicates that a `uint64_t` field shall be decoded and encoded as a non-negative integer.
  */
 struct NonNegativeIntegerTag;
 
@@ -176,10 +177,10 @@
 class FieldDecl
 {
 public:
-  typedef LOCATION FieldLocation;
-  typedef VALUE ValueType;
-  typedef std::integral_constant<uint64_t, TYPE> TlvType;
-  typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
+  using FieldLocation = LOCATION;
+  using ValueType = VALUE;
+  using TlvType = std::integral_constant<uint64_t, TYPE>;
+  using IsRepeatable = std::bool_constant<REPEATABLE>;
 
   /** \brief Decode a field.
    *  \param wire an element with top-level TLV-TYPE \c TlvType::value.
diff --git a/ndn-cxx/lp/field.hpp b/ndn-cxx/lp/field.hpp
index abe40a1..e1d2164 100644
--- a/ndn-cxx/lp/field.hpp
+++ b/ndn-cxx/lp/field.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -60,11 +60,11 @@
 template<class X>
 struct Field
 {
-  static_assert(std::is_base_of<field_location_tags::Base, typename X::FieldLocation>::value, "");
-  static_assert(std::is_same<typename X::TlvType::value_type, uint64_t>::value, "");
-  static_assert(std::is_same<typename X::IsRepeatable::value_type, bool>::value, "");
-  static_assert(std::is_default_constructible<typename X::ValueType>::value, "");
-  static_assert(std::is_copy_constructible<typename X::ValueType>::value, "");
+  static_assert(std::is_base_of_v<field_location_tags::Base, typename X::FieldLocation>, "");
+  static_assert(std::is_same_v<typename X::TlvType::value_type, uint64_t>, "");
+  static_assert(std::is_same_v<typename X::IsRepeatable::value_type, bool>, "");
+  static_assert(std::is_default_constructible_v<typename X::ValueType>, "");
+  static_assert(std::is_copy_constructible_v<typename X::ValueType>, "");
   BOOST_CONCEPT_USAGE(Field)
   {
     Block wire;
diff --git a/ndn-cxx/lp/sequence.hpp b/ndn-cxx/lp/sequence.hpp
index b6dfddd..4b662dd 100644
--- a/ndn-cxx/lp/sequence.hpp
+++ b/ndn-cxx/lp/sequence.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,7 +24,7 @@
 #ifndef NDN_CXX_LP_SEQUENCE_HPP
 #define NDN_CXX_LP_SEQUENCE_HPP
 
-#include "ndn-cxx/detail/common.hpp"
+#include <cstdint>
 
 namespace ndn {
 namespace lp {
@@ -32,7 +32,7 @@
 /**
  * \brief Represents a sequence number.
  */
-typedef uint64_t Sequence;
+using Sequence = uint64_t;
 
 } // namespace lp
 } // namespace ndn
diff --git a/ndn-cxx/meta-info.cpp b/ndn-cxx/meta-info.cpp
index 2fde11e..338da33 100644
--- a/ndn-cxx/meta-info.cpp
+++ b/ndn-cxx/meta-info.cpp
@@ -30,7 +30,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<MetaInfo>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<MetaInfo>));
 BOOST_CONCEPT_ASSERT((WireDecodable<MetaInfo>));
-static_assert(std::is_base_of<tlv::Error, MetaInfo::Error>::value,
+static_assert(std::is_convertible_v<MetaInfo::Error*, tlv::Error*>,
               "MetaInfo::Error must inherit from tlv::Error");
 
 MetaInfo::MetaInfo()
diff --git a/ndn-cxx/metadata-object.cpp b/ndn-cxx/metadata-object.cpp
index 46c67d3..69db187 100644
--- a/ndn-cxx/metadata-object.cpp
+++ b/ndn-cxx/metadata-object.cpp
@@ -25,7 +25,7 @@
 
 namespace ndn {
 
-static_assert(std::is_base_of<tlv::Error, MetadataObject::Error>::value,
+static_assert(std::is_convertible_v<MetadataObject::Error*, tlv::Error*>,
               "MetadataObject::Error must inherit from tlv::Error");
 
 MetadataObject::MetadataObject() = default;
diff --git a/ndn-cxx/mgmt/control-response.cpp b/ndn-cxx/mgmt/control-response.cpp
index d0abdaf..5a18f48 100644
--- a/ndn-cxx/mgmt/control-response.cpp
+++ b/ndn-cxx/mgmt/control-response.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -29,7 +29,7 @@
 // BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlResponse>));
 BOOST_CONCEPT_ASSERT((WireEncodable<ControlResponse>));
 BOOST_CONCEPT_ASSERT((WireDecodable<ControlResponse>));
-static_assert(std::is_base_of<tlv::Error, ControlResponse::Error>::value,
+static_assert(std::is_convertible_v<ControlResponse::Error*, tlv::Error*>,
               "ControlResponse::Error must inherit from tlv::Error");
 
 ControlResponse::ControlResponse()
diff --git a/ndn-cxx/mgmt/dispatcher.hpp b/ndn-cxx/mgmt/dispatcher.hpp
index d0c88ef..3cc9092 100644
--- a/ndn-cxx/mgmt/dispatcher.hpp
+++ b/ndn-cxx/mgmt/dispatcher.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -42,25 +42,29 @@
  *                   the Authorization function; this value is intended for logging only,
  *                   and should not affect how the request is processed
  */
-typedef std::function<void(const std::string& requester)> AcceptContinuation;
+using AcceptContinuation = std::function<void(const std::string& requester)>;
 
-/** \brief Indicate how to reply in case authorization is rejected.
+/**
+ * \brief Indicates how to reply in case authorization is rejected.
  */
 enum class RejectReply {
-  /** \brief Do not reply.
+  /**
+   * \brief Do not reply.
    */
   SILENT,
-  /** \brief Reply with a ControlResponse where StatusCode is 403.
+  /**
+   * \brief Reply with a ControlResponse where StatusCode is 403.
    */
   STATUS403
 };
 
-/** \brief A function to be called if authorization is rejected.
+/**
+ * \brief A function to be called if authorization is rejected.
  */
-typedef std::function<void(RejectReply reply)> RejectContinuation;
+using RejectContinuation = std::function<void(RejectReply)>;
 
 /** \brief A function that performs authorization.
- *  \param prefix top-level prefix, e.g., "/localhost/nfd";
+ *  \param prefix top-level prefix, e.g., `/localhost/nfd`;
  *                This argument can be inspected to allow Interests only under a subset of
  *                top-level prefixes (e.g., allow "/localhost/nfd" only),
  *                or to use different trust model regarding to the prefix.
@@ -69,14 +73,15 @@
  *                This is guaranteed to be not-null and have correct type for the command,
  *                but may not be valid (e.g., can have missing fields).
  *
- *  Either accept or reject must be called after authorization completes.
+ *  Either \p accept or \p reject must be called after authorization completes.
  */
-typedef std::function<void(const Name& prefix, const Interest& interest,
-                           const ControlParameters* params,
-                           const AcceptContinuation& accept,
-                           const RejectContinuation& reject)> Authorization;
+using Authorization = std::function<void(const Name& prefix, const Interest& interest,
+                                         const ControlParameters* params,
+                                         const AcceptContinuation& accept,
+                                         const RejectContinuation& reject)>;
 
-/** \brief Return an Authorization that accepts all Interests, with empty string as requester.
+/**
+ * \brief Return an Authorization that accepts all Interests, with empty string as requester.
  */
 Authorization
 makeAcceptAllAuthorization();
@@ -87,12 +92,12 @@
  *  \param params parsed ControlParameters;
  *                This is guaranteed to have correct type for the command.
  */
-typedef std::function<bool(const ControlParameters& params)> ValidateParameters;
+using ValidateParameters = std::function<bool(const ControlParameters& params)>;
 
 /** \brief A function to be called after ControlCommandHandler completes.
  *  \param resp the response to be sent to requester
  */
-typedef std::function<void(const ControlResponse& resp)> CommandContinuation;
+using CommandContinuation = std::function<void(const ControlResponse& resp)>;
 
 /** \brief A function to handle an authorized ControlCommand.
  *  \param prefix top-level prefix, e.g., "/localhost/nfd";
@@ -101,9 +106,9 @@
  *                This is guaranteed to have correct type for the command,
  *                and is valid (e.g., has all required fields).
  */
-typedef std::function<void(const Name& prefix, const Interest& interest,
-                           const ControlParameters& params,
-                           const CommandContinuation& done)> ControlCommandHandler;
+using ControlCommandHandler = std::function<void(const Name& prefix, const Interest& interest,
+                                                 const ControlParameters& params,
+                                                 const CommandContinuation& done)>;
 
 // ---- STATUS DATASET ----
 
@@ -114,18 +119,20 @@
  *  This function can generate zero or more blocks and pass them to \p append,
  *  and must call \p end upon completion.
  */
-typedef std::function<void(const Name& prefix, const Interest& interest,
-                           StatusDatasetContext& context)> StatusDatasetHandler;
+using StatusDatasetHandler = std::function<void(const Name& prefix, const Interest& interest,
+                                                StatusDatasetContext& context)>;
 
 //---- NOTIFICATION STREAM ----
 
-/** \brief A function to post a notification.
+/**
+ * \brief A function to post a notification.
  */
-typedef std::function<void(const Block& notification)> PostNotification;
+using PostNotification = std::function<void(const Block& notification)>;
 
 // ---- DISPATCHER ----
 
-/** \brief Implements a request dispatcher on server side of NFD Management protocol.
+/**
+ * \brief Implements a request dispatcher on server side of NFD Management protocol.
  */
 class Dispatcher : noncopyable
 {
diff --git a/ndn-cxx/mgmt/nfd/control-parameters.cpp b/ndn-cxx/mgmt/nfd/control-parameters.cpp
index 6c8f091..1734272 100644
--- a/ndn-cxx/mgmt/nfd/control-parameters.cpp
+++ b/ndn-cxx/mgmt/nfd/control-parameters.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -31,7 +31,7 @@
 //BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlParameters>));
 BOOST_CONCEPT_ASSERT((WireEncodable<ControlParameters>));
 BOOST_CONCEPT_ASSERT((WireDecodable<ControlParameters>));
-static_assert(std::is_base_of<tlv::Error, ControlParameters::Error>::value,
+static_assert(std::is_convertible_v<ControlParameters::Error*, tlv::Error*>,
               "ControlParameters::Error must inherit from tlv::Error");
 
 ControlParameters::ControlParameters()
diff --git a/ndn-cxx/mgmt/nfd/controller.cpp b/ndn-cxx/mgmt/nfd/controller.cpp
index d1c2489..9698ada 100644
--- a/ndn-cxx/mgmt/nfd/controller.cpp
+++ b/ndn-cxx/mgmt/nfd/controller.cpp
@@ -48,8 +48,8 @@
 void
 Controller::startCommand(const shared_ptr<ControlCommand>& command,
                          const ControlParameters& parameters,
-                         const CommandSucceedCallback& onSuccess,
-                         const CommandFailCallback& onFailure,
+                         const CommandSuccessCallback& onSuccess,
+                         const CommandFailureCallback& onFailure,
                          const CommandOptions& options)
 {
   Interest interest;
@@ -75,8 +75,8 @@
 void
 Controller::processCommandResponse(const Data& data,
                                    const shared_ptr<ControlCommand>& command,
-                                   const CommandSucceedCallback& onSuccess,
-                                   const CommandFailCallback& onFailure)
+                                   const CommandSuccessCallback& onSuccess,
+                                   const CommandFailureCallback& onFailure)
 {
   m_validator.validate(data,
     [=] (const Data& data) {
@@ -92,8 +92,8 @@
 void
 Controller::processValidatedCommandResponse(const Data& data,
                                             const shared_ptr<ControlCommand>& command,
-                                            const CommandSucceedCallback& onSuccess,
-                                            const CommandFailCallback& onFailure)
+                                            const CommandSuccessCallback& onSuccess,
+                                            const CommandFailureCallback& onFailure)
 {
   ControlResponse response;
   try {
@@ -138,7 +138,7 @@
 void
 Controller::fetchDataset(const Name& prefix,
                          const std::function<void(ConstBufferPtr)>& processResponse,
-                         const DatasetFailCallback& onFailure,
+                         const DatasetFailureCallback& onFailure,
                          const CommandOptions& options)
 {
   SegmentFetcher::Options fetcherOptions;
@@ -160,7 +160,7 @@
 }
 
 void
-Controller::processDatasetFetchError(const DatasetFailCallback& onFailure,
+Controller::processDatasetFetchError(const DatasetFailureCallback& onFailure,
                                      uint32_t code, std::string msg)
 {
   BOOST_ASSERT(onFailure);
diff --git a/ndn-cxx/mgmt/nfd/controller.hpp b/ndn-cxx/mgmt/nfd/controller.hpp
index 7fdeb55..3671182 100644
--- a/ndn-cxx/mgmt/nfd/controller.hpp
+++ b/ndn-cxx/mgmt/nfd/controller.hpp
@@ -53,17 +53,26 @@
   /**
    * \brief Callback on command success.
    */
-  using CommandSucceedCallback = std::function<void(const ControlParameters&)>;
+  using CommandSuccessCallback = std::function<void(const ControlParameters&)>;
 
   /**
    * \brief Callback on command failure.
    */
-  using CommandFailCallback = std::function<void(const ControlResponse&)>;
+  using CommandFailureCallback = std::function<void(const ControlResponse&)>;
+  using CommandFailCallback = CommandFailureCallback; // backward compat
+
+  /**
+   * \brief Callback on dataset retrieval success.
+   */
+  template<typename Dataset>
+  using DatasetSuccessCallback = std::function<void(const std::invoke_result_t<decltype(&Dataset::parseResult),
+                                                                               Dataset, ConstBufferPtr>&)>;
 
   /**
    * \brief Callback on dataset retrieval failure.
    */
-  using DatasetFailCallback = std::function<void(uint32_t code, const std::string& reason)>;
+  using DatasetFailureCallback = std::function<void(uint32_t code, const std::string& reason)>;
+  using DatasetFailCallback = DatasetFailureCallback; // backward compat
 
   /**
    * \brief Construct a Controller that uses \p face as transport and \p keyChain to sign commands.
@@ -79,80 +88,74 @@
   template<typename Command>
   void
   start(const ControlParameters& parameters,
-        const CommandSucceedCallback& onSuccess,
-        const CommandFailCallback& onFailure,
+        const CommandSuccessCallback& onSuccess,
+        const CommandFailureCallback& onFailure,
         const CommandOptions& options = CommandOptions())
   {
-    startCommand(make_shared<Command>(), parameters, onSuccess, onFailure, options);
+    startCommand(std::make_shared<Command>(), parameters, onSuccess, onFailure, options);
   }
 
   /**
    * \brief Start dataset fetching.
    */
   template<typename Dataset>
-  std::enable_if_t<std::is_default_constructible<Dataset>::value>
-  fetch(const std::function<void(typename Dataset::ResultType)>& onSuccess,
-        const DatasetFailCallback& onFailure,
+  std::enable_if_t<std::is_default_constructible_v<Dataset>>
+  fetch(const DatasetSuccessCallback<Dataset>& onSuccess,
+        const DatasetFailureCallback& onFailure,
         const CommandOptions& options = CommandOptions())
   {
-    fetchDataset(make_shared<Dataset>(), onSuccess, onFailure, options);
+    fetchDataset(std::make_shared<Dataset>(), onSuccess, onFailure, options);
   }
 
   /**
    * \brief Start dataset fetching.
    */
-  template<typename Dataset, typename ParamType = typename Dataset::ParamType>
+  template<typename Dataset, typename ParamType>
   void
-  fetch(const ParamType& param,
-        const std::function<void(typename Dataset::ResultType)>& onSuccess,
-        const DatasetFailCallback& onFailure,
+  fetch(ParamType&& param,
+        const DatasetSuccessCallback<Dataset>& onSuccess,
+        const DatasetFailureCallback& onFailure,
         const CommandOptions& options = CommandOptions())
   {
-    fetchDataset(make_shared<Dataset>(param), onSuccess, onFailure, options);
+    fetchDataset(std::make_shared<Dataset>(std::forward<ParamType>(param)),
+                 onSuccess, onFailure, options);
   }
 
 private:
   void
   startCommand(const shared_ptr<ControlCommand>& command,
                const ControlParameters& parameters,
-               const CommandSucceedCallback& onSuccess,
-               const CommandFailCallback& onFailure,
+               const CommandSuccessCallback& onSuccess,
+               const CommandFailureCallback& onFailure,
                const CommandOptions& options);
 
   void
   processCommandResponse(const Data& data,
                          const shared_ptr<ControlCommand>& command,
-                         const CommandSucceedCallback& onSuccess,
-                         const CommandFailCallback& onFailure);
+                         const CommandSuccessCallback& onSuccess,
+                         const CommandFailureCallback& onFailure);
 
   void
   processValidatedCommandResponse(const Data& data,
                                   const shared_ptr<ControlCommand>& command,
-                                  const CommandSucceedCallback& onSuccess,
-                                  const CommandFailCallback& onFailure);
+                                  const CommandSuccessCallback& onSuccess,
+                                  const CommandFailureCallback& onFailure);
 
   template<typename Dataset>
   void
   fetchDataset(shared_ptr<Dataset> dataset,
-               const std::function<void(typename Dataset::ResultType)>& onSuccess,
-               const DatasetFailCallback& onFailure,
+               const DatasetSuccessCallback<Dataset>& onSuccess,
+               const DatasetFailureCallback& onFailure,
                const CommandOptions& options);
 
   void
   fetchDataset(const Name& prefix,
                const std::function<void(ConstBufferPtr)>& processResponse,
-               const DatasetFailCallback& onFailure,
+               const DatasetFailureCallback& onFailure,
                const CommandOptions& options);
 
-  template<typename Dataset>
   void
-  processDatasetResponse(shared_ptr<Dataset> dataset,
-                         const std::function<void(typename Dataset::ResultType)>& onSuccess,
-                         const DatasetFailCallback& onFailure,
-                         ConstBufferPtr payload);
-
-  void
-  processDatasetFetchError(const DatasetFailCallback& onFailure, uint32_t code, std::string msg);
+  processDatasetFetchError(const DatasetFailureCallback& onFailure, uint32_t code, std::string msg);
 
 public:
   /// Error code for timeout.
@@ -183,40 +186,28 @@
 template<typename Dataset>
 void
 Controller::fetchDataset(shared_ptr<Dataset> dataset,
-                         const std::function<void(typename Dataset::ResultType)>& onSuccess,
-                         const DatasetFailCallback& onFailure,
+                         const DatasetSuccessCallback<Dataset>& onSuccess,
+                         const DatasetFailureCallback& onFailure,
                          const CommandOptions& options)
 {
   Name prefix = dataset->getDatasetPrefix(options.getPrefix());
   fetchDataset(prefix,
-    [=, d = std::move(dataset)] (ConstBufferPtr p) {
-      processDatasetResponse(std::move(d), onSuccess, onFailure, std::move(p));
+    [dataset = std::move(dataset), onSuccess, onFailure] (ConstBufferPtr payload) {
+      std::invoke_result_t<decltype(&Dataset::parseResult), Dataset, ConstBufferPtr> result;
+      try {
+        result = dataset->parseResult(std::move(payload));
+      }
+      catch (const tlv::Error& e) {
+        if (onFailure)
+          onFailure(ERROR_SERVER, e.what());
+        return;
+      }
+      if (onSuccess)
+        onSuccess(result);
     },
     onFailure, options);
 }
 
-template<typename Dataset>
-void
-Controller::processDatasetResponse(shared_ptr<Dataset> dataset,
-                                   const std::function<void(typename Dataset::ResultType)>& onSuccess,
-                                   const DatasetFailCallback& onFailure,
-                                   ConstBufferPtr payload)
-{
-  typename Dataset::ResultType result;
-
-  try {
-    result = dataset->parseResult(std::move(payload));
-  }
-  catch (const tlv::Error& e) {
-    if (onFailure)
-      onFailure(ERROR_SERVER, e.what());
-    return;
-  }
-
-  if (onSuccess)
-    onSuccess(result);
-}
-
 } // namespace nfd
 } // namespace ndn
 
diff --git a/ndn-cxx/mgmt/nfd/face-query-filter.cpp b/ndn-cxx/mgmt/nfd/face-query-filter.cpp
index 39264fa..ef4158a 100644
--- a/ndn-cxx/mgmt/nfd/face-query-filter.cpp
+++ b/ndn-cxx/mgmt/nfd/face-query-filter.cpp
@@ -30,7 +30,7 @@
 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FaceQueryFilter>));
 BOOST_CONCEPT_ASSERT((WireEncodable<FaceQueryFilter>));
 BOOST_CONCEPT_ASSERT((WireDecodable<FaceQueryFilter>));
-static_assert(std::is_base_of<tlv::Error, FaceQueryFilter::Error>::value,
+static_assert(std::is_convertible_v<FaceQueryFilter::Error*, tlv::Error*>,
               "FaceQueryFilter::Error must inherit from tlv::Error");
 
 FaceQueryFilter::FaceQueryFilter() = default;
diff --git a/ndn-cxx/mgmt/nfd/status-dataset.cpp b/ndn-cxx/mgmt/nfd/status-dataset.cpp
index 54d638f..f9d801a 100644
--- a/ndn-cxx/mgmt/nfd/status-dataset.cpp
+++ b/ndn-cxx/mgmt/nfd/status-dataset.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -63,9 +63,7 @@
 
   size_t offset = 0;
   while (offset < payload->size()) {
-    bool isOk = false;
-    Block block;
-    std::tie(isOk, block) = Block::fromBuffer(payload, offset);
+    auto [isOk, block] = Block::fromBuffer(payload, offset);
     if (!isOk) {
       NDN_THROW(StatusDataset::ParseResultError("cannot decode Block"));
     }
@@ -82,7 +80,7 @@
 {
 }
 
-ForwarderGeneralStatusDataset::ResultType
+ForwarderStatus
 ForwarderGeneralStatusDataset::parseResult(ConstBufferPtr payload) const
 {
   return ForwarderStatus(Block(tlv::Content, std::move(payload)));
@@ -93,7 +91,7 @@
 {
 }
 
-FaceDatasetBase::ResultType
+std::vector<FaceStatus>
 FaceDatasetBase::parseResult(ConstBufferPtr payload) const
 {
   return parseDatasetVector<FaceStatus>(payload);
@@ -121,7 +119,7 @@
 {
 }
 
-ChannelDataset::ResultType
+std::vector<ChannelStatus>
 ChannelDataset::parseResult(ConstBufferPtr payload) const
 {
   return parseDatasetVector<ChannelStatus>(payload);
@@ -132,7 +130,7 @@
 {
 }
 
-FibDataset::ResultType
+std::vector<FibEntry>
 FibDataset::parseResult(ConstBufferPtr payload) const
 {
   return parseDatasetVector<FibEntry>(payload);
@@ -143,7 +141,7 @@
 {
 }
 
-CsInfoDataset::ResultType
+CsInfo
 CsInfoDataset::parseResult(ConstBufferPtr payload) const
 {
   return CsInfo(Block(payload));
@@ -154,7 +152,7 @@
 {
 }
 
-StrategyChoiceDataset::ResultType
+std::vector<StrategyChoice>
 StrategyChoiceDataset::parseResult(ConstBufferPtr payload) const
 {
   return parseDatasetVector<StrategyChoice>(payload);
@@ -165,7 +163,7 @@
 {
 }
 
-RibDataset::ResultType
+std::vector<RibEntry>
 RibDataset::parseResult(ConstBufferPtr payload) const
 {
   return parseDatasetVector<RibEntry>(payload);
diff --git a/ndn-cxx/mgmt/nfd/status-dataset.hpp b/ndn-cxx/mgmt/nfd/status-dataset.hpp
index 24ac0a8..4fd0681 100644
--- a/ndn-cxx/mgmt/nfd/status-dataset.hpp
+++ b/ndn-cxx/mgmt/nfd/status-dataset.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -46,31 +46,17 @@
   virtual
   ~StatusDataset();
 
-#ifdef DOXYGEN
-  /**
-   * \brief If defined, specifies constructor argument type;
-   *        otherwise, the constructor has no arguments.
-   */
-  using ParamType = int;
-#endif
-
   /**
    * \brief Constructs a name prefix for the dataset.
-   * \param prefix top-level prefix, such as ndn:/localhost/nfd
+   * \param prefix Top-level prefix, such as `/localhost/nfd`.
    * \return %Name prefix without version and segment components.
    */
   Name
   getDatasetPrefix(const Name& prefix) const;
 
-#ifdef DOXYGEN
   /**
-   * \brief Specifies the result type, usually a vector.
-   */
-  using ResultType = std::vector<int>;
-#endif
-
-  /**
-   * \brief Indicates reassembled payload cannot be parsed as ResultType.
+   * \brief Indicates the reassembled payload cannot be parsed successfully.
+   * \sa parseResult()
    */
   class ParseResultError : public tlv::Error
   {
@@ -80,9 +66,10 @@
 
 #ifdef DOXYGEN
   /**
-   * \brief Parses a result from reassembled payload.
-   * \param payload reassembled payload
-   * \throw tlv::Error cannot parse payload
+   * \brief Parses a result from a reassembled payload.
+   * \param payload The reassembled payload.
+   * \return The parsed result, usually a vector.
+   * \throw tlv::Error Cannot parse the payload.
    */
   ResultType
   parseResult(ConstBufferPtr payload) const;
@@ -90,8 +77,8 @@
 
 protected:
   /**
-   * \brief Constructs a StatusDataset instance with given sub-prefix.
-   * \param datasetName dataset name after top-level prefix, such as faces/list
+   * \brief Constructs a StatusDataset instance with the given sub-prefix.
+   * \param datasetName Dataset name after top-level prefix, such as `faces/list`.
    */
   explicit
   StatusDataset(const PartialName& datasetName);
@@ -99,7 +86,7 @@
 private:
   /**
    * \brief Appends parameters to the dataset name prefix.
-   * \param[in,out] the dataset name prefix onto which parameter components can be appended
+   * \param[in,out] name The dataset name prefix onto which parameter components can be appended.
    */
   virtual void
   addParameters(Name& name) const;
@@ -118,9 +105,7 @@
 public:
   ForwarderGeneralStatusDataset();
 
-  using ResultType = ForwarderStatus;
-
-  ResultType
+  ForwarderStatus
   parseResult(ConstBufferPtr payload) const;
 };
 
@@ -131,9 +116,7 @@
 class FaceDatasetBase : public StatusDataset
 {
 public:
-  using ResultType = std::vector<FaceStatus>;
-
-  ResultType
+  std::vector<FaceStatus>
   parseResult(ConstBufferPtr payload) const;
 
 protected:
@@ -160,8 +143,6 @@
 class FaceQueryDataset : public FaceDatasetBase
 {
 public:
-  using ParamType = FaceQueryFilter;
-
   explicit
   FaceQueryDataset(const FaceQueryFilter& filter);
 
@@ -183,9 +164,7 @@
 public:
   ChannelDataset();
 
-  using ResultType = std::vector<ChannelStatus>;
-
-  ResultType
+  std::vector<ChannelStatus>
   parseResult(ConstBufferPtr payload) const;
 };
 
@@ -199,9 +178,7 @@
 public:
   FibDataset();
 
-  using ResultType = std::vector<FibEntry>;
-
-  ResultType
+  std::vector<FibEntry>
   parseResult(ConstBufferPtr payload) const;
 };
 
@@ -215,9 +192,7 @@
 public:
   CsInfoDataset();
 
-  using ResultType = CsInfo;
-
-  ResultType
+  CsInfo
   parseResult(ConstBufferPtr payload) const;
 };
 
@@ -231,9 +206,7 @@
 public:
   StrategyChoiceDataset();
 
-  using ResultType = std::vector<StrategyChoice>;
-
-  ResultType
+  std::vector<StrategyChoice>
   parseResult(ConstBufferPtr payload) const;
 };
 
@@ -247,9 +220,7 @@
 public:
   RibDataset();
 
-  using ResultType = std::vector<RibEntry>;
-
-  ResultType
+  std::vector<RibEntry>
   parseResult(ConstBufferPtr payload) const;
 };
 
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index a18818a..acd53d0 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -39,7 +39,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<Component>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Component>));
 BOOST_CONCEPT_ASSERT((WireDecodable<Component>));
-static_assert(std::is_base_of<tlv::Error, Component::Error>::value,
+static_assert(std::is_convertible_v<Component::Error*, tlv::Error*>,
               "name::Component::Error must inherit from tlv::Error");
 
 static Convention g_conventionEncoding = Convention::TYPED;
@@ -498,9 +498,7 @@
 Component
 Component::getSuccessor() const
 {
-  bool isOverflow = false;
-  Component successor;
-  std::tie(isOverflow, successor) = getComponentTypeTable().get(type()).getSuccessor(*this);
+  auto [isOverflow, successor] = getComponentTypeTable().get(type()).getSuccessor(*this);
   if (!isOverflow) {
     return successor;
   }
diff --git a/ndn-cxx/name.cpp b/ndn-cxx/name.cpp
index 50fd40c..42f3f26 100644
--- a/ndn-cxx/name.cpp
+++ b/ndn-cxx/name.cpp
@@ -44,7 +44,7 @@
 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Name::reverse_iterator>));
 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Name::const_reverse_iterator>));
 BOOST_CONCEPT_ASSERT((boost::RandomAccessRangeConcept<Name>));
-static_assert(std::is_base_of<tlv::Error, Name::Error>::value,
+static_assert(std::is_convertible_v<Name::Error*, tlv::Error*>,
               "Name::Error must inherit from tlv::Error");
 
 // ---- constructors, encoding, decoding ----
@@ -70,8 +70,7 @@
   if (uri.empty())
     return;
 
-  size_t iColon = uri.find(':');
-  if (iColon != std::string::npos) {
+  if (size_t iColon = uri.find(':'); iColon != std::string::npos) {
     // Make sure the colon came before a '/'.
     size_t iFirstSlash = uri.find('/');
     if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
diff --git a/ndn-cxx/net/face-uri.cpp b/ndn-cxx/net/face-uri.cpp
index cb4e279..14db8d9 100644
--- a/ndn-cxx/net/face-uri.cpp
+++ b/ndn-cxx/net/face-uri.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California,
+ * Copyright (c) 2013-2023 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -356,9 +356,7 @@
                const FaceUri::CanonizeFailureCallback& onFailure,
                const dns::IpAddress& ipAddress) const
   {
-    bool isOk = false;
-    std::string reason;
-    std::tie(isOk, reason) = this->checkAddress(ipAddress);
+    auto [isOk, reason] = this->checkAddress(ipAddress);
     if (!isOk) {
       return onFailure(reason);
     }
diff --git a/ndn-cxx/net/impl/netlink-message.hpp b/ndn-cxx/net/impl/netlink-message.hpp
index ed2567b..01d5282 100644
--- a/ndn-cxx/net/impl/netlink-message.hpp
+++ b/ndn-cxx/net/impl/netlink-message.hpp
@@ -262,7 +262,7 @@
   }
 
   template<typename Integral>
-  static std::enable_if_t<std::is_integral<Integral>::value, std::optional<Integral>>
+  static std::enable_if_t<std::is_integral_v<Integral>, std::optional<Integral>>
   convertAttrValue(const uint8_t* val, size_t len, AttrValueTypeTag<Integral>)
   {
     if (len < sizeof(Integral))
@@ -293,8 +293,8 @@
   }
 
   template<typename IpAddress>
-  static std::enable_if_t<std::is_same<IpAddress, boost::asio::ip::address_v4>::value ||
-                          std::is_same<IpAddress, boost::asio::ip::address_v6>::value,
+  static std::enable_if_t<std::is_same_v<IpAddress, boost::asio::ip::address_v4> ||
+                          std::is_same_v<IpAddress, boost::asio::ip::address_v6>,
                           std::optional<IpAddress>>
   convertAttrValue(const uint8_t* val, size_t len, AttrValueTypeTag<IpAddress>)
   {
diff --git a/ndn-cxx/net/impl/netlink-socket.cpp b/ndn-cxx/net/impl/netlink-socket.cpp
index 52b37fa..b12998c 100644
--- a/ndn-cxx/net/impl/netlink-socket.cpp
+++ b/ndn-cxx/net/impl/netlink-socket.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -198,7 +198,7 @@
   }
   else {
     bool wasEmpty = m_pendingRequests.empty();
-    m_pendingRequests.emplace(seq, std::move(cb));
+    m_pendingRequests.try_emplace(seq, std::move(cb));
     if (wasEmpty)
       asyncWait();
   }
@@ -445,11 +445,9 @@
     return;
   }
 
-  auto ret = m_familyResolvers.emplace(std::piecewise_construct,
-                                       std::forward_as_tuple(familyName),
-                                       std::forward_as_tuple(familyName, *this));
-  auto& resolver = ret.first->second;
-  if (ret.second) {
+  auto [resIt, isNew] = m_familyResolvers.try_emplace(familyName, familyName, *this);
+  auto& resolver = resIt->second;
+  if (isNew) {
     // cache the result
     resolver.onResolved.connectSingleShot([=] (uint16_t familyId) {
       m_cachedFamilyIds[familyName] = familyId;
diff --git a/ndn-cxx/net/network-monitor-stub.cpp b/ndn-cxx/net/network-monitor-stub.cpp
index 5dcc185..c84d8ae 100644
--- a/ndn-cxx/net/network-monitor-stub.cpp
+++ b/ndn-cxx/net/network-monitor-stub.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,7 +69,7 @@
   addInterface(shared_ptr<NetworkInterface> netif)
   {
     BOOST_ASSERT(netif != nullptr);
-    bool isNew = m_interfaces.emplace(netif->getName(), netif).second;
+    bool isNew = m_interfaces.try_emplace(netif->getName(), netif).second;
     if (!isNew) {
       NDN_THROW(std::invalid_argument("duplicate ifname"));
     }
diff --git a/ndn-cxx/prefix-announcement.cpp b/ndn-cxx/prefix-announcement.cpp
index decb314..e718fc5 100644
--- a/ndn-cxx/prefix-announcement.cpp
+++ b/ndn-cxx/prefix-announcement.cpp
@@ -24,7 +24,7 @@
 
 namespace ndn {
 
-static_assert(std::is_base_of<tlv::Error, PrefixAnnouncement::Error>::value,
+static_assert(std::is_convertible_v<PrefixAnnouncement::Error*, tlv::Error*>,
               "PrefixAnnouncement::Error must inherit from tlv::Error");
 
 PrefixAnnouncement::PrefixAnnouncement() = default;
diff --git a/ndn-cxx/security/additional-description.cpp b/ndn-cxx/security/additional-description.cpp
index 25cde15..c5091ee 100644
--- a/ndn-cxx/security/additional-description.cpp
+++ b/ndn-cxx/security/additional-description.cpp
@@ -32,7 +32,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<AdditionalDescription>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<AdditionalDescription>));
 BOOST_CONCEPT_ASSERT((WireDecodable<AdditionalDescription>));
-static_assert(std::is_base_of<tlv::Error, AdditionalDescription::Error>::value,
+static_assert(std::is_convertible_v<AdditionalDescription::Error*, tlv::Error*>,
               "AdditionalDescription::Error must inherit from tlv::Error");
 
 constexpr size_t KEY_OFFSET = 0;
@@ -46,11 +46,11 @@
 const std::string&
 AdditionalDescription::get(const std::string& key) const
 {
-  auto it = m_info.find(key);
-  if (it == m_info.end())
-    NDN_THROW(Error("Entry does not exist for key (" + key + ")"));
+  if (auto it = m_info.find(key); it != m_info.end()) {
+    return it->second;
+  }
 
-  return it->second;
+  NDN_THROW(Error("Entry does not exist for key (" + key + ")"));
 }
 
 void
@@ -62,7 +62,7 @@
 bool
 AdditionalDescription::has(const std::string& key) const
 {
-  return (m_info.find(key) != m_info.end());
+  return m_info.find(key) != m_info.end();
 }
 
 AdditionalDescription::iterator
diff --git a/ndn-cxx/security/certificate-storage.cpp b/ndn-cxx/security/certificate-storage.cpp
index 3120cba..95a2cb4 100644
--- a/ndn-cxx/security/certificate-storage.cpp
+++ b/ndn-cxx/security/certificate-storage.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,21 +34,18 @@
 const Certificate*
 CertificateStorage::findTrustedCert(const Interest& interestForCert) const
 {
-  auto cert = m_trustAnchors.find(interestForCert);
-  if (cert != nullptr) {
+  if (auto cert = m_trustAnchors.find(interestForCert); cert != nullptr) {
     return cert;
   }
-
-  cert = m_verifiedCertCache.find(interestForCert);
-  return cert;
+  return m_verifiedCertCache.find(interestForCert);
 }
 
 bool
 CertificateStorage::isCertKnown(const Name& certName) const
 {
-  return (m_trustAnchors.find(certName) != nullptr ||
-          m_verifiedCertCache.find(certName) != nullptr ||
-          m_unverifiedCertCache.find(certName) != nullptr);
+  return m_trustAnchors.find(certName) != nullptr ||
+         m_verifiedCertCache.find(certName) != nullptr ||
+         m_unverifiedCertCache.find(certName) != nullptr;
 }
 
 void
diff --git a/ndn-cxx/security/certificate.cpp b/ndn-cxx/security/certificate.cpp
index f912b4a..68f7c83 100644
--- a/ndn-cxx/security/certificate.cpp
+++ b/ndn-cxx/security/certificate.cpp
@@ -33,7 +33,7 @@
 
 BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
 BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
-static_assert(std::is_base_of<Data::Error, Certificate::Error>::value,
+static_assert(std::is_convertible_v<Certificate::Error*, Data::Error*>,
               "Certificate::Error must inherit from Data::Error");
 
 Certificate::Certificate()
diff --git a/ndn-cxx/security/detail/certificate-bundle-decoder.cpp b/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
index 83f94e1..c66a50b 100644
--- a/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
+++ b/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -43,9 +43,7 @@
   auto onThrow = make_scope_fail([this] { m_hasError = true; });
 
   while (!m_bufferedData.empty()) {
-    bool isOk;
-    Block element;
-    std::tie(isOk, element) = Block::fromBuffer(m_bufferedData);
+    auto [isOk, element] = Block::fromBuffer(m_bufferedData);
     if (!isOk) {
       return;
     }
diff --git a/ndn-cxx/security/key-chain.cpp b/ndn-cxx/security/key-chain.cpp
index 20e522d..2e27086 100644
--- a/ndn-cxx/security/key-chain.cpp
+++ b/ndn-cxx/security/key-chain.cpp
@@ -402,12 +402,9 @@
 void
 KeyChain::sign(Data& data, const SigningInfo& params)
 {
-  Name keyName;
-  SignatureInfo sigInfo;
-  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
+  auto [keyName, sigInfo] = prepareSignatureInfo(params);
 
   data.setSignatureInfo(sigInfo);
-
   EncodingBuffer encoder;
   data.wireEncode(encoder, true);
 
@@ -418,9 +415,7 @@
 void
 KeyChain::sign(Interest& interest, const SigningInfo& params)
 {
-  Name keyName;
-  SignatureInfo sigInfo;
-  std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
+  auto [keyName, sigInfo] = prepareSignatureInfo(params);
 
   if (params.getSignedInterestFormat() == SignedInterestFormat::V03) {
     interest.setSignatureInfo(sigInfo);
@@ -473,8 +468,7 @@
 static std::tuple<std::string/*scheme*/, std::string/*location*/>
 parseLocatorUri(const std::string& uri)
 {
-  auto pos = uri.find(':');
-  if (pos != std::string::npos) {
+  if (auto pos = uri.find(':'); pos != std::string::npos) {
     return {uri.substr(0, pos), uri.substr(pos + 1)};
   }
   else {
@@ -485,9 +479,7 @@
 KeyChain::Locator
 KeyChain::parseAndCheckPibLocator(const std::string& pibLocator)
 {
-  std::string pibScheme, pibLocation;
-  std::tie(pibScheme, pibLocation) = parseLocatorUri(pibLocator);
-
+  auto [pibScheme, pibLocation] = parseLocatorUri(pibLocator);
   if (pibScheme.empty()) {
     pibScheme = getDefaultPibScheme();
   }
@@ -503,9 +495,7 @@
 KeyChain::Locator
 KeyChain::parseAndCheckTpmLocator(const std::string& tpmLocator)
 {
-  std::string tpmScheme, tpmLocation;
-  std::tie(tpmScheme, tpmLocation) = parseLocatorUri(tpmLocator);
-
+  auto [tpmScheme, tpmLocation] = parseLocatorUri(tpmLocator);
   if (tpmScheme.empty()) {
     tpmScheme = getDefaultTpmScheme();
   }
diff --git a/ndn-cxx/security/key-chain.hpp b/ndn-cxx/security/key-chain.hpp
index 1740bb0..4257cae 100644
--- a/ndn-cxx/security/key-chain.hpp
+++ b/ndn-cxx/security/key-chain.hpp
@@ -34,26 +34,26 @@
 namespace security {
 
 /**
- * @brief Options to KeyChain::makeCertificate() .
+ * @brief Options to KeyChain::makeCertificate().
  */
 struct MakeCertificateOptions
 {
   /**
-   * @brief Certificate name IssuerId component.
+   * @brief %Certificate name IssuerId component.
    *
    * Default is "NA".
    */
   name::Component issuerId = Certificate::DEFAULT_ISSUER_ID;
 
   /**
-   * @brief Certificate name version component.
+   * @brief %Certificate name version component.
    *
-   * Default is deriving from current timestamp using the logic of Name::appendVersion() .
+   * Default is deriving from current timestamp using the logic of Name::appendVersion().
    */
   std::optional<uint64_t> version;
 
   /**
-   * @brief Certificate packet FreshnessPeriod.
+   * @brief %Certificate packet FreshnessPeriod.
    *
    * As required by the certificate format, this must be positive.
    * Setting this to zero or negative causes @c std::invalid_argument exception.
@@ -63,7 +63,7 @@
   time::milliseconds freshnessPeriod = 1_h;
 
   /**
-   * @brief Certificate ValidityPeriod.
+   * @brief %Certificate ValidityPeriod.
    *
    * It isn't an error to specify a ValidityPeriod that does not include the current time
    * or has zero duration, but the certificate won't be valid.
diff --git a/ndn-cxx/security/key-params.hpp b/ndn-cxx/security/key-params.hpp
index fc28f10..b9e573d 100644
--- a/ndn-cxx/security/key-params.hpp
+++ b/ndn-cxx/security/key-params.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -196,10 +196,10 @@
 };
 
 /// @brief RsaKeyParams carries parameters for RSA key.
-typedef SimplePublicKeyParams<detail::RsaKeyParamsInfo> RsaKeyParams;
+using RsaKeyParams = SimplePublicKeyParams<detail::RsaKeyParamsInfo>;
 
 /// @brief EcKeyParams carries parameters for EC key.
-typedef SimplePublicKeyParams<detail::EcKeyParamsInfo> EcKeyParams;
+using EcKeyParams = SimplePublicKeyParams<detail::EcKeyParamsInfo>;
 
 
 namespace detail {
@@ -303,10 +303,10 @@
 };
 
 /// @brief AesKeyParams carries parameters for AES key.
-typedef SimpleSymmetricKeyParams<detail::AesKeyParamsInfo> AesKeyParams;
+using AesKeyParams = SimpleSymmetricKeyParams<detail::AesKeyParamsInfo>;
 
 /// @brief HmacKeyParams carries parameters for HMAC key.
-typedef SimpleSymmetricKeyParams<detail::HmacKeyParamsInfo> HmacKeyParams;
+using HmacKeyParams = SimpleSymmetricKeyParams<detail::HmacKeyParamsInfo>;
 
 } // namespace ndn
 
diff --git a/ndn-cxx/security/pib/certificate-container.cpp b/ndn-cxx/security/pib/certificate-container.cpp
index d3d6cbb..76746ba 100644
--- a/ndn-cxx/security/pib/certificate-container.cpp
+++ b/ndn-cxx/security/pib/certificate-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -113,8 +113,7 @@
                                     "does not match key `" + m_keyName.toUri() + "`"));
   }
 
-  auto it = m_certs.find(certName);
-  if (it != m_certs.end()) {
+  if (auto it = m_certs.find(certName); it != m_certs.end()) {
     return it->second;
   }
 
diff --git a/ndn-cxx/security/pib/identity-container.cpp b/ndn-cxx/security/pib/identity-container.cpp
index 1231c45..f91832e 100644
--- a/ndn-cxx/security/pib/identity-container.cpp
+++ b/ndn-cxx/security/pib/identity-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -106,8 +106,7 @@
 Identity
 IdentityContainer::get(const Name& identityName) const
 {
-  auto it = m_identities.find(identityName);
-  if (it != m_identities.end()) {
+  if (auto it = m_identities.find(identityName); it != m_identities.end()) {
     return Identity(it->second);
   }
 
diff --git a/ndn-cxx/security/pib/key-container.cpp b/ndn-cxx/security/pib/key-container.cpp
index e79d96f..b2e2d60 100644
--- a/ndn-cxx/security/pib/key-container.cpp
+++ b/ndn-cxx/security/pib/key-container.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -115,8 +115,7 @@
                                     "`" + m_identity.toUri() + "`"));
   }
 
-  auto it = m_keys.find(keyName);
-  if (it != m_keys.end()) {
+  if (auto it = m_keys.find(keyName); it != m_keys.end()) {
     return Key(it->second);
   }
 
diff --git a/ndn-cxx/security/tpm/impl/back-end-mem.cpp b/ndn-cxx/security/tpm/impl/back-end-mem.cpp
index f80c0f8..ec9828b 100644
--- a/ndn-cxx/security/tpm/impl/back-end-mem.cpp
+++ b/ndn-cxx/security/tpm/impl/back-end-mem.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,7 +41,7 @@
 };
 
 BackEndMem::BackEndMem(const std::string&)
-  : m_impl(make_unique<Impl>())
+  : m_impl(std::make_unique<Impl>())
 {
 }
 
@@ -63,10 +63,10 @@
 unique_ptr<KeyHandle>
 BackEndMem::doGetKeyHandle(const Name& keyName) const
 {
-  auto it = m_impl->keys.find(keyName);
-  if (it == m_impl->keys.end())
-    return nullptr;
-  return make_unique<KeyHandleMem>(it->second);
+  if (auto it = m_impl->keys.find(keyName); it != m_impl->keys.end()) {
+    return std::make_unique<KeyHandleMem>(it->second);
+  }
+  return nullptr;
 }
 
 unique_ptr<KeyHandle>
@@ -83,7 +83,7 @@
   }
 
   shared_ptr<PrivateKey> key(transform::generatePrivateKey(params).release());
-  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleMem>(key);
+  unique_ptr<KeyHandle> keyHandle = std::make_unique<KeyHandleMem>(key);
 
   Name keyName;
   if (params.getKeyType() == KeyType::HMAC) {
@@ -115,7 +115,7 @@
 void
 BackEndMem::doImportKey(const Name& keyName, span<const uint8_t> pkcs8, const char* pw, size_t pwLen)
 {
-  auto key = make_shared<PrivateKey>();
+  auto key = std::make_shared<PrivateKey>();
   try {
     key->loadPkcs8(pkcs8, pw, pwLen);
   }
diff --git a/ndn-cxx/security/tpm/tpm.cpp b/ndn-cxx/security/tpm/tpm.cpp
index 3218be9..ded3ca8 100644
--- a/ndn-cxx/security/tpm/tpm.cpp
+++ b/ndn-cxx/security/tpm/tpm.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -21,7 +21,7 @@
 
 #include "ndn-cxx/security/tpm/tpm.hpp"
 #include "ndn-cxx/security/tpm/back-end.hpp"
-#include "ndn-cxx/encoding/buffer-stream.hpp"
+#include "ndn-cxx/encoding/buffer.hpp"
 
 #include <boost/lexical_cast.hpp>
 
@@ -55,8 +55,7 @@
 void
 Tpm::deleteKey(const Name& keyName)
 {
-  auto it = m_keys.find(keyName);
-  if (it != m_keys.end())
+  if (auto it = m_keys.find(keyName); it != m_keys.end())
     m_keys.erase(it);
 
   m_backEnd->deleteKey(keyName);
@@ -139,8 +138,7 @@
 const KeyHandle*
 Tpm::findKey(const Name& keyName) const
 {
-  auto it = m_keys.find(keyName);
-  if (it != m_keys.end())
+  if (auto it = m_keys.find(keyName); it != m_keys.end())
     return it->second.get();
 
   auto handle = m_backEnd->getKeyHandle(keyName);
diff --git a/ndn-cxx/security/transform/hex-decode.cpp b/ndn-cxx/security/transform/hex-decode.cpp
index d46c301..6970a65 100644
--- a/ndn-cxx/security/transform/hex-decode.cpp
+++ b/ndn-cxx/security/transform/hex-decode.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -45,7 +45,7 @@
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 240-255
 };
-static_assert(std::extent<decltype(C2H)>::value == 256, "");
+static_assert(std::extent_v<decltype(C2H)> == 256, "");
 
 
 HexDecode::HexDecode()
diff --git a/ndn-cxx/security/transform/hex-encode.cpp b/ndn-cxx/security/transform/hex-encode.cpp
index 865bb6b..204466f 100644
--- a/ndn-cxx/security/transform/hex-encode.cpp
+++ b/ndn-cxx/security/transform/hex-encode.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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -29,13 +29,13 @@
   '0', '1', '2', '3', '4', '5', '6', '7',
   '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
 };
-static_assert(std::extent<decltype(H2CL)>::value == 16, "");
+static_assert(std::extent_v<decltype(H2CL)> == 16, "");
 
 static const uint8_t H2CU[] = {
   '0', '1', '2', '3', '4', '5', '6', '7',
   '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
 };
-static_assert(std::extent<decltype(H2CU)>::value == 16, "");
+static_assert(std::extent_v<decltype(H2CU)> == 16, "");
 
 
 HexEncode::HexEncode(bool useUpperCase)
diff --git a/ndn-cxx/security/validation-policy-command-interest.cpp b/ndn-cxx/security/validation-policy-command-interest.cpp
index 171848e..adf8bd1 100644
--- a/ndn-cxx/security/validation-policy-command-interest.cpp
+++ b/ndn-cxx/security/validation-policy-command-interest.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -50,10 +50,7 @@
 ValidationPolicyCommandInterest::checkPolicy(const Interest& interest, const shared_ptr<ValidationState>& state,
                                              const ValidationContinuation& continueValidation)
 {
-  bool isOk;
-  Name keyName;
-  time::system_clock::TimePoint timestamp;
-  std::tie(isOk, keyName, timestamp) = parseCommandInterest(interest, state);
+  auto [isOk, keyName, timestamp] = parseCommandInterest(interest, state);
   if (!isOk) {
     return;
   }
@@ -65,16 +62,16 @@
   getInnerPolicy().checkPolicy(interest, state, continueValidation);
 }
 
-std::tuple<bool, Name, time::system_clock::TimePoint>
+std::tuple<bool, Name, time::system_clock::time_point>
 ValidationPolicyCommandInterest::parseCommandInterest(const Interest& interest,
                                                       const shared_ptr<ValidationState>& state)
 {
   auto sigInfo = getSignatureInfo(interest, *state);
   if (!state->getOutcome()) { // already failed
-    return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
+    return {false, {}, {}};
   }
 
-  time::system_clock::TimePoint timestamp;
+  time::system_clock::time_point timestamp;
 
   auto fmt = state->getTag<SignedInterestFormatTag>();
   BOOST_ASSERT(fmt);
@@ -85,7 +82,7 @@
     if (!optionalTimestamp) {
       state->fail({ValidationError::POLICY_ERROR, "Signed Interest `" +
                    interest.getName().toUri() + "` lacks required SignatureTime element"});
-      return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
+      return {false, {}, {}};
     }
 
     timestamp = *optionalTimestamp;
@@ -95,14 +92,14 @@
     if (name.size() < command_interest::MIN_SIZE) {
       state->fail({ValidationError::POLICY_ERROR,
                    "Command Interest name too short `" + interest.getName().toUri() + "`"});
-      return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
+      return {false, {}, {}};
     }
 
     const auto& timestampComp = name.at(command_interest::POS_TIMESTAMP);
     if (!timestampComp.isNumber()) {
       state->fail({ValidationError::POLICY_ERROR, "Command Interest `" +
                    interest.getName().toUri() + "` lacks required timestamp component"});
-      return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
+      return {false, {}, {}};
     }
 
     timestamp = time::fromUnixTimestamp(time::milliseconds(timestampComp.toNumber()));
@@ -110,10 +107,10 @@
 
   Name klName = getKeyLocatorName(sigInfo, *state);
   if (!state->getOutcome()) { // already failed
-    return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
+    return {false, {}, {}};
   }
 
-  return std::make_tuple(true, klName, timestamp);
+  return {true, klName, timestamp};
 }
 
 void
@@ -130,7 +127,7 @@
 
 bool
 ValidationPolicyCommandInterest::checkTimestamp(const shared_ptr<ValidationState>& state,
-                                                const Name& keyName, time::system_clock::TimePoint timestamp)
+                                                const Name& keyName, time::system_clock::time_point timestamp)
 {
   this->cleanup();
 
@@ -158,14 +155,11 @@
 }
 
 void
-ValidationPolicyCommandInterest::insertNewRecord(const Name& keyName, time::system_clock::TimePoint timestamp)
+ValidationPolicyCommandInterest::insertNewRecord(const Name& keyName, time::system_clock::time_point timestamp)
 {
   // try to insert new record
-  auto now = time::steady_clock::now();
-  auto i = m_queue.end();
-  bool isNew = false;
-  LastTimestampRecord newRecord{keyName, timestamp, now};
-  std::tie(i, isNew) = m_queue.push_back(newRecord);
+  LastTimestampRecord newRecord{keyName, timestamp, time::steady_clock::now()};
+  auto [i, isNew] = m_queue.push_back(newRecord);
 
   if (!isNew) {
     BOOST_ASSERT(i->keyName == keyName);
diff --git a/ndn-cxx/security/validation-policy-signed-interest.cpp b/ndn-cxx/security/validation-policy-signed-interest.cpp
index efaf82a..8071a3c 100644
--- a/ndn-cxx/security/validation-policy-signed-interest.cpp
+++ b/ndn-cxx/security/validation-policy-signed-interest.cpp
@@ -147,9 +147,7 @@
                                              std::optional<SigNonce> nonce)
 {
   // If key record exists, update last refreshed time. Otherwise, create new record.
-  Container::nth_index<0>::type::iterator it;
-  bool isOk;
-  std::tie(it, isOk) = m_byKeyName.emplace(keyName, timestamp, seqNum);
+  auto [it, isOk] = m_byKeyName.emplace(keyName, timestamp, seqNum);
   if (!isOk) {
     // There was already a record for this key, we just need to update it
     isOk = m_byKeyName.modify(it, [&] (LastInterestRecord& record) {
diff --git a/ndn-cxx/security/validity-period.cpp b/ndn-cxx/security/validity-period.cpp
index 22e53dd..ff77747 100644
--- a/ndn-cxx/security/validity-period.cpp
+++ b/ndn-cxx/security/validity-period.cpp
@@ -30,7 +30,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<ValidityPeriod>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<ValidityPeriod>));
 BOOST_CONCEPT_ASSERT((WireDecodable<ValidityPeriod>));
-static_assert(std::is_base_of<tlv::Error, ValidityPeriod::Error>::value,
+static_assert(std::is_convertible_v<ValidityPeriod::Error*, tlv::Error*>,
               "ValidityPeriod::Error must inherit from tlv::Error");
 
 constexpr size_t ISO_DATETIME_SIZE = 15;
diff --git a/ndn-cxx/security/validity-period.hpp b/ndn-cxx/security/validity-period.hpp
index a8a1c0f..97bc47c 100644
--- a/ndn-cxx/security/validity-period.hpp
+++ b/ndn-cxx/security/validity-period.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -133,7 +133,7 @@
   }
 
 private:
-  typedef boost::chrono::time_point<time::system_clock, time::seconds> TimePoint;
+  using TimePoint = boost::chrono::time_point<time::system_clock, time::seconds>;
 
   TimePoint m_notBefore;
   TimePoint m_notAfter;
diff --git a/ndn-cxx/signature-info.cpp b/ndn-cxx/signature-info.cpp
index bba5682..5188002 100644
--- a/ndn-cxx/signature-info.cpp
+++ b/ndn-cxx/signature-info.cpp
@@ -33,7 +33,7 @@
 BOOST_CONCEPT_ASSERT((WireEncodable<SignatureInfo>));
 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<SignatureInfo>));
 BOOST_CONCEPT_ASSERT((WireDecodable<SignatureInfo>));
-static_assert(std::is_base_of<tlv::Error, SignatureInfo::Error>::value,
+static_assert(std::is_convertible_v<SignatureInfo::Error*, tlv::Error*>,
               "SignatureInfo::Error must inherit from tlv::Error");
 
 SignatureInfo::SignatureInfo() = default;
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index 4c52005..1b47f49 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -221,12 +221,10 @@
   processAllReceived(uint8_t* buffer, size_t& offset, size_t nBytesAvailable)
   {
     while (offset < nBytesAvailable) {
-      bool isOk = false;
-      Block element;
-      std::tie(isOk, element) = Block::fromBuffer({buffer + offset, nBytesAvailable - offset});
-      if (!isOk)
+      auto [isOk, element] = Block::fromBuffer({buffer + offset, nBytesAvailable - offset});
+      if (!isOk) {
         return false;
-
+      }
       m_transport.m_receiveCallback(element);
       offset += element.size();
     }
diff --git a/ndn-cxx/util/backports.hpp b/ndn-cxx/util/backports.hpp
index 3977da1..d9932f5 100644
--- a/ndn-cxx/util/backports.hpp
+++ b/ndn-cxx/util/backports.hpp
@@ -44,7 +44,7 @@
 to_underlying(T val) noexcept
 {
   // instantiating underlying_type with a non-enum type is UB before C++20
-  static_assert(std::is_enum<T>::value, "");
+  static_assert(std::is_enum_v<T>, "");
   return static_cast<std::underlying_type_t<T>>(val);
 }
 #endif // __cpp_lib_to_underlying
diff --git a/ndn-cxx/util/concepts.hpp b/ndn-cxx/util/concepts.hpp
index 7170c9d..de721b6 100644
--- a/ndn-cxx/util/concepts.hpp
+++ b/ndn-cxx/util/concepts.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2022 Regents of the University of California,
+ * Copyright (c) 2014-2023 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -98,11 +98,12 @@
 public:
   BOOST_CONCEPT_USAGE(NfdMgmtProtocolStruct)
   {
-    static_assert(std::is_default_constructible<X>::value, "");
+    static_assert(std::is_default_constructible_v<X>, "");
     static_assert(boost::has_equal_to<X, X, bool>::value, "");
     static_assert(boost::has_not_equal_to<X, X, bool>::value, "");
     static_assert(boost::has_left_shift<std::ostream, X, std::ostream&>::value, "");
-    static_assert(std::is_base_of<tlv::Error, typename X::Error>::value, "");
+    static_assert(std::is_convertible_v<typename X::Error*, tlv::Error*>,
+                  "ndn::tlv::Error must be a public base of X::Error");
   }
 };
 
@@ -145,8 +146,7 @@
  *        SGI standard which doesn't require DefaultConstructible, so a separate check is needed.
  */
 #define NDN_CXX_ASSERT_FORWARD_ITERATOR(T) \
-  static_assert(std::is_default_constructible<T>::value, \
-                #T " must be default-constructible"); \
+  static_assert(std::is_default_constructible_v<T>, #T " must be default-constructible"); \
   BOOST_CONCEPT_ASSERT((::ndn::detail::StlForwardIteratorConcept<T>))
 
 #endif // NDN_CXX_UTIL_CONCEPTS_HPP
diff --git a/ndn-cxx/util/io.hpp b/ndn-cxx/util/io.hpp
index 4eb321b..3500507 100644
--- a/ndn-cxx/util/io.hpp
+++ b/ndn-cxx/util/io.hpp
@@ -63,7 +63,7 @@
 static void
 checkNestedError(typename T::Error*)
 {
-  static_assert(std::is_convertible<typename T::Error*, tlv::Error*>::value,
+  static_assert(std::is_convertible_v<typename T::Error*, tlv::Error*>,
                 "T::Error, if defined, must be a subclass of ndn::tlv::Error");
 }
 
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index d88a1a8..b6ffe7d 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -61,7 +61,7 @@
   std::string buffer(10 + 1 + 6 + 1, '\0'); // note 1 extra byte still needed for snprintf
   BOOST_ASSERT_MSG(usecs / usecsPerSec <= 9999999999, "whole seconds cannot fit in 10 characters");
 
-  static_assert(std::is_same<microseconds::rep, int_least64_t>::value,
+  static_assert(std::is_same_v<microseconds::rep, int_least64_t>,
                 "PRIdLEAST64 is incompatible with microseconds::rep");
   std::snprintf(&buffer.front(), buffer.size(), "%" PRIdLEAST64 ".%06" PRIdLEAST64,
                 usecs / usecsPerSec, usecs % usecsPerSec);
@@ -140,8 +140,7 @@
 Logging::findLevel(std::string mn) const
 {
   while (!mn.empty()) {
-    auto it = m_enabledLevel.find(mn);
-    if (it != m_enabledLevel.end()) {
+    if (auto it = m_enabledLevel.find(mn); it != m_enabledLevel.end()) {
       return it->second;
     }
     size_t pos = mn.find_last_of('.');
diff --git a/ndn-cxx/util/ostream-joiner.hpp b/ndn-cxx/util/ostream-joiner.hpp
index e187854..80f4c3c 100644
--- a/ndn-cxx/util/ostream-joiner.hpp
+++ b/ndn-cxx/util/ostream-joiner.hpp
@@ -66,13 +66,13 @@
   typedef void reference;
 
   ostream_joiner(ostream_type& os, const DelimT& delimiter)
-  noexcept(std::is_nothrow_copy_constructible<DelimT>::value)
+  noexcept(std::is_nothrow_copy_constructible_v<DelimT>)
     : m_os(std::addressof(os)), m_delim(delimiter)
   {
   }
 
   ostream_joiner(ostream_type& os, DelimT&& delimiter)
-  noexcept(std::is_nothrow_move_constructible<DelimT>::value)
+  noexcept(std::is_nothrow_move_constructible_v<DelimT>)
     : m_os(std::addressof(os)), m_delim(std::move(delimiter))
   {
   }
diff --git a/ndn-cxx/util/segment-fetcher.cpp b/ndn-cxx/util/segment-fetcher.cpp
index dcacf94..727b836 100644
--- a/ndn-cxx/util/segment-fetcher.cpp
+++ b/ndn-cxx/util/segment-fetcher.cpp
@@ -198,7 +198,7 @@
 
   PendingSegment pendingSegment{SegmentState::FirstInterest, time::steady_clock::now(),
                                 pendingInterest, timeoutEvent};
-  bool isNew = m_pendingSegments.emplace(segNum, std::move(pendingSegment)).second;
+  bool isNew = m_pendingSegments.try_emplace(segNum, std::move(pendingSegment)).second;
   BOOST_VERIFY(isNew);
   m_highInterest = segNum;
 }
@@ -271,11 +271,10 @@
   m_pendingSegments.erase(pendingSegmentIt);
 
   // Copy data in segment to temporary buffer
-  auto receivedSegmentIt = m_segmentBuffer.emplace(std::piecewise_construct,
-                                                   std::forward_as_tuple(currentSegment),
-                                                   std::forward_as_tuple(data.getContent().value_size()));
+  auto receivedSegmentIt = m_segmentBuffer.try_emplace(currentSegment, data.getContent().value_size())
+                           .first;
   std::copy(data.getContent().value_begin(), data.getContent().value_end(),
-            receivedSegmentIt.first->second.begin());
+            receivedSegmentIt->second.begin());
   m_nBytesReceived += data.getContent().value_size();
   afterSegmentValidated(data);
 
diff --git a/ndn-cxx/util/signal/signal.hpp b/ndn-cxx/util/signal/signal.hpp
index 054529f..a097f9c 100644
--- a/ndn-cxx/util/signal/signal.hpp
+++ b/ndn-cxx/util/signal/signal.hpp
@@ -101,7 +101,7 @@
   friend Owner;
 
 private: // internal implementation
-  typedef Signal<Owner, TArgs...> Self;
+  using Self = Signal<Owner, TArgs...>;
 
   /** \brief Stores a handler function, and a function to disconnect this handler.
    */
@@ -128,7 +128,7 @@
    *  \note std::list is used because iterators must not be invalidated
    *        when other slots are added or removed
    */
-  typedef std::list<Slot> SlotList;
+  using SlotList = std::list<Slot>;
   SlotList m_slots;
 
   /** \brief Is a signal handler executing?
diff --git a/tests/benchmarks/timed-execute.hpp b/tests/benchmarks/timed-execute.hpp
index 50bec30..b33873d 100644
--- a/tests/benchmarks/timed-execute.hpp
+++ b/tests/benchmarks/timed-execute.hpp
@@ -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-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -29,10 +29,10 @@
 
 template<typename F>
 time::nanoseconds
-timedExecute(const F& f)
+timedExecute(F&& f)
 {
   auto before = time::steady_clock::now();
-  f();
+  std::invoke(std::forward<F>(f));
   auto after = time::steady_clock::now();
   return after - before;
 }
diff --git a/tests/unit/encoding/tlv.t.cpp b/tests/unit/encoding/tlv.t.cpp
index b21476b..5eaa17a 100644
--- a/tests/unit/encoding/tlv.t.cpp
+++ b/tests/unit/encoding/tlv.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -59,10 +59,10 @@
 using StreamIterator = std::istream_iterator<uint8_t>;
 
 #define ASSERT_READ_NUMBER_IS_FAST(T) \
-  static_assert(std::is_base_of<detail::ReadNumberFast<T>, detail::ReadNumber<T>>::value, \
+  static_assert(std::is_base_of_v<detail::ReadNumberFast<T>, detail::ReadNumber<T>>, \
                 # T " should use ReadNumberFast")
 #define ASSERT_READ_NUMBER_IS_SLOW(T) \
-  static_assert(std::is_base_of<detail::ReadNumberSlow<T>, detail::ReadNumber<T>>::value, \
+  static_assert(std::is_base_of_v<detail::ReadNumberSlow<T>, detail::ReadNumber<T>>, \
                 # T " should use ReadNumberSlow")
 
 ASSERT_READ_NUMBER_IS_FAST(const uint8_t*);
diff --git a/tests/unit/face.t.cpp b/tests/unit/face.t.cpp
index 7e5b7be..2372e24 100644
--- a/tests/unit/face.t.cpp
+++ b/tests/unit/face.t.cpp
@@ -25,7 +25,6 @@
 #include "ndn-cxx/transport/unix-transport.hpp"
 #include "ndn-cxx/util/config-file.hpp"
 #include "ndn-cxx/util/dummy-client-face.hpp"
-#include "ndn-cxx/util/scheduler.hpp"
 
 #include "tests/test-common.hpp"
 #include "tests/unit/io-key-chain-fixture.hpp"
@@ -46,10 +45,10 @@
 {
 protected:
   FaceFixture()
-    : face(m_io, m_keyChain, {true, !std::is_same<PrefixRegReply, NoPrefixRegReply>::value})
+    : face(m_io, m_keyChain, {true, !std::is_same_v<PrefixRegReply, NoPrefixRegReply>})
   {
-    static_assert(std::is_same<PrefixRegReply, WantPrefixRegReply>::value ||
-                  std::is_same<PrefixRegReply, NoPrefixRegReply>::value, "");
+    static_assert(std::is_same_v<PrefixRegReply, WantPrefixRegReply> ||
+                  std::is_same_v<PrefixRegReply, NoPrefixRegReply>, "");
   }
 
   /** \brief Execute a prefix registration, and optionally check the name in callback.
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index 588dedf..68f55fc 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -213,8 +213,7 @@
   BOOST_CHECK_EQUAL(packet.get<AckField>(2), 2);
 
   BOOST_CHECK_EQUAL(packet.count<FragmentField>(), 1);
-  Buffer::const_iterator first, last;
-  std::tie(first, last) = packet.get<FragmentField>(0);
+  auto [first, last] = packet.get<FragmentField>(0);
   BOOST_CHECK_EQUAL(2, last - first);
   BOOST_CHECK_EQUAL(0x03, *first);
   BOOST_CHECK_EQUAL(0xe8, *(last - 1));
@@ -253,8 +252,7 @@
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
   BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
-  Buffer::const_iterator first, last;
-  std::tie(first, last) = packet.get<FragmentField>(0);
+  auto [first, last] = packet.get<FragmentField>(0);
   BOOST_CHECK_EQUAL(2, last - first);
   BOOST_CHECK_EQUAL(0x03, *first);
   BOOST_CHECK_EQUAL(0xe8, *(last - 1));
diff --git a/tests/unit/mgmt/nfd/controller-fixture.hpp b/tests/unit/mgmt/nfd/controller-fixture.hpp
index ae4ab3c..8afee13 100644
--- a/tests/unit/mgmt/nfd/controller-fixture.hpp
+++ b/tests/unit/mgmt/nfd/controller-fixture.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,7 +23,6 @@
 #define NDN_CXX_TESTS_UNIT_MGMT_NFD_CONTROLLER_FIXTURE_HPP
 
 #include "ndn-cxx/mgmt/nfd/controller.hpp"
-#include "ndn-cxx/security/certificate-fetcher-offline.hpp"
 #include "ndn-cxx/util/dummy-client-face.hpp"
 
 #include "tests/unit/dummy-validator.hpp"
@@ -63,8 +62,8 @@
   ndn::util::DummyClientFace face;
   DummyValidator m_validator;
   Controller controller;
-  Controller::CommandFailCallback commandFailCallback;
-  Controller::DatasetFailCallback datasetFailCallback;
+  Controller::CommandFailureCallback commandFailCallback;
+  Controller::DatasetFailureCallback datasetFailCallback;
   std::vector<uint32_t> failCodes;
 };
 
diff --git a/tests/unit/mgmt/nfd/controller.t.cpp b/tests/unit/mgmt/nfd/controller.t.cpp
index d871c8b..f7f4a9a 100644
--- a/tests/unit/mgmt/nfd/controller.t.cpp
+++ b/tests/unit/mgmt/nfd/controller.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -47,7 +47,7 @@
   }
 
 protected:
-  Controller::CommandSucceedCallback succeedCallback = [this] (const auto& params) {
+  Controller::CommandSuccessCallback succeedCallback = [this] (const auto& params) {
     succeeds.push_back(params);
   };
   std::vector<ControlParameters> succeeds;
diff --git a/tests/unit/security/validity-period.t.cpp b/tests/unit/security/validity-period.t.cpp
index 4a28df2..ff0089f 100644
--- a/tests/unit/security/validity-period.t.cpp
+++ b/tests/unit/security/validity-period.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -85,7 +85,7 @@
   BOOST_CHECK_EQUAL(validity2.isValid(), false);
 
   validity2.setPeriod(notBefore, notAfter);
-  BOOST_CHECK(validity2.getPeriod() != std::make_pair(time::getUnixEpoch(), time::getUnixEpoch()));
+  BOOST_CHECK(validity2.getPeriod() != std::pair(time::getUnixEpoch(), time::getUnixEpoch()));
   BOOST_CHECK_EQUAL(validity2, validity1);
 
   validity1.setPeriod(time::getUnixEpoch(), time::getUnixEpoch() + 10 * 365_days);
diff --git a/tests/unit/signature-info.t.cpp b/tests/unit/signature-info.t.cpp
index 1257851..6924a07 100644
--- a/tests/unit/signature-info.t.cpp
+++ b/tests/unit/signature-info.t.cpp
@@ -447,7 +447,7 @@
 
   info2.setValidityPeriod(security::ValidityPeriod(notBefore, notBefore + 42_days));
   BOOST_CHECK_NE(info2.getValidityPeriod(), vp1);
-  BOOST_CHECK(info2.getValidityPeriod().getPeriod() == std::make_pair(notBefore, notBefore + 42_days));
+  BOOST_CHECK(info2.getValidityPeriod().getPeriod() == std::pair(notBefore, notBefore + 42_days));
   BOOST_CHECK_EQUAL(info2.hasWire(), false);
 
   info2.wireEncode();
diff --git a/tests/unit/util/ostream-joiner.t.cpp b/tests/unit/util/ostream-joiner.t.cpp
index 4c617fa..7e8e63f 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-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,7 +38,7 @@
 
   auto joiner1 = ostream_joiner<char>(os, ' ');
   auto joiner2 = make_ostream_joiner(os, ' ');
-  static_assert(std::is_same<decltype(joiner1), decltype(joiner2)>::value, "");
+  static_assert(std::is_same_v<decltype(joiner1), decltype(joiner2)>, "");
 
   std::vector<int> v(5);
   std::iota(v.begin(), v.end(), 1);
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index cc77f02..c151471 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2022 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -100,8 +100,8 @@
     additionalDescription.set(key, value);
   }
 
-  time::system_clock::TimePoint notBefore;
-  time::system_clock::TimePoint notAfter;
+  time::system_clock::time_point notBefore;
+  time::system_clock::time_point notAfter;
 
   if (vm.count("not-before") == 0) {
     notBefore = time::system_clock::now();