Use std::string_view in several APIs

Change-Id: I2c13b229162b247738cbf46d6bf71fc69d45816f
diff --git a/examples/producer.cpp b/examples/producer.cpp
index 80f1986..e9f7e50 100644
--- a/examples/producer.cpp
+++ b/examples/producer.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).
  *
@@ -56,10 +56,10 @@
   {
     std::cout << ">> I: " << interest << std::endl;
 
-    static const std::string content("Hello, world!");
+    constexpr std::string_view content{"Hello, world!"};
 
     // Create Data packet
-    auto data = make_shared<Data>(interest.getName());
+    auto data = std::make_shared<Data>(interest.getName());
     data->setFreshnessPeriod(10_s);
     data->setContent(make_span(reinterpret_cast<const uint8_t*>(content.data()), content.size()));
 
diff --git a/ndn-cxx/detail/common.hpp b/ndn-cxx/detail/common.hpp
index daf5f7a..631aa2f 100644
--- a/ndn-cxx/detail/common.hpp
+++ b/ndn-cxx/detail/common.hpp
@@ -56,6 +56,7 @@
 #include <memory>
 #include <stdexcept>
 #include <string>
+#include <string_view>
 #include <type_traits>
 #include <utility>
 
@@ -72,8 +73,8 @@
 using std::const_pointer_cast;
 
 using std::to_string;
-
 using namespace std::string_literals;
+using namespace std::string_view_literals;
 
 } // namespace ndn
 
diff --git a/ndn-cxx/encoding/block-helpers.cpp b/ndn-cxx/encoding/block-helpers.cpp
index c3037c8..a4b5e8d 100644
--- a/ndn-cxx/encoding/block-helpers.cpp
+++ b/ndn-cxx/encoding/block-helpers.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).
  *
@@ -28,6 +28,36 @@
 
 namespace endian = boost::endian;
 
+// ---- empty ----
+
+template<Tag TAG>
+size_t
+prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
+{
+  size_t length = encoder.prependVarNumber(0);
+  length += encoder.prependVarNumber(type);
+
+  return length;
+}
+
+template size_t
+prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
+
+template size_t
+prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
+
+Block
+makeEmptyBlock(uint32_t type)
+{
+  EncodingEstimator estimator;
+  size_t totalLength = prependEmptyBlock(estimator, type);
+
+  EncodingBuffer encoder(totalLength, 0);
+  prependEmptyBlock(encoder, type);
+
+  return encoder.block();
+}
+
 // ---- non-negative integer ----
 
 template<Tag TAG>
@@ -66,63 +96,6 @@
   return tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
 }
 
-// ---- empty ----
-
-template<Tag TAG>
-size_t
-prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
-{
-  size_t length = encoder.prependVarNumber(0);
-  length += encoder.prependVarNumber(type);
-
-  return length;
-}
-
-template size_t
-prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
-
-template size_t
-prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
-
-Block
-makeEmptyBlock(uint32_t type)
-{
-  EncodingEstimator estimator;
-  size_t totalLength = prependEmptyBlock(estimator, type);
-
-  EncodingBuffer encoder(totalLength, 0);
-  prependEmptyBlock(encoder, type);
-
-  return encoder.block();
-}
-
-// ---- string ----
-
-template<Tag TAG>
-size_t
-prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
-{
-  return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
-}
-
-template size_t
-prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
-
-template size_t
-prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
-
-Block
-makeStringBlock(uint32_t type, const std::string& value)
-{
-  return makeBinaryBlock(type, value.data(), value.size());
-}
-
-std::string
-readString(const Block& block)
-{
-  return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
-}
-
 // ---- double ----
 
 static_assert(std::numeric_limits<double>::is_iec559, "This code requires IEEE-754 doubles");
@@ -205,6 +178,27 @@
   return encoder.block();
 }
 
+// ---- string ----
+
+template<Tag TAG>
+size_t
+prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value)
+{
+  return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
+}
+
+template size_t
+prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
+
+template size_t
+prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
+
+std::string
+readString(const Block& block)
+{
+  return std::string(reinterpret_cast<const char*>(block.value()), block.value_size());
+}
+
 // ---- block ----
 
 template<Tag TAG>
diff --git a/ndn-cxx/encoding/block-helpers.hpp b/ndn-cxx/encoding/block-helpers.hpp
index 232c2b3..fc74354 100644
--- a/ndn-cxx/encoding/block-helpers.hpp
+++ b/ndn-cxx/encoding/block-helpers.hpp
@@ -29,6 +29,30 @@
 namespace ndn {
 namespace encoding {
 
+/** @brief Prepend an empty TLV element.
+ *  @param encoder an EncodingBuffer or EncodingEstimator
+ *  @param type TLV-TYPE number
+ *  @details The TLV element has zero-length TLV-VALUE.
+ *  @sa makeEmptyBlock
+ */
+template<Tag TAG>
+size_t
+prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
+
+extern template size_t
+prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
+
+extern template size_t
+prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
+
+/** @brief Create an empty TLV block.
+ *  @param type TLV-TYPE number
+ *  @return A TLV block with zero-length TLV-VALUE
+ *  @sa prependEmptyBlock
+ */
+Block
+makeEmptyBlock(uint32_t type);
+
 /** @brief Prepend a TLV element containing a non-negative integer.
  *  @param encoder an EncodingBuffer or EncodingEstimator
  *  @param type TLV-TYPE number
@@ -93,62 +117,6 @@
   return static_cast<R>(readNonNegativeIntegerAs<std::underlying_type_t<R>>(block));
 }
 
-/** @brief Prepend an empty TLV element.
- *  @param encoder an EncodingBuffer or EncodingEstimator
- *  @param type TLV-TYPE number
- *  @details The TLV element has zero-length TLV-VALUE.
- *  @sa makeEmptyBlock
- */
-template<Tag TAG>
-size_t
-prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
-
-extern template size_t
-prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
-
-extern template size_t
-prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
-
-/** @brief Create an empty TLV block.
- *  @param type TLV-TYPE number
- *  @return A TLV block with zero-length TLV-VALUE
- *  @sa prependEmptyBlock
- */
-Block
-makeEmptyBlock(uint32_t type);
-
-/** @brief Prepend a TLV element containing a string.
- *  @param encoder an EncodingBuffer or EncodingEstimator
- *  @param type TLV-TYPE number
- *  @param value string value, may contain NUL octets
- *  @sa makeStringBlock, readString
- */
-template<Tag TAG>
-size_t
-prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
-
-extern template size_t
-prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
-
-extern template size_t
-prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
-
-/** @brief Create a TLV block containing a string.
- *  @param type TLV-TYPE number
- *  @param value string value, may contain NUL octets
- *  @sa prependStringBlock, readString
- */
-Block
-makeStringBlock(uint32_t type, const std::string& value);
-
-/** @brief Read TLV-VALUE of a TLV element as a string.
- *  @param block the TLV element
- *  @return a string, may contain NUL octets
- *  @sa prependStringBlock, makeStringBlock
- */
-std::string
-readString(const Block& block);
-
 /** @brief Prepend a TLV element containing an IEEE 754 double-precision floating-point number.
  *  @param encoder an EncodingBuffer or EncodingEstimator
  *  @param type TLV-TYPE number
@@ -207,18 +175,6 @@
 Block
 makeBinaryBlock(uint32_t type, span<const uint8_t> value);
 
-/** @brief Create a TLV block copying the TLV-VALUE from a raw buffer.
- *  @param type TLV-TYPE number
- *  @param value raw buffer as TLV-VALUE
- *  @param length length of value buffer
- *  @deprecated
- */
-inline Block
-makeBinaryBlock(uint32_t type, const char* value, size_t length)
-{
-  return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value), length});
-}
-
 namespace detail {
 
 /**
@@ -295,6 +251,58 @@
 }
 
 /**
+ * @brief Create a TLV block copying the TLV-VALUE from a char buffer.
+ * @param type TLV-TYPE number
+ * @param value raw buffer as TLV-VALUE
+ * @param length length of value buffer
+ * @deprecated Use makeStringBlock()
+ */
+[[deprecated("use makeStringBlock")]]
+inline Block
+makeBinaryBlock(uint32_t type, const char* value, size_t length)
+{
+  return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value), length});
+}
+
+/**
+ * @brief Prepend a TLV element containing a string.
+ * @param encoder an EncodingBuffer or EncodingEstimator
+ * @param type TLV-TYPE number
+ * @param value string value, may contain NUL octets
+ * @sa makeStringBlock, readString
+ */
+template<Tag TAG>
+size_t
+prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, std::string_view value);
+
+extern template size_t
+prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, std::string_view);
+
+extern template size_t
+prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, std::string_view);
+
+/**
+ * @brief Create a TLV block containing a string.
+ * @param type TLV-TYPE number
+ * @param value string value, may contain NUL octets
+ * @sa prependStringBlock, readString
+ */
+inline Block
+makeStringBlock(uint32_t type, std::string_view value)
+{
+  return makeBinaryBlock(type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
+}
+
+/**
+ * @brief Read the TLV-VALUE of a TLV element as a string.
+ * @param block the TLV element
+ * @return a string, may contain NUL octets
+ * @sa prependStringBlock, makeStringBlock
+ */
+std::string
+readString(const Block& block);
+
+/**
  * @brief Prepend a TLV element.
  * @param encoder an EncodingBuffer or EncodingEstimator
  * @param block the TLV element
@@ -394,13 +402,13 @@
 
 } // namespace encoding
 
+using encoding::makeEmptyBlock;
 using encoding::makeNonNegativeIntegerBlock;
 using encoding::readNonNegativeInteger;
 using encoding::readNonNegativeIntegerAs;
-using encoding::makeEmptyBlock;
+using encoding::makeBinaryBlock;
 using encoding::makeStringBlock;
 using encoding::readString;
-using encoding::makeBinaryBlock;
 using encoding::makeNestedBlock;
 
 } // namespace ndn
diff --git a/ndn-cxx/encoding/nfd-constants.cpp b/ndn-cxx/encoding/nfd-constants.cpp
index 1840c36..28c842a 100644
--- a/ndn-cxx/encoding/nfd-constants.cpp
+++ b/ndn-cxx/encoding/nfd-constants.cpp
@@ -176,13 +176,13 @@
     return os << "none";
   }
 
-  static const std::map<RouteFlags, std::string> knownBits = {
-    {ROUTE_FLAG_CHILD_INHERIT, "child-inherit"},
-    {ROUTE_FLAG_CAPTURE, "capture"}
+  static const std::map<RouteFlags, std::string_view> knownBits = {
+    {ROUTE_FLAG_CHILD_INHERIT, "child-inherit"sv},
+    {ROUTE_FLAG_CAPTURE, "capture"sv}
   };
 
   auto join = make_ostream_joiner(os, '|');
-  for (const auto& [bit, token] : knownBits) {
+  for (auto [bit, token] : knownBits) {
     if ((routeFlags & bit) != 0) {
       join = token;
       routeFlags = static_cast<RouteFlags>(routeFlags & ~bit);
diff --git a/ndn-cxx/face.cpp b/ndn-cxx/face.cpp
index b73039e..f4d685c 100644
--- a/ndn-cxx/face.cpp
+++ b/ndn-cxx/face.cpp
@@ -47,8 +47,8 @@
 
 Face::OversizedPacketError::OversizedPacketError(char pktType, const Name& name, size_t wireSize)
   : Error((pktType == 'I' ? "Interest " : pktType == 'D' ? "Data " : "Nack ") +
-          name.toUri() + " encodes into " + to_string(wireSize) + " octets, "
-          "exceeding the implementation limit of " + to_string(MAX_NDN_PACKET_SIZE) + " octets")
+          name.toUri() + " encodes into " + std::to_string(wireSize) + " octets, "
+          "exceeding the implementation limit of " + std::to_string(MAX_NDN_PACKET_SIZE) + " octets")
   , pktType(pktType)
   , name(name)
   , wireSize(wireSize)
diff --git a/ndn-cxx/impl/name-component-types.hpp b/ndn-cxx/impl/name-component-types.hpp
index ca2a0ac..6f63031 100644
--- a/ndn-cxx/impl/name-component-types.hpp
+++ b/ndn-cxx/impl/name-component-types.hpp
@@ -52,10 +52,11 @@
   {
   }
 
-  /** \brief Calculate the successor of \p comp.
+  /**
+   * \brief Calculate the successor of \p comp.
    *
-   *  If \p comp is the maximum possible value of this component type, return true to indicate
-   *  that the successor should have a greater TLV-TYPE.
+   * If \p comp is the maximum possible value of this component type, return true to indicate
+   * that the successor should have a greater TLV-TYPE.
    */
   virtual std::tuple<bool, Component>
   getSuccessor(const Component& comp) const
@@ -63,7 +64,8 @@
     return {false, Component(std::get<Block>(getSuccessorImpl(comp)))};
   }
 
