]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
chore: Replace nonstd::string_view with std::string_view
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 17 May 2022 19:55:48 +0000 (21:55 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Mon, 23 May 2022 17:16:29 +0000 (19:16 +0200)
46 files changed:
LICENSE.adoc
src/Args.cpp
src/Args.hpp
src/CMakeLists.txt
src/Context.cpp
src/Context.hpp
src/Depfile.cpp
src/Depfile.hpp
src/FormatNonstdStringView.hpp [deleted file]
src/Hash.cpp
src/Hash.hpp
src/Logging.cpp
src/Logging.hpp
src/Result.cpp
src/TemporaryFile.cpp
src/TemporaryFile.hpp
src/Util.cpp
src/Util.hpp
src/argprocessing.cpp
src/ccache.cpp
src/ccache.hpp
src/core/exceptions.hpp
src/execute.cpp
src/fmtmacros.hpp
src/hashutil.cpp
src/hashutil.hpp
src/storage/Storage.cpp
src/storage/Storage.hpp
src/storage/primary/PrimaryStorage.cpp
src/storage/primary/PrimaryStorage.hpp
src/storage/primary/util.cpp
src/storage/secondary/FileStorage.cpp
src/storage/secondary/HttpStorage.cpp
src/third_party/nonstd/string_view.hpp [deleted file]
src/util/Tokenizer.cpp
src/util/Tokenizer.hpp
src/util/path.cpp
src/util/path.hpp
src/util/string.cpp
src/util/string.hpp
unittest/CMakeLists.txt
unittest/test_FormatNonstdStringView.cpp [deleted file]
unittest/test_hashutil.cpp
unittest/test_util_Tokenizer.cpp
unittest/test_util_path.cpp
unittest/test_util_string.cpp

index 407f3971f92df74ee6348fc7f6484679200daf9b..3f33b7207a28bc81d80d6ac7f21e15d35fae5826 100644 (file)
@@ -609,41 +609,6 @@ DEALINGS IN THE SOFTWARE.
 ----
 
 
-=== src/third_party/nonstd/string_view.hpp
-
-This alternative implementation of `std::string_view` was downloaded from
-<https://github.com/martinmoene/string-view-lite> and has the following license
-text:
-
-----
-Copyright 2017-2020 by Martin Moene
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-----
-
-
 === src/third_party/url.*
 
 CxxUrl - A simple C++ URL class. Copied from CxxUrl v0.3 downloaded from
index b965f6fe1c24131fb8b8174d3aea16fe3fc71acc..f8796e0e9f04cfbd537c1342b40dd26926b91086 100644 (file)
@@ -23,8 +23,6 @@
 #include <core/exceptions.hpp>
 #include <util/string.hpp>
 
-using nonstd::string_view;
-
 Args::Args(Args&& other) noexcept : m_args(std::move(other.m_args))
 {
 }
@@ -171,7 +169,7 @@ Args::to_string() const
 }
 
 void
