From: Joel Rosdahl Date: Tue, 17 May 2022 19:55:48 +0000 (+0200) Subject: chore: Replace nonstd::string_view with std::string_view X-Git-Tag: v4.7~228 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=60005c836ac34d7ee42e3f57e441ea97c0e321ad;p=thirdparty%2Fccache.git chore: Replace nonstd::string_view with std::string_view --- diff --git a/LICENSE.adoc b/LICENSE.adoc index 407f3971f..3f33b7207 100644 --- a/LICENSE.adoc +++ b/LICENSE.adoc @@ -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 - 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 diff --git a/src/Args.cpp b/src/Args.cpp index b965f6fe1..f8796e0e9 100644 --- a/src/Args.cpp +++ b/src/Args.cpp @@ -23,8 +23,6 @@ #include #include -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(), diff --git a/src/Args.hpp b/src/Args.hpp index f0ffd9489..1df0529f0 100644 --- a/src/Args.hpp +++ b/src/Args.hpp @@ -21,11 +21,10 @@ #include "NonCopyable.hpp" #include "Util.hpp" -#include "third_party/nonstd/string_view.hpp" - #include #include #include +#include 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); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fb4dd607..161f127bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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") diff --git a/src/Context.cpp b/src/Context.cpp index bcfff8c78..e8dc80d73 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -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 #include -using nonstd::string_view; - Context::Context() : actual_cwd(Util::get_actual_cwd()), apparent_cwd(Util::get_apparent_cwd(actual_cwd)), diff --git a/src/Context.hpp b/src/Context.hpp index 650ceee28..c2861f76b 100644 --- a/src/Context.hpp +++ b/src/Context.hpp @@ -32,11 +32,10 @@ #include -#include "third_party/nonstd/string_view.hpp" - #include #include #include +#include #include #include diff --git a/src/Depfile.cpp b/src/Depfile.cpp index 9bb6219f3..259006e4d 100644 --- a/src/Depfile.cpp +++ b/src/Depfile.cpp @@ -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 -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. diff --git a/src/Depfile.hpp b/src/Depfile.hpp index 0ca6a0cb3..fc453c310 100644 --- a/src/Depfile.hpp +++ b/src/Depfile.hpp @@ -23,18 +23,17 @@ class Hash; #include "Digest.hpp" -#include "third_party/nonstd/string_view.hpp" - #include #include +#include #include namespace Depfile { -std::string escape_filename(nonstd::string_view filename); +std::string escape_filename(std::string_view filename); std::optional rewrite_paths(const Context& ctx, const std::string& file_content); void make_paths_relative_in_output_dep(const Context& ctx); -std::vector tokenize(nonstd::string_view file_content); +std::vector tokenize(std::string_view file_content); } // namespace Depfile diff --git a/src/FormatNonstdStringView.hpp b/src/FormatNonstdStringView.hpp deleted file mode 100644 index 4834dc41e..000000000 --- a/src/FormatNonstdStringView.hpp +++ /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 -{ - template - constexpr auto - parse(ParseContext& ctx) const -> decltype(ctx.begin()) - { - return ctx.begin(); - } - - template - 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 diff --git a/src/Hash.cpp b/src/Hash.cpp index 2eb491dc9..ecd19e303 100644 --- a/src/Hash.cpp +++ b/src/Hash.cpp @@ -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 #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(data), size); + std::string_view buffer(static_cast(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(&x), sizeof(x))); + hash_buffer(std::string_view(reinterpret_cast(&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); diff --git a/src/Hash.hpp b/src/Hash.hpp index 02c5a4d12..968e55814 100644 --- a/src/Hash.hpp +++ b/src/Hash.hpp @@ -21,10 +21,10 @@ #include "Digest.hpp" #include "third_party/blake3/blake3.h" -#include "third_party/nonstd/string_view.hpp" #include #include +#include // 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); }; diff --git a/src/Logging.cpp b/src/Logging.cpp index 5068c853c..46b62f554 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -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; diff --git a/src/Logging.hpp b/src/Logging.hpp index b6b6ce981..669b1126c 100644 --- a/src/Logging.hpp +++ b/src/Logging.hpp @@ -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. // @@ -18,21 +18,19 @@ #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 #include +#include #include // 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); diff --git a/src/Result.cpp b/src/Result.cpp index c4e3b65a3..bc7c313d6 100644 --- a/src/Result.cpp +++ b/src/Result.cpp @@ -69,8 +69,6 @@ // ::= // ::= 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 diff --git a/src/TemporaryFile.cpp b/src/TemporaryFile.cpp index 3b6ccabd1..d4182855a 100644 --- a/src/TemporaryFile.cpp +++ b/src/TemporaryFile.cpp @@ -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)); diff --git a/src/TemporaryFile.hpp b/src/TemporaryFile.hpp index 032cbfa8d..5d1154bec 100644 --- a/src/TemporaryFile.hpp +++ b/src/TemporaryFile.hpp @@ -20,9 +20,8 @@ #include "Fd.hpp" -#include "third_party/nonstd/string_view.hpp" - #include +#include // 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; diff --git a/src/Util.cpp b/src/Util.cpp index d39b74667..b94ee1a81 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -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 std::vector -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(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 -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 -split_into_views(string_view string, +std::vector +split_into_views(std::string_view string, const char* separators, util::Tokenizer::Mode mode, IncludeDelimiter include_delimiter) { - return split_into(string, separators, mode, include_delimiter); + return split_into( + string, separators, mode, include_delimiter); } std::vector -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()); diff --git a/src/Util.hpp b/src/Util.hpp index 1502af4ef..bf5548440 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -21,8 +21,6 @@ #include #include -#include "third_party/nonstd/string_view.hpp" - #include #include #include @@ -30,6 +28,7 @@ #include #include #include +#include #include #include @@ -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 @@ -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 is_absolute_path_with_prefix(nonstd::string_view path); +std::optional 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 localtime(std::optional 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 -split_into_views(nonstd::string_view string, +std::vector +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 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). diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index 90603af6c..077704f02 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -35,7 +35,6 @@ #include 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()) { diff --git a/src/ccache.cpp b/src/ccache.cpp index edff616da..2a57d2c94 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -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" @@ -64,11 +63,11 @@ #include #include "third_party/fmt/core.h" -#include "third_party/nonstd/string_view.hpp" #include #include +#include #ifdef HAVE_UNISTD_H # include @@ -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 \"\"\n"; - static const string_view hash_32_command_line_2_newline = + static const std::string_view hash_32_command_line_2_newline = "# 32 \"\" 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))); diff --git a/src/ccache.hpp b/src/ccache.hpp index 2b799fe8e..7590ad584 100644 --- a/src/ccache.hpp +++ b/src/ccache.hpp @@ -21,10 +21,9 @@ #include "Config.hpp" -#include "third_party/nonstd/string_view.hpp" - #include #include +#include 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); diff --git a/src/core/exceptions.hpp b/src/core/exceptions.hpp index 95176d7ca..a9b70b588 100644 --- a/src/core/exceptions.hpp +++ b/src/core/exceptions.hpp @@ -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 - #include #include diff --git a/src/execute.cpp b/src/execute.cpp index 8f4e787a5..2355c622f 100644 --- a/src/execute.cpp +++ b/src/execute.cpp @@ -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, diff --git a/src/fmtmacros.hpp b/src/fmtmacros.hpp index 3b7cf5d31..6f396fd26 100644 --- a/src/fmtmacros.hpp +++ b/src/fmtmacros.hpp @@ -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 - #include #include diff --git a/src/hashutil.cpp b/src/hashutil.cpp index d61282fcc..7e0ca23f7 100644 --- a/src/hashutil.cpp +++ b/src/hashutil.cpp @@ -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 #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 // . 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; diff --git a/src/hashutil.hpp b/src/hashutil.hpp index b3f1756d7..01ee8e6ba 100644 --- a/src/hashutil.hpp +++ b/src/hashutil.hpp @@ -18,10 +18,9 @@ #pragma once -#include "third_party/nonstd/string_view.hpp" - #include #include +#include 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_* diff --git a/src/storage/Storage.cpp b/src/storage/Storage.cpp index cc56beff5..02dd573cb 100644 --- a/src/storage/Storage.cpp +++ b/src/storage/Storage.cpp @@ -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 -parse_storage_configs(const nonstd::string_view& configs) +parse_storage_configs(const std::string_view& configs) { std::vector 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; } diff --git a/src/storage/Storage.hpp b/src/storage/Storage.hpp index ab41c86e5..5593e03c3 100644 --- a/src/storage/Storage.hpp +++ b/src/storage/Storage.hpp @@ -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> get_from_secondary_storage(const Digest& key); diff --git a/src/storage/primary/PrimaryStorage.cpp b/src/storage/primary/PrimaryStorage.cpp index c4e058170..6c048f352 100644 --- a/src/storage/primary/PrimaryStorage.cpp +++ b/src/storage/primary/PrimaryStorage.cpp @@ -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; diff --git a/src/storage/primary/PrimaryStorage.hpp b/src/storage/primary/PrimaryStorage.hpp index babb7d79b..593f0c2ae 100644 --- a/src/storage/primary/PrimaryStorage.hpp +++ b/src/storage/primary/PrimaryStorage.hpp @@ -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, diff --git a/src/storage/primary/util.cpp b/src/storage/primary/util.cpp index f50b4defd..7d89cb92d 100644 --- a/src/storage/primary/util.cpp +++ b/src/storage/primary/util.cpp @@ -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 #include +#include 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; } diff --git a/src/storage/secondary/FileStorage.cpp b/src/storage/secondary/FileStorage.cpp index 906127d76..9ae10c61f 100644 --- a/src/storage/secondary/FileStorage.cpp +++ b/src/storage/secondary/FileStorage.cpp @@ -30,10 +30,10 @@ #include #include -#include - #include // for mode_t +#include + namespace storage { namespace secondary { diff --git a/src/storage/secondary/HttpStorage.cpp b/src/storage/secondary/HttpStorage.cpp index 2c253a11b..a59948b9e 100644 --- a/src/storage/secondary/HttpStorage.cpp +++ b/src/storage/secondary/HttpStorage.cpp @@ -27,9 +27,10 @@ #include #include -#include #include +#include + 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 index 2784272e7..000000000 --- a/src/third_party/nonstd/string_view.hpp +++ /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() -# include -# 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( ) -# 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 - -// Extensions for std::string: - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { - -template< class CharT, class Traits, class Allocator = std::allocator > -std::basic_string -to_string( std::basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string_view -to_string_view( std::basic_string const & s ) -{ - return std::basic_string_view( 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 -#include -#include -#include -#include -#include // std::char_traits<> - -#if ! nssv_CONFIG_NO_EXCEPTIONS -# include -#endif - -#if nssv_CPP11_OR_GREATER -# include -#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 -> -class basic_string_view; - -// -// basic_string_view: -// - -template -< - class CharT, - class Traits /* = std::char_traits */ -> -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 const & s ) nssv_noexcept - : data_( s.data() ) - , size_( s.size() ) - {} - -#if nssv_HAVE_EXPLICIT_CONVERSION - - template< class Allocator > - explicit operator std::basic_string() const - { - return to_string( Allocator() ); - } - -#endif // nssv_HAVE_EXPLICIT_CONVERSION - -#if nssv_CPP11_OR_GREATER - - template< class Allocator = std::allocator > - std::basic_string - to_string( Allocator const & a = Allocator() ) const - { - return std::basic_string( begin(), end(), a ); - } - -#else - - std::basic_string - to_string() const - { - return std::basic_string( begin(), end() ); - } - - template< class Allocator > - std::basic_string - to_string( Allocator const & a ) const - { - return std::basic_string( 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 lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator!= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits > -nssv_constexpr bool operator< ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator<= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator> ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits > -nssv_constexpr bool operator>= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -// Let S be basic_string_view, 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 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 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 lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator==( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -// != - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - basic_string_view lhs, - char const * rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - char const * lhs, - basic_string_view rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -template< class CharT, class Traits> -nssv_constexpr bool operator!=( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return !( lhs == rhs ); } - -// < - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - basic_string_view 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 rhs ) nssv_noexcept -{ return rhs.compare( lhs ) > 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) > 0; } - -// <= - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - basic_string_view 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 rhs ) nssv_noexcept -{ return rhs.compare( lhs ) >= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator<=( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) >= 0; } - -// > - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - basic_string_view 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 rhs ) nssv_noexcept -{ return rhs.compare( lhs ) < 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>( - std::basic_string rhs, - basic_string_view lhs ) nssv_noexcept -{ return rhs.compare( lhs ) < 0; } - -// >= - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - basic_string_view 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 rhs ) nssv_noexcept -{ return rhs.compare( lhs ) <= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - basic_string_view lhs, - std::basic_string rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0; } - -template< class CharT, class Traits> -nssv_constexpr bool operator>=( - std::basic_string rhs, - basic_string_view 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 >::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 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 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( 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 & -operator<<( - std::basic_ostream& os, - basic_string_view sv ) -{ - return detail::write_to_stream( os, sv ); -} - -// Several typedefs for common character types are provided: - -typedef basic_string_view string_view; -typedef basic_string_view wstring_view; -#if nssv_HAVE_WCHAR16_T -typedef basic_string_view u16string_view; -typedef basic_string_view 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 > -std::basic_string -to_string( basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#else - -template< class CharT, class Traits > -std::basic_string -to_string( basic_string_view v ) -{ - return std::basic_string( v.begin(), v.end() ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string -to_string( basic_string_view v, Allocator const & a ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#endif // nssv_CPP11_OR_GREATER - -template< class CharT, class Traits, class Allocator > -basic_string_view -to_string_view( std::basic_string const & s ) -{ - return basic_string_view( 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 - -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( 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( 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( 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( 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 diff --git a/src/util/Tokenizer.cpp b/src/util/Tokenizer.cpp index 6300cd5ce..a379c4f29 100644 --- a/src/util/Tokenizer.cpp +++ b/src/util/Tokenizer.cpp @@ -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); diff --git a/src/util/Tokenizer.hpp b/src/util/Tokenizer.hpp index 763185b77..624a8057f 100644 --- a/src/util/Tokenizer.hpp +++ b/src/util/Tokenizer.hpp @@ -21,7 +21,8 @@ #include #include -#include + +#include 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 diff --git a/src/util/path.cpp b/src/util/path.cpp index 86d9d0202..c42e4fcf1 100644 --- a/src/util/path.cpp +++ b/src/util/path.cpp @@ -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 -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 diff --git a/src/util/path.hpp b/src/util/path.hpp index 51fcd5815..98345e36e 100644 --- a/src/util/path.hpp +++ b/src/util/path.hpp @@ -18,9 +18,8 @@ #pragma once -#include - #include +#include #include 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 split_path_list(nonstd::string_view path_list); +std::vector 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 diff --git a/src/util/string.cpp b/src/util/string.cpp index 6c390f355..560b8b9a8 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -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 #include +#include #include #include @@ -50,7 +51,7 @@ nonstd::expected parse_signed(const std::string& value, const std::optional min_value, const std::optional 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 parse_unsigned(const std::string& value, const std::optional min_value, const std::optional 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 -percent_decode(nonstd::string_view string) +percent_decode(std::string_view string) { const auto from_hex = [](const char digit) { return static_cast( @@ -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> -split_once(const nonstd::string_view string, const char split_char) +std::pair> +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); diff --git a/src/util/string.hpp b/src/util/string.hpp index adc77bf85..54b0e68ab 100644 --- a/src/util/string.hpp +++ b/src/util/string.hpp @@ -19,13 +19,13 @@ #pragma once #include -#include #include // for mode_t #include #include #include +#include #include 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 -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 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 parse_signed(const std::string& value, std::optional min_value = std::nullopt, std::optional max_value = std::nullopt, - nonstd::string_view description = "integer"); + std::string_view description = "integer"); // Parse `value` (an octal integer). nonstd::expected parse_umask(const std::string& value); @@ -77,61 +77,64 @@ nonstd::expected parse_unsigned(const std::string& value, std::optional min_value = std::nullopt, std::optional 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 -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> -split_once(nonstd::string_view string, char split_char); +std::pair> +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 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 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 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 +inline std::string +to_string(const T& t) +{ + using std::to_string; + return to_string(std::forward(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 diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 06d137046..bc205d2bf 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -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 index c171c74aa..000000000 --- a/unittest/test_FormatNonstdStringView.cpp +++ /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(); diff --git a/unittest/test_hashutil.cpp b/unittest/test_hashutil.cpp index 0ae17c624..3c1459fc3 100644 --- a/unittest/test_hashutil.cpp +++ b/unittest/test_hashutil.cpp @@ -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__"; diff --git a/unittest/test_util_Tokenizer.cpp b/unittest/test_util_Tokenizer.cpp index c2fa94e2a..1ea0ad4f6 100644 --- a/unittest/test_util_Tokenizer.cpp +++ b/unittest/test_util_Tokenizer.cpp @@ -20,6 +20,8 @@ #include "third_party/doctest.h" +#include // https://github.com/doctest/doctest/issues/618 + TEST_CASE("util::Tokenizer") { using Mode = util::Tokenizer::Mode; diff --git a/unittest/test_util_path.cpp b/unittest/test_util_path.cpp index e999570cf..a4a4876aa 100644 --- a/unittest/test_util_path.cpp +++ b/unittest/test_util_path.cpp @@ -22,6 +22,8 @@ #include +#include // https://github.com/doctest/doctest/issues/618 + TEST_CASE("util::is_absolute_path") { #ifdef _WIN32 diff --git a/unittest/test_util_string.cpp b/unittest/test_util_string.cpp index 70d831ef5..848186da6 100644 --- a/unittest/test_util_string.cpp +++ b/unittest/test_util_string.cpp @@ -23,9 +23,8 @@ #include static bool -operator==( - std::pair> left, - std::pair> right) +operator==(std::pair> left, + std::pair> 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 v{"1", "2"}; + std::vector v{"1", "2"}; CHECK(util::join(v, " ") == "1 2"); } }