-  /** \brief Return the minimum allowable TLV-VALUE of this component type.
+  /**
+   * \brief Return the minimum allowable TLV-VALUE of this component type.
    */
   virtual span<const uint8_t>
   getMinValue() const
@@ -72,36 +74,39 @@
     return value;
   }
 
-  /** \brief Return the prefix of the alternate URI representation.
+  /**
+   * \brief Return the prefix of the alternate URI representation.
    *
-   *  NDN URI specification allows a name component type to declare an alternate URI representation
-   *  in the form of `<prefix>=<value>`, in addition to the plain `<type-number>=<escaped-value>`
-   *  syntax.
+   * NDN URI specification allows a name component type to declare an alternate URI representation
+   * in the form of `<prefix>=<value>`, in addition to the plain `<type-number>=<escaped-value>`
+   * syntax.
    *
-   *  \return The `<prefix>` portion of the alternate URI representation.
-   *  \retval nullptr This component does not have an alternate URI representation.
+   * \return The `<prefix>` portion of the alternate URI representation.
+   * \retval empty This component does not have an alternate URI representation.
    */
-  virtual const char*
+  virtual std::string_view
   getAltUriPrefix() const
   {
-    return nullptr;
+    return {};
   }
 
-  /** \brief Parse component from alternate URI representation.
-   *  \param input the `<value>` portion of the alternate URI representation.
-   *  \throw Component::Error
-   *  \pre getAltUriPrefix() != nullptr
+  /**
+   * \brief Parse component from alternate URI representation.
+   * \param input the `<value>` portion of the alternate URI representation.
+   * \throw Component::Error
+   * \pre `getAltUriPrefix().empty() == false`
    */
   virtual Component
-  parseAltUriValue(const std::string& input) const
+  parseAltUriValue(std::string_view input) const
   {
     NDN_CXX_UNREACHABLE;
   }
 
-  /** \brief Write URI representation of \p comp to \p os.
+  /**
+   * \brief Write URI representation of \p comp to \p os.
    *
-   *  This base class implementation encodes the component using the plain
-   *  `<type-number>=<escaped-value>` syntax (aka canonical format).
+   * This base class implementation encodes the component using the plain
+   * `<type-number>=<escaped-value>` syntax (aka canonical format).
    */
   virtual void
   writeUri(std::ostream& os, const Component& comp) const
@@ -151,7 +156,7 @@
     if (isAllPeriods) {
       os << "...";
     }
-    escape(os, reinterpret_cast<const char*>(comp.value()), comp.value_size());
+    escape(os, {reinterpret_cast<const char*>(comp.value()), comp.value_size()});
   }
 };
 
@@ -178,7 +183,8 @@
 class Sha256ComponentType final : public ComponentType
 {
 public:
-  Sha256ComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
+  constexpr
+  Sha256ComponentType(uint32_t type, std::string_view typeName, std::string_view uriPrefix)
     : m_type(type)
     , m_typeName(typeName)
     , m_uriPrefix(uriPrefix)
@@ -190,7 +196,8 @@
   {
     BOOST_ASSERT(comp.type() == m_type);
     if (comp.value_size() != util::Sha256::DIGEST_SIZE) {
-      NDN_THROW(Error(m_typeName + " TLV-LENGTH must be " + to_string(util::Sha256::DIGEST_SIZE)));
+      NDN_THROW(Error(std::string(m_typeName) + " TLV-LENGTH must be " +
+                      std::to_string(util::Sha256::DIGEST_SIZE)));
     }
   }
 
@@ -208,21 +215,21 @@
     return value;
   }
 
-  const char*
+  std::string_view
   getAltUriPrefix() const final
   {
-    return m_uriPrefix.data();
+    return m_uriPrefix;
   }
 
   Component
-  parseAltUriValue(const std::string& input) const final
+  parseAltUriValue(std::string_view input) const final
   {
     shared_ptr<Buffer> value;
     try {
       value = fromHex(input);
     }
     catch (const StringHelperError&) {
-      NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid hex encoding)"));
+      NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid hex encoding)"));
     }
     return {m_type, std::move(value)};
   }
@@ -236,8 +243,8 @@
 
 private:
   const uint32_t m_type;
-  const std::string m_typeName;
-  const std::string m_uriPrefix;
+  const std::string_view m_typeName;
+  const std::string_view m_uriPrefix;
 };
 
 /**
@@ -247,7 +254,8 @@
 class DecimalComponentType final : public ComponentType
 {
 public:
-  DecimalComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
+  constexpr
+  DecimalComponentType(uint32_t type, std::string_view typeName, std::string_view uriPrefix)
     : m_type(type)
     , m_typeName(typeName)
     , m_uriPrefix(uriPrefix)
@@ -259,27 +267,27 @@
   // NonNegativeInteger, because the application may be using the same typed component
   // with different syntax and semantics.
 
-  const char*
+  std::string_view
   getAltUriPrefix() const final
   {
-    return m_uriPrefix.data();
+    return m_uriPrefix;
   }
 
   Component
-  parseAltUriValue(const std::string& input) const final
+  parseAltUriValue(std::string_view input) const final
   {
     uint64_t n = 0;
     try {
-      n = std::stoull(input);
+      n = std::stoull(std::string(input));
     }
     catch (const std::invalid_argument&) {
-      NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
+      NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid format)"));
     }
     catch (const std::out_of_range&) {
-      NDN_THROW(Error("Cannot convert to " + m_typeName + " (out of range)"));
+      NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (out of range)"));
     }
-    if (to_string(n) != input) {
-      NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
+    if (std::to_string(n) != input) {
+      NDN_THROW(Error("Cannot convert to " + std::string(m_typeName) + " (invalid format)"));
     }
     return Component::fromNumber(n, m_type);
   }
@@ -297,8 +305,8 @@
 
 private:
   const uint32_t m_type;
-  const std::string m_typeName;
-  const std::string m_uriPrefix;
+  const std::string_view m_typeName;
+  const std::string_view m_uriPrefix;
 };
 
 /**
@@ -325,7 +333,7 @@
    * \brief Retrieve a ComponentType by its alternate URI prefix.
    */
   const ComponentType*
-  findByUriPrefix(const std::string& prefix) const
+  findByUriPrefix(std::string_view prefix) const
   {
     if (auto it = m_uriPrefixes.find(prefix); it != m_uriPrefixes.end()) {
       return it->second;
@@ -338,7 +346,7 @@
   set(uint32_t type, const ComponentType& ct)
   {
     m_table.at(type) = &ct;
-    if (ct.getAltUriPrefix() != nullptr) {
+    if (!ct.getAltUriPrefix().empty()) {
       m_uriPrefixes[ct.getAltUriPrefix()] = &ct;
     }
   }
@@ -346,7 +354,7 @@
 private:
   const ComponentType m_baseType;
   std::array<const ComponentType*, 60> m_table;
-  std::unordered_map<std::string, const ComponentType*> m_uriPrefixes;
+  std::unordered_map<std::string_view, const ComponentType*> m_uriPrefixes;
 };
 
 inline
@@ -355,10 +363,10 @@
   m_table.fill(nullptr);
 
   static const Sha256ComponentType ct1(tlv::ImplicitSha256DigestComponent,
-                                       "ImplicitSha256DigestComponent", "sha256digest");
+                                       "ImplicitSha256DigestComponent"sv, "sha256digest"sv);
   set(tlv::ImplicitSha256DigestComponent, ct1);
   static const Sha256ComponentType ct2(tlv::ParametersSha256DigestComponent,
-                                       "ParametersSha256DigestComponent", "params-sha256");
+                                       "ParametersSha256DigestComponent"sv, "params-sha256"sv);
   set(tlv::ParametersSha256DigestComponent, ct2);
 
   static const GenericNameComponentType ct8;