-Args::erase_last(string_view arg)
+Args::erase_last(std::string_view arg)
 {
   const auto it = std::find(m_args.rbegin(), m_args.rend(), arg);
   if (it != m_args.rend()) {
@@ -180,7 +178,7 @@ Args::erase_last(string_view arg)
 }
 
 void
-Args::erase_with_prefix(string_view prefix)
+Args::erase_with_prefix(std::string_view prefix)
 {
   m_args.erase(std::remove_if(m_args.begin(),
                               m_args.end(),
index f0ffd94893cd3e152407fc04933c484760ffbc83..1df0529f0ba1038804b32a057a2eee5ba0434846 100644 (file)
 #include "NonCopyable.hpp"
 #include "Util.hpp"
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <deque>
 #include <optional>
 #include <string>
+#include <string_view>
 
 class Args
 {
@@ -67,10 +66,10 @@ public:
   std::string to_string() const;
 
   // Remove last argument equal to `arg`, if any.
-  void erase_last(nonstd::string_view arg);
+  void erase_last(std::string_view arg);
 
   // Remove all arguments with prefix `prefix`.
-  void erase_with_prefix(nonstd::string_view prefix);
+  void erase_with_prefix(std::string_view prefix);
 
   // Insert arguments in `args` at position `index`.
   void insert(size_t index, const Args& args);
index 8fb4dd607faddd6a5d1caa582bbf9c6f1fb3918f..161f127bd646001c2bacf44e76f849293c660e9a 100644 (file)
@@ -42,9 +42,6 @@ if(WIN32)
 endif()
 
 add_library(ccache_framework STATIC ${source_files})
-target_compile_definitions(
-  ccache_framework PUBLIC -Dnssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_NONSTD
-)
 
 if(WIN32)
   target_link_libraries(ccache_framework PRIVATE "psapi")
index bcfff8c78a46d97b4bc21340510ebc7ed4f008bf..e8dc80d734976cdb4138d00bcb3eb5874d6b8cd8 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -34,8 +34,6 @@
 #include <string>
 #include <vector>
 
-using nonstd::string_view;
-
 Context::Context()
   : actual_cwd(Util::get_actual_cwd()),
     apparent_cwd(Util::get_apparent_cwd(actual_cwd)),
index 650ceee28f500f8aceccebd4522bd1f0d3322251..c2861f76b09cf5d302cdc62fd0a0828d8f6f0d10 100644 (file)
 
 #include <storage/Storage.hpp>
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <ctime>
 #include <optional>
 #include <string>
+#include <string_view>
 #include <unordered_map>
 #include <vector>
 
index 9bb6219f391ae6f4905681b8113202d6eb37dfe8..259006e4da59365108df83e51085974d0ad14de0 100644 (file)
@@ -35,7 +35,7 @@ is_blank(const std::string& s)
 namespace Depfile {
 
 std::string
-escape_filename(nonstd::string_view filename)
+escape_filename(std::string_view filename)
 {
   std::string result;
   result.reserve(filename.size());
@@ -139,7 +139,7 @@ make_paths_relative_in_output_dep(const Context& ctx)
 }
 
 std::vector<std::string>
-tokenize(nonstd::string_view file_content)
+tokenize(std::string_view file_content)
 {
   // A dependency file uses Makefile syntax. This is not perfect parser but
   // should be enough for parsing a regular dependency file.
index 0ca6a0cb332221112d6d2d4ed40e656805e1baa0..fc453c310f1656777a9bae7fb82552990ad6fc0c 100644 (file)
@@ -23,18 +23,17 @@ class Hash;
 
 #include "Digest.hpp"
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <optional>
 #include <string>
+#include <string_view>
 #include <vector>
 
 namespace Depfile {
 
-std::string escape_filename(nonstd::string_view filename);
+std::string escape_filename(std::string_view filename);
 std::optional<std::string> rewrite_paths(const Context& ctx,
                                          const std::string& file_content);
 void make_paths_relative_in_output_dep(const Context& ctx);
-std::vector<std::string> tokenize(nonstd::string_view file_content);
+std::vector<std::string> tokenize(std::string_view file_content);
 
 } // namespace Depfile
diff --git a/src/FormatNonstdStringView.hpp b/src/FormatNonstdStringView.hpp
deleted file mode 100644 (file)
index 4834dc4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#pragma once
-
-#include "third_party/fmt/core.h"
-#include "third_party/nonstd/string_view.hpp"
-
-// Specialization of fmt::formatter for nonstd::string_view.
-namespace fmt {
-
-template<> struct formatter<nonstd::string_view>
-{
-  template<typename ParseContext>
-  constexpr auto
-  parse(ParseContext& ctx) const -> decltype(ctx.begin())
-  {
-    return ctx.begin();
-  }
-
-  template<typename FormatContext>
-  auto
-  format(const nonstd::string_view& sv, FormatContext& ctx)
-    -> decltype(ctx.out())
-  {
-    return format_to(ctx.out(), "{}", fmt::string_view(sv.data(), sv.size()));
-  }
-};
-
-} // namespace fmt
index 2eb491dc966d7243951cd20eb700c9018f042b93..ecd19e303772b4b75fd08ba8eb51556b6340e09a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -32,9 +32,7 @@
 #  include <unistd.h>
 #endif
 
-using nonstd::string_view;
-
-const string_view HASH_DELIMITER("\000cCaChE\000", 8);
+const std::string_view HASH_DELIMITER("\000cCaChE\000", 8);
 
 Hash::Hash()
 {
@@ -42,7 +40,7 @@ Hash::Hash()
 }
 
 void
-Hash::enable_debug(string_view section_name,
+Hash::enable_debug(std::string_view section_name,
                    FILE* debug_binary,
                    FILE* debug_text)
 {
@@ -65,11 +63,11 @@ Hash::digest() const
 }
 
 Hash&
-Hash::hash_delimiter(string_view type)
+Hash::hash_delimiter(std::string_view type)
 {
   hash_buffer(HASH_DELIMITER);
   hash_buffer(type);
-  hash_buffer(string_view("", 1)); // NUL
+  hash_buffer(std::string_view("", 1)); // NUL
   add_debug_text("### ");
   add_debug_text(type);
   add_debug_text("\n");
@@ -79,7 +77,7 @@ Hash::hash_delimiter(string_view type)
 Hash&
 Hash::hash(const void* data, size_t size, HashType hash_type)
 {
-  string_view buffer(static_cast<const char*>(data), size);
+  std::string_view buffer(static_cast<const char*>(data), size);
   hash_buffer(buffer);
 
   switch (hash_type) {
@@ -98,7 +96,7 @@ Hash::hash(const void* data, size_t size, HashType hash_type)
 }
 
 Hash&
-Hash::hash(string_view data)
+Hash::hash(std::string_view data)
 {
   hash(data.data(), data.length());
   return *this;
@@ -107,7 +105,7 @@ Hash::hash(string_view data)
 Hash&
 Hash::hash(int64_t x)
 {
-  hash_buffer(string_view(reinterpret_cast<const char*>(&x), sizeof(x)));
+  hash_buffer(std::string_view(reinterpret_cast<const char*>(&x), sizeof(x)));
   add_debug_text(FMT("{}\n", x));
   return *this;
 }
@@ -133,7 +131,7 @@ Hash::hash_file(const std::string& path)
 }
 
 void
-Hash::hash_buffer(string_view buffer)
+Hash::hash_buffer(std::string_view buffer)
 {
   blake3_hasher_update(&m_hasher, buffer.data(), buffer.size());
   if (!buffer.empty() && m_debug_binary) {
@@ -142,7 +140,7 @@ Hash::hash_buffer(string_view buffer)
 }
 
 void
-Hash::add_debug_text(string_view text)
+Hash::add_debug_text(std::string_view text)
 {
   if (!text.empty() && m_debug_text) {
     (void)fwrite(text.data(), 1, text.length(), m_debug_text);
index 02c5a4d1227fd4d52cf90018f2cd3f3c998e0664..968e558145b6caf7776d2fca2c7eafea79a46596 100644 (file)
 #include "Digest.hpp"
 
 #include "third_party/blake3/blake3.h"
-#include "third_party/nonstd/string_view.hpp"
 
 #include <cstdint>
 #include <cstdio>
+#include <string_view>
 
 // This class represents a hash state.
 class Hash
@@ -38,7 +38,7 @@ public:
   Hash& operator=(const Hash& other) = default;
 
   // Enable debug logging of the hashed input to a binary and a text file.
-  void enable_debug(nonstd::string_view section_name,
+  void enable_debug(std::string_view section_name,
                     FILE* debug_binary,
                     FILE* debug_text);
 
@@ -53,7 +53,7 @@ public:
   //   conditional hashing of information in a safe way (e.g., if we want to
   //   hash information X if CCACHE_A is set and information Y if CCACHE_B is
   //   set, there should never be a hash collision risk).
-  Hash& hash_delimiter(nonstd::string_view type);
+  Hash& hash_delimiter(std::string_view type);
 
   // Add bytes to the hash.
   //
@@ -72,7 +72,7 @@ public:
   //
   // If hash debugging is enabled, the string is written to the text input file
   // followed by a newline.
-  Hash& hash(nonstd::string_view data);
+  Hash& hash(std::string_view data);
 
   // Add an integer to the hash.
   //
@@ -101,6 +101,6 @@ private:
   FILE* m_debug_binary = nullptr;
   FILE* m_debug_text = nullptr;
 
-  void hash_buffer(nonstd::string_view buffer);
-  void add_debug_text(nonstd::string_view text);
+  void hash_buffer(std::string_view buffer);
+  void add_debug_text(std::string_view text);
 };
index 5068c853c96f7a4709d13e337470a4264e0731cd..46b62f5542ed769e5ebfa0ca7be8cbe465a480f6 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2009-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -45,8 +45,6 @@
 #  endif
 #endif
 
-using nonstd::string_view;
-
 namespace {
 
 // Logfile path and file handle, read from Config::log_file().
@@ -76,7 +74,7 @@ print_fatal_error_and_exit()
 }
 
 void
-do_log(string_view message, bool bulk)
+do_log(std::string_view message, bool bulk)
 {
   static char prefix[200];
 
@@ -159,7 +157,7 @@ enabled()
 }
 
 void
-log(string_view message)
+log(std::string_view message)
 {
   if (!enabled()) {
     return;
@@ -168,7 +166,7 @@ log(string_view message)
 }
 
 void
-bulk_log(string_view message)
+bulk_log(std::string_view message)
 {
   if (!enabled()) {
     return;
index b6b6ce9818f1b63d3c7234d2761ab645e491ee55..669b1126c2df1ecb43525956d100c4fc919b5c2d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
 
 #pragma once
 
-#include "FormatNonstdStringView.hpp"
-
 #include "third_party/fmt/core.h"
 #include "third_party/fmt/format.h"
-#include "third_party/nonstd/string_view.hpp"
 
 #include <optional>
 #include <string>
+#include <string_view>
 #include <utility>
 
 // Log a raw message (plus a newline character).
 #define LOG_RAW(message_)                                                      \
   do {                                                                         \
     if (Logging::enabled()) {                                                  \
-      Logging::log(nonstd::string_view(message_));                             \
+      Logging::log(std::string_view(message_));                                \
     }                                                                          \
   } while (false)
 
@@ -62,11 +60,11 @@ void init(const Config& config);
 bool enabled();
 
 // Log `message` (plus a newline character).
-void log(nonstd::string_view message);
+void log(std::string_view message);
 
 // Log `message` (plus a newline character) without flushing and with a reused
 // timestamp.
-void bulk_log(nonstd::string_view message);
+void bulk_log(std::string_view message);
 
 // Write the current log memory buffer `path`.
 void dump_log(const std::string& path);
index c4e3b65a3c209d1d5513872cc8f8a4ddc8d17f9e..bc7c313d6c21c5e8d85b5211da315faa0b0f5caa 100644 (file)
@@ -69,8 +69,6 @@
 // <epilogue>             ::= <checksum>
 // <checksum>             ::= uint64_t ; XXH3 of content bytes
 
-using nonstd::string_view;
-
 namespace {
 
 const uint8_t k_result_format_version = 0;
@@ -82,7 +80,7 @@ const uint8_t k_embedded_file_marker = 0;
 const uint8_t k_raw_file_marker = 1;
 
 std::string
-get_raw_file_path(string_view result_path, uint8_t entry_number)
+get_raw_file_path(std::string_view result_path, uint8_t entry_number)
 {
   if (entry_number >= 10) {
     // To support more entries in the future, encode to [0-9a-z]. Note that
index 3b6ccabd15d66e2566853a4785bc111e6f03e8e8..d4182855a61faf945ceeecc119ad493885406c9e 100644 (file)
@@ -26,9 +26,7 @@
 #  include "third_party/win32/mktemp.h"
 #endif
 
-using nonstd::string_view;
-
-TemporaryFile::TemporaryFile(string_view path_prefix)
+TemporaryFile::TemporaryFile(std::string_view path_prefix)
   : path(std::string(path_prefix) + ".XXXXXX")
 {
   Util::ensure_dir_exists(Util::dir_name(path));
index 032cbfa8def0a144f7124c621686cdcb15c33042..5d1154becd9cef4d4203abf55200122b6b62a22f 100644 (file)
@@ -20,9 +20,8 @@
 
 #include "Fd.hpp"
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <string>
+#include <string_view>
 
 // This class represents a unique temporary file created by mkstemp. The file is
 // not deleted by the destructor.
@@ -32,7 +31,7 @@ public:
   // `path_prefix` is the base path. The resulting filename will be this path
   //  plus a unique suffix. If `path_prefix` refers to a nonexistent directory
   //  the directory will be created if possible.`
-  TemporaryFile(nonstd::string_view path_prefix);
+  TemporaryFile(std::string_view path_prefix);
 
   TemporaryFile(TemporaryFile&& other) noexcept = default;
 
index d39b74667350ba4a95e74d9da8e74f7ac71f0927..b94ee1a81b71bb252db9244be64d6629480981bb 100644 (file)
@@ -100,7 +100,6 @@ extern "C" {
 #  endif
 #endif
 
-using nonstd::string_view;
 using IncludeDelimiter = util::Tokenizer::IncludeDelimiter;
 
 namespace {
@@ -112,8 +111,8 @@ namespace {
 // The primary reason for not using std::regex is that it's not available for
 // GCC 4.8. It's also a bit bloated. The reason for not using POSIX regex
 // functionality is that it's are not available in MinGW.
-string_view
-find_first_ansi_csi_seq(string_view string)
+std::string_view
+find_first_ansi_csi_seq(std::string_view string)
 {
   size_t pos = 0;
   while (pos < string.length() && string[pos] != 0x1b) {
@@ -156,7 +155,7 @@ path_max(const std::string& path)
 
 template<typename T>
 std::vector<T>
-split_into(string_view string,
+split_into(std::string_view string,
            const char* separators,
            util::Tokenizer::Mode mode,
            IncludeDelimiter include_delimiter)
@@ -171,7 +170,7 @@ split_into(string_view string,
 }
 
 std::string
-rewrite_stderr_to_absolute_paths(string_view text)
+rewrite_stderr_to_absolute_paths(std::string_view text)
 {
   static const std::string in_file_included_from = "In file included from ";
 
@@ -197,7 +196,7 @@ rewrite_stderr_to_absolute_paths(string_view text)
       line = line.substr(csi_seq.length());
     }
     size_t path_end = line.find(':');
-    if (path_end == string_view::npos) {
+    if (path_end == std::string_view::npos) {
       result.append(line.data(), line.length());
     } else {
       std::string path(line.substr(0, path_end));
@@ -215,7 +214,7 @@ rewrite_stderr_to_absolute_paths(string_view text)
 
 #ifdef _WIN32
 bool
-has_utf16_le_bom(string_view text)
+has_utf16_le_bom(std::string_view text)
 {
   return text.size() > 1
          && ((static_cast<uint8_t>(text[0]) == 0xff
@@ -227,8 +226,8 @@ has_utf16_le_bom(string_view text)
 
 namespace Util {
 
-string_view
-base_name(string_view path)
+std::string_view
+base_name(std::string_view path)
 {
 #ifdef _WIN32
   const char delim[] = "/\\";
@@ -240,9 +239,9 @@ base_name(string_view path)
 }
 
 std::string
-change_extension(string_view path, string_view new_ext)
+change_extension(std::string_view path, std::string_view new_ext)
 {
-  string_view without_ext = Util::remove_extension(path);
+  std::string_view without_ext = Util::remove_extension(path);
   return std::string(without_ext).append(new_ext.data(), new_ext.length());
 }
 
@@ -334,7 +333,7 @@ clone_hard_link_or_copy_file(const Context& ctx,
 }
 
 size_t
-common_dir_prefix_length(string_view dir, string_view path)
+common_dir_prefix_length(std::string_view dir, std::string_view path)
 {
   if (dir.empty() || path.empty() || dir == "/" || path == "/") {
     return 0;
@@ -402,7 +401,7 @@ copy_file(const std::string& src, const std::string& dest, bool via_tmp_file)
 }
 
 bool
-create_dir(string_view dir)
+create_dir(std::string_view dir)
 {
   std::string dir_str(dir);
   auto st = Stat::stat(dir_str);
@@ -429,8 +428,8 @@ create_dir(string_view dir)
   }
 }
 
-string_view
-dir_name(string_view path)
+std::string_view
+dir_name(std::string_view path)
 {
 #ifdef _WIN32
   const char delim[] = "/\\";
@@ -596,7 +595,7 @@ format_parsable_size_with_suffix(uint64_t size)
 }
 
 void
-ensure_dir_exists(nonstd::string_view dir)
+ensure_dir_exists(std::string_view dir)
 {
   if (!create_dir(dir)) {
     throw core::Fatal(
@@ -640,8 +639,8 @@ get_apparent_cwd(const std::string& actual_cwd)
 #endif
 }
 
-string_view
-get_extension(string_view path)
+std::string_view
+get_extension(std::string_view path)
 {
 #ifndef _WIN32
   const char stop_at_chars[] = "./";
@@ -649,7 +648,7 @@ get_extension(string_view path)
   const char stop_at_chars[] = "./\\";
 #endif
   size_t pos = path.find_last_of(stop_at_chars);
-  if (pos == string_view::npos || path.at(pos) == '/') {
+  if (pos == std::string_view::npos || path.at(pos) == '/') {
     return {};
 #ifdef _WIN32
   } else if (path.at(pos) == '\\') {
@@ -702,7 +701,7 @@ get_hostname()
 }
 
 std::string
-get_relative_path(string_view dir, string_view path)
+get_relative_path(std::string_view dir, std::string_view path)
 {
   ASSERT(util::is_absolute_path(dir));
   ASSERT(util::is_absolute_path(path));
@@ -785,7 +784,7 @@ hard_link(const std::string& oldpath, const std::string& newpath)
 }
 
 std::optional<size_t>
-is_absolute_path_with_prefix(nonstd::string_view path)
+is_absolute_path_with_prefix(std::string_view path)
 {
 #ifdef _WIN32
   const char delim[] = "/\\";
@@ -833,9 +832,9 @@ is_nfs_fd(int /*fd*/, bool* /*is_nfs*/)
 #endif
 
 bool
-is_precompiled_header(string_view path)
+is_precompiled_header(std::string_view path)
 {
-  string_view ext = get_extension(path);
+  std::string_view ext = get_extension(path);
   return ext == ".gch" || ext == ".pch" || ext == ".pth"
          || get_extension(dir_name(path)) == ".gch";
 }
@@ -856,7 +855,7 @@ std::string
 make_relative_path(const std::string& base_dir,
                    const std::string& actual_cwd,
                    const std::string& apparent_cwd,
-                   nonstd::string_view path)
+                   std::string_view path)
 {
   if (base_dir.empty() || !util::path_starts_with(path, base_dir)) {
     return std::string(path);
@@ -922,32 +921,33 @@ make_relative_path(const std::string& base_dir,
 }
 
 std::string
-make_relative_path(const Context& ctx, string_view path)
+make_relative_path(const Context& ctx, std::string_view path)
 {
   return make_relative_path(
     ctx.config.base_dir(), ctx.actual_cwd, ctx.apparent_cwd, path);
 }
 
 bool
-matches_dir_prefix_or_file(string_view dir_prefix_or_file, string_view path)
+matches_dir_prefix_or_file(std::string_view dir_prefix_or_file,
+                           std::string_view path)
 {
   return !dir_prefix_or_file.empty() && !path.empty()
          && dir_prefix_or_file.length() <= path.length()
-         && path.starts_with(dir_prefix_or_file)
+         && util::starts_with(path, dir_prefix_or_file)
          && (dir_prefix_or_file.length() == path.length()
              || is_dir_separator(path[dir_prefix_or_file.length()])
              || is_dir_separator(dir_prefix_or_file.back()));
 }
 
 std::string
-normalize_abstract_absolute_path(string_view path)
+normalize_abstract_absolute_path(std::string_view path)
 {
   if (!util::is_absolute_path(path)) {
     return std::string(path);
   }
 
 #ifdef _WIN32
-  if (path.find("\\") != string_view::npos) {
+  if (path.find("\\") != std::string_view::npos) {
     std::string new_path(path);
     std::replace(new_path.begin(), new_path.end(), '\\', '/');
     return normalize_abstract_absolute_path(new_path);
@@ -958,7 +958,7 @@ normalize_abstract_absolute_path(string_view path)
 #endif
 
   std::string result = "/";
-  const size_t npos = string_view::npos;
+  const size_t npos = std::string_view::npos;
   size_t left = 1;
 
   while (true) {
@@ -966,7 +966,8 @@ normalize_abstract_absolute_path(string_view path)
       break;
     }
     const auto right = path.find('/', left);
-    string_view part = path.substr(left, right == npos ? npos : right - left);
+    std::string_view part =
+      path.substr(left, right == npos ? npos : right - left);
     if (part == "..") {
       if (result.length() > 1) {
         // "/x/../part" -> "/part"
@@ -1218,8 +1219,8 @@ read_text_file(const std::string& path, size_t size_hint)
   return result;
 }
 
-string_view
-remove_extension(string_view path)
+std::string_view
+remove_extension(std::string_view path)
 {
   return path.substr(0, path.length() - get_extension(path).length());
 }
@@ -1247,8 +1248,8 @@ rename(const std::string& oldpath, const std::string& newpath)
 }
 
 bool
-same_program_name(nonstd::string_view program_name,
-                  nonstd::string_view canonical_program_name)
+same_program_name(std::string_view program_name,
+                  std::string_view canonical_program_name)
 {
 #ifdef _WIN32
   std::string lowercase_program_name = Util::to_lowercase(program_name);
@@ -1319,17 +1320,18 @@ setenv(const std::string& name, const std::string& value)
 #endif
 }
 
-std::vector<string_view>
-split_into_views(string_view string,
+std::vector<std::string_view>
+split_into_views(std::string_view string,
                  const char* separators,
                  util::Tokenizer::Mode mode,
                  IncludeDelimiter include_delimiter)
 {
-  return split_into<string_view>(string, separators, mode, include_delimiter);
+  return split_into<std::string_view>(
+    string, separators, mode, include_delimiter);
 }
 
 std::vector<std::string>
-split_into_strings(string_view string,
+split_into_strings(std::string_view string,
                    const char* separators,
                    util::Tokenizer::Mode mode,
                    IncludeDelimiter include_delimiter)
@@ -1338,7 +1340,7 @@ split_into_strings(string_view string,
 }
 
 std::string
-strip_ansi_csi_seqs(string_view string)
+strip_ansi_csi_seqs(std::string_view string)
 {
   size_t pos = 0;
   std::string result;
@@ -1360,7 +1362,7 @@ strip_ansi_csi_seqs(string_view string)
 }
 
 std::string
-to_lowercase(string_view string)
+to_lowercase(std::string_view string)
 {
   std::string result;
   result.resize(string.length());
index 1502af4efaee9a400acabfcf8aca4432ba2fc601..bf55484409f83ffc573812fcf39da7119f649f9a 100644 (file)
@@ -21,8 +21,6 @@
 #include <Stat.hpp>
 #include <util/Tokenizer.hpp>
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <algorithm>
 #include <cstdint>
 #include <functional>
@@ -30,6 +28,7 @@
 #include <memory>
 #include <optional>
 #include <string>
+#include <string_view>
 #include <utility>
 #include <vector>
 
@@ -44,7 +43,7 @@ using TraverseVisitor =
 enum class UnlinkLog { log_failure, ignore_failure };
 
 // Get base name of path.
-nonstd::string_view base_name(nonstd::string_view path);
+std::string_view base_name(std::string_view path);
 
 // Get an integer value from bytes in big endian order.
 //
@@ -78,8 +77,7 @@ big_endian_to_int(const uint8_t* buffer, uint8_t& value)
 
 // Remove the extension via `remove_extension()`, then add `new_ext`. `new_ext`
 // should start with a dot, no extra dot is inserted.
-std::string change_extension(nonstd::string_view path,
-                             nonstd::string_view new_ext);
+std::string change_extension(std::string_view path, std::string_view new_ext);
 
 // Return `value` adjusted to not be less than `min` and not more than `max`.
 template<typename T>
@@ -106,8 +104,7 @@ void clone_hard_link_or_copy_file(const Context& ctx,
 
 // Compute the length of the longest directory path that is common to paths
 // `dir` (a directory) and `path` (any path).
-size_t common_dir_prefix_length(nonstd::string_view dir,
-                                nonstd::string_view path);
+size_t common_dir_prefix_length(std::string_view dir, std::string_view path);
 
 // Copy all data from `fd_in` to `fd_out`. Throws `core::Error` on error.
 void copy_fd(int fd_in, int fd_out);
@@ -121,13 +118,13 @@ void copy_file(const std::string& src,
 // Create a directory if needed, including its parents if needed.
 //
 // Returns true if the directory exists or could be created, otherwise false.
-bool create_dir(nonstd::string_view dir);
+bool create_dir(std::string_view dir);
 
 // Get directory name of path.
-nonstd::string_view dir_name(nonstd::string_view path);
+std::string_view dir_name(std::string_view path);
 
 // Like create_dir but throws Fatal on error.
-void ensure_dir_exists(nonstd::string_view dir);
+void ensure_dir_exists(std::string_view dir);
 
 // Expand all instances of $VAR or ${VAR}, where VAR is an environment variable,
 // in `str`. Throws `core::Error` if one of the environment variables.
@@ -172,7 +169,7 @@ std::string get_apparent_cwd(const std::string& actual_cwd);
 
 // Return the file extension (including the dot) as a view into `path`. If
 // `path` has no file extension, an empty string_view is returned.
-nonstd::string_view get_extension(nonstd::string_view path);
+std::string_view get_extension(std::string_view path);
 
 // Return the current user's home directory, or throw `Fatal` if it can't
 // be determined.
@@ -185,8 +182,7 @@ const char* get_hostname();
 // `path` (an absolute path). Assumes that both `dir` and `path` are normalized.
 // The algorithm does *not* follow symlinks, so the result may not actually
 // resolve to the same file as `path`.
-std::string get_relative_path(nonstd::string_view dir,
-                              nonstd::string_view path);
+std::string get_relative_path(std::string_view dir, std::string_view path);
 
 #ifndef _WIN32
 // Get process umask.
@@ -227,7 +223,7 @@ int_to_big_endian(int8_t value, uint8_t* buffer)
 
 // Determine if `path` is an absolute path with prefix, returning the split
 // point.
-std::optional<size_t> is_absolute_path_with_prefix(nonstd::string_view path);
+std::optional<size_t> is_absolute_path_with_prefix(std::string_view path);
 
 // Test if a file is on nfs.
 //
@@ -251,7 +247,7 @@ is_dir_separator(char ch)
 
 // Return whether `path` represents a precompiled header (see "Precompiled
 // Headers" in GCC docs).
-bool is_precompiled_header(nonstd::string_view path);
+bool is_precompiled_header(std::string_view path);
 
 // Thread-safe version of `localtime(3)`. If `time` is not specified the current
 // time of day is used.
@@ -262,15 +258,15 @@ std::optional<tm> localtime(std::optional<time_t> time = {});
 std::string make_relative_path(const std::string& base_dir,
                                const std::string& actual_cwd,
                                const std::string& apparent_cwd,
-                               nonstd::string_view path);
+                               std::string_view path);
 
 // Like above but with base directory and apparent/actual CWD taken from `ctx`.
-std::string make_relative_path(const Context& ctx, nonstd::string_view path);
+std::string make_relative_path(const Context& ctx, std::string_view path);
 
 // Return whether `path` is equal to `dir_prefix_or_file` or if
 // `dir_prefix_or_file` is a directory prefix of `path`.
-bool matches_dir_prefix_or_file(nonstd::string_view dir_prefix_or_file,
-                                nonstd::string_view path);
+bool matches_dir_prefix_or_file(std::string_view dir_prefix_or_file,
+                                std::string_view path);
 
 // Normalize absolute path `path`, not taking symlinks into account.
 //
@@ -280,7 +276,7 @@ bool matches_dir_prefix_or_file(nonstd::string_view dir_prefix_or_file,
 // as `path` (nor to any existing file system entry for that matter).
 //
 // On Windows: Backslashes are replaced with forward slashes.
-std::string normalize_abstract_absolute_path(nonstd::string_view path);
+std::string normalize_abstract_absolute_path(std::string_view path);
 
 // Like normalize_abstract_absolute_path, but returns `path` unchanged if the
 // normalized result doesn't resolve to the same file system entry as `path`.
@@ -326,7 +322,7 @@ std::string read_text_file(const std::string& path, size_t size_hint = 0);
 
 // Return a view into `path` containing the given path without the filename
 // extension as determined by `get_extension()`.
-nonstd::string_view remove_extension(nonstd::string_view path);
+std::string_view remove_extension(std::string_view path);
 
 // Rename `oldpath` to `newpath` (deleting `newpath`). Throws `core::Error` on
 // error.
@@ -335,8 +331,8 @@ void rename(const std::string& oldpath, const std::string& newpath);
 // Detmine if `program_name` is equal to `canonical_program_name`. On Windows,
 // this means performing a case insensitive equality check with and without a
 // ".exe" suffix. On non-Windows, it is a simple equality check.
-bool same_program_name(nonstd::string_view program_name,
-                       nonstd::string_view canonical_program_name);
+bool same_program_name(std::string_view program_name,
+                       std::string_view canonical_program_name);
 
 // Send `text` to file descriptor `fd`, optionally stripping ANSI color
 // sequences if `ctx.args_info.strip_diagnostics_colors` is true and rewriting
@@ -362,8 +358,8 @@ size_change_kibibyte(const Stat& old_stat, const Stat& new_stat)
 // Split `string` into tokens at any of the characters in `separators`. These
 // tokens are views into `string`. `separators` must neither be the empty string
 // nor a nullptr.
-std::vector<nonstd::string_view>
-split_into_views(nonstd::string_view string,
+std::vector<std::string_view>
+split_into_views(std::string_view string,
                  const char* separators,
                  util::Tokenizer::Mode mode = util::Tokenizer::Mode::skip_empty,
                  util::Tokenizer::IncludeDelimiter include_delimiter =
@@ -371,17 +367,17 @@ split_into_views(nonstd::string_view string,
 
 // Same as `split_into_views` but the tokens are copied from `string`.
 std::vector<std::string> split_into_strings(
-  nonstd::string_view string,
+  std::string_view string,
   const char* separators,
   util::Tokenizer::Mode mode = util::Tokenizer::Mode::skip_empty,
   util::Tokenizer::IncludeDelimiter include_delimiter =
     util::Tokenizer::IncludeDelimiter::no);
 
 // Returns a copy of string with the specified ANSI CSI sequences removed.
-[[nodiscard]] std::string strip_ansi_csi_seqs(nonstd::string_view string);
+[[nodiscard]] std::string strip_ansi_csi_seqs(std::string_view string);
 
 // Convert a string to lowercase.
-[[nodiscard]] std::string to_lowercase(nonstd::string_view string);
+[[nodiscard]] std::string to_lowercase(std::string_view string);
 
 // Traverse `path` recursively (postorder, i.e. files are visited before their
 // parent directory).
index 90603af6c381b4453c7705bb0f09e0007955cbfd..077704f02cb3f33f6e15c2f171352ddf19a260ba 100644 (file)
@@ -35,7 +35,6 @@
 #include <cassert>
 
 using core::Statistic;
-using nonstd::string_view;
 
 namespace {
 
@@ -452,7 +451,7 @@ process_arg(const Context& ctx,
   // MSVC -Fo with no space.
   if (util::starts_with(args[i], "-Fo") && config.is_compiler_group_msvc()) {
     args_info.output_obj =
-      Util::make_relative_path(ctx, string_view(args[i]).substr(3));
+      Util::make_relative_path(ctx, std::string_view(args[i]).substr(3));
     return std::nullopt;
   }
 
@@ -520,7 +519,7 @@ process_arg(const Context& ctx,
       && config.compiler_type() != CompilerType::nvcc
       && config.compiler_type() != CompilerType::msvc) {
     args_info.output_obj =
-      Util::make_relative_path(ctx, string_view(args[i]).substr(2));
+      Util::make_relative_path(ctx, std::string_view(args[i]).substr(2));
     return std::nullopt;
   }
 
@@ -619,8 +618,8 @@ process_arg(const Context& ctx,
       state.dep_args.push_back(relpath);
       i++;
     } else {
-      auto arg_opt = string_view(args[i]).substr(0, 3);
-      auto option = string_view(args[i]).substr(3);
+      auto arg_opt = std::string_view(args[i]).substr(0, 3);
+      auto option = std::string_view(args[i]).substr(3);
       auto relpath = Util::make_relative_path(ctx, option);
       state.dep_args.push_back(FMT("{}{}", arg_opt, relpath));
     }
@@ -690,7 +689,7 @@ process_arg(const Context& ctx,
   }
 
   if (util::starts_with(args[i], "--sysroot=")) {
-    auto path = string_view(args[i]).substr(10);
+    auto path = std::string_view(args[i]).substr(10);
     auto relpath = Util::make_relative_path(ctx, path);
     state.common_args.push_back("--sysroot=" + relpath);
     return std::nullopt;
@@ -740,7 +739,7 @@ process_arg(const Context& ctx,
       args_info.generating_dependencies = true;
       state.dependency_filename_specified = true;
       args_info.output_dep =
-        Util::make_relative_path(ctx, string_view(args[i]).substr(8));
+        Util::make_relative_path(ctx, std::string_view(args[i]).substr(8));
       state.dep_args.push_back(args[i]);
       return std::nullopt;
     } else if (util::starts_with(args[i], "-Wp,-MMD,")
@@ -748,7 +747,7 @@ process_arg(const Context& ctx,
       args_info.generating_dependencies = true;
       state.dependency_filename_specified = true;
       args_info.output_dep =
-        Util::make_relative_path(ctx, string_view(args[i]).substr(9));
+        Util::make_relative_path(ctx, std::string_view(args[i]).substr(9));
       state.dep_args.push_back(args[i]);
       return std::nullopt;
     } else if (util::starts_with(args[i], "-Wp,-D")
@@ -938,8 +937,8 @@ process_arg(const Context& ctx,
     if (path_pos) {
       const std::string option = args[i].substr(0, *path_pos);
       if (compopt_takes_concat_arg(option) && compopt_takes_path(option)) {
-        const auto relpath =
-          Util::make_relative_path(ctx, string_view(args[i]).substr(*path_pos));
+        const auto relpath = Util::make_relative_path(
+          ctx, std::string_view(args[i]).substr(*path_pos));
         std::string new_option = option + relpath;
         if (compopt_affects_cpp_output(option)) {
           state.cpp_args.push_back(new_option);
@@ -1060,7 +1059,7 @@ handle_dependency_environment_variables(Context& ctx,
   if (dependencies.size() > 1) {
     // It's the "file target" form.
     ctx.args_info.dependency_target_specified = true;
-    string_view abspath_obj = dependencies[1];
+    std::string_view abspath_obj = dependencies[1];
     std::string relpath_obj = Util::make_relative_path(ctx, abspath_obj);
     // Ensure that the compiler gets a relative path.
     std::string relpath_both = FMT("{} {}", args_info.output_dep, relpath_obj);
@@ -1129,7 +1128,7 @@ process_args(Context& ctx)
   }
 
   if (output_obj_by_source && !args_info.input_file.empty()) {
-    string_view extension;
+    std::string_view extension;
     if (state.found_S_opt) {
       extension = ".s";
     } else if (!ctx.config.is_compiler_group_msvc()) {
index edff616dab19f8f832decf99013a6869024f2408..2a57d2c944fdcfb4dc1d38a533c88c5caf13410e 100644 (file)
@@ -26,7 +26,6 @@
 #include "Fd.hpp"
 #include "File.hpp"
 #include "Finalizer.hpp"
-#include "FormatNonstdStringView.hpp"
 #include "Hash.hpp"
 #include "Lockfile.hpp"
 #include "Logging.hpp"
 #include <util/string.hpp>
 
 #include "third_party/fmt/core.h"
-#include "third_party/nonstd/string_view.hpp"
 
 #include <fcntl.h>
 
 #include <optional>
+#include <string_view>
 
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
@@ -85,7 +84,6 @@
 const char CCACHE_NAME[] = MYNAME;
 
 using core::Statistic;
-using nonstd::string_view;
 
 // This is a string that identifies the current "version" of the hash sum
 // computed by ccache. If, for any reason, we want to force the hash sum to be
@@ -170,7 +168,7 @@ add_prefix(const Context& ctx, Args& args, const std::string& prefix_command)
 static std::string
 prepare_debug_path(const std::string& debug_dir,
                    const std::string& output_obj,
-                   string_view suffix)
+                   std::string_view suffix)
 {
   auto prefix = debug_dir.empty()
                   ? output_obj
@@ -186,7 +184,7 @@ static void
 init_hash_debug(Context& ctx,
                 Hash& hash,
                 char type,
-                string_view section_name,
+                std::string_view section_name,
                 FILE* debug_text_file)
 {
   if (!ctx.config.debug()) {
@@ -205,7 +203,7 @@ init_hash_debug(Context& ctx,
 }
 
 CompilerType
-guess_compiler(string_view path)
+guess_compiler(std::string_view path)
 {
   std::string compiler_path(path);
 
@@ -228,14 +226,14 @@ guess_compiler(string_view path)
 
   const auto name =
     Util::to_lowercase(Util::remove_extension(Util::base_name(compiler_path)));
-  if (name.find("clang-cl") != nonstd::string_view::npos) {
+  if (name.find("clang-cl") != std::string_view::npos) {
     return CompilerType::clang_cl;
-  } else if (name.find("clang") != nonstd::string_view::npos) {
+  } else if (name.find("clang") != std::string_view::npos) {
     return CompilerType::clang;
-  } else if (name.find("gcc") != nonstd::string_view::npos
-             || name.find("g++") != nonstd::string_view::npos) {
+  } else if (name.find("gcc") != std::string_view::npos
+             || name.find("g++") != std::string_view::npos) {
     return CompilerType::gcc;
-  } else if (name.find("nvcc") != nonstd::string_view::npos) {
+  } else if (name.find("nvcc") != std::string_view::npos) {
     return CompilerType::nvcc;
   } else if (name == "cl") {
     return CompilerType::msvc;
@@ -456,11 +454,11 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
   // There must be at least 7 characters (# 1 "x") left to potentially find an
   // include file path.
   while (q < end - 7) {
-    static const string_view pragma_gcc_pch_preprocess =
+    static const std::string_view pragma_gcc_pch_preprocess =
       "pragma GCC pch_preprocess ";
-    static const string_view hash_31_command_line_newline =
+    static const std::string_view hash_31_command_line_newline =
       "# 31 \"<command-line>\"\n";
-    static const string_view hash_32_command_line_2_newline =
+    static const std::string_view hash_32_command_line_2_newline =
       "# 32 \"<command-line>\" 2\n";
     // Note: Intentionally not using the string form to avoid false positive
     // match by ccache itself.
@@ -633,8 +631,8 @@ result_key_from_depfile(Context& ctx, Hash& hash)
     return std::nullopt;
   }
 
-  for (string_view token : Depfile::tokenize(file_content)) {
-    if (token.ends_with(":")) {
+  for (std::string_view token : Depfile::tokenize(file_content)) {
+    if (util::ends_with(token, ":")) {
       continue;
     }
     if (!ctx.has_absolute_include_headers) {
@@ -1420,7 +1418,7 @@ hash_common_info(const Context& ctx,
       dir =
         Util::real_path(std::string(Util::dir_name(ctx.args_info.output_obj)));
     }
-    string_view stem =
+    std::string_view stem =
       Util::remove_extension(Util::base_name(ctx.args_info.output_obj));
     std::string gcda_path = FMT("{}/{}.gcda", dir, stem);
     LOG("Hashing coverage path {}", gcda_path);
@@ -1464,7 +1462,7 @@ static bool
 hash_profile_data_file(const Context& ctx, Hash& hash)
 {
   const std::string& profile_path = ctx.args_info.profile_path;
-  string_view base_name = Util::remove_extension(ctx.args_info.output_obj);
+  std::string_view base_name = Util::remove_extension(ctx.args_info.output_obj);
   std::string hashified_cwd = ctx.apparent_cwd;
   std::replace(hashified_cwd.begin(), hashified_cwd.end(), '/', '#');
 
@@ -1503,7 +1501,8 @@ option_should_be_ignored(const std::string& arg,
 {
   return std::any_of(
     patterns.cbegin(), patterns.cend(), [&arg](const auto& pattern) {
-      const auto& prefix = string_view(pattern).substr(0, pattern.length() - 1);
+      const auto& prefix =
+        std::string_view(pattern).substr(0, pattern.length() - 1);
       return (
         pattern == arg
         || (util::ends_with(pattern, "*") && util::starts_with(arg, prefix)));
index 2b799fe8e12dceb04ce2996947f90ad4bc3a4029..7590ad584ee58bf43ded064015aa2414c96b89a0 100644 (file)
 
 #include "Config.hpp"
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <functional>
 #include <string>
+#include <string_view>
 
 class Context;
 
@@ -41,4 +40,4 @@ int ccache_main(int argc, const char* const* argv);
 // Tested by unit tests.
 void find_compiler(Context& ctx,
                    const FindExecutableFunction& find_executable_function);
-CompilerType guess_compiler(nonstd::string_view path);
+CompilerType guess_compiler(std::string_view path);
index 95176d7ca9148cd9d1216b77b542e641f5b8d3be..a9b70b588ca80ad162dcd3cbe91e36e4664778b4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -18,8 +18,6 @@
 
 #pragma once
 
-#include <FormatNonstdStringView.hpp>
-
 #include <third_party/fmt/core.h>
 
 #include <optional>
index 8f4e787a577dc24a590339a64cac1c82c673bbf2..2355c622f0b71ebc3238c39911a25ba276e6f9b6 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2011-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2011-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -46,8 +46,6 @@
 #  include "Finalizer.hpp"
 #endif
 
-using nonstd::string_view;
-
 #ifdef _WIN32
 static int win32execute(const char* path,
                         const char* const* argv,
index 3b7cf5d3118e9744805e2e4555cddfdba5ff5030..6f396fd262c34cdb06c4b796fd0304cb329255e1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -18,8 +18,6 @@
 
 #pragma once
 
-#include <FormatNonstdStringView.hpp>
-
 #include <third_party/fmt/core.h>
 #include <third_party/fmt/format.h>
 
index d61282fcc7cf84c03381fd646a1d1d6753f98133..7e0ca23f70ccc939749a1fb07e46bcfd16d8eaa4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2009-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2009-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -52,8 +52,6 @@
 #  include <immintrin.h>
 #endif
 
-using nonstd::string_view;
-
 namespace {
 
 // Returns one of HASH_SOURCE_CODE_FOUND_DATE, HASH_SOURCE_CODE_FOUND_TIME or
@@ -62,7 +60,7 @@ namespace {
 //
 // Pre-condition: str[pos - 1] == '_'
 int
-check_for_temporal_macros_helper(string_view str, size_t pos)
+check_for_temporal_macros_helper(std::string_view str, size_t pos)
 {
   if (pos + 7 > str.length()) {
     return 0;
@@ -94,7 +92,7 @@ check_for_temporal_macros_helper(string_view str, size_t pos)
 }
 
 int
-check_for_temporal_macros_bmh(string_view str)
+check_for_temporal_macros_bmh(std::string_view str)
 {
   int result = 0;
 
@@ -121,7 +119,7 @@ check_for_temporal_macros_bmh(string_view str)
 
 #ifdef HAVE_AVX2
 #  ifndef _MSC_VER // MSVC does not need explicit enabling of AVX2.
-int check_for_temporal_macros_avx2(string_view str)
+int check_for_temporal_macros_avx2(std::string_view str)
   __attribute__((target("avx2")));
 #  endif
 
@@ -129,7 +127,7 @@ int check_for_temporal_macros_avx2(string_view str)
 // __TIME__ and __TIMESTAMP__, is heavily inspired by
 // <http://0x80.pl/articles/simd-strfind.html>.
 int
-check_for_temporal_macros_avx2(string_view str)
+check_for_temporal_macros_avx2(std::string_view str)
 {
   int result = 0;
 
@@ -222,7 +220,7 @@ get_content_type(const Config& config, const std::string& path)
 } // namespace
 
 int
-check_for_temporal_macros(string_view str)
+check_for_temporal_macros(std::string_view str)
 {
 #ifdef HAVE_AVX2
   if (blake3_cpu_supports_avx2()) {
@@ -235,7 +233,7 @@ check_for_temporal_macros(string_view str)
 int
 hash_source_code_string(const Context& ctx,
                         Hash& hash,
-                        string_view str,
+                        std::string_view str,
                         const std::string& path)
 {
   int result = HASH_SOURCE_CODE_OK;
index b3f1756d7b7b0504d18a234b1f96c0c3d0bcf01a..01ee8e6ba90178f0592dd29d53436b8f0885d190 100644 (file)
 
 #pragma once
 
-#include "third_party/nonstd/string_view.hpp"
-
 #include <cstddef>
 #include <string>
+#include <string_view>
 
 class Config;
 class Context;
@@ -39,12 +38,12 @@ const int HASH_SOURCE_CODE_FOUND_TIMESTAMP = (1 << 3);
 // Returns a bitmask with HASH_SOURCE_CODE_FOUND_DATE,
 // HASH_SOURCE_CODE_FOUND_TIME and HASH_SOURCE_CODE_FOUND_TIMESTAMP set
 // appropriately.
-int check_for_temporal_macros(nonstd::string_view str);
+int check_for_temporal_macros(std::string_view str);
 
 // Hash a string. Returns a bitmask of HASH_SOURCE_CODE_* results.
 int hash_source_code_string(const Context& ctx,
                             Hash& hash,
-                            nonstd::string_view str,
+                            std::string_view str,
                             const std::string& path);
 
 // Hash a file ignoring comments. Returns a bitmask of HASH_SOURCE_CODE_*
index cc56beff59b04837edc5b7dc18ec9dfc45138c06..02dd573cb075c0d5e0afb5188d5b5be85d9e397b 100644 (file)
@@ -111,7 +111,7 @@ to_string(const SecondaryStorageConfig& entry)
 }
 
 static SecondaryStorageConfig
-parse_storage_config(const nonstd::string_view entry)
+parse_storage_config(const std::string_view entry)
 {
   const auto parts =
     Util::split_into_views(entry, "|", util::Tokenizer::Mode::include_empty);
@@ -152,9 +152,9 @@ parse_storage_config(const nonstd::string_view entry)
       }
       for (const auto& shard : util::Tokenizer(value, ",")) {
         double weight = 1.0;
-        nonstd::string_view name;
+        std::string_view name;
         const auto lp_pos = shard.find('(');
-        if (lp_pos != nonstd::string_view::npos) {
+        if (lp_pos != std::string_view::npos) {
           if (shard.back() != ')') {
             throw core::Error("Invalid shard name: \"{}\"", shard);
           }
@@ -183,7 +183,7 @@ parse_storage_config(const nonstd::string_view entry)
 }
 
 static std::vector<SecondaryStorageConfig>
-parse_storage_configs(const nonstd::string_view& configs)
+parse_storage_configs(const std::string_view& configs)
 {
   std::vector<SecondaryStorageConfig> result;
   for (const auto& config : util::Tokenizer(configs, " ")) {
@@ -418,7 +418,7 @@ get_shard_url(const Digest& key,
 SecondaryStorageBackendEntry*
 Storage::get_backend(SecondaryStorageEntry& entry,
                      const Digest& key,
-                     const nonstd::string_view operation_description,
+                     const std::string_view operation_description,
                      const bool for_writing)
 {
   if (for_writing && entry.config.read_only) {
@@ -449,7 +449,7 @@ Storage::get_backend(SecondaryStorageEntry& entry,
     } catch (const secondary::SecondaryStorage::Backend::Failed& e) {
       LOG("Failed to construct backend for {}{}",
           entry.url_for_logging,
-          nonstd::string_view(e.what()).empty() ? "" : FMT(": {}", e.what()));
+          std::string_view(e.what()).empty() ? "" : FMT(": {}", e.what()));
       mark_backend_as_failed(entry.backends.back(), e.failure());
       return nullptr;
     }
index ab41c86e533218498c6d883e7983c9cb74fb5b35..5593e03c334d1feee9c7b58812b9f4eaa9a52838 100644 (file)
@@ -76,7 +76,7 @@ private:
   SecondaryStorageBackendEntry*
   get_backend(SecondaryStorageEntry& entry,
               const Digest& key,
-              nonstd::string_view operation_description,
+              std::string_view operation_description,
               const bool for_writing);
   std::optional<std::pair<std::string, bool>>
   get_from_secondary_storage(const Digest& key);
index c4e058170996dcbd6d83983e1f19480219437f45..6c048f352d9fe5250f14a6ca5727f6073d26eaeb 100644 (file)
@@ -385,7 +385,7 @@ PrimaryStorage::update_stats_and_maybe_move_cache_file(
 
 std::string
 PrimaryStorage::get_path_in_cache(const uint8_t level,
-                                  const nonstd::string_view name) const
+                                  const std::string_view name) const
 {
   ASSERT(level >= 1 && level <= 8);
   ASSERT(name.length() >= level);
@@ -399,7 +399,7 @@ PrimaryStorage::get_path_in_cache(const uint8_t level,
   }
 
   path.push_back('/');
-  const nonstd::string_view name_remaining = name.substr(level);
+  const std::string_view name_remaining = name.substr(level);
   path.append(name_remaining.data(), name_remaining.length());
 
   return path;
index babb7d79b3d367bcdd11556eab2225fd1a43e564..593f0c2aee1027ab740154c69112fbde9bf63d14 100644 (file)
@@ -133,7 +133,7 @@ private:
   // Join the cache directory, a '/' and `name` into a single path and return
   // it. Additionally, `level` single-character, '/'-separated subpaths are
   // split from the beginning of `name` before joining them all.
-  std::string get_path_in_cache(uint8_t level, nonstd::string_view name) const;
+  std::string get_path_in_cache(uint8_t level, std::string_view name) const;
 
   static void clean_dir(const std::string& subdir,
                         uint64_t max_size,
index f50b4defd2ccb6f187d81a62a19c280e44fe3a24..7d89cb92defe751da7e3ca9dc78adb0f54ff5645 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -20,6 +20,7 @@
 
 #include <Util.hpp>
 #include <fmtmacros.hpp>
+#include <util/string.hpp>
 
 namespace storage {
 namespace primary {
@@ -54,7 +55,8 @@ get_level_1_files(const std::string& dir,
 
   Util::traverse(dir, [&](const std::string& path, bool is_dir) {
     auto name = Util::base_name(path);
-    if (name == "CACHEDIR.TAG" || name == "stats" || name.starts_with(".nfs")) {
+    if (name == "CACHEDIR.TAG" || name == "stats"
+        || util::starts_with(name, ".nfs")) {
       return;
     }
 
index 906127d761442b521a638a3e4df0802a1edc3721..9ae10c61f34194fb7d8ddb254dc94720f887b0e2 100644 (file)
 #include <util/file.hpp>
 #include <util/string.hpp>
 
-#include <third_party/nonstd/string_view.hpp>
-
 #include <sys/stat.h> // for mode_t
 
+#include <string_view>
+
 namespace storage {
 namespace secondary {
 
index 2c253a11b9ab3ed7051ed9862387467235775c08..a59948b9e43958cee2f3a3875f0b359be92fb85f 100644 (file)
 #include <util/string.hpp>
 
 #include <third_party/httplib.h>
-#include <third_party/nonstd/string_view.hpp>
 #include <third_party/url.hpp>
 
+#include <string_view>
+
 namespace storage {
 namespace secondary {
 
diff --git a/src/third_party/nonstd/string_view.hpp b/src/third_party/nonstd/string_view.hpp
deleted file mode 100644 (file)
index 2784272..0000000
+++ /dev/null
@@ -1,1626 +0,0 @@
-// Copyright 2017-2020 by Martin Moene
-//
-// string-view lite, a C++17-like string_view for C++98 and later.
-// For more information see https://github.com/martinmoene/string-view-lite
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#pragma once
-
-#ifndef NONSTD_SV_LITE_H_INCLUDED
-#define NONSTD_SV_LITE_H_INCLUDED
-
-#define string_view_lite_MAJOR  1
-#define string_view_lite_MINOR  6
-#define string_view_lite_PATCH  0
-
-#define string_view_lite_VERSION  nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
-
-#define nssv_STRINGIFY(  x )  nssv_STRINGIFY_( x )
-#define nssv_STRINGIFY_( x )  #x
-
-// string-view lite configuration:
-
-#define nssv_STRING_VIEW_DEFAULT  0
-#define nssv_STRING_VIEW_NONSTD   1
-#define nssv_STRING_VIEW_STD      2
-
-// tweak header support:
-
-#ifdef __has_include
-# if __has_include(<nonstd/string_view.tweak.hpp>)
-#  include <nonstd/string_view.tweak.hpp>
-# endif
-#define nssv_HAVE_TWEAK_HEADER  1
-#else
-#define nssv_HAVE_TWEAK_HEADER  0
-//# pragma message("string_view.hpp: Note: Tweak header not supported.")
-#endif
-
-// string_view selection and configuration:
-
-#if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
-# define nssv_CONFIG_SELECT_STRING_VIEW  ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
-#endif
-
-#if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW )
-# error nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and removed, please use nssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_...
-#endif
-
-#ifndef  nssv_CONFIG_STD_SV_OPERATOR
-# define nssv_CONFIG_STD_SV_OPERATOR  0
-#endif
-
-#ifndef  nssv_CONFIG_USR_SV_OPERATOR
-# define nssv_CONFIG_USR_SV_OPERATOR  1
-#endif
-
-#ifdef   nssv_CONFIG_CONVERSION_STD_STRING
-# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS   nssv_CONFIG_CONVERSION_STD_STRING
-# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS  nssv_CONFIG_CONVERSION_STD_STRING
-#endif
-
-#ifndef  nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS  1
-#endif
-
-#ifndef  nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS  1
-#endif
-
-// Control presence of exception handling (try and auto discover):
-
-#ifndef nssv_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
-#  define nssv_CONFIG_NO_EXCEPTIONS  0
-# else
-#  define nssv_CONFIG_NO_EXCEPTIONS  1
-# endif
-#endif
-
-// C++ language version detection (C++20 is speculative):
-// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
-
-#ifndef   nssv_CPLUSPLUS
-# if defined(_MSVC_LANG ) && !defined(__clang__)
-#  define nssv_CPLUSPLUS  (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
-# else
-#  define nssv_CPLUSPLUS  __cplusplus
-# endif
-#endif
-
-#define nssv_CPP98_OR_GREATER  ( nssv_CPLUSPLUS >= 199711L )
-#define nssv_CPP11_OR_GREATER  ( nssv_CPLUSPLUS >= 201103L )
-#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
-#define nssv_CPP14_OR_GREATER  ( nssv_CPLUSPLUS >= 201402L )
-#define nssv_CPP17_OR_GREATER  ( nssv_CPLUSPLUS >= 201703L )
-#define nssv_CPP20_OR_GREATER  ( nssv_CPLUSPLUS >= 202000L )
-
-// use C++17 std::string_view if available and requested:
-
-#if nssv_CPP17_OR_GREATER && defined(__has_include )
-# if __has_include( <string_view> )
-#  define nssv_HAVE_STD_STRING_VIEW  1
-# else
-#  define nssv_HAVE_STD_STRING_VIEW  0
-# endif
-#else
-# define  nssv_HAVE_STD_STRING_VIEW  0
-#endif
-
-#define  nssv_USES_STD_STRING_VIEW  ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) )
-
-#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
-#define nssv_HAVE_ENDS_WITH     nssv_HAVE_STARTS_WITH
-
-//
-// Use C++17 std::string_view:
-//
-
-#if nssv_USES_STD_STRING_VIEW
-
-#include <string_view>
-
-// Extensions for std::string:
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-
-template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
-std::basic_string<CharT, Traits, Allocator>
-to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
-{
-    return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-template< class CharT, class Traits, class Allocator >
-std::basic_string_view<CharT, Traits>
-to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
-{
-    return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
-}
-
-// Literal operators sv and _sv:
-
-#if nssv_CONFIG_STD_SV_OPERATOR
-
-using namespace std::literals::string_view_literals;
-
-#endif
-
-#if nssv_CONFIG_USR_SV_OPERATOR
-
-inline namespace literals {
-inline namespace string_view_literals {
-
-
-constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept  // (1)
-{
-    return std::string_view{ str, len };
-}
-
-constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept  // (2)
-{
-    return std::u16string_view{ str, len };
-}
-
-constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept  // (3)
-{
-    return std::u32string_view{ str, len };
-}
-
-constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept  // (4)
-{
-    return std::wstring_view{ str, len };
-}
-
-}} // namespace literals::string_view_literals
-
-#endif // nssv_CONFIG_USR_SV_OPERATOR
-
-} // namespace nonstd
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-
-using std::string_view;
-using std::wstring_view;
-using std::u16string_view;
-using std::u32string_view;
-using std::basic_string_view;
-
-// literal "sv" and "_sv", see above
-
-using std::operator==;
-using std::operator!=;
-using std::operator<;
-using std::operator<=;
-using std::operator>;
-using std::operator>=;
-
-using std::operator<<;
-
-} // namespace nonstd
-
-#else // nssv_HAVE_STD_STRING_VIEW
-
-//
-// Before C++17: use string_view lite:
-//
-
-// Compiler versions:
-//
-// MSVC++  6.0  _MSC_VER == 1200  nssv_COMPILER_MSVC_VERSION ==  60  (Visual Studio 6.0)
-// MSVC++  7.0  _MSC_VER == 1300  nssv_COMPILER_MSVC_VERSION ==  70  (Visual Studio .NET 2002)
-// MSVC++  7.1  _MSC_VER == 1310  nssv_COMPILER_MSVC_VERSION ==  71  (Visual Studio .NET 2003)
-// MSVC++  8.0  _MSC_VER == 1400  nssv_COMPILER_MSVC_VERSION ==  80  (Visual Studio 2005)
-// MSVC++  9.0  _MSC_VER == 1500  nssv_COMPILER_MSVC_VERSION ==  90  (Visual Studio 2008)
-// MSVC++ 10.0  _MSC_VER == 1600  nssv_COMPILER_MSVC_VERSION == 100  (Visual Studio 2010)
-// MSVC++ 11.0  _MSC_VER == 1700  nssv_COMPILER_MSVC_VERSION == 110  (Visual Studio 2012)
-// MSVC++ 12.0  _MSC_VER == 1800  nssv_COMPILER_MSVC_VERSION == 120  (Visual Studio 2013)
-// MSVC++ 14.0  _MSC_VER == 1900  nssv_COMPILER_MSVC_VERSION == 140  (Visual Studio 2015)
-// MSVC++ 14.1  _MSC_VER >= 1910  nssv_COMPILER_MSVC_VERSION == 141  (Visual Studio 2017)
-// MSVC++ 14.2  _MSC_VER >= 1920  nssv_COMPILER_MSVC_VERSION == 142  (Visual Studio 2019)
-
-#if defined(_MSC_VER ) && !defined(__clang__)
-# define nssv_COMPILER_MSVC_VER      (_MSC_VER )
-# define nssv_COMPILER_MSVC_VERSION  (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
-#else
-# define nssv_COMPILER_MSVC_VER      0
-# define nssv_COMPILER_MSVC_VERSION  0
-#endif
-
-#define nssv_COMPILER_VERSION( major, minor, patch )  ( 10 * ( 10 * (major) + (minor) ) + (patch) )
-
-#if defined( __apple_build_version__ )
-# define nssv_COMPILER_APPLECLANG_VERSION  nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
-# define nssv_COMPILER_CLANG_VERSION       0
-#elif defined( __clang__ )
-# define nssv_COMPILER_APPLECLANG_VERSION  0
-# define nssv_COMPILER_CLANG_VERSION       nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
-#else
-# define nssv_COMPILER_APPLECLANG_VERSION  0
-# define nssv_COMPILER_CLANG_VERSION       0
-#endif
-
-#if defined(__GNUC__) && !defined(__clang__)
-# define nssv_COMPILER_GNUC_VERSION  nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
-#else
-# define nssv_COMPILER_GNUC_VERSION  0
-#endif
-
-// half-open range [lo..hi):
-#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
-
-// Presence of language and library features:
-
-#ifdef _HAS_CPP0X
-# define nssv_HAS_CPP0X  _HAS_CPP0X
-#else
-# define nssv_HAS_CPP0X  0
-#endif
-
-// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
-
-#if nssv_COMPILER_MSVC_VER >= 1900
-# undef  nssv_CPP11_OR_GREATER
-# define nssv_CPP11_OR_GREATER  1
-#endif
-
-#define nssv_CPP11_90   (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
-#define nssv_CPP11_100  (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
-#define nssv_CPP11_110  (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
-#define nssv_CPP11_120  (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
-#define nssv_CPP11_140  (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
-#define nssv_CPP11_141  (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
-
-#define nssv_CPP14_000  (nssv_CPP14_OR_GREATER)
-#define nssv_CPP17_000  (nssv_CPP17_OR_GREATER)
-
-// Presence of C++11 language features:
-
-#define nssv_HAVE_CONSTEXPR_11          nssv_CPP11_140
-#define nssv_HAVE_EXPLICIT_CONVERSION   nssv_CPP11_140
-#define nssv_HAVE_INLINE_NAMESPACE      nssv_CPP11_140
-#define nssv_HAVE_NOEXCEPT              nssv_CPP11_140
-#define nssv_HAVE_NULLPTR               nssv_CPP11_100
-#define nssv_HAVE_REF_QUALIFIER         nssv_CPP11_140
-#define nssv_HAVE_UNICODE_LITERALS      nssv_CPP11_140
-#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
-#define nssv_HAVE_WCHAR16_T             nssv_CPP11_100
-#define nssv_HAVE_WCHAR32_T             nssv_CPP11_100
-
-#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
-# define nssv_HAVE_STD_DEFINED_LITERALS  nssv_CPP11_140
-#else
-# define nssv_HAVE_STD_DEFINED_LITERALS  0
-#endif
-
-// Presence of C++14 language features:
-
-#define nssv_HAVE_CONSTEXPR_14          nssv_CPP14_000
-
-// Presence of C++17 language features:
-
-#define nssv_HAVE_NODISCARD             nssv_CPP17_000
-
-// Presence of C++ library features:
-
-#define nssv_HAVE_STD_HASH              nssv_CPP11_120
-
-// Presence of compiler intrinsics:
-
-// Providing char-type specializations for compare() and length() that
-// use compiler intrinsics can improve compile- and run-time performance.
-//
-// The challenge is in using the right combinations of builtin availablity
-// and its constexpr-ness.
-//
-// | compiler | __builtin_memcmp (constexpr) | memcmp  (constexpr) |
-// |----------|------------------------------|---------------------|
-// | clang    | 4.0              (>= 4.0   ) | any     (?        ) |
-// | clang-a  | 9.0              (>= 9.0   ) | any     (?        ) |
-// | gcc      | any              (constexpr) | any     (?        ) |
-// | msvc     | >= 14.2 C++17    (>= 14.2  ) | any     (?        ) |
-
-#define nssv_HAVE_BUILTIN_VER     ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 )
-#define nssv_HAVE_BUILTIN_CE      (  nssv_HAVE_BUILTIN_VER )
-
-#define nssv_HAVE_BUILTIN_MEMCMP  ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 )
-#define nssv_HAVE_BUILTIN_STRLEN  ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 )
-
-#ifdef __has_builtin
-# define nssv_HAVE_BUILTIN( x )  __has_builtin( x )
-#else
-# define nssv_HAVE_BUILTIN( x )  0
-#endif
-
-#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
-# define nssv_BUILTIN_MEMCMP  __builtin_memcmp
-#else
-# define nssv_BUILTIN_MEMCMP  memcmp
-#endif
-
-#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
-# define nssv_BUILTIN_STRLEN  __builtin_strlen
-#else
-# define nssv_BUILTIN_STRLEN  strlen
-#endif
-
-// C++ feature usage:
-
-#if nssv_HAVE_CONSTEXPR_11
-# define nssv_constexpr  constexpr
-#else
-# define nssv_constexpr  /*constexpr*/
-#endif
-
-#if  nssv_HAVE_CONSTEXPR_14
-# define nssv_constexpr14  constexpr
-#else
-# define nssv_constexpr14  /*constexpr*/
-#endif
-
-#if nssv_HAVE_EXPLICIT_CONVERSION
-# define nssv_explicit  explicit
-#else
-# define nssv_explicit  /*explicit*/
-#endif
-
-#if nssv_HAVE_INLINE_NAMESPACE
-# define nssv_inline_ns  inline
-#else
-# define nssv_inline_ns  /*inline*/
-#endif
-
-#if nssv_HAVE_NOEXCEPT
-# define nssv_noexcept  noexcept
-#else
-# define nssv_noexcept  /*noexcept*/
-#endif
-
-//#if nssv_HAVE_REF_QUALIFIER
-//# define nssv_ref_qual  &
-//# define nssv_refref_qual  &&
-//#else
-//# define nssv_ref_qual  /*&*/
-//# define nssv_refref_qual  /*&&*/
-//#endif
-
-#if nssv_HAVE_NULLPTR
-# define nssv_nullptr  nullptr
-#else
-# define nssv_nullptr  NULL
-#endif
-
-#if nssv_HAVE_NODISCARD
-# define nssv_nodiscard  [[nodiscard]]
-#else
-# define nssv_nodiscard  /*[[nodiscard]]*/
-#endif
-
-// Additional includes:
-
-#include <algorithm>
-#include <cassert>
-#include <iterator>
-#include <limits>
-#include <ostream>
-#include <string>   // std::char_traits<>
-
-#if ! nssv_CONFIG_NO_EXCEPTIONS
-# include <stdexcept>
-#endif
-
-#if nssv_CPP11_OR_GREATER
-# include <type_traits>
-#endif
-
-// Clang, GNUC, MSVC warning suppression macros:
-
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wuser-defined-literals"
-#elif defined(__GNUC__)
-# pragma  GCC  diagnostic push
-# pragma  GCC  diagnostic ignored "-Wliteral-suffix"
-#endif // __clang__
-
-#if nssv_COMPILER_MSVC_VERSION >= 140
-# define nssv_SUPPRESS_MSGSL_WARNING(expr)        [[gsl::suppress(expr)]]
-# define nssv_SUPPRESS_MSVC_WARNING(code, descr)  __pragma(warning(suppress: code) )
-# define nssv_DISABLE_MSVC_WARNINGS(codes)        __pragma(warning(push))  __pragma(warning(disable: codes))
-#else
-# define nssv_SUPPRESS_MSGSL_WARNING(expr)
-# define nssv_SUPPRESS_MSVC_WARNING(code, descr)
-# define nssv_DISABLE_MSVC_WARNINGS(codes)
-#endif
-
-#if defined(__clang__)
-# define nssv_RESTORE_WARNINGS()  _Pragma("clang diagnostic pop")
-#elif defined(__GNUC__)
-# define nssv_RESTORE_WARNINGS()  _Pragma("GCC diagnostic pop")
-#elif nssv_COMPILER_MSVC_VERSION >= 140
-# define nssv_RESTORE_WARNINGS()  __pragma(warning(pop ))
-#else
-# define nssv_RESTORE_WARNINGS()
-#endif
-
-// Suppress the following MSVC (GSL) warnings:
-// - C4455, non-gsl   : 'operator ""sv': literal suffix identifiers that do not
-//                      start with an underscore are reserved
-// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
-//                      use brace initialization, gsl::narrow_cast or gsl::narow
-// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
-
-nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
-//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
-//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
-
-namespace nonstd { namespace sv_lite {
-
-namespace detail {
-
-// support constexpr comparison in C++14;
-// for C++17 and later, use provided traits:
-
-template< typename CharT >
-inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count )
-{
-    while ( count-- != 0 )
-    {
-        if ( *s1 < *s2 ) return -1;
-        if ( *s1 > *s2 ) return +1;
-        ++s1; ++s2;
-    }
-    return 0;
-}
-
-#if nssv_HAVE_BUILTIN_MEMCMP
-
-// specialization of compare() for char, see also generic compare() above:
-
-inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count )
-{
-    return nssv_BUILTIN_MEMCMP( s1, s2, count );
-}
-
-#endif
-
-#if nssv_HAVE_BUILTIN_STRLEN
-
-// specialization of length() for char, see also generic length() further below:
-
-inline nssv_constexpr std::size_t length( char const * s )
-{
-    return nssv_BUILTIN_STRLEN( s );
-}
-
-#endif
-
-#if defined(__OPTIMIZE__)
-
-// gcc, clang provide __OPTIMIZE__
-// Expect tail call optimization to make length() non-recursive:
-
-template< typename CharT >
-inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 )
-{
-    return *s == '\0' ? result : length( s + 1, result + 1 );
-}
-
-#else // OPTIMIZE
-
-// non-recursive:
-
-template< typename CharT >
-inline nssv_constexpr14 std::size_t length( CharT * s )
-{
-    std::size_t result = 0;
-    while ( *s++ != '\0' )
-    {
-       ++result;
-    }
-    return result;
-}
-
-#endif // OPTIMIZE
-
-} // namespace detail
-
-template
-<
-    class CharT,
-    class Traits = std::char_traits<CharT>
->
-class basic_string_view;
-
-//
-// basic_string_view:
-//
-
-template
-<
-    class CharT,
-    class Traits /* = std::char_traits<CharT> */
->
-class basic_string_view
-{
-public:
-    // Member types:
-
-    typedef Traits traits_type;
-    typedef CharT  value_type;
-
-    typedef CharT       * pointer;
-    typedef CharT const * const_pointer;
-    typedef CharT       & reference;
-    typedef CharT const & const_reference;
-
-    typedef const_pointer iterator;
-    typedef const_pointer const_iterator;
-    typedef std::reverse_iterator< const_iterator > reverse_iterator;
-    typedef    std::reverse_iterator< const_iterator > const_reverse_iterator;
-
-    typedef std::size_t     size_type;
-    typedef std::ptrdiff_t  difference_type;
-
-    // 24.4.2.1 Construction and assignment:
-
-    nssv_constexpr basic_string_view() nssv_noexcept
-        : data_( nssv_nullptr )
-        , size_( 0 )
-    {}
-
-#if nssv_CPP11_OR_GREATER
-    nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
-#else
-    nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
-        : data_( other.data_)
-        , size_( other.size_)
-    {}
-#endif
-
-    nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept
-        : data_( s )
-        , size_( count )
-    {}
-
-    nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept
-        : data_( s )
-#if nssv_CPP17_OR_GREATER
-        , size_( Traits::length(s) )
-#elif nssv_CPP11_OR_GREATER
-        , size_( detail::length(s) )
-#else
-        , size_( Traits::length(s) )
-#endif
-    {}
-
-    // Assignment:
-
-#if nssv_CPP11_OR_GREATER
-    nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
-#else
-    nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
-    {
-        data_ = other.data_;
-        size_ = other.size_;
-        return *this;
-    }
-#endif
-
-    // 24.4.2.2 Iterator support:
-
-    nssv_constexpr const_iterator begin()  const nssv_noexcept { return data_;         }
-    nssv_constexpr const_iterator end()    const nssv_noexcept { return data_ + size_; }
-
-    nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
-    nssv_constexpr const_iterator cend()   const nssv_noexcept { return end();   }
-
-    nssv_constexpr const_reverse_iterator rbegin()  const nssv_noexcept { return const_reverse_iterator( end() );   }
-    nssv_constexpr const_reverse_iterator rend()    const nssv_noexcept { return const_reverse_iterator( begin() ); }
-
-    nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
-    nssv_constexpr const_reverse_iterator crend()   const nssv_noexcept { return rend();   }
-
-    // 24.4.2.3 Capacity:
-
-    nssv_constexpr size_type size()     const nssv_noexcept { return size_; }
-    nssv_constexpr size_type length()   const nssv_noexcept { return size_; }
-    nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
-
-    // since C++20
-    nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
-    {
-        return 0 == size_;
-    }
-
-    // 24.4.2.4 Element access:
-
-    nssv_constexpr const_reference operator[]( size_type pos ) const
-    {
-        return data_at( pos );
-    }
-
-    nssv_constexpr14 const_reference at( size_type pos ) const
-    {
-#if nssv_CONFIG_NO_EXCEPTIONS
-        assert( pos < size() );
-#else
-        if ( pos >= size() )
-        {
-            throw std::out_of_range("nonstd::string_view::at()");
-        }
-#endif
-        return data_at( pos );
-    }
-
-    nssv_constexpr const_reference front() const { return data_at( 0 );          }
-    nssv_constexpr const_reference back()  const { return data_at( size() - 1 ); }
-
-    nssv_constexpr const_pointer   data()  const nssv_noexcept { return data_; }
-
-    // 24.4.2.5 Modifiers:
-
-    nssv_constexpr14 void remove_prefix( size_type n )
-    {
-        assert( n <= size() );
-        data_ += n;
-        size_ -= n;
-    }
-
-    nssv_constexpr14 void remove_suffix( size_type n )
-    {
-        assert( n <= size() );
-        size_ -= n;
-    }
-
-    nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
-    {
-        using std::swap;
-        swap( data_, other.data_ );
-        swap( size_, other.size_ );
-    }
-
-    // 24.4.2.6 String operations:
-
-    size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
-    {
-#if nssv_CONFIG_NO_EXCEPTIONS
-        assert( pos <= size() );
-#else
-        if ( pos > size() )
-        {
-            throw std::out_of_range("nonstd::string_view::copy()");
-        }
-#endif
-        const size_type rlen = (std::min)( n, size() - pos );
-
-        (void) Traits::copy( dest, data() + pos, rlen );
-
-        return rlen;
-    }
-
-    nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
-    {
-#if nssv_CONFIG_NO_EXCEPTIONS
-        assert( pos <= size() );
-#else
-        if ( pos > size() )
-        {
-            throw std::out_of_range("nonstd::string_view::substr()");
-        }
-#endif
-        return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
-    }
-
-    // compare(), 6x:
-
-    nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
-    {
-#if nssv_CPP17_OR_GREATER
-        if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
-#else
-        if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
-#endif
-        {
-            return result;
-        }
-
-        return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
-    }
-
-    nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2)
-    {
-        return substr( pos1, n1 ).compare( other );
-    }
-
-    nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3)
-    {
-        return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
-    }
-
-    nssv_constexpr int compare( CharT const * s ) const // (4)
-    {
-        return compare( basic_string_view( s ) );
-    }
-
-    nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5)
-    {
-        return substr( pos1, n1 ).compare( basic_string_view( s ) );
-    }
-
-    nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6)
-    {
-        return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
-    }
-
-    // 24.4.2.7 Searching:
-
-    // starts_with(), 3x, since C++20:
-
-    nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept  // (1)
-    {
-        return size() >= v.size() && compare( 0, v.size(), v ) == 0;
-    }
-
-    nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept  // (2)
-    {
-        return starts_with( basic_string_view( &c, 1 ) );
-    }
-
-    nssv_constexpr bool starts_with( CharT const * s ) const  // (3)
-    {
-        return starts_with( basic_string_view( s ) );
-    }
-
-    // ends_with(), 3x, since C++20:
-
-    nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept  // (1)
-    {
-        return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
-    }
-
-    nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept  // (2)
-    {
-        return ends_with( basic_string_view( &c, 1 ) );
-    }
-
-    nssv_constexpr bool ends_with( CharT const * s ) const  // (3)
-    {
-        return ends_with( basic_string_view( s ) );
-    }
-
-    // find(), 4x:
-
-    nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
-    {
-        return assert( v.size() == 0 || v.data() != nssv_nullptr )
-            , pos >= size()
-            ? npos
-            : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
-    }
-
-    nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept  // (2)
-    {
-        return find( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const  // (3)
-    {
-        return find( basic_string_view( s, n ), pos );
-    }
-
-    nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const  // (4)
-    {
-        return find( basic_string_view( s ), pos );
-    }
-
-    // rfind(), 4x:
-
-    nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
-    {
-        if ( size() < v.size() )
-        {
-            return npos;
-        }
-
-        if ( v.empty() )
-        {
-            return (std::min)( size(), pos );
-        }
-
-        const_iterator last   = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
-        const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
-
-        return result != last ? size_type( result - cbegin() ) : npos;
-    }
-
-    nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept  // (2)
-    {
-        return rfind( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const  // (3)
-    {
-        return rfind( basic_string_view( s, n ), pos );
-    }
-
-    nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const  // (4)
-    {
-        return rfind( basic_string_view( s ), pos );
-    }
-
-    // find_first_of(), 4x:
-
-    nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
-    {
-        return pos >= size()
-            ? npos
-            : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
-    }
-
-    nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept  // (2)
-    {
-        return find_first_of( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const  // (3)
-    {
-        return find_first_of( basic_string_view( s, n ), pos );
-    }
-
-    nssv_constexpr size_type find_first_of(  CharT const * s, size_type pos = 0 ) const  // (4)
-    {
-        return find_first_of( basic_string_view( s ), pos );
-    }
-
-    // find_last_of(), 4x:
-
-    nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
-    {
-        return empty()
-            ? npos
-            : pos >= size()
-            ? find_last_of( v, size() - 1 )
-            : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
-    }
-
-    nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept  // (2)
-    {
-        return find_last_of( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const  // (3)
-    {
-        return find_last_of( basic_string_view( s, count ), pos );
-    }
-
-    nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const  // (4)
-    {
-        return find_last_of( basic_string_view( s ), pos );
-    }
-
-    // find_first_not_of(), 4x:
-
-    nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept  // (1)
-    {
-        return pos >= size()
-            ? npos
-            : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
-    }
-
-    nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept  // (2)
-    {
-        return find_first_not_of( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const  // (3)
-    {
-        return find_first_not_of( basic_string_view( s, count ), pos );
-    }
-
-    nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const  // (4)
-    {
-        return find_first_not_of( basic_string_view( s ), pos );
-    }
-
-    // find_last_not_of(), 4x:
-
-    nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept  // (1)
-    {
-        return empty()
-            ? npos
-            : pos >= size()
-            ? find_last_not_of( v, size() - 1 )
-            : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
-    }
-
-    nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept  // (2)
-    {
-        return find_last_not_of( basic_string_view( &c, 1 ), pos );
-    }
-
-    nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const  // (3)
-    {
-        return find_last_not_of( basic_string_view( s, count ), pos );
-    }
-
-    nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const  // (4)
-    {
-        return find_last_not_of( basic_string_view( s ), pos );
-    }
-
-    // Constants:
-
-#if nssv_CPP17_OR_GREATER
-    static nssv_constexpr size_type npos = size_type(-1);
-#elif nssv_CPP11_OR_GREATER
-    enum : size_type { npos = size_type(-1) };
-#else
-    enum { npos = size_type(-1) };
-#endif
-
-private:
-    struct not_in_view
-    {
-        const basic_string_view v;
-
-        nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {}
-
-        nssv_constexpr bool operator()( CharT c ) const
-        {
-            return npos == v.find_first_of( c );
-        }
-    };
-
-    nssv_constexpr size_type to_pos( const_iterator it ) const
-    {
-        return it == cend() ? npos : size_type( it - cbegin() );
-    }
-
-    nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
-    {
-        return it == crend() ? npos : size_type( crend() - it - 1 );
-    }
-
-    nssv_constexpr const_reference data_at( size_type pos ) const
-    {
-#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
-        return data_[pos];
-#else
-        return assert( pos < size() ), data_[pos];
-#endif
-    }
-
-private:
-    const_pointer data_;
-    size_type     size_;
-
-public:
-#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-
-    template< class Allocator >
-    basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
-        : data_( s.data() )
-        , size_( s.size() )
-    {}
-
-#if nssv_HAVE_EXPLICIT_CONVERSION
-
-    template< class Allocator >
-    explicit operator std::basic_string<CharT, Traits, Allocator>() const
-    {
-        return to_string( Allocator() );
-    }
-
-#endif // nssv_HAVE_EXPLICIT_CONVERSION
-
-#if nssv_CPP11_OR_GREATER
-
-    template< class Allocator = std::allocator<CharT> >
-    std::basic_string<CharT, Traits, Allocator>
-    to_string( Allocator const & a = Allocator() ) const
-    {
-        return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
-    }
-
-#else
-
-    std::basic_string<CharT, Traits>
-    to_string() const
-    {
-        return std::basic_string<CharT, Traits>( begin(), end() );
-    }
-
-    template< class Allocator >
-    std::basic_string<CharT, Traits, Allocator>
-    to_string( Allocator const & a ) const
-    {
-        return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
-    }
-
-#endif // nssv_CPP11_OR_GREATER
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-};
-
-//
-// Non-member functions:
-//
-
-// 24.4.3 Non-member comparison functions:
-// lexicographically compare two string views (function template):
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator== (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator!= (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator< (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator<= (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator> (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator>= (
-    basic_string_view <CharT, Traits> lhs,
-    basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-// Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
-// Implementations shall provide sufficient additional overloads marked
-// constexpr and noexcept so that an object t with an implicit conversion
-// to S can be compared according to Table 67.
-
-#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
-
-// accomodate for older compilers:
-
-// ==
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
-    basic_string_view<CharT, Traits> lhs,
-    CharT const * rhs ) nssv_noexcept
-{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
-    CharT const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-// !=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
-    basic_string_view<CharT, Traits> lhs,
-    char const * rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
-    char const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-// <
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
-    basic_string_view<CharT, Traits> lhs,
-    char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
-    char const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) > 0; }
-
-// <=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
-    basic_string_view<CharT, Traits> lhs,
-    char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
-    char const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) >= 0; }
-
-// >
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
-    basic_string_view<CharT, Traits> lhs,
-    char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
-    char const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) < 0; }
-
-// >=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
-    basic_string_view<CharT, Traits> lhs,
-    char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
-    char const * lhs,
-    basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
-    basic_string_view<CharT, Traits> lhs,
-    std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
-    std::basic_string<CharT, Traits> rhs,
-    basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) <= 0; }
-
-#else // newer compilers:
-
-#define nssv_BASIC_STRING_VIEW_I(T,U)  typename std::decay< basic_string_view<T,U> >::type
-
-#if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
-# define nssv_MSVC_ORDER(x)  , int=x
-#else
-# define nssv_MSVC_ORDER(x)  /*, int=x*/
-#endif
-
-// ==
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator==(
-         basic_string_view  <CharT, Traits> lhs,
-    nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator==(
-    nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
-         basic_string_view  <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-// !=
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator!= (
-         basic_string_view  < CharT, Traits > lhs,
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator!= (
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
-         basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-// <
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator< (
-         basic_string_view  < CharT, Traits > lhs,
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator< (
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
-         basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-// <=
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator<= (
-         basic_string_view  < CharT, Traits > lhs,
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator<= (
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
-         basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-// >
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator> (
-         basic_string_view  < CharT, Traits > lhs,
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator> (
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
-         basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-// >=
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator>= (
-         basic_string_view  < CharT, Traits > lhs,
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits  nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator>= (
-    nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
-         basic_string_view  < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-#undef nssv_MSVC_ORDER
-#undef nssv_BASIC_STRING_VIEW_I
-
-#endif // compiler-dependent approach to comparisons
-
-// 24.4.4 Inserters and extractors:
-
-namespace detail {
-
-template< class Stream >
-void write_padding( Stream & os, std::streamsize n )
-{
-    for ( std::streamsize i = 0; i < n; ++i )
-        os.rdbuf()->sputc( os.fill() );
-}
-
-template< class Stream, class View >
-Stream & write_to_stream( Stream & os, View const & sv )
-{
-    typename Stream::sentry sentry( os );
-
-    if ( !os )
-        return os;
-
-    const std::streamsize length = static_cast<std::streamsize>( sv.length() );
-
-    // Whether, and how, to pad:
-    const bool      pad = ( length < os.width() );
-    const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
-
-    if ( left_pad )
-        write_padding( os, os.width() - length );
-
-    // Write span characters:
-    os.rdbuf()->sputn( sv.begin(), length );
-
-    if ( pad && !left_pad )
-        write_padding( os, os.width() - length );
-
-    // Reset output stream width:
-    os.width( 0 );
-
-    return os;
-}
-
-} // namespace detail
-
-template< class CharT, class Traits >
-std::basic_ostream<CharT, Traits> &
-operator<<(
-    std::basic_ostream<CharT, Traits>& os,
-    basic_string_view <CharT, Traits> sv )
-{
-    return detail::write_to_stream( os, sv );
-}
-
-// Several typedefs for common character types are provided:
-
-typedef basic_string_view<char>      string_view;
-typedef basic_string_view<wchar_t>   wstring_view;
-#if nssv_HAVE_WCHAR16_T
-typedef basic_string_view<char16_t>  u16string_view;
-typedef basic_string_view<char32_t>  u32string_view;
-#endif
-
-}} // namespace nonstd::sv_lite
-
-//
-// 24.4.6 Suffix for basic_string_view literals:
-//
-
-#if nssv_HAVE_USER_DEFINED_LITERALS
-
-namespace nonstd {
-nssv_inline_ns namespace literals {
-nssv_inline_ns namespace string_view_literals {
-
-#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
-
-nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept  // (1)
-{
-    return nonstd::sv_lite::string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept  // (2)
-{
-    return nonstd::sv_lite::u16string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept  // (3)
-{
-    return nonstd::sv_lite::u32string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept  // (4)
-{
-    return nonstd::sv_lite::wstring_view{ str, len };
-}
-
-#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
-
-#if nssv_CONFIG_USR_SV_OPERATOR
-
-nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept  // (1)
-{
-    return nonstd::sv_lite::string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept  // (2)
-{
-    return nonstd::sv_lite::u16string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept  // (3)
-{
-    return nonstd::sv_lite::u32string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept  // (4)
-{
-    return nonstd::sv_lite::wstring_view{ str, len };
-}
-
-#endif // nssv_CONFIG_USR_SV_OPERATOR
-
-}}} // namespace nonstd::literals::string_view_literals
-
-#endif
-
-//
-// Extensions for std::string:
-//
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-namespace sv_lite {
-
-// Exclude MSVC 14 (19.00): it yields ambiguous to_string():
-
-#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
-
-template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
-std::basic_string<CharT, Traits, Allocator>
-to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
-{
-    return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-#else
-
-template< class CharT, class Traits >
-std::basic_string<CharT, Traits>
-to_string( basic_string_view<CharT, Traits> v )
-{
-    return std::basic_string<CharT, Traits>( v.begin(), v.end() );
-}
-
-template< class CharT, class Traits, class Allocator >
-std::basic_string<CharT, Traits, Allocator>
-to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
-{
-    return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-#endif // nssv_CPP11_OR_GREATER
-
-template< class CharT, class Traits, class Allocator >
-basic_string_view<CharT, Traits>
-to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
-{
-    return basic_string_view<CharT, Traits>( s.data(), s.size() );
-}
-
-}} // namespace nonstd::sv_lite
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-//
-// make types and algorithms available in namespace nonstd:
-//
-
-namespace nonstd {
-
-using sv_lite::basic_string_view;
-using sv_lite::string_view;
-using sv_lite::wstring_view;
-
-#if nssv_HAVE_WCHAR16_T
-using sv_lite::u16string_view;
-#endif
-#if nssv_HAVE_WCHAR32_T
-using sv_lite::u32string_view;
-#endif
-
-// literal "sv"
-
-using sv_lite::operator==;
-using sv_lite::operator!=;
-using sv_lite::operator<;
-using sv_lite::operator<=;
-using sv_lite::operator>;
-using sv_lite::operator>=;
-
-using sv_lite::operator<<;
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-using sv_lite::to_string;
-using sv_lite::to_string_view;
-#endif
-
-} // namespace nonstd
-
-// 24.4.5 Hash support (C++11):
-
-// Note: The hash value of a string view object is equal to the hash value of
-// the corresponding string object.
-
-#if nssv_HAVE_STD_HASH
-
-#include <functional>
-
-namespace std {
-
-template<>
-struct hash< nonstd::string_view >
-{
-public:
-    std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
-    {
-        return std::hash<std::string>()( std::string( v.data(), v.size() ) );
-    }
-};
-
-template<>
-struct hash< nonstd::wstring_view >
-{
-public:
-    std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
-    {
-        return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
-    }
-};
-
-template<>
-struct hash< nonstd::u16string_view >
-{
-public:
-    std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
-    {
-        return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
-    }
-};
-
-template<>
-struct hash< nonstd::u32string_view >
-{
-public:
-    std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
-    {
-        return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
-    }
-};
-
-} // namespace std
-
-#endif // nssv_HAVE_STD_HASH
-
-nssv_RESTORE_WARNINGS()
-
-#endif // nssv_HAVE_STD_STRING_VIEW
-#endif // NONSTD_SV_LITE_H_INCLUDED
index 6300cd5ce750874d39065457e3eeaad272971985..a379c4f293fed2eba7689b3a4935a64be9fd69ce 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -23,7 +23,7 @@ namespace util {
 void
 Tokenizer::Iterator::advance(bool initial)
 {
-  constexpr auto npos = nonstd::string_view::npos;
+  constexpr auto npos = std::string_view::npos;
   const auto string = m_tokenizer.m_string;
   const auto delimiters = m_tokenizer.m_delimiters;
   const auto mode = m_tokenizer.m_mode;
@@ -46,7 +46,7 @@ Tokenizer::Iterator::advance(bool initial)
   } while (mode == Mode::skip_empty && m_left == m_right);
 }
 
-nonstd::sv_lite::string_view
+std::string_view
 Tokenizer::Iterator::operator*() const
 {
   DEBUG_ASSERT(m_left <= m_right);
index 763185b775143c91142881d9503a296968e65685..624a8057fcf05f3c923fc03407361d2c99090e06 100644 (file)
@@ -21,7 +21,8 @@
 #include <assertions.hpp>
 
 #include <third_party/fmt/core.h>
-#include <third_party/nonstd/string_view.hpp>
+
+#include <string_view>
 
 namespace util {
 
@@ -39,7 +40,7 @@ public:
 
   // Split `string` into tokens at any of the characters in `separators` which
   // must neither be the empty string nor a nullptr.
-  Tokenizer(nonstd::string_view string,
+  Tokenizer(std::string_view string,
             const char* delimiters,
             Mode mode = Mode::skip_empty,
             IncludeDelimiter include_delimiter = IncludeDelimiter::no);
@@ -51,7 +52,7 @@ public:
 
     Iterator operator++();
     bool operator!=(const Iterator& other) const;
-    nonstd::string_view operator*() const;
+    std::string_view operator*() const;
 
   private:
     const Tokenizer& m_tokenizer;
@@ -67,13 +68,13 @@ public:
 private:
   friend Iterator;
 
-  const nonstd::string_view m_string;
+  const std::string_view m_string;
   const char* const m_delimiters;
   const Mode m_mode;
   const IncludeDelimiter m_include_delimiter;
 };
 
-inline Tokenizer::Tokenizer(const nonstd::string_view string,
+inline Tokenizer::Tokenizer(const std::string_view string,
                             const char* const delimiters,
                             Tokenizer::Mode mode,
                             Tokenizer::IncludeDelimiter include_delimiter)
@@ -94,7 +95,7 @@ inline Tokenizer::Iterator::Iterator(const Tokenizer& tokenizer,
   if (start_pos == 0) {
     advance(true);
   } else {
-    DEBUG_ASSERT(start_pos == nonstd::string_view::npos);
+    DEBUG_ASSERT(start_pos == std::string_view::npos);
   }
 }
 
@@ -120,7 +121,7 @@ Tokenizer::begin()
 inline Tokenizer::Iterator
 Tokenizer::end()
 {
-  return Iterator(*this, nonstd::string_view::npos);
+  return Iterator(*this, std::string_view::npos);
 }
 
 } // namespace util
index 86d9d0202d7c0045daea1aac3e7fc97837ceeffe..c42e4fcf1bd0027f031c13e1330b4a5576956dad 100644 (file)
@@ -30,7 +30,7 @@ const char k_path_delimiter[] = ":";
 namespace util {
 
 bool
-is_absolute_path(nonstd::string_view path)
+is_absolute_path(std::string_view path)
 {
 #ifdef _WIN32
   if (path.length() >= 2 && path[1] == ':'
@@ -42,7 +42,7 @@ is_absolute_path(nonstd::string_view path)
 }
 
 bool
-path_starts_with(nonstd::string_view path, nonstd::string_view prefix)
+path_starts_with(std::string_view path, std::string_view prefix)
 {
   for (size_t i = 0, j = 0; i < path.length() && j < prefix.length();
        ++i, ++j) {
@@ -71,13 +71,13 @@ path_starts_with(nonstd::string_view path, nonstd::string_view prefix)
 }
 
 std::vector<std::string>
-split_path_list(nonstd::string_view path_list)
+split_path_list(std::string_view path_list)
 {
   return Util::split_into_strings(path_list, k_path_delimiter);
 }
 
 std::string
-to_absolute_path(nonstd::string_view path)
+to_absolute_path(std::string_view path)
 {
   if (util::is_absolute_path(path)) {
     return std::string(path);
@@ -88,7 +88,7 @@ to_absolute_path(nonstd::string_view path)
 }
 
 std::string
-to_absolute_path_no_drive(nonstd::string_view path)
+to_absolute_path_no_drive(std::string_view path)
 {
   std::string abs_path = to_absolute_path(path);
 #ifdef _WIN32
index 51fcd58153f7fb43e69cb9766b4f47538647cb38..98345e36e7665570044ea90f5077b8b3a0dfcaae 100644 (file)
@@ -18,9 +18,8 @@
 
 #pragma once
 
-#include <third_party/nonstd/string_view.hpp>
-
 #include <string>
+#include <string_view>
 #include <vector>
 
 namespace util {
@@ -28,36 +27,36 @@ namespace util {
 // --- Interface ---
 
 // Return whether `path` is absolute.
-bool is_absolute_path(nonstd::string_view path);
+bool is_absolute_path(std::string_view path);
 
 // Return whether `path` includes at least one directory separator.
-bool is_full_path(nonstd::string_view path);
+bool is_full_path(std::string_view path);
 
 // Return whether `path` starts with `prefix` considering path specifics on
 // Windows
-bool path_starts_with(nonstd::string_view path, nonstd::string_view prefix);
+bool path_starts_with(std::string_view path, std::string_view prefix);
 
 // Split a list of paths (such as the content of $PATH on Unix platforms or
 // %PATH% on Windows platforms) into paths.
-std::vector<std::string> split_path_list(nonstd::string_view path_list);
+std::vector<std::string> split_path_list(std::string_view path_list);
 
 // Make `path` an absolute path.
-std::string to_absolute_path(nonstd::string_view path);
+std::string to_absolute_path(std::string_view path);
 
 // Make `path` an absolute path, but do not include Windows drive.
-std::string to_absolute_path_no_drive(nonstd::string_view path);
+std::string to_absolute_path_no_drive(std::string_view path);
 
 // --- Inline implementations ---
 
 inline bool
-is_full_path(const nonstd::string_view path)
+is_full_path(const std::string_view path)
 {
 #ifdef _WIN32
-  if (path.find('\\') != nonstd::string_view::npos) {
+  if (path.find('\\') != std::string_view::npos) {
     return true;
   }
 #endif
-  return path.find('/') != nonstd::string_view::npos;
+  return path.find('/') != std::string_view::npos;
 }
 
 } // namespace util
index 6c390f35537a539e4f014043b3b30c2201f3898a..560b8b9a830e2726be5af91f9dda9c6135ba069e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Joel Rosdahl and other contributors
+// Copyright (C) 2021-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -21,6 +21,7 @@
 #include <assertions.hpp>
 #include <fmtmacros.hpp>
 
+#include <algorithm>
 #include <cctype>
 #include <iostream>
 
@@ -50,7 +51,7 @@ nonstd::expected<int64_t, std::string>
 parse_signed(const std::string& value,
              const std::optional<int64_t> min_value,
              const std::optional<int64_t> max_value,
-             const nonstd::string_view description)
+             const std::string_view description)
 {
   const std::string stripped_value = strip_whitespace(value);
 
@@ -88,7 +89,7 @@ nonstd::expected<uint64_t, std::string>
 parse_unsigned(const std::string& value,
                const std::optional<uint64_t> min_value,
                const std::optional<uint64_t> max_value,
-               const nonstd::string_view description,
+               const std::string_view description,
                const int base)
 {
   const std::string stripped_value = strip_whitespace(value);
@@ -124,7 +125,7 @@ parse_unsigned(const std::string& value,
 }
 
 nonstd::expected<std::string, std::string>
-percent_decode(nonstd::string_view string)
+percent_decode(std::string_view string)
 {
   const auto from_hex = [](const char digit) {
     return static_cast<uint8_t>(
@@ -152,9 +153,9 @@ percent_decode(nonstd::string_view string)
 }
 
 std::string
-replace_all(const nonstd::string_view string,
-            const nonstd::string_view from,
-            const nonstd::string_view to)
+replace_all(const std::string_view string,
+            const std::string_view from,
+            const std::string_view to)
 {
   if (from.empty()) {
     return std::string(string);
@@ -165,7 +166,7 @@ replace_all(const nonstd::string_view string,
   size_t right = 0;
   while (left < string.size()) {
     right = string.find(from, left);
-    if (right == nonstd::string_view::npos) {
+    if (right == std::string_view::npos) {
       result.append(string.data() + left);
       break;
     }
@@ -177,9 +178,9 @@ replace_all(const nonstd::string_view string,
 }
 
 std::string
-replace_first(const nonstd::string_view string,
-              const nonstd::string_view from,
-              const nonstd::string_view to)
+replace_first(const std::string_view string,
+              const std::string_view from,
+              const std::string_view to)
 {
   if (from.empty()) {
     return std::string(string);
@@ -187,7 +188,7 @@ replace_first(const nonstd::string_view string,
 
   std::string result;
   const auto pos = string.find(from);
-  if (pos != nonstd::string_view::npos) {
+  if (pos != std::string_view::npos) {
     result.append(string.data(), pos);
     result.append(to.data(), to.length());
     result.append(string.data() + pos + from.size());
@@ -197,11 +198,11 @@ replace_first(const nonstd::string_view string,
   return result;
 }
 
-std::pair<nonstd::string_view, std::optional<nonstd::string_view>>
-split_once(const nonstd::string_view string, const char split_char)
+std::pair<std::string_view, std::optional<std::string_view>>
+split_once(const std::string_view string, const char split_char)
 {
   const size_t sep_pos = string.find(split_char);
-  if (sep_pos == nonstd::string_view::npos) {
+  if (sep_pos == std::string_view::npos) {
     return std::make_pair(string, std::nullopt);
   } else {
     return std::make_pair(string.substr(0, sep_pos),
@@ -210,7 +211,7 @@ split_once(const nonstd::string_view string, const char split_char)
 }
 
 std::string
-strip_whitespace(const nonstd::string_view string)
+strip_whitespace(const std::string_view string)
 {
   const auto is_space = [](const int ch) { return std::isspace(ch); };
   const auto start = std::find_if_not(string.begin(), string.end(), is_space);
index adc77bf853e51808d729aab2edb56a2bf96c27a5..54b0e68abdd5536efb8c7bd3b425eaf89d8456e2 100644 (file)
 #pragma once
 
 #include <third_party/nonstd/expected.hpp>
-#include <third_party/nonstd/string_view.hpp>
 
 #include <sys/stat.h> // for mode_t
 
 #include <cstring>
 #include <optional>
 #include <string>
+#include <string_view>
 #include <utility>
 
 namespace util {
@@ -33,19 +33,19 @@ namespace util {
 // --- Interface ---
 
 // Return true if `suffix` is a suffix of `string`.
-bool ends_with(nonstd::string_view string, nonstd::string_view suffix);
+bool ends_with(std::string_view string, std::string_view suffix);
 
 // Join stringified elements of `container` delimited by `delimiter` into a
 // string. There must exist an `std::string to_string(T::value_type)` function.
 template<typename T>
-std::string join(const T& container, const nonstd::string_view delimiter);
+std::string join(const T& container, const std::string_view delimiter);
 
 // Join stringified elements between input iterators `begin` and `end` delimited
 // by `delimiter` into a string. There must exist an `std::string
 // to_string(T::value_type)` function.
 template<typename T>
 std::string
-join(const T& begin, const T& end, const nonstd::string_view delimiter);
+join(const T& begin, const T& end, const std::string_view delimiter);
 
 // Parse a string into a double.
 //
@@ -62,7 +62,7 @@ nonstd::expected<int64_t, std::string>
 parse_signed(const std::string& value,
              std::optional<int64_t> min_value = std::nullopt,
              std::optional<int64_t> max_value = std::nullopt,
-             nonstd::string_view description = "integer");
+             std::string_view description = "integer");
 
 // Parse `value` (an octal integer).
 nonstd::expected<mode_t, std::string> parse_umask(const std::string& value);
@@ -77,61 +77,64 @@ nonstd::expected<uint64_t, std::string>
 parse_unsigned(const std::string& value,
                std::optional<uint64_t> min_value = std::nullopt,
                std::optional<uint64_t> max_value = std::nullopt,
-               nonstd::string_view description = "integer",
+               std::string_view description = "integer",
                int base = 10);
 
 // Percent-decode[1] `string`.
 //
 // [1]: https://en.wikipedia.org/wiki/Percent-encoding
 nonstd::expected<std::string, std::string>
-percent_decode(nonstd::string_view string);
+percent_decode(std::string_view string);
 
 // Replace the all occurrences of `from` to `to` in `string`.
-std::string replace_all(nonstd::string_view string,
-                        nonstd::string_view from,
-                        nonstd::string_view to);
+std::string replace_all(std::string_view string,
+                        std::string_view from,
+                        std::string_view to);
 
 // Replace the first occurrence of `from` to `to` in `string`.
-std::string replace_first(nonstd::string_view string,
-                          nonstd::string_view from,
-                          nonstd::string_view to);
+std::string replace_first(std::string_view string,
+                          std::string_view from,
+                          std::string_view to);
 
 // Split `string` into two parts using `split_char` as the delimiter. The second
 // part will be `nullopt` if there is no `split_char` in `string.`
-std::pair<nonstd::string_view, std::optional<nonstd::string_view>>
-split_once(nonstd::string_view string, char split_char);
+std::pair<std::string_view, std::optional<std::string_view>>
+split_once(std::string_view string, char split_char);
 
 // Return true if `prefix` is a prefix of `string`.
-bool starts_with(const char* string, nonstd::string_view prefix);
+bool starts_with(const char* string, std::string_view prefix);
 
 // Return true if `prefix` is a prefix of `string`.
-bool starts_with(nonstd::string_view string, nonstd::string_view prefix);
+bool starts_with(std::string_view string, std::string_view prefix);
 
 // Strip whitespace from left and right side of a string.
-[[nodiscard]] std::string strip_whitespace(nonstd::string_view string);
+[[nodiscard]] std::string strip_whitespace(std::string_view string);
 
-// Convert `string` to a string. This function is used when joining
+// Convert `value` to a string. This function is used when joining
 // `std::string`s with `util::join`.
-std::string to_string(const std::string& string);
+template<typename T> std::string to_string(const T& value);
 
 // --- Inline implementations ---
 
 inline bool
-ends_with(const nonstd::string_view string, const nonstd::string_view suffix)
+ends_with(const std::string_view string, const std::string_view suffix)
 {
-  return string.ends_with(suffix);
+  return string.length() >= suffix.length()
+         && string.compare(
+              string.length() - suffix.length(), std::string_view::npos, suffix)
+              == 0;
 }
 
 template<typename T>
 inline std::string
-join(const T& container, const nonstd::string_view delimiter)
+join(const T& container, const std::string_view delimiter)
 {
   return join(container.begin(), container.end(), delimiter);
 }
 
 template<typename T>
 inline std::string
-join(const T& begin, const T& end, const nonstd::string_view delimiter)
+join(const T& begin, const T& end, const std::string_view delimiter)
 {
   std::string result;
   for (auto it = begin; it != end; ++it) {
@@ -144,7 +147,7 @@ join(const T& begin, const T& end, const nonstd::string_view delimiter)
 }
 
 inline bool
-starts_with(const char* const string, const nonstd::string_view prefix)
+starts_with(const char* const string, const std::string_view prefix)
 {
   // Optimized version of starts_with(string_view, string_view): avoid computing
   // the length of the string argument.
@@ -152,16 +155,31 @@ starts_with(const char* const string, const nonstd::string_view prefix)
 }
 
 inline bool
-starts_with(const nonstd::string_view string, const nonstd::string_view prefix)
+starts_with(const std::string_view string, const std::string_view prefix)
 {
-  return string.starts_with(prefix);
+  return string.substr(0, prefix.size()) == prefix;
 }
 
-// Convert `string` to `string`. This is used by util::join.
+template<typename T>
+inline std::string
+to_string(const T& t)
+{
+  using std::to_string;
+  return to_string(std::forward<T>(t));
+}
+
+template<>
 inline std::string
 to_string(const std::string& string)
 {
-  return string;
+  return std::string(string);
+}
+
+template<>
+inline std::string
+to_string(const std::string_view& sv)
+{
+  return std::string(sv);
 }
 
 } // namespace util
index 06d1370460df7d8909109ea7fbb48d435f578111..bc205d2bfbab25dc48e0194e7608e991cac66289 100644 (file)
@@ -6,7 +6,6 @@ set(
   test_AtomicFile.cpp
   test_Config.cpp
   test_Depfile.cpp
-  test_FormatNonstdStringView.cpp
   test_Hash.cpp
   test_Lockfile.cpp
   test_NullCompression.cpp
diff --git a/unittest/test_FormatNonstdStringView.cpp b/unittest/test_FormatNonstdStringView.cpp
deleted file mode 100644 (file)
index c171c74..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2019-2020 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#include "FormatNonstdStringView.hpp"
-
-#include "third_party/doctest.h"
-
-using nonstd::string_view;
-
-TEST_SUITE_BEGIN("FormatNonstdStringView");
-
-TEST_CASE("fmt::format and nonstd::string_view")
-{
-  string_view null;
-  CHECK(fmt::format("{}", null) == "");
-
-  const std::string s = "0123456789";
-
-  string_view empty(s.data(), 0);
-  CHECK(fmt::format("{}", empty) == "");
-
-  string_view empty_end(s.data() + s.length(), 0);
-  CHECK(fmt::format("{}", empty_end) == "");
-
-  string_view start(s.data(), 2);
-  CHECK(fmt::format("{}", start) == "01");
-
-  string_view middle(s.data() + 3, 4);
-  CHECK(fmt::format("{}", middle) == "3456");
-
-  string_view end(s.data() + s.length() - 2, 2);
-  CHECK(fmt::format("{}", end) == "89");
-}
-
-TEST_SUITE_END();
index 0ae17c62440de1a11d4ad33d5353edfeac119492..3c1459fc3b19df4711eea702c6a2b825d33caeba 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2010-2022 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -22,7 +22,6 @@
 
 #include "third_party/doctest.h"
 
-using nonstd::string_view;
 using TestUtil::TestContext;
 
 TEST_SUITE_BEGIN("hashutil");
@@ -115,31 +114,31 @@ TEST_CASE("hash_multicommand_output_error_handling")
 
 TEST_CASE("check_for_temporal_macros")
 {
-  const string_view time_start =
+  const std::string_view time_start =
     "__TIME__\n"
     "int a;\n";
-  const string_view time_middle =
+  const std::string_view time_middle =
     "#define a __TIME__\n"
     "int a;\n";
-  const string_view time_end = "#define a __TIME__";
+  const std::string_view time_end = "#define a __TIME__";
 
-  const string_view date_start =
+  const std::string_view date_start =
     "__DATE__\n"
     "int ab;\n";
-  const string_view date_middle =
+  const std::string_view date_middle =
     "#define ab __DATE__\n"
     "int ab;\n";
-  const string_view date_end = "#define ab __DATE__";
+  const std::string_view date_end = "#define ab __DATE__";
 
-  const string_view timestamp_start =
+  const std::string_view timestamp_start =
     "__TIMESTAMP__\n"
     "int c;\n";
-  const string_view timestamp_middle =
+  const std::string_view timestamp_middle =
     "#define c __TIMESTAMP__\n"
     "int c;\n";
-  const string_view timestamp_end = "#define c __TIMESTAMP__";
+  const std::string_view timestamp_end = "#define c __TIMESTAMP__";
 
-  const string_view no_temporal =
+  const std::string_view no_temporal =
     "#define ab a__DATE__\n"
     "#define ab  __DATE__a\n"
     "#define ab A__DATE__\n"
@@ -162,7 +161,7 @@ TEST_CASE("check_for_temporal_macros")
     "#define ab __TIME __\n"
     "#define ab __TIME_ _\n";
 
-  const string_view temporal_at_avx_boundary =
+  const std::string_view temporal_at_avx_boundary =
     "#define alphabet abcdefghijklmnopqrstuvwxyz\n"
     "__DATE__";
 
index c2fa94e2a1bf4c6906a6bf5424af0e8c1060a826..1ea0ad4f6a0adce6cbbc6c048d46c54259891392 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "third_party/doctest.h"
 
+#include <ostream> // https://github.com/doctest/doctest/issues/618
+
 TEST_CASE("util::Tokenizer")
 {
   using Mode = util::Tokenizer::Mode;
index e999570cf746fd1a5dcc9e85e0ce002f69ce181c..a4a4876aaa5d2091e04f3d8715c3dfcb49c10314 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <third_party/doctest.h>
 
+#include <ostream> // https://github.com/doctest/doctest/issues/618
+
 TEST_CASE("util::is_absolute_path")
 {
 #ifdef _WIN32
index 70d831ef5fd7cb55cb595b5cf4f982bf2a650410..848186da68b643e5faa1355c42c6ae6242fc1d4d 100644 (file)
@@ -23,9 +23,8 @@
 #include <vector>
 
 static bool
-operator==(
-  std::pair<nonstd::string_view, std::optional<nonstd::string_view>> left,
-  std::pair<nonstd::string_view, std::optional<nonstd::string_view>> right)
+operator==(std::pair<std::string_view, std::optional<std::string_view>> left,
+           std::pair<std::string_view, std::optional<std::string_view>> right)
 {
   return left.first == right.first && left.second == right.second;
 }
@@ -67,7 +66,7 @@ TEST_CASE("util::join")
     CHECK(util::join(v.begin() + 1, v.end(), "|") == " b |c|");
   }
   {
-    std::vector<nonstd::string_view> v{"1", "2"};
+    std::vector<std::string_view> v{"1", "2"};
     CHECK(util::join(v, " ") == "1 2");
   }
 }