@@ -367,15 +375,15 @@
   static const ComponentType ct32;
   set(tlv::KeywordNameComponent, ct32);
 
-  static const DecimalComponentType ct50(tlv::SegmentNameComponent, "SegmentNameComponent", "seg");
+  static const DecimalComponentType ct50(tlv::SegmentNameComponent, "SegmentNameComponent"sv, "seg"sv);
   set(tlv::SegmentNameComponent, ct50);
-  static const DecimalComponentType ct52(tlv::ByteOffsetNameComponent, "ByteOffsetNameComponent", "off");
+  static const DecimalComponentType ct52(tlv::ByteOffsetNameComponent, "ByteOffsetNameComponent"sv, "off"sv);
   set(tlv::ByteOffsetNameComponent, ct52);
-  static const DecimalComponentType ct54(tlv::VersionNameComponent, "VersionNameComponent", "v");
+  static const DecimalComponentType ct54(tlv::VersionNameComponent, "VersionNameComponent"sv, "v"sv);
   set(tlv::VersionNameComponent, ct54);
-  static const DecimalComponentType ct56(tlv::TimestampNameComponent, "TimestampNameComponent", "t");
+  static const DecimalComponentType ct56(tlv::TimestampNameComponent, "TimestampNameComponent"sv, "t"sv);
   set(tlv::TimestampNameComponent, ct56);
-  static const DecimalComponentType ct58(tlv::SequenceNumNameComponent, "SequenceNumNameComponent", "seq");
+  static const DecimalComponentType ct58(tlv::SequenceNumNameComponent, "SequenceNumNameComponent"sv, "seq"sv);
   set(tlv::SequenceNumNameComponent, ct58);
 }
 
diff --git a/ndn-cxx/mgmt/nfd/channel-status.cpp b/ndn-cxx/mgmt/nfd/channel-status.cpp
index 32d69a1..98e72fc 100644
--- a/ndn-cxx/mgmt/nfd/channel-status.cpp
+++ b/ndn-cxx/mgmt/nfd/channel-status.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).
  *
@@ -86,7 +86,7 @@
 }
 
 ChannelStatus&
-ChannelStatus::setLocalUri(const std::string localUri)
+ChannelStatus::setLocalUri(const std::string& localUri)
 {
   m_wire.reset();
   m_localUri = localUri;
diff --git a/ndn-cxx/mgmt/nfd/channel-status.hpp b/ndn-cxx/mgmt/nfd/channel-status.hpp
index 2373ef5..4fbc06b 100644
--- a/ndn-cxx/mgmt/nfd/channel-status.hpp
+++ b/ndn-cxx/mgmt/nfd/channel-status.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).
  *
@@ -64,7 +64,7 @@
   }
 
   ChannelStatus&
-  setLocalUri(const std::string localUri);
+  setLocalUri(const std::string& localUri);
 
 private:
   std::string m_localUri;
diff --git a/ndn-cxx/mgmt/nfd/control-command.cpp b/ndn-cxx/mgmt/nfd/control-command.cpp
index cc6fa13..a6daa76 100644
--- a/ndn-cxx/mgmt/nfd/control-command.cpp
+++ b/ndn-cxx/mgmt/nfd/control-command.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 @@
 }
 
 void
-ControlCommand::applyDefaultsToRequest(ControlParameters& parameters) const
+ControlCommand::applyDefaultsToRequest(ControlParameters&) const
 {
 }
 
@@ -50,7 +50,7 @@
 }
 
 void
-ControlCommand::applyDefaultsToResponse(ControlParameters& parameters) const
+ControlCommand::applyDefaultsToResponse(ControlParameters&) const
 {
 }
 
@@ -81,11 +81,11 @@
     bool isPresent = presentFields[i];
     if (m_required[i]) {
       if (!isPresent) {
-        NDN_THROW(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is required but missing"));
+        NDN_THROW(ArgumentError(std::string(CONTROL_PARAMETER_FIELD[i]) + " is required but missing"));
       }
     }
     else if (isPresent && !m_optional[i]) {
-      NDN_THROW(ArgumentError(CONTROL_PARAMETER_FIELD[i] + " is forbidden but present"));
+      NDN_THROW(ArgumentError(std::string(CONTROL_PARAMETER_FIELD[i]) + " is forbidden but present"));
     }
   }
 
diff --git a/ndn-cxx/mgmt/nfd/control-parameters.hpp b/ndn-cxx/mgmt/nfd/control-parameters.hpp
index 682c590..18e5534 100644
--- a/ndn-cxx/mgmt/nfd/control-parameters.hpp
+++ b/ndn-cxx/mgmt/nfd/control-parameters.hpp
@@ -50,26 +50,26 @@
   CONTROL_PARAMETER_BASE_CONGESTION_MARKING_INTERVAL,
   CONTROL_PARAMETER_DEFAULT_CONGESTION_THRESHOLD,
   CONTROL_PARAMETER_MTU,
-  CONTROL_PARAMETER_UBOUND
+  CONTROL_PARAMETER_UBOUND,
 };
 
-inline const std::string CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
-  "Name",
-  "FaceId",
-  "Uri",
-  "LocalUri",
-  "Origin",
-  "Cost",
-  "Capacity",
-  "Count",
-  "Flags",
-  "Mask",
-  "Strategy",
-  "ExpirationPeriod",
-  "FacePersistency",
-  "BaseCongestionMarkingInterval",
-  "DefaultCongestionThreshold",
-  "Mtu"
+inline constexpr std::string_view CONTROL_PARAMETER_FIELD[CONTROL_PARAMETER_UBOUND] = {
+  "Name"sv,
+  "FaceId"sv,
+  "Uri"sv,
+  "LocalUri"sv,
+  "Origin"sv,
+  "Cost"sv,
+  "Capacity"sv,
+  "Count"sv,
+  "Flags"sv,
+  "Mask"sv,
+  "Strategy"sv,
+  "ExpirationPeriod"sv,
+  "FacePersistency"sv,
+  "BaseCongestionMarkingInterval"sv,
+  "DefaultCongestionThreshold"sv,
+  "Mtu"sv,
 };
 
 /**
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index ece7cc0..cc98046 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -114,12 +114,7 @@
   ensureValid();
 }
 
-Component::Component(const char* str)
-  : Block(makeBinaryBlock(tlv::GenericNameComponent, str, std::char_traits<char>::length(str)))
-{
-}
-
-Component::Component(const std::string& str)
+Component::Component(std::string_view str)
   : Block(makeStringBlock(tlv::GenericNameComponent, str))
 {
 }
@@ -134,10 +129,10 @@
 }
 
 static Component
-parseUriEscapedValue(uint32_t type, const char* input, size_t len)
+parseUriEscapedValue(uint32_t type, std::string_view input)
 {
   std::ostringstream oss;
-  unescape(oss, input, len);
+  unescape(oss, input);
   std::string value = oss.str();
   if (value.find_first_not_of('.') == std::string::npos) { // all periods
     if (value.size() < 3) {
@@ -149,25 +144,23 @@
 }
 
 Component
-Component::fromEscapedString(const std::string& input)
+Component::fromEscapedString(std::string_view input)
 {
   size_t equalPos = input.find('=');
-  if (equalPos == std::string::npos) {
-    return parseUriEscapedValue(tlv::GenericNameComponent, input.data(), input.size());
+  if (equalPos == std::string_view::npos) {
+    return parseUriEscapedValue(tlv::GenericNameComponent, input);
   }
 
   auto typePrefix = input.substr(0, equalPos);
   auto type = std::strtoul(typePrefix.data(), nullptr, 10);
   if (type >= tlv::NameComponentMin && type <= tlv::NameComponentMax &&
       std::to_string(type) == typePrefix) {
-    size_t valuePos = equalPos + 1;
-    return parseUriEscapedValue(static_cast<uint32_t>(type),
-                                input.data() + valuePos, input.size() - valuePos);
+    return parseUriEscapedValue(static_cast<uint32_t>(type), input.substr(equalPos + 1));
   }
 
   auto ct = getComponentTypeTable().findByUriPrefix(typePrefix);
   if (ct == nullptr) {
-    NDN_THROW(Error("Unknown TLV-TYPE '" + typePrefix + "' in NameComponent URI"));
+    NDN_THROW(Error("Unknown TLV-TYPE '" + std::string(typePrefix) + "' in NameComponent URI"));
   }
   return ct->parseAltUriValue(input.substr(equalPos + 1));
 }
diff --git a/ndn-cxx/name-component.hpp b/ndn-cxx/name-component.hpp
index 2c2deeb..839b46e 100644
--- a/ndn-cxx/name-component.hpp
+++ b/ndn-cxx/name-component.hpp
@@ -194,20 +194,12 @@
   }
 
   /**
-   * @brief Construct a GenericNameComponent, copying the TLV-VALUE from a null-terminated string.
-   *
-   * Bytes from the string are copied as is, and not interpreted as URI component.
-   */
-  explicit
-  Component(const char* str);
-
-  /**
    * @brief Construct a GenericNameComponent, copying the TLV-VALUE from a string.
    *
    * Bytes from the string are copied as is, and not interpreted as URI component.
    */
   explicit
-  Component(const std::string& str);
+  Component(std::string_view str);
 
 public: // encoding and URI
   /**
@@ -235,11 +227,13 @@
    * The URI component is read from `[input+beginOffset, input+endOffset)` range.
    *
    * @throw Error URI component does not represent a valid NameComponent.
+   * @deprecated Use fromEscapedString(std::string_view)
    */
+  [[deprecated("use the string_view overload")]]
   static Component
   fromEscapedString(const char* input, size_t beginOffset, size_t endOffset)
   {
-    return fromEscapedString(std::string(input + beginOffset, input + endOffset));
+    return fromEscapedString(std::string_view(input + beginOffset, endOffset - beginOffset));
   }
 
   /**
@@ -247,17 +241,7 @@
    * @throw Error URI component does not represent a valid NameComponent.
    */
   static Component
-  fromEscapedString(const char* input)
-  {
-    return fromEscapedString(std::string(input));
-  }
-
-  /**
-   * @brief Decode NameComponent from a URI component.
-   * @throw Error URI component does not represent a valid NameComponent.
-   */
-  static Component
-  fromEscapedString(const std::string& input);
+  fromEscapedString(std::string_view input);
 
   /**
    * @brief Write `*this` to the output stream, escaping characters according to the NDN URI format.
diff --git a/ndn-cxx/name.cpp b/ndn-cxx/name.cpp
index 42f3f26..1c158ce 100644
--- a/ndn-cxx/name.cpp
+++ b/ndn-cxx/name.cpp
@@ -60,52 +60,47 @@
   m_wire.parse();
 }
 
-Name::Name(const char* uri)
-  : Name(std::string(uri))
-{
-}
-
-Name::Name(std::string uri)
+Name::Name(std::string_view uri)
 {
   if (uri.empty())
     return;
 
-  if (size_t iColon = uri.find(':'); iColon != std::string::npos) {
-    // Make sure the colon came before a '/'.
+  if (size_t iColon = uri.find(':'); iColon != std::string_view::npos) {
+    // Make sure the colon came before a '/', if any.
     size_t iFirstSlash = uri.find('/');
-    if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
-      // Omit the leading protocol such as ndn:
-      uri.erase(0, iColon + 1);
+    if (iFirstSlash == std::string_view::npos || iColon < iFirstSlash) {
+      // Strip the leading protocol such as "ndn:".
+      uri.remove_prefix(iColon + 1);
     }
   }
 
   // Trim the leading slash and possibly the authority.
-  if (uri[0] == '/') {
+  if (uri.size() >= 1 && uri[0] == '/') {
     if (uri.size() >= 2 && uri[1] == '/') {
       // Strip the authority following "//".
       size_t iAfterAuthority = uri.find('/', 2);
-      if (iAfterAuthority == std::string::npos)
+      if (iAfterAuthority == std::string_view::npos) {
         // Unusual case: there was only an authority.
         return;
+      }
       else {
-        uri.erase(0, iAfterAuthority + 1);
+        uri.remove_prefix(iAfterAuthority + 1);
       }
     }
     else {
-      uri.erase(0, 1);
+      uri.remove_prefix(1);
     }
   }
 
-  size_t iComponentStart = 0;
-
   // Unescape the components.
-  while (iComponentStart < uri.size()) {
-    size_t iComponentEnd = uri.find('/', iComponentStart);
-    if (iComponentEnd == std::string::npos)
-      iComponentEnd = uri.size();
-
-    append(Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd));
-    iComponentStart = iComponentEnd + 1;
+  while (!uri.empty()) {
+    auto component = uri.substr(0, uri.find('/'));
+    append(Component::fromEscapedString(component));
+    if (component.size() + 1 >= uri.size()) {
+      // We reached the end of the string.
+      return;
+    }
+    uri.remove_prefix(component.size() + 1);
   }
 }
 
diff --git a/ndn-cxx/name.hpp b/ndn-cxx/name.hpp
index 936cf5b..a45c3fc 100644
--- a/ndn-cxx/name.hpp
+++ b/ndn-cxx/name.hpp
@@ -64,34 +64,51 @@
   using size_type              = component_container::size_type;
 
 public: // constructors, encoding, decoding
-  /** @brief Create an empty name.
-   *  @post empty() == true
+  /**
+   * @brief Create an empty name.
+   * @post empty() == true
    */
   Name();
 
-  /** @brief Decode Name from wire encoding.
-   *  @throw tlv::Error wire encoding is invalid
+  /**
+   * @brief Decode Name from wire encoding.
+   * @throw tlv::Error wire encoding is invalid
    *
-   *  This is a more efficient equivalent for
-   *  @code
-   *    Name name;
-   *    name.wireDecode(wire);
-   *  @endcode
+   * This is a more efficient equivalent for:
+   * @code
+   * Name name;
+   * name.wireDecode(wire);
+   * @endcode
    */
   explicit
   Name(const Block& wire);
 
-  /** @brief Parse name from NDN URI.
-   *  @param uri a null-terminated URI string
-   *  @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+  /**
+   * @brief Create name from NDN URI.
+   * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
    */
-  Name(const char* uri);
+  explicit
+  Name(std::string_view uri);
 
-  /** @brief Create name from NDN URI.
-   *  @param uri a URI string
-   *  @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+  /**
+   * @brief Create name from NDN URI.
+   * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+   * @note This constructor enables implicit conversion from a string literal
    */
-  Name(std::string uri);
+  Name(const char* uri)
+    : Name(std::string_view(uri))
+  {
+  }
+
+  /**
+   * @brief Create name from NDN URI.
+   * @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
+   * @note This constructor enables implicit conversion from `std::string`
+   */
+  Name(const std::string& uri)
+    : Name(std::string_view(uri))
+  {
+  }
 
   /** @brief Write URI representation of the name to the output stream.
    *  @sa https://docs.named-data.net/NDN-packet-spec/0.3/name.html#ndn-uri-scheme
@@ -510,10 +527,10 @@
    * @return A reference to this Name, to allow chaining.
    */
   Name&
-  appendKeyword(const char* keyword)
+  appendKeyword(std::string_view keyword)
   {
-    return append(Component(tlv::KeywordNameComponent, {reinterpret_cast<const uint8_t*>(keyword),
-                                                        std::char_traits<char>::length(keyword)}));
+    return append(Component(tlv::KeywordNameComponent,
+                            {reinterpret_cast<const uint8_t*>(keyword.data()), keyword.size()}));
   }
 
   /**
diff --git a/ndn-cxx/net/ethernet.hpp b/ndn-cxx/net/ethernet.hpp
index ed25834..62b233c 100644
--- a/ndn-cxx/net/ethernet.hpp
+++ b/ndn-cxx/net/ethernet.hpp
@@ -89,8 +89,7 @@
    *        in hexadecimal notation, with colons or hyphens as separators.
    *
    * \param str The string to be parsed
-   * \return Always an instance of Address, which will be null
-   *         if the parsing fails
+   * \return Always an instance of Address, which will be null if parsing fails
    */
   static Address
   fromString(const std::string& str);
diff --git a/ndn-cxx/net/face-uri.cpp b/ndn-cxx/net/face-uri.cpp
index 14db8d9..239c0d2 100644
--- a/ndn-cxx/net/face-uri.cpp
+++ b/ndn-cxx/net/face-uri.cpp
@@ -43,35 +43,30 @@
 
 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FaceUri>));
 
-FaceUri::FaceUri()
-  : m_isV6(false)
-{
-}
+FaceUri::FaceUri() = default;
 
 FaceUri::FaceUri(const std::string& uri)
 {
   if (!parse(uri)) {
-    NDN_THROW(Error("Malformed URI: " + uri));
+    NDN_THROW(Error("Malformed URI: "s + uri));
   }
 }
 
 FaceUri::FaceUri(const char* uri)
-  : FaceUri(std::string(uri))
 {
+  if (!parse(uri)) {
+    NDN_THROW(Error("Malformed URI: "s + uri));
+  }
 }
 
 bool
-FaceUri::parse(const std::string& uri)
+FaceUri::parse(std::string_view uri)
 {
-  m_scheme.clear();
-  m_host.clear();
-  m_port.clear();
-  m_path.clear();
-  m_isV6 = false;
+  *this = {};
 
   static const std::regex protocolExp("(\\w+\\d?(\\+\\w+)?)://([^/]*)(\\/[^?]*)?");
-  std::smatch protocolMatch;
-  if (!std::regex_match(uri, protocolMatch, protocolExp)) {
+  std::match_results<std::string_view::const_iterator> protocolMatch;
+  if (!std::regex_match(uri.begin(), uri.end(), protocolMatch, protocolExp)) {
     return false;
   }
   m_scheme = protocolMatch[1];
@@ -133,7 +128,7 @@
   m_port = to_string(endpoint.port());
 }
 
-FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
+FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, std::string_view scheme)
 {
   m_isV6 = endpoint.address().is_v6();
   m_scheme = scheme;
@@ -145,11 +140,17 @@
 FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
   : m_scheme("unix")
   , m_path(endpoint.path())
-  , m_isV6(false)
 {
 }
 #endif // BOOST_ASIO_HAS_LOCAL_SOCKETS
 
+FaceUri::FaceUri(const ethernet::Address& address)
+  : m_scheme("ether")
+  , m_host(address.toString())
+  , m_isV6(true)
+{
+}
+
 FaceUri
 FaceUri::fromFd(int fd)
 {
@@ -159,15 +160,8 @@
   return uri;
 }
 
-FaceUri::FaceUri(const ethernet::Address& address)
-  : m_scheme("ether")
-  , m_host(address.toString())
-  , m_isV6(true)
-{
-}
-
 FaceUri
-FaceUri::fromDev(const std::string& ifname)
+FaceUri::fromDev(std::string_view ifname)
 {
   FaceUri uri;
   uri.m_scheme = "dev";
@@ -176,7 +170,7 @@
 }
 
 FaceUri
-FaceUri::fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname)
+FaceUri::fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, std::string_view ifname)
 {
   FaceUri uri;
   uri.m_scheme = endpoint.address().is_v6() ? "udp6+dev" : "udp4+dev";
diff --git a/ndn-cxx/net/face-uri.hpp b/ndn-cxx/net/face-uri.hpp
index 412a4ea..d427858 100644
--- a/ndn-cxx/net/face-uri.hpp
+++ b/ndn-cxx/net/face-uri.hpp
@@ -51,24 +51,30 @@
     using std::invalid_argument::invalid_argument;
   };
 
+  /// Construct an empty FaceUri.
   FaceUri();
 
   /**
-   * \brief Construct by parsing.
-   * \param uri scheme://host[:port]/path
-   * \throw FaceUri::Error if URI cannot be parsed
+   * \brief Construct by parsing from a string.
+   * \param uri `scheme://host[:port]/path`
+   * \throw Error URI cannot be parsed
    */
   explicit
   FaceUri(const std::string& uri);
 
-  // This overload is needed so that calls with string literal won't be
-  // resolved to boost::asio::local::stream_protocol::endpoint overload.
+  /**
+   * \brief Construct by parsing from a null-terminated string.
+   * \param uri `scheme://host[:port]/path`
+   * \throw Error URI cannot be parsed
+   * \note This overload is needed so that calls with a string literal won't be
+   *       resolved to the boost::asio::local::stream_protocol::endpoint overload.
+   */
   explicit
   FaceUri(const char* uri);
 
   /// Exception-safe parsing.
   [[nodiscard]] bool
-  parse(const std::string& uri);
+  parse(std::string_view uri);
 
 public: // scheme-specific construction
   /// Construct a udp4 or udp6 canonical FaceUri.
@@ -80,7 +86,7 @@
   FaceUri(const boost::asio::ip::tcp::endpoint& endpoint);
 
   /// Construct a tcp canonical FaceUri with custom scheme.
-  FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme);
+  FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, std::string_view scheme);
 
 #ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
   /// Construct a unix canonical FaceUri.
@@ -88,21 +94,21 @@
   FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint);
 #endif // BOOST_ASIO_HAS_LOCAL_SOCKETS
 
-  /// Construct an fd FaceUri from a file descriptor.
-  static FaceUri
-  fromFd(int fd);
-
   /// Construct an ether canonical FaceUri.
   explicit
   FaceUri(const ethernet::Address& address);
 
+  /// Construct an fd FaceUri from a file descriptor.
+  static FaceUri
+  fromFd(int fd);
+
   /// Construct a dev FaceUri from a network device name.
   static FaceUri
-  fromDev(const std::string& ifname);
+  fromDev(std::string_view ifname);
 
   /// Construct a udp4 or udp6 NIC-associated FaceUri from endpoint and network device name.
   static FaceUri
-  fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, const std::string& ifname);
+  fromUdpDev(const boost::asio::ip::udp::endpoint& endpoint, std::string_view ifname);
 
 public: // getters
   /// Get scheme (protocol)
@@ -112,7 +118,7 @@
     return m_scheme;
   }
 
-  /// Get host (domain)
+  /// Get host (domain or address)
   const std::string&
   getHost() const
   {
@@ -133,7 +139,7 @@
     return m_path;
   }
 
-  /// Serialize as a string
+  /// Return string representation
   std::string
   toString() const;
 
@@ -156,8 +162,9 @@
   using CanonizeFailureCallback = std::function<void(const std::string& reason)>;
 
   /** \brief Asynchronously convert this FaceUri to canonical form.
-   *  \param onSuccess function to call after this FaceUri is converted to canonical form
    *  \note A new FaceUri in canonical form will be created; this FaceUri is unchanged.
+   *
+   *  \param onSuccess function to call after this FaceUri is converted to canonical form
    *  \param onFailure function to call if this FaceUri cannot be converted to canonical form
    *  \param io        reference to `boost::asio::io_service` instance
    *  \param timeout   maximum allowable duration of the operations.
@@ -195,8 +202,7 @@
   std::string m_host;
   std::string m_port;
   std::string m_path;
-  /// whether to add [] around host when writing string
-  bool m_isV6;
+  bool m_isV6 = false; ///< whether to add [] around host when converting to string representation
 
   friend std::ostream& operator<<(std::ostream& os, const FaceUri& uri);
 };
diff --git a/ndn-cxx/security/pib/identity.hpp b/ndn-cxx/security/pib/identity.hpp
index 0bf3821..31acd9b 100644
--- a/ndn-cxx/security/pib/identity.hpp
+++ b/ndn-cxx/security/pib/identity.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).
  *
@@ -176,7 +176,10 @@
   friend std::ostream&
   operator<<(std::ostream& os, const Identity& id)
   {
-    return os << (id ? id.getName() : "(empty)");
+    if (id)
+      return os << id.getName();
+    else
+      return os << "(empty)";
   }
 
 private:
diff --git a/ndn-cxx/security/pib/key.hpp b/ndn-cxx/security/pib/key.hpp
index 3172342..124ddc5 100644
--- a/ndn-cxx/security/pib/key.hpp
+++ b/ndn-cxx/security/pib/key.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).
  *
@@ -195,7 +195,10 @@
   friend std::ostream&
   operator<<(std::ostream& os, const Key& key)
   {
-    return os << (key ? key.getName() : "(empty)");
+    if (key)
+      return os << key.getName();
+    else
+      return os << "(empty)";
   }
 
 private:
diff --git a/ndn-cxx/security/signing-info.cpp b/ndn-cxx/security/signing-info.cpp
index aa73fea..1fd152f 100644
--- a/ndn-cxx/security/signing-info.cpp
+++ b/ndn-cxx/security/signing-info.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).
  *
@@ -24,7 +24,6 @@
 #include "ndn-cxx/encoding/buffer-stream.hpp"
 #include "ndn-cxx/security/transform/base64-decode.hpp"
 #include "ndn-cxx/security/transform/buffer-source.hpp"
-#include "ndn-cxx/security/transform/digest-filter.hpp"
 #include "ndn-cxx/security/transform/stream-sink.hpp"
 
 namespace ndn {
@@ -68,34 +67,34 @@
   this->setPibKey(key);
 }
 
-SigningInfo::SigningInfo(const std::string& signingStr)
+SigningInfo::SigningInfo(std::string_view signingStr)
   : SigningInfo(SIGNER_TYPE_NULL)
 {
   if (signingStr.empty()) {
     return;
   }
 
-  size_t pos = signingStr.find(':');
-  if (pos == std::string::npos) {
+  auto pos = signingStr.find(':');
+  if (pos == std::string_view::npos) {
     NDN_THROW(std::invalid_argument("Invalid signing string cannot represent SigningInfo"));
   }
 
-  std::string scheme = signingStr.substr(0, pos);
-  std::string nameArg = signingStr.substr(pos + 1);
+  auto scheme = signingStr.substr(0, pos);
+  auto nameArg = signingStr.substr(pos + 1);
 
   if (scheme == "id") {
     if (nameArg == getDigestSha256Identity().toUri()) {
       setSha256Signing();
     }
     else {
-      setSigningIdentity(nameArg);
+      setSigningIdentity(Name(nameArg));
     }
   }
   else if (scheme == "key") {
-    setSigningKeyName(nameArg);
+    setSigningKeyName(Name(nameArg));
   }
   else if (scheme == "cert") {
-    setSigningCertName(nameArg);
+    setSigningCertName(Name(nameArg));
   }
   else if (scheme == "hmac-sha256") {
     setSigningHmacKey(nameArg);
@@ -133,7 +132,7 @@
 }
 
 SigningInfo&
-SigningInfo::setSigningHmacKey(const std::string& hmacKey)
+SigningInfo::setSigningHmacKey(std::string_view hmacKey)
 {
   m_type = SIGNER_TYPE_HMAC;
 
diff --git a/ndn-cxx/security/signing-info.hpp b/ndn-cxx/security/signing-info.hpp
index 7a87a3f..1cf56fa 100644
--- a/ndn-cxx/security/signing-info.hpp
+++ b/ndn-cxx/security/signing-info.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).
  *
@@ -114,7 +114,7 @@
    * - sign with SHA-256 (digest only): `id:/localhost/identity/digest-sha256`
    */
   explicit
-  SigningInfo(const std::string& signingStr);
+  SigningInfo(std::string_view signingStr);
 
   /**
    * @brief Set signer as an identity with name @p identity
@@ -142,7 +142,7 @@
    * @post Change the signerType to SIGNER_TYPE_HMAC
    */
   SigningInfo&
-  setSigningHmacKey(const std::string& hmacKey);
+  setSigningHmacKey(std::string_view hmacKey);
 
   /**
    * @brief Set SHA-256 as the signing method
diff --git a/ndn-cxx/security/transform/buffer-source.cpp b/ndn-cxx/security/transform/buffer-source.cpp
index e050f7f..8333368 100644
--- a/ndn-cxx/security/transform/buffer-source.cpp
+++ b/ndn-cxx/security/transform/buffer-source.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).
  *
@@ -30,7 +30,7 @@
 {
 }
 
-BufferSource::BufferSource(const std::string& string)
+BufferSource::BufferSource(std::string_view string)
   : m_bufs({{reinterpret_cast<const uint8_t*>(string.data()), string.size()}})
 {
 }
diff --git a/ndn-cxx/security/transform/buffer-source.hpp b/ndn-cxx/security/transform/buffer-source.hpp
index 9a9cd64..7d87320 100644
--- a/ndn-cxx/security/transform/buffer-source.hpp
+++ b/ndn-cxx/security/transform/buffer-source.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_SECURITY_TRANSFORM_BUFFER_SOURCE_HPP
 
 #include "ndn-cxx/security/transform/transform-base.hpp"
-#include "ndn-cxx/encoding/buffer.hpp"
 #include "ndn-cxx/security/security-common.hpp"
 
 namespace ndn {
@@ -50,7 +49,7 @@
    * Caller must not destroy the string before the transformation is completed.
    */
   explicit
-  BufferSource(const std::string& string);
+  BufferSource(std::string_view string);
 
   /**
    * @brief Take @p buffers as input.
diff --git a/ndn-cxx/security/validator-config/checker.cpp b/ndn-cxx/security/validator-config/checker.cpp
index 675a54b..c11b477 100644
--- a/ndn-cxx/security/validator-config/checker.cpp
+++ b/ndn-cxx/security/validator-config/checker.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).
  *
@@ -22,8 +22,6 @@
 #include "ndn-cxx/security/validator-config/checker.hpp"
 #include "ndn-cxx/security/validation-policy.hpp"
 #include "ndn-cxx/security/validation-state.hpp"
-#include "ndn-cxx/security/verification-helpers.hpp"
-#include "ndn-cxx/security/pib/key.hpp"
 
 #include <boost/algorithm/string/predicate.hpp>
 
@@ -147,8 +145,8 @@
 }
 
 HyperRelationChecker::HyperRelationChecker(tlv::SignatureTypeValue sigType,
-                                           const std::string& pktNameExpr, const std::string pktNameExpand,
-                                           const std::string& klNameExpr, const std::string klNameExpand,
+                                           const std::string& pktNameExpr, const std::string& pktNameExpand,
+                                           const std::string& klNameExpr, const std::string& klNameExpand,
                                            const NameRelation& hyperRelation)
   : Checker(sigType)
   , m_hyperPRegex(pktNameExpr, pktNameExpand)
diff --git a/ndn-cxx/security/validator-config/checker.hpp b/ndn-cxx/security/validator-config/checker.hpp
index fa5c021..1156011 100644
--- a/ndn-cxx/security/validator-config/checker.hpp
+++ b/ndn-cxx/security/validator-config/checker.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).
  *
@@ -170,8 +170,8 @@
 {
 public:
   HyperRelationChecker(tlv::SignatureTypeValue sigType,
-                       const std::string& pktNameExpr, const std::string pktNameExpand,
-                       const std::string& klNameExpr, const std::string klNameExpand,
+                       const std::string& pktNameExpr, const std::string& pktNameExpand,
+                       const std::string& klNameExpr, const std::string& klNameExpand,
                        const NameRelation& hyperRelation);
 
 protected:
diff --git a/ndn-cxx/transport/tcp-transport.cpp b/ndn-cxx/transport/tcp-transport.cpp
index 0c5e516..20360ef 100644
--- a/ndn-cxx/transport/tcp-transport.cpp
+++ b/ndn-cxx/transport/tcp-transport.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,6 +21,7 @@
 
 #include "ndn-cxx/transport/tcp-transport.hpp"
 #include "ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp"
+
 #include "ndn-cxx/net/face-uri.hpp"
 #include "ndn-cxx/util/logger.hpp"
 
@@ -29,7 +30,7 @@
 
 namespace ndn {
 
-TcpTransport::TcpTransport(const std::string& host, const std::string& port/* = "6363"*/)
+TcpTransport::TcpTransport(const std::string& host, const std::string& port)
   : m_host(host)
   , m_port(port)
 {
@@ -40,8 +41,8 @@
 shared_ptr<TcpTransport>
 TcpTransport::create(const std::string& uri)
 {
-  const auto hostAndPort(getSocketHostAndPortFromUri(uri));
-  return make_shared<TcpTransport>(hostAndPort.first, hostAndPort.second);
+  auto [host, port] = getSocketHostAndPortFromUri(uri);
+  return make_shared<TcpTransport>(host, port);
 }
 
 std::pair<std::string, std::string>
@@ -57,7 +58,7 @@
   try {
     const FaceUri uri(uriString);
 
-    const std::string scheme = uri.getScheme();
+    const auto& scheme = uri.getScheme();
     if (scheme != "tcp" && scheme != "tcp4" && scheme != "tcp6") {
       NDN_THROW(Error("Cannot create TcpTransport from \"" + scheme + "\" URI"));
     }
@@ -65,7 +66,6 @@
     if (!uri.getHost().empty()) {
       host = uri.getHost();
     }
-
     if (!uri.getPort().empty()) {
       port = uri.getPort();
     }
diff --git a/ndn-cxx/transport/unix-transport.cpp b/ndn-cxx/transport/unix-transport.cpp
index b8404eb..110423a 100644
--- a/ndn-cxx/transport/unix-transport.cpp
+++ b/ndn-cxx/transport/unix-transport.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).
  *
@@ -22,7 +22,6 @@
 #include "ndn-cxx/transport/unix-transport.hpp"
 #include "ndn-cxx/transport/detail/stream-transport-impl.hpp"
 
-#include "ndn-cxx/face.hpp"
 #include "ndn-cxx/net/face-uri.hpp"
 #include "ndn-cxx/util/logger.hpp"
 
diff --git a/ndn-cxx/util/indented-stream.cpp b/ndn-cxx/util/indented-stream.cpp
index ba78f33..e178c13 100644
--- a/ndn-cxx/util/indented-stream.cpp
+++ b/ndn-cxx/util/indented-stream.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2023 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,7 +30,7 @@
 namespace ndn {
 namespace util {
 
-IndentedStream::IndentedStream(std::ostream& os, const std::string& indent)
+IndentedStream::IndentedStream(std::ostream& os, std::string_view indent)
   : std::ostream(&m_buffer)
   , m_buffer(os, indent)
 {
@@ -41,7 +41,7 @@
   flush();
 }
 
-IndentedStream::StreamBuf::StreamBuf(std::ostream& os, const std::string& indent)
+IndentedStream::StreamBuf::StreamBuf(std::ostream& os, std::string_view indent)
   : m_output(os)
   , m_indent(indent)
 {
@@ -50,9 +50,9 @@
 int
 IndentedStream::StreamBuf::sync()
 {
-  typedef boost::iterator_range<std::string::const_iterator> StringView;
+  using StringView = boost::iterator_range<std::string::const_iterator>;
 
-  const std::string& output = str();
+  std::string output = str();
   std::vector<StringView> splitOutput;
   boost::split(splitOutput, output, boost::is_any_of("\n"));
 
diff --git a/ndn-cxx/util/indented-stream.hpp b/ndn-cxx/util/indented-stream.hpp
index 7b05960..b2d5059 100644
--- a/ndn-cxx/util/indented-stream.hpp
+++ b/ndn-cxx/util/indented-stream.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).
  *
@@ -54,7 +54,7 @@
 class IndentedStream : public std::ostream
 {
 public:
-  IndentedStream(std::ostream& os, const std::string& indent);
+  IndentedStream(std::ostream& os, std::string_view indent);
 
   ~IndentedStream() override;
 
@@ -63,7 +63,7 @@
   class StreamBuf : public std::stringbuf
   {
   public:
-    StreamBuf(std::ostream& os, const std::string& indent);
+    StreamBuf(std::ostream& os, std::string_view indent);
 
     int
     sync() override;
diff --git a/ndn-cxx/util/logger.cpp b/ndn-cxx/util/logger.cpp
index 4ebdf15..c9bea26 100644
--- a/ndn-cxx/util/logger.cpp
+++ b/ndn-cxx/util/logger.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).
  *
@@ -22,8 +22,6 @@
 #include "ndn-cxx/util/logger.hpp"
 #include "ndn-cxx/util/logging.hpp"
 
-#include <cstring> // for std::strspn()
-
 namespace ndn {
 namespace util {
 
@@ -49,11 +47,11 @@
     return os << "ALL";
   }
 
-  NDN_THROW(std::invalid_argument("unknown log level " + to_string(to_underlying(level))));
+  NDN_THROW(std::invalid_argument("unknown log level " + std::to_string(to_underlying(level))));
 }
 
 LogLevel
-parseLogLevel(const std::string& s)
+parseLogLevel(std::string_view s)
 {
   if (s == "FATAL")
     return LogLevel::FATAL;
@@ -72,24 +70,19 @@
   else if (s == "ALL")
     return LogLevel::ALL;
 
-  NDN_THROW(std::invalid_argument("unrecognized log level '" + s + "'"));
+  NDN_THROW(std::invalid_argument("unrecognized log level '" + std::string(s) + "'"));
 }
 
-static bool
-isValidLoggerName(const std::string& name)
+static constexpr bool
+isValidLoggerName(std::string_view name)
 {
+  if (name.empty() || name.front() == '.' || name.back() == '.' ||
+      name.find("..") != std::string_view::npos) {
+    return false;
+  }
   // acceptable characters for Logger name
-  const char* okChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~#%_<>.-";
-  if (std::strspn(name.c_str(), okChars) != name.size()) {
-    return false;
-  }
-  if (name.empty() || name.front() == '.' || name.back() == '.') {
-    return false;
-  }
-  if (name.find("..") != std::string::npos) {
-    return false;
-  }
-  return true;
+  constexpr std::string_view okChars{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~#%_<>.-"sv};
+  return name.find_first_not_of(okChars) == std::string_view::npos;
 }
 
 Logger::Logger(const char* name)
@@ -99,18 +92,17 @@
     NDN_THROW(std::invalid_argument("Logger name '" + m_moduleName + "' is invalid"));
   }
   this->setLevel(LogLevel::NONE);
-  this->add_attribute(log::module.get_name(), boost::log::attributes::constant<std::string>(m_moduleName));
+  this->add_attribute(log::module.get_name(), boost::log::attributes::constant(m_moduleName));
   Logging::get().addLoggerImpl(*this);
 }
 
 void
 Logger::registerModuleName(const char* name)
 {
-  std::string moduleName(name);
-  if (!isValidLoggerName(moduleName)) {
-    NDN_THROW(std::invalid_argument("Logger name '" + moduleName + "' is invalid"));
+  if (!isValidLoggerName(name)) {
+    NDN_THROW(std::invalid_argument("Logger name '"s + name + "' is invalid"));
   }
-  Logging::get().registerLoggerNameImpl(std::move(moduleName));
+  Logging::get().registerLoggerNameImpl(name);
 }
 
 } // namespace util
diff --git a/ndn-cxx/util/logger.hpp b/ndn-cxx/util/logger.hpp
index bdf1c07..3261b85 100644
--- a/ndn-cxx/util/logger.hpp
+++ b/ndn-cxx/util/logger.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).
  *
@@ -37,7 +37,8 @@
 namespace ndn {
 namespace util {
 
-/** \brief Indicates the severity level of a log message.
+/**
+ * \brief Indicates the severity level of a log message.
  */
 enum class LogLevel {
   FATAL   = -1,   ///< fatal (will be logged unconditionally)
@@ -50,17 +51,19 @@
   ALL     = 255   ///< all messages
 };
 
-/** \brief Output LogLevel as a string.
- *  \throw std::invalid_argument unknown \p level
+/**
+ * \brief Output LogLevel as a string.
+ * \throw std::invalid_argument Unknown \p level
  */
 std::ostream&
 operator<<(std::ostream& os, LogLevel level);
 
-/** \brief Parse LogLevel from a string.
- *  \throw std::invalid_argument unknown level name
+/**
+ * \brief Parse LogLevel from a string.
+ * \throw std::invalid_argument Unknown level name
  */
 LogLevel
-parseLogLevel(const std::string& s);
+parseLogLevel(std::string_view s);
 
 namespace log {
 
@@ -69,10 +72,11 @@
 
 } // namespace log
 
-/** \brief Represents a log module in the logging facility.
+/**
+ * \brief Represents a log module in the logging facility.
  *
- *  \note Normally, loggers should be defined using #NDN_LOG_INIT, #NDN_LOG_MEMBER_INIT,
- *        or #NDN_LOG_MEMBER_INIT_SPECIALIZED.
+ * \note Normally, loggers should be defined using #NDN_LOG_INIT, #NDN_LOG_MEMBER_INIT,
+ *       or #NDN_LOG_MEMBER_INIT_SPECIALIZED.
  */
 class Logger : public boost::log::sources::severity_logger_mt<LogLevel>
 {
diff --git a/ndn-cxx/util/sha256.cpp b/ndn-cxx/util/sha256.cpp
index c789a7e..66355d6 100644
--- a/ndn-cxx/util/sha256.cpp
+++ b/ndn-cxx/util/sha256.cpp
@@ -92,7 +92,7 @@
 }
 
 Sha256&
-Sha256::operator<<(const std::string& str)
+Sha256::operator<<(std::string_view str)
 {
   update({reinterpret_cast<const uint8_t*>(str.data()), str.size()});
   return *this;
diff --git a/ndn-cxx/util/sha256.hpp b/ndn-cxx/util/sha256.hpp
index 76a094e..2e7b09c 100644
--- a/ndn-cxx/util/sha256.hpp
+++ b/ndn-cxx/util/sha256.hpp
@@ -122,7 +122,7 @@
    * @throw Error the digest has already been finalized
    */
   Sha256&
-  operator<<(const std::string& str);
+  operator<<(std::string_view str);
 
   /**
    * @brief Add a uint64_t value to the digest calculation.
diff --git a/ndn-cxx/util/string-helper.cpp b/ndn-cxx/util/string-helper.cpp
index 011f967..ef7f85b 100644
--- a/ndn-cxx/util/string-helper.cpp
+++ b/ndn-cxx/util/string-helper.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).
  *
@@ -57,7 +57,7 @@
 }
 
 shared_ptr<Buffer>
-fromHex(const std::string& hexString)
+fromHex(std::string_view hexString)
 {
   namespace tr = security::transform;
 
@@ -73,18 +73,17 @@
 }
 
 std::string
-escape(const std::string& str)
+escape(std::string_view str)
 {
   std::ostringstream os;
-  escape(os, str.data(), str.size());
+  escape(os, str);
   return os.str();
 }
 
 void
-escape(std::ostream& os, const char* str, size_t len)
+escape(std::ostream& os, std::string_view str)
 {
-  for (size_t i = 0; i < len; ++i) {
-    auto c = str[i];
+  for (auto c : str) {
     // Unreserved characters don't need to be escaped.
     if ((c >= 'a' && c <= 'z') ||
         (c >= 'A' && c <= 'Z') ||
@@ -102,18 +101,18 @@
 }
 
 std::string
-unescape(const std::string& str)
+unescape(std::string_view str)
 {
   std::ostringstream os;
-  unescape(os, str.data(), str.size());
+  unescape(os, str);
   return os.str();
 }
 
 void
-unescape(std::ostream& os, const char* str, size_t len)
+unescape(std::ostream& os, std::string_view str)
 {
-  for (size_t i = 0; i < len; ++i) {
-    if (str[i] == '%' && i + 2 < len) {
+  for (size_t i = 0; i < str.size(); ++i) {
+    if (str[i] == '%' && i + 2 < str.size()) {
       int hi = fromHexChar(str[i + 1]);
       int lo = fromHexChar(str[i + 2]);
 
diff --git a/ndn-cxx/util/string-helper.hpp b/ndn-cxx/util/string-helper.hpp
index 4447df4..9aa58c9 100644
--- a/ndn-cxx/util/string-helper.hpp
+++ b/ndn-cxx/util/string-helper.hpp
@@ -109,7 +109,7 @@
  * @throw StringHelperError Input string is invalid
  */
 shared_ptr<Buffer>
-fromHex(const std::string& hexString);
+fromHex(std::string_view hexString);
 
 /**
  * @brief Convert (the least significant nibble of) @p n to the corresponding hex character.
@@ -152,10 +152,17 @@
  * @see RFC 3986 section 2
  */
 [[nodiscard]] std::string
-escape(const std::string& str);
+escape(std::string_view str);
 
 void
-escape(std::ostream& os, const char* str, size_t len);
+escape(std::ostream& os, std::string_view str);
+
+[[deprecated("use the string_view overload")]]
+inline void
+escape(std::ostream& os, const char* str, size_t len)
+{
+  escape(os, {str, len});
+}
 
 /**
  * @brief Decode a percent-encoded string.
@@ -172,10 +179,17 @@
  * @see RFC 3986 section 2
  */
 [[nodiscard]] std::string
-unescape(const std::string& str);
+unescape(std::string_view str);
 
 void
-unescape(std::ostream& os, const char* str, size_t len);
+unescape(std::ostream& os, std::string_view str);
+
+[[deprecated("use the string_view overload")]]
+inline void
+unescape(std::ostream& os, const char* str, size_t len)
+{
+  unescape(os, {str, len});
+}
 
 } // namespace ndn
 
diff --git a/tests/test-home-fixture.hpp b/tests/test-home-fixture.hpp
index 3e3673f..5778a6e 100644
--- a/tests/test-home-fixture.hpp
+++ b/tests/test-home-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).
  *
@@ -46,7 +46,6 @@
 {
 public:
   PibDirFixture()
-    : m_pibDir(Path().PATH)
   {
     if (std::getenv("NDN_CLIENT_PIB") != nullptr) {
       m_oldPib = std::getenv("NDN_CLIENT_PIB");
@@ -81,7 +80,7 @@
   }
 
 protected:
-  const std::string m_pibDir;
+  const std::string m_pibDir{Path::PATH};
 
 private:
   std::string m_oldPib;
@@ -119,7 +118,7 @@
 
 struct DefaultPibDir
 {
-  const std::string PATH = "build/keys";
+  static constexpr std::string_view PATH{"build/keys"};
 };
 
 } // namespace tests
diff --git a/tests/unit/encoding/block-helpers.t.cpp b/tests/unit/encoding/block-helpers.t.cpp
index 9325851..ed8641e 100644
--- a/tests/unit/encoding/block-helpers.t.cpp
+++ b/tests/unit/encoding/block-helpers.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).
  *
@@ -31,6 +31,13 @@
 BOOST_AUTO_TEST_SUITE(Encoding)
 BOOST_AUTO_TEST_SUITE(TestBlockHelpers)
 
+BOOST_AUTO_TEST_CASE(Empty)
+{
+  Block b = makeEmptyBlock(200);
+  BOOST_CHECK_EQUAL(b.type(), 200);
+  BOOST_CHECK_EQUAL(b.value_size(), 0);
+}
+
 enum E8 : uint8_t
 {
   E8_NONE
@@ -69,21 +76,6 @@
   BOOST_CHECK_EQUAL(static_cast<uint16_t>(readNonNegativeIntegerAs<EC16>(b)), 1000);
 }
 
-BOOST_AUTO_TEST_CASE(Empty)
-{
-  Block b = makeEmptyBlock(200);
-  BOOST_CHECK_EQUAL(b.type(), 200);
-  BOOST_CHECK_EQUAL(b.value_size(), 0);
-}
-
-BOOST_AUTO_TEST_CASE(String)
-{
-  Block b = makeStringBlock(100, "Hello, world!");
-  BOOST_CHECK_EQUAL(b.type(), 100);
-  BOOST_CHECK_GT(b.value_size(), 0);
-  BOOST_CHECK_EQUAL(readString(b), "Hello, world!");
-}
-
 BOOST_AUTO_TEST_CASE(Double)
 {
   const double f = 0.25;
@@ -103,29 +95,41 @@
 
 BOOST_AUTO_TEST_CASE(Binary)
 {
-  std::string buf1{1, 1, 1, 1};
+  const std::string buf1{1, 1, 1, 1};
   const uint8_t buf2[]{1, 1, 1, 1};
-  std::list<uint8_t> buf3{1, 1, 1, 1};
+  const std::list<uint8_t> buf3{1, 1, 1, 1};
 
-  Block b1 = makeBinaryBlock(100, buf1.data(), buf1.size()); // char* overload
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  Block b1 = makeBinaryBlock(100, buf1.data(), buf1.size()); // char* overload (deprecated)
+#pragma GCC diagnostic pop
   Block b2 = makeBinaryBlock(100, buf2);                     // span overload
   Block b3 = makeBinaryBlock(100, buf1.begin(), buf1.end()); // fast encoding (random access iterator)
   Block b4 = makeBinaryBlock(100, buf3.begin(), buf3.end()); // slow encoding (general iterator)
 
-  BOOST_CHECK_EQUAL(b1, b2);
-  BOOST_CHECK_EQUAL(b1, b3);
-  BOOST_CHECK_EQUAL(b1, b4);
-  BOOST_CHECK_EQUAL(b1.type(), 100);
-  BOOST_CHECK_EQUAL(b1.value_size(), buf1.size());
-  BOOST_CHECK_EQUAL_COLLECTIONS(b1.value_begin(), b1.value_end(), buf2, buf2 + sizeof(buf2));
+  BOOST_TEST(b1 == b2);
+  BOOST_TEST(b1 == b3);
+  BOOST_TEST(b1 == b4);
+  BOOST_TEST(b1.type() == 100);
+  BOOST_TEST(b1.value_size() == sizeof(buf2));
+  BOOST_TEST(b1.value_bytes() == buf2, boost::test_tools::per_element());
 
   EncodingEstimator estimator;
   size_t length = prependBinaryBlock(estimator, 100, buf2);
-  BOOST_CHECK_EQUAL(length, 6);
+  BOOST_TEST(length == 6);
 
   EncodingBuffer encoder(length, 0);
-  BOOST_CHECK_EQUAL(prependBinaryBlock(encoder, 100, buf2), 6);
-  BOOST_CHECK_EQUAL(encoder.block(), b1);
+  BOOST_TEST(prependBinaryBlock(encoder, 100, buf2) == 6);
+  BOOST_TEST(encoder.block() == b1);
+}
+
+BOOST_AUTO_TEST_CASE(String)
+{
+  constexpr std::string_view sv{"Hello, world!"sv};
+  Block b = makeStringBlock(100, sv);
+  BOOST_TEST(b.type() == 100);
+  BOOST_TEST(b.value_size() == sv.size());
+  BOOST_TEST(readString(b) == sv);
 }
 
 BOOST_AUTO_TEST_CASE(PrependBlock)
diff --git a/tests/unit/face.t.cpp b/tests/unit/face.t.cpp
index 2372e24..94a2649 100644
--- a/tests/unit/face.t.cpp
+++ b/tests/unit/face.t.cpp
@@ -854,11 +854,6 @@
 
 using ndn::Transport;
 
-struct PibDirWithDefaultTpm
-{
-  const std::string PATH = "build/keys-with-default-tpm";
-};
-
 BOOST_FIXTURE_TEST_CASE(FaceTransport, IoKeyChainFixture)
 {
   BOOST_CHECK(Face().getTransport() != nullptr);
diff --git a/tests/unit/name.t.cpp b/tests/unit/name.t.cpp
index bfddb4f..cfe13e0 100644
--- a/tests/unit/name.t.cpp
+++ b/tests/unit/name.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).
  *
@@ -68,13 +68,19 @@
 
   // URI with correct scheme
   BOOST_CHECK_EQUAL(Name("ndn:/hello/world").toUri(), "/hello/world");
+  BOOST_CHECK_EQUAL(Name("ndn:/").toUri(), "/");
+  BOOST_CHECK_EQUAL(Name("ndn:").toUri(), "/");
 
   // URI with incorrect scheme: auto-corrected
   BOOST_CHECK_EQUAL(Name("ncc:/hello/world").toUri(), "/hello/world");
+  BOOST_CHECK_EQUAL(Name(":/").toUri(), "/");
+  BOOST_CHECK_EQUAL(Name(":").toUri(), "/");
 
   // URI with authority: authority ignored
   BOOST_CHECK_EQUAL(Name("//authority/hello/world").toUri(), "/hello/world");
   BOOST_CHECK_EQUAL(Name("ndn://authority/hello/world").toUri(), "/hello/world");
+  BOOST_CHECK_EQUAL(Name("//authority").toUri(), "/");
+  BOOST_CHECK_EQUAL(Name("ndn://").toUri(), "/");
 
   // URI containing unescaped characters: auto-corrected
   BOOST_CHECK_EQUAL(Name("/ hello\t/\tworld \r\n").toUri(), "/%20hello%09/%09world%20%0D%0A");
@@ -84,8 +90,12 @@
   // URI not starting with '/': accepted as PartialName
   BOOST_CHECK_EQUAL(Name("").toUri(), "/");
   BOOST_CHECK_EQUAL(Name(" ").toUri(), "/%20");
+  BOOST_CHECK_EQUAL(Name("ndn: ").toUri(), "/%20");
+  BOOST_CHECK_EQUAL(Name("ndn: /").toUri(), "/%20");
   BOOST_CHECK_EQUAL(Name("  /hello/world").toUri(), "/%20%20/hello/world");
   BOOST_CHECK_EQUAL(Name("hello/world").toUri(), "/hello/world");
+  BOOST_CHECK_EQUAL(Name("hello").toUri(), "/hello");
+  BOOST_CHECK_EQUAL(Name("ndn:hello").toUri(), "/hello");
 
   // URI ending with '/': auto-corrected
   BOOST_CHECK_EQUAL(Name("/hello/world/").toUri(), "/hello/world");
diff --git a/tests/unit/security/key-chain.t.cpp b/tests/unit/security/key-chain.t.cpp
index 9bd97af..be544a4 100644
--- a/tests/unit/security/key-chain.t.cpp
+++ b/tests/unit/security/key-chain.t.cpp
@@ -59,7 +59,7 @@
 
 struct PibPathConfigFileHome
 {
-  const std::string PATH = "build/config-file-home/";
+  static constexpr std::string_view PATH = "build/config-file-home/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorNormalConfig, TestHomeAndPibFixture<PibPathConfigFileHome>)
@@ -74,7 +74,7 @@
 
 struct PibPathConfigFileEmptyHome
 {
-  const std::string PATH = "build/config-file-empty-home/";
+  static constexpr std::string_view PATH = "build/config-file-empty-home/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorEmptyConfig, TestHomeAndPibFixture<PibPathConfigFileEmptyHome>)
@@ -122,7 +122,7 @@
 
 struct PibPathConfigFileEmpty2Home
 {
-  const std::string PATH = "build/config-file-empty2-home/";
+  static constexpr std::string_view PATH = "build/config-file-empty2-home/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorEmptyConfig2, TestHomeAndPibFixture<PibPathConfigFileEmpty2Home>)
@@ -137,7 +137,7 @@
 
 struct PibPathConfigFileMalformedHome
 {
-  const std::string PATH = "build/config-file-malformed-home/";
+  static constexpr std::string_view PATH = "build/config-file-malformed-home/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorBadConfig, TestHomeAndPibFixture<PibPathConfigFileMalformedHome>)
@@ -148,7 +148,7 @@
 
 struct PibPathConfigFileMalformed2Home
 {
-  const std::string PATH = "build/config-file-malformed2-home/";
+  static constexpr std::string_view PATH = "build/config-file-malformed2-home/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorBadConfig2, TestHomeAndPibFixture<PibPathConfigFileMalformed2Home>)
@@ -159,7 +159,7 @@
 
 struct PibPathConfigFileNonCanonicalTpm
 {
-  const std::string PATH = "build/config-file-non-canonical-tpm/";
+  static constexpr std::string_view PATH = "build/config-file-non-canonical-tpm/";
 };
 
 BOOST_FIXTURE_TEST_CASE(ConstructorNonCanonicalTpm, TestHomeAndPibFixture<PibPathConfigFileNonCanonicalTpm>) // Bug 4297
diff --git a/tests/unit/util/logging.t.cpp b/tests/unit/util/logging.t.cpp
index 821e11e..02da03a 100644
--- a/tests/unit/util/logging.t.cpp
+++ b/tests/unit/util/logging.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-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).
  *
@@ -162,7 +162,7 @@
 NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, double>), ndn.util.tests.Specialized1);
 NDN_LOG_MEMBER_INIT_SPECIALIZED((ClassTemplateWithLogger<int, std::string>), ndn.util.tests.Specialized2);
 
-const time::microseconds LOG_SYSTIME(1468108800311239LL);
+constexpr time::microseconds LOG_SYSTIME{1468108800311239LL};
 const std::string LOG_SYSTIME_STR("1468108800.311239");
 
 class LoggingFixture : public ndn::tests::ClockFixture
@@ -177,7 +177,7 @@
     Logging::setDestination(os, true);
   }
 
-  ~LoggingFixture()
+  ~LoggingFixture() override
   {
     Logging::get().setLevelImpl(m_oldEnabledLevel);
     Logging::setDestination(m_oldDestination);
diff --git a/tests/unit/util/string-helper.t.cpp b/tests/unit/util/string-helper.t.cpp
index e3229e5..3816fab 100644
--- a/tests/unit/util/string-helper.t.cpp
+++ b/tests/unit/util/string-helper.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).
  *
@@ -182,8 +182,7 @@
   BOOST_CHECK_EQUAL(escape(":/?#[]@"), "%3A%2F%3F%23%5B%5D%40");
 
   output_test_stream os;
-  const char str[] = "\x01\x2a\x3b\xc4\xde\xfa\xb5\xcd\xef";
-  escape(os, str, std::strlen(str));
+  escape(os, "\x01\x2a\x3b\xc4\xde\xfa\xb5\xcd\xef");
   BOOST_CHECK(os.is_equal("%01%2A%3B%C4%DE%FA%B5%CD%EF"));
 }
 
@@ -196,8 +195,7 @@
   BOOST_CHECK_EQUAL(unescape("Bad %a"), "Bad %a");
 
   output_test_stream os;
-  const char str[] = "%01%2a%3B%c4%de%fA%B5%Cd%EF";
-  unescape(os, str, std::strlen(str));
+  unescape(os, "%01%2a%3B%c4%de%fA%B5%Cd%EF");
   BOOST_CHECK(os.is_equal("\x01\x2a\x3b\xc4\xde\xfa\xb5\xcd\xef"));
 }