----
-=== src/third_party/nonstd/string_view.hpp
-
-This alternative implementation of `std::string_view` was downloaded from
-<https://github.com/martinmoene/string-view-lite> and has the following license
-text:
-
-----
-Copyright 2017-2020 by Martin Moene
-
-Boost Software License - Version 1.0 - August 17th, 2003
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-----
-
-
=== src/third_party/url.*
CxxUrl - A simple C++ URL class. Copied from CxxUrl v0.3 downloaded from
#include <core/exceptions.hpp>
#include <util/string.hpp>
-using nonstd::string_view;
-
Args::Args(Args&& other) noexcept : m_args(std::move(other.m_args))
{
}
}
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()) {
}
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(),
#include "NonCopyable.hpp"
#include "Util.hpp"
-#include "third_party/nonstd/string_view.hpp"
-
#include <deque>
#include <optional>
#include <string>
+#include <string_view>
class Args
{
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);
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")
-// 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.
//
#include <string>
#include <vector>
-using nonstd::string_view;
-
Context::Context()
: actual_cwd(Util::get_actual_cwd()),
apparent_cwd(Util::get_apparent_cwd(actual_cwd)),
#include <storage/Storage.hpp>
-#include "third_party/nonstd/string_view.hpp"
-
#include <ctime>
#include <optional>
#include <string>
+#include <string_view>
#include <unordered_map>
#include <vector>
namespace Depfile {
std::string
-escape_filename(nonstd::string_view filename)
+escape_filename(std::string_view filename)
{
std::string result;
result.reserve(filename.size());
}
std::vector<std::string>
-tokenize(nonstd::string_view file_content)
+tokenize(std::string_view file_content)
{
// A dependency file uses Makefile syntax. This is not perfect parser but
// should be enough for parsing a regular dependency file.
#include "Digest.hpp"
-#include "third_party/nonstd/string_view.hpp"
-
#include <optional>
#include <string>
+#include <string_view>
#include <vector>
namespace Depfile {
-std::string escape_filename(nonstd::string_view filename);
+std::string escape_filename(std::string_view filename);
std::optional<std::string> rewrite_paths(const Context& ctx,
const std::string& file_content);
void make_paths_relative_in_output_dep(const Context& ctx);
-std::vector<std::string> tokenize(nonstd::string_view file_content);
+std::vector<std::string> tokenize(std::string_view file_content);
} // namespace Depfile
+++ /dev/null
-// Copyright (C) 2019-2021 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#pragma once
-
-#include "third_party/fmt/core.h"
-#include "third_party/nonstd/string_view.hpp"
-
-// Specialization of fmt::formatter for nonstd::string_view.
-namespace fmt {
-
-template<> struct formatter<nonstd::string_view>
-{
- template<typename ParseContext>
- constexpr auto
- parse(ParseContext& ctx) const -> decltype(ctx.begin())
- {
- return ctx.begin();
- }
-
- template<typename FormatContext>
- auto
- format(const nonstd::string_view& sv, FormatContext& ctx)
- -> decltype(ctx.out())
- {
- return format_to(ctx.out(), "{}", fmt::string_view(sv.data(), sv.size()));
- }
-};
-
-} // namespace fmt
-// 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.
//
# include <unistd.h>
#endif
-using nonstd::string_view;
-
-const string_view HASH_DELIMITER("\000cCaChE\000", 8);
+const std::string_view HASH_DELIMITER("\000cCaChE\000", 8);
Hash::Hash()
{
}
void
-Hash::enable_debug(string_view section_name,
+Hash::enable_debug(std::string_view section_name,
FILE* debug_binary,
FILE* debug_text)
{
}
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");
Hash&
Hash::hash(const void* data, size_t size, HashType hash_type)
{
- string_view buffer(static_cast<const char*>(data), size);
+ std::string_view buffer(static_cast<const char*>(data), size);
hash_buffer(buffer);
switch (hash_type) {
}
Hash&
-Hash::hash(string_view data)
+Hash::hash(std::string_view data)
{
hash(data.data(), data.length());
return *this;
Hash&
Hash::hash(int64_t x)
{
- hash_buffer(string_view(reinterpret_cast<const char*>(&x), sizeof(x)));
+ hash_buffer(std::string_view(reinterpret_cast<const char*>(&x), sizeof(x)));
add_debug_text(FMT("{}\n", x));
return *this;
}
}
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) {
}
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);
#include "Digest.hpp"
#include "third_party/blake3/blake3.h"
-#include "third_party/nonstd/string_view.hpp"
#include <cstdint>
#include <cstdio>
+#include <string_view>
// This class represents a hash state.
class Hash
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);
// 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.
//
//
// 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.
//
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);
};
// 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.
//
# endif
#endif
-using nonstd::string_view;
-
namespace {
// Logfile path and file handle, read from Config::log_file().
}
void
-do_log(string_view message, bool bulk)
+do_log(std::string_view message, bool bulk)
{
static char prefix[200];
}
void
-log(string_view message)
+log(std::string_view message)
{
if (!enabled()) {
return;
}
void
-bulk_log(string_view message)
+bulk_log(std::string_view message)
{
if (!enabled()) {
return;
-// Copyright (C) 2020-2021 Joel Rosdahl and other contributors
+// Copyright (C) 2020-2022 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#pragma once
-#include "FormatNonstdStringView.hpp"
-
#include "third_party/fmt/core.h"
#include "third_party/fmt/format.h"
-#include "third_party/nonstd/string_view.hpp"
#include <optional>
#include <string>
+#include <string_view>
#include <utility>
// Log a raw message (plus a newline character).
#define LOG_RAW(message_) \
do { \
if (Logging::enabled()) { \
- Logging::log(nonstd::string_view(message_)); \
+ Logging::log(std::string_view(message_)); \
} \
} while (false)
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);
// <epilogue> ::= <checksum>
// <checksum> ::= uint64_t ; XXH3 of content bytes
-using nonstd::string_view;
-
namespace {
const uint8_t k_result_format_version = 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
# 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));
#include "Fd.hpp"
-#include "third_party/nonstd/string_view.hpp"
-
#include <string>
+#include <string_view>
// This class represents a unique temporary file created by mkstemp. The file is
// not deleted by the destructor.
// `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;
# endif
#endif
-using nonstd::string_view;
using IncludeDelimiter = util::Tokenizer::IncludeDelimiter;
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) {
template<typename T>
std::vector<T>
-split_into(string_view string,
+split_into(std::string_view string,
const char* separators,
util::Tokenizer::Mode mode,
IncludeDelimiter include_delimiter)
}
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 ";
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));
#ifdef _WIN32
bool
-has_utf16_le_bom(string_view text)
+has_utf16_le_bom(std::string_view text)
{
return text.size() > 1
&& ((static_cast<uint8_t>(text[0]) == 0xff
namespace Util {
-string_view
-base_name(string_view path)
+std::string_view
+base_name(std::string_view path)
{
#ifdef _WIN32
const char delim[] = "/\\";
}
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());
}
}
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;
}
bool
-create_dir(string_view dir)
+create_dir(std::string_view dir)
{
std::string dir_str(dir);
auto st = Stat::stat(dir_str);
}
}
-string_view
-dir_name(string_view path)
+std::string_view
+dir_name(std::string_view path)
{
#ifdef _WIN32
const char delim[] = "/\\";
}
void
-ensure_dir_exists(nonstd::string_view dir)
+ensure_dir_exists(std::string_view dir)
{
if (!create_dir(dir)) {
throw core::Fatal(
#endif
}
-string_view
-get_extension(string_view path)
+std::string_view
+get_extension(std::string_view path)
{
#ifndef _WIN32
const char stop_at_chars[] = "./";
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) == '\\') {
}
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));
}
std::optional<size_t>
-is_absolute_path_with_prefix(nonstd::string_view path)
+is_absolute_path_with_prefix(std::string_view path)
{
#ifdef _WIN32
const char delim[] = "/\\";
#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";
}
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);
}
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);
#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) {
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"
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());
}
}
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);
#endif
}
-std::vector<string_view>
-split_into_views(string_view string,
+std::vector<std::string_view>
+split_into_views(std::string_view string,
const char* separators,
util::Tokenizer::Mode mode,
IncludeDelimiter include_delimiter)
{
- return split_into<string_view>(string, separators, mode, include_delimiter);
+ return split_into<std::string_view>(
+ string, separators, mode, include_delimiter);
}
std::vector<std::string>
-split_into_strings(string_view string,
+split_into_strings(std::string_view string,
const char* separators,
util::Tokenizer::Mode mode,
IncludeDelimiter include_delimiter)
}
std::string
-strip_ansi_csi_seqs(string_view string)
+strip_ansi_csi_seqs(std::string_view string)
{
size_t pos = 0;
std::string result;
}
std::string
-to_lowercase(string_view string)
+to_lowercase(std::string_view string)
{
std::string result;
result.resize(string.length());
#include <Stat.hpp>
#include <util/Tokenizer.hpp>
-#include "third_party/nonstd/string_view.hpp"
-
#include <algorithm>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
+#include <string_view>
#include <utility>
#include <vector>
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.
//
// Remove the extension via `remove_extension()`, then add `new_ext`. `new_ext`
// should start with a dot, no extra dot is inserted.
-std::string change_extension(nonstd::string_view path,
- nonstd::string_view new_ext);
+std::string change_extension(std::string_view path, std::string_view new_ext);
// Return `value` adjusted to not be less than `min` and not more than `max`.
template<typename T>
// 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);
// 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.
// 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.
// `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.
// Determine if `path` is an absolute path with prefix, returning the split
// point.
-std::optional<size_t> is_absolute_path_with_prefix(nonstd::string_view path);
+std::optional<size_t> is_absolute_path_with_prefix(std::string_view path);
// Test if a file is on nfs.
//
// 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.
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.
//
// 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`.
// 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.
// 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
// Split `string` into tokens at any of the characters in `separators`. These
// tokens are views into `string`. `separators` must neither be the empty string
// nor a nullptr.
-std::vector<nonstd::string_view>
-split_into_views(nonstd::string_view string,
+std::vector<std::string_view>
+split_into_views(std::string_view string,
const char* separators,
util::Tokenizer::Mode mode = util::Tokenizer::Mode::skip_empty,
util::Tokenizer::IncludeDelimiter include_delimiter =
// Same as `split_into_views` but the tokens are copied from `string`.
std::vector<std::string> split_into_strings(
- nonstd::string_view string,
+ std::string_view string,
const char* separators,
util::Tokenizer::Mode mode = util::Tokenizer::Mode::skip_empty,
util::Tokenizer::IncludeDelimiter include_delimiter =
util::Tokenizer::IncludeDelimiter::no);
// Returns a copy of string with the specified ANSI CSI sequences removed.
-[[nodiscard]] std::string strip_ansi_csi_seqs(nonstd::string_view string);
+[[nodiscard]] std::string strip_ansi_csi_seqs(std::string_view string);
// Convert a string to lowercase.
-[[nodiscard]] std::string to_lowercase(nonstd::string_view string);
+[[nodiscard]] std::string to_lowercase(std::string_view string);
// Traverse `path` recursively (postorder, i.e. files are visited before their
// parent directory).
#include <cassert>
using core::Statistic;
-using nonstd::string_view;
namespace {
// 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;
}
&& 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;
}
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));
}
}
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;
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,")
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")
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);
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);
}
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()) {
#include "Fd.hpp"
#include "File.hpp"
#include "Finalizer.hpp"
-#include "FormatNonstdStringView.hpp"
#include "Hash.hpp"
#include "Lockfile.hpp"
#include "Logging.hpp"
#include <util/string.hpp>
#include "third_party/fmt/core.h"
-#include "third_party/nonstd/string_view.hpp"
#include <fcntl.h>
#include <optional>
+#include <string_view>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
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
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
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()) {
}
CompilerType
-guess_compiler(string_view path)
+guess_compiler(std::string_view path)
{
std::string compiler_path(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;
// There must be at least 7 characters (# 1 "x") left to potentially find an
// include file path.
while (q < end - 7) {
- static const string_view pragma_gcc_pch_preprocess =
+ static const std::string_view pragma_gcc_pch_preprocess =
"pragma GCC pch_preprocess ";
- static const string_view hash_31_command_line_newline =
+ static const std::string_view hash_31_command_line_newline =
"# 31 \"<command-line>\"\n";
- static const string_view hash_32_command_line_2_newline =
+ static const std::string_view hash_32_command_line_2_newline =
"# 32 \"<command-line>\" 2\n";
// Note: Intentionally not using the string form to avoid false positive
// match by ccache itself.
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) {
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);
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(), '/', '#');
{
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)));
#include "Config.hpp"
-#include "third_party/nonstd/string_view.hpp"
-
#include <functional>
#include <string>
+#include <string_view>
class Context;
// 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);
-// 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.
//
#pragma once
-#include <FormatNonstdStringView.hpp>
-
#include <third_party/fmt/core.h>
#include <optional>
// 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.
//
# include "Finalizer.hpp"
#endif
-using nonstd::string_view;
-
#ifdef _WIN32
static int win32execute(const char* path,
const char* const* argv,
-// 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.
//
#pragma once
-#include <FormatNonstdStringView.hpp>
-
#include <third_party/fmt/core.h>
#include <third_party/fmt/format.h>
-// 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.
//
# include <immintrin.h>
#endif
-using nonstd::string_view;
-
namespace {
// Returns one of HASH_SOURCE_CODE_FOUND_DATE, HASH_SOURCE_CODE_FOUND_TIME or
//
// 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;
}
int
-check_for_temporal_macros_bmh(string_view str)
+check_for_temporal_macros_bmh(std::string_view str)
{
int result = 0;
#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
// __TIME__ and __TIMESTAMP__, is heavily inspired by
// <http://0x80.pl/articles/simd-strfind.html>.
int
-check_for_temporal_macros_avx2(string_view str)
+check_for_temporal_macros_avx2(std::string_view str)
{
int result = 0;
} // 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()) {
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;
#pragma once
-#include "third_party/nonstd/string_view.hpp"
-
#include <cstddef>
#include <string>
+#include <string_view>
class Config;
class Context;
// 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_*
}
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);
}
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);
}
}
static std::vector<SecondaryStorageConfig>
-parse_storage_configs(const nonstd::string_view& configs)
+parse_storage_configs(const std::string_view& configs)
{
std::vector<SecondaryStorageConfig> result;
for (const auto& config : util::Tokenizer(configs, " ")) {
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) {
} 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;
}
SecondaryStorageBackendEntry*
get_backend(SecondaryStorageEntry& entry,
const Digest& key,
- nonstd::string_view operation_description,
+ std::string_view operation_description,
const bool for_writing);
std::optional<std::pair<std::string, bool>>
get_from_secondary_storage(const Digest& key);
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);
}
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;
// 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,
-// 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.
//
#include <Util.hpp>
#include <fmtmacros.hpp>
+#include <util/string.hpp>
namespace storage {
namespace primary {
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;
}
#include <util/file.hpp>
#include <util/string.hpp>
-#include <third_party/nonstd/string_view.hpp>
-
#include <sys/stat.h> // for mode_t
+#include <string_view>
+
namespace storage {
namespace secondary {
#include <util/string.hpp>
#include <third_party/httplib.h>
-#include <third_party/nonstd/string_view.hpp>
#include <third_party/url.hpp>
+#include <string_view>
+
namespace storage {
namespace secondary {
+++ /dev/null
-// Copyright 2017-2020 by Martin Moene
-//
-// string-view lite, a C++17-like string_view for C++98 and later.
-// For more information see https://github.com/martinmoene/string-view-lite
-//
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#pragma once
-
-#ifndef NONSTD_SV_LITE_H_INCLUDED
-#define NONSTD_SV_LITE_H_INCLUDED
-
-#define string_view_lite_MAJOR 1
-#define string_view_lite_MINOR 6
-#define string_view_lite_PATCH 0
-
-#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
-
-#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x )
-#define nssv_STRINGIFY_( x ) #x
-
-// string-view lite configuration:
-
-#define nssv_STRING_VIEW_DEFAULT 0
-#define nssv_STRING_VIEW_NONSTD 1
-#define nssv_STRING_VIEW_STD 2
-
-// tweak header support:
-
-#ifdef __has_include
-# if __has_include(<nonstd/string_view.tweak.hpp>)
-# include <nonstd/string_view.tweak.hpp>
-# endif
-#define nssv_HAVE_TWEAK_HEADER 1
-#else
-#define nssv_HAVE_TWEAK_HEADER 0
-//# pragma message("string_view.hpp: Note: Tweak header not supported.")
-#endif
-
-// string_view selection and configuration:
-
-#if !defined( nssv_CONFIG_SELECT_STRING_VIEW )
-# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD )
-#endif
-
-#if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW )
-# error nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and removed, please use nssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_...
-#endif
-
-#ifndef nssv_CONFIG_STD_SV_OPERATOR
-# define nssv_CONFIG_STD_SV_OPERATOR 0
-#endif
-
-#ifndef nssv_CONFIG_USR_SV_OPERATOR
-# define nssv_CONFIG_USR_SV_OPERATOR 1
-#endif
-
-#ifdef nssv_CONFIG_CONVERSION_STD_STRING
-# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING
-# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING
-#endif
-
-#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1
-#endif
-
-#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1
-#endif
-
-// Control presence of exception handling (try and auto discover):
-
-#ifndef nssv_CONFIG_NO_EXCEPTIONS
-# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
-# define nssv_CONFIG_NO_EXCEPTIONS 0
-# else
-# define nssv_CONFIG_NO_EXCEPTIONS 1
-# endif
-#endif
-
-// C++ language version detection (C++20 is speculative):
-// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
-
-#ifndef nssv_CPLUSPLUS
-# if defined(_MSVC_LANG ) && !defined(__clang__)
-# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
-# else
-# define nssv_CPLUSPLUS __cplusplus
-# endif
-#endif
-
-#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L )
-#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L )
-#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
-#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
-#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
-#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
-
-// use C++17 std::string_view if available and requested:
-
-#if nssv_CPP17_OR_GREATER && defined(__has_include )
-# if __has_include( <string_view> )
-# define nssv_HAVE_STD_STRING_VIEW 1
-# else
-# define nssv_HAVE_STD_STRING_VIEW 0
-# endif
-#else
-# define nssv_HAVE_STD_STRING_VIEW 0
-#endif
-
-#define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) )
-
-#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW )
-#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH
-
-//
-// Use C++17 std::string_view:
-//
-
-#if nssv_USES_STD_STRING_VIEW
-
-#include <string_view>
-
-// Extensions for std::string:
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-
-template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
-std::basic_string<CharT, Traits, Allocator>
-to_string( std::basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
-{
- return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-template< class CharT, class Traits, class Allocator >
-std::basic_string_view<CharT, Traits>
-to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
-{
- return std::basic_string_view<CharT, Traits>( s.data(), s.size() );
-}
-
-// Literal operators sv and _sv:
-
-#if nssv_CONFIG_STD_SV_OPERATOR
-
-using namespace std::literals::string_view_literals;
-
-#endif
-
-#if nssv_CONFIG_USR_SV_OPERATOR
-
-inline namespace literals {
-inline namespace string_view_literals {
-
-
-constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1)
-{
- return std::string_view{ str, len };
-}
-
-constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2)
-{
- return std::u16string_view{ str, len };
-}
-
-constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3)
-{
- return std::u32string_view{ str, len };
-}
-
-constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4)
-{
- return std::wstring_view{ str, len };
-}
-
-}} // namespace literals::string_view_literals
-
-#endif // nssv_CONFIG_USR_SV_OPERATOR
-
-} // namespace nonstd
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-
-using std::string_view;
-using std::wstring_view;
-using std::u16string_view;
-using std::u32string_view;
-using std::basic_string_view;
-
-// literal "sv" and "_sv", see above
-
-using std::operator==;
-using std::operator!=;
-using std::operator<;
-using std::operator<=;
-using std::operator>;
-using std::operator>=;
-
-using std::operator<<;
-
-} // namespace nonstd
-
-#else // nssv_HAVE_STD_STRING_VIEW
-
-//
-// Before C++17: use string_view lite:
-//
-
-// Compiler versions:
-//
-// MSVC++ 6.0 _MSC_VER == 1200 nssv_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
-// MSVC++ 7.0 _MSC_VER == 1300 nssv_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
-// MSVC++ 7.1 _MSC_VER == 1310 nssv_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
-// MSVC++ 8.0 _MSC_VER == 1400 nssv_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
-// MSVC++ 9.0 _MSC_VER == 1500 nssv_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
-// MSVC++ 10.0 _MSC_VER == 1600 nssv_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
-// MSVC++ 11.0 _MSC_VER == 1700 nssv_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
-// MSVC++ 12.0 _MSC_VER == 1800 nssv_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
-// MSVC++ 14.0 _MSC_VER == 1900 nssv_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
-// MSVC++ 14.1 _MSC_VER >= 1910 nssv_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
-// MSVC++ 14.2 _MSC_VER >= 1920 nssv_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
-
-#if defined(_MSC_VER ) && !defined(__clang__)
-# define nssv_COMPILER_MSVC_VER (_MSC_VER )
-# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
-#else
-# define nssv_COMPILER_MSVC_VER 0
-# define nssv_COMPILER_MSVC_VERSION 0
-#endif
-
-#define nssv_COMPILER_VERSION( major, minor, patch ) ( 10 * ( 10 * (major) + (minor) ) + (patch) )
-
-#if defined( __apple_build_version__ )
-# define nssv_COMPILER_APPLECLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
-# define nssv_COMPILER_CLANG_VERSION 0
-#elif defined( __clang__ )
-# define nssv_COMPILER_APPLECLANG_VERSION 0
-# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
-#else
-# define nssv_COMPILER_APPLECLANG_VERSION 0
-# define nssv_COMPILER_CLANG_VERSION 0
-#endif
-
-#if defined(__GNUC__) && !defined(__clang__)
-# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
-#else
-# define nssv_COMPILER_GNUC_VERSION 0
-#endif
-
-// half-open range [lo..hi):
-#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
-
-// Presence of language and library features:
-
-#ifdef _HAS_CPP0X
-# define nssv_HAS_CPP0X _HAS_CPP0X
-#else
-# define nssv_HAS_CPP0X 0
-#endif
-
-// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
-
-#if nssv_COMPILER_MSVC_VER >= 1900
-# undef nssv_CPP11_OR_GREATER
-# define nssv_CPP11_OR_GREATER 1
-#endif
-
-#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500)
-#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600)
-#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700)
-#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800)
-#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900)
-#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910)
-
-#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER)
-#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER)
-
-// Presence of C++11 language features:
-
-#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
-#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
-#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
-#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
-#define nssv_HAVE_NULLPTR nssv_CPP11_100
-#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
-#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140
-#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140
-#define nssv_HAVE_WCHAR16_T nssv_CPP11_100
-#define nssv_HAVE_WCHAR32_T nssv_CPP11_100
-
-#if ! ( ( nssv_CPP11_OR_GREATER && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) )
-# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140
-#else
-# define nssv_HAVE_STD_DEFINED_LITERALS 0
-#endif
-
-// Presence of C++14 language features:
-
-#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000
-
-// Presence of C++17 language features:
-
-#define nssv_HAVE_NODISCARD nssv_CPP17_000
-
-// Presence of C++ library features:
-
-#define nssv_HAVE_STD_HASH nssv_CPP11_120
-
-// Presence of compiler intrinsics:
-
-// Providing char-type specializations for compare() and length() that
-// use compiler intrinsics can improve compile- and run-time performance.
-//
-// The challenge is in using the right combinations of builtin availablity
-// and its constexpr-ness.
-//
-// | compiler | __builtin_memcmp (constexpr) | memcmp (constexpr) |
-// |----------|------------------------------|---------------------|
-// | clang | 4.0 (>= 4.0 ) | any (? ) |
-// | clang-a | 9.0 (>= 9.0 ) | any (? ) |
-// | gcc | any (constexpr) | any (? ) |
-// | msvc | >= 14.2 C++17 (>= 14.2 ) | any (? ) |
-
-#define nssv_HAVE_BUILTIN_VER ( (nssv_CPP17_000 && nssv_COMPILER_MSVC_VERSION >= 142) || nssv_COMPILER_GNUC_VERSION > 0 || nssv_COMPILER_CLANG_VERSION >= 400 || nssv_COMPILER_APPLECLANG_VERSION >= 900 )
-#define nssv_HAVE_BUILTIN_CE ( nssv_HAVE_BUILTIN_VER )
-
-#define nssv_HAVE_BUILTIN_MEMCMP ( (nssv_HAVE_CONSTEXPR_14 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_14 )
-#define nssv_HAVE_BUILTIN_STRLEN ( (nssv_HAVE_CONSTEXPR_11 && nssv_HAVE_BUILTIN_CE) || !nssv_HAVE_CONSTEXPR_11 )
-
-#ifdef __has_builtin
-# define nssv_HAVE_BUILTIN( x ) __has_builtin( x )
-#else
-# define nssv_HAVE_BUILTIN( x ) 0
-#endif
-
-#if nssv_HAVE_BUILTIN(__builtin_memcmp) || nssv_HAVE_BUILTIN_VER
-# define nssv_BUILTIN_MEMCMP __builtin_memcmp
-#else
-# define nssv_BUILTIN_MEMCMP memcmp
-#endif
-
-#if nssv_HAVE_BUILTIN(__builtin_strlen) || nssv_HAVE_BUILTIN_VER
-# define nssv_BUILTIN_STRLEN __builtin_strlen
-#else
-# define nssv_BUILTIN_STRLEN strlen
-#endif
-
-// C++ feature usage:
-
-#if nssv_HAVE_CONSTEXPR_11
-# define nssv_constexpr constexpr
-#else
-# define nssv_constexpr /*constexpr*/
-#endif
-
-#if nssv_HAVE_CONSTEXPR_14
-# define nssv_constexpr14 constexpr
-#else
-# define nssv_constexpr14 /*constexpr*/
-#endif
-
-#if nssv_HAVE_EXPLICIT_CONVERSION
-# define nssv_explicit explicit
-#else
-# define nssv_explicit /*explicit*/
-#endif
-
-#if nssv_HAVE_INLINE_NAMESPACE
-# define nssv_inline_ns inline
-#else
-# define nssv_inline_ns /*inline*/
-#endif
-
-#if nssv_HAVE_NOEXCEPT
-# define nssv_noexcept noexcept
-#else
-# define nssv_noexcept /*noexcept*/
-#endif
-
-//#if nssv_HAVE_REF_QUALIFIER
-//# define nssv_ref_qual &
-//# define nssv_refref_qual &&
-//#else
-//# define nssv_ref_qual /*&*/
-//# define nssv_refref_qual /*&&*/
-//#endif
-
-#if nssv_HAVE_NULLPTR
-# define nssv_nullptr nullptr
-#else
-# define nssv_nullptr NULL
-#endif
-
-#if nssv_HAVE_NODISCARD
-# define nssv_nodiscard [[nodiscard]]
-#else
-# define nssv_nodiscard /*[[nodiscard]]*/
-#endif
-
-// Additional includes:
-
-#include <algorithm>
-#include <cassert>
-#include <iterator>
-#include <limits>
-#include <ostream>
-#include <string> // std::char_traits<>
-
-#if ! nssv_CONFIG_NO_EXCEPTIONS
-# include <stdexcept>
-#endif
-
-#if nssv_CPP11_OR_GREATER
-# include <type_traits>
-#endif
-
-// Clang, GNUC, MSVC warning suppression macros:
-
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wuser-defined-literals"
-#elif defined(__GNUC__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wliteral-suffix"
-#endif // __clang__
-
-#if nssv_COMPILER_MSVC_VERSION >= 140
-# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]]
-# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) )
-# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes))
-#else
-# define nssv_SUPPRESS_MSGSL_WARNING(expr)
-# define nssv_SUPPRESS_MSVC_WARNING(code, descr)
-# define nssv_DISABLE_MSVC_WARNINGS(codes)
-#endif
-
-#if defined(__clang__)
-# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
-#elif defined(__GNUC__)
-# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
-#elif nssv_COMPILER_MSVC_VERSION >= 140
-# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
-#else
-# define nssv_RESTORE_WARNINGS()
-#endif
-
-// Suppress the following MSVC (GSL) warnings:
-// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not
-// start with an underscore are reserved
-// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions;
-// use brace initialization, gsl::narrow_cast or gsl::narow
-// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead
-
-nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
-//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" )
-//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix )
-
-namespace nonstd { namespace sv_lite {
-
-namespace detail {
-
-// support constexpr comparison in C++14;
-// for C++17 and later, use provided traits:
-
-template< typename CharT >
-inline nssv_constexpr14 int compare( CharT const * s1, CharT const * s2, std::size_t count )
-{
- while ( count-- != 0 )
- {
- if ( *s1 < *s2 ) return -1;
- if ( *s1 > *s2 ) return +1;
- ++s1; ++s2;
- }
- return 0;
-}
-
-#if nssv_HAVE_BUILTIN_MEMCMP
-
-// specialization of compare() for char, see also generic compare() above:
-
-inline nssv_constexpr14 int compare( char const * s1, char const * s2, std::size_t count )
-{
- return nssv_BUILTIN_MEMCMP( s1, s2, count );
-}
-
-#endif
-
-#if nssv_HAVE_BUILTIN_STRLEN
-
-// specialization of length() for char, see also generic length() further below:
-
-inline nssv_constexpr std::size_t length( char const * s )
-{
- return nssv_BUILTIN_STRLEN( s );
-}
-
-#endif
-
-#if defined(__OPTIMIZE__)
-
-// gcc, clang provide __OPTIMIZE__
-// Expect tail call optimization to make length() non-recursive:
-
-template< typename CharT >
-inline nssv_constexpr std::size_t length( CharT * s, std::size_t result = 0 )
-{
- return *s == '\0' ? result : length( s + 1, result + 1 );
-}
-
-#else // OPTIMIZE
-
-// non-recursive:
-
-template< typename CharT >
-inline nssv_constexpr14 std::size_t length( CharT * s )
-{
- std::size_t result = 0;
- while ( *s++ != '\0' )
- {
- ++result;
- }
- return result;
-}
-
-#endif // OPTIMIZE
-
-} // namespace detail
-
-template
-<
- class CharT,
- class Traits = std::char_traits<CharT>
->
-class basic_string_view;
-
-//
-// basic_string_view:
-//
-
-template
-<
- class CharT,
- class Traits /* = std::char_traits<CharT> */
->
-class basic_string_view
-{
-public:
- // Member types:
-
- typedef Traits traits_type;
- typedef CharT value_type;
-
- typedef CharT * pointer;
- typedef CharT const * const_pointer;
- typedef CharT & reference;
- typedef CharT const & const_reference;
-
- typedef const_pointer iterator;
- typedef const_pointer const_iterator;
- typedef std::reverse_iterator< const_iterator > reverse_iterator;
- typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- // 24.4.2.1 Construction and assignment:
-
- nssv_constexpr basic_string_view() nssv_noexcept
- : data_( nssv_nullptr )
- , size_( 0 )
- {}
-
-#if nssv_CPP11_OR_GREATER
- nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default;
-#else
- nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept
- : data_( other.data_)
- , size_( other.size_)
- {}
-#endif
-
- nssv_constexpr basic_string_view( CharT const * s, size_type count ) nssv_noexcept // non-standard noexcept
- : data_( s )
- , size_( count )
- {}
-
- nssv_constexpr basic_string_view( CharT const * s) nssv_noexcept // non-standard noexcept
- : data_( s )
-#if nssv_CPP17_OR_GREATER
- , size_( Traits::length(s) )
-#elif nssv_CPP11_OR_GREATER
- , size_( detail::length(s) )
-#else
- , size_( Traits::length(s) )
-#endif
- {}
-
- // Assignment:
-
-#if nssv_CPP11_OR_GREATER
- nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default;
-#else
- nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept
- {
- data_ = other.data_;
- size_ = other.size_;
- return *this;
- }
-#endif
-
- // 24.4.2.2 Iterator support:
-
- nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; }
- nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; }
-
- nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); }
- nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); }
-
- nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); }
- nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); }
-
- nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); }
- nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); }
-
- // 24.4.2.3 Capacity:
-
- nssv_constexpr size_type size() const nssv_noexcept { return size_; }
- nssv_constexpr size_type length() const nssv_noexcept { return size_; }
- nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); }
-
- // since C++20
- nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept
- {
- return 0 == size_;
- }
-
- // 24.4.2.4 Element access:
-
- nssv_constexpr const_reference operator[]( size_type pos ) const
- {
- return data_at( pos );
- }
-
- nssv_constexpr14 const_reference at( size_type pos ) const
- {
-#if nssv_CONFIG_NO_EXCEPTIONS
- assert( pos < size() );
-#else
- if ( pos >= size() )
- {
- throw std::out_of_range("nonstd::string_view::at()");
- }
-#endif
- return data_at( pos );
- }
-
- nssv_constexpr const_reference front() const { return data_at( 0 ); }
- nssv_constexpr const_reference back() const { return data_at( size() - 1 ); }
-
- nssv_constexpr const_pointer data() const nssv_noexcept { return data_; }
-
- // 24.4.2.5 Modifiers:
-
- nssv_constexpr14 void remove_prefix( size_type n )
- {
- assert( n <= size() );
- data_ += n;
- size_ -= n;
- }
-
- nssv_constexpr14 void remove_suffix( size_type n )
- {
- assert( n <= size() );
- size_ -= n;
- }
-
- nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept
- {
- using std::swap;
- swap( data_, other.data_ );
- swap( size_, other.size_ );
- }
-
- // 24.4.2.6 String operations:
-
- size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const
- {
-#if nssv_CONFIG_NO_EXCEPTIONS
- assert( pos <= size() );
-#else
- if ( pos > size() )
- {
- throw std::out_of_range("nonstd::string_view::copy()");
- }
-#endif
- const size_type rlen = (std::min)( n, size() - pos );
-
- (void) Traits::copy( dest, data() + pos, rlen );
-
- return rlen;
- }
-
- nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const
- {
-#if nssv_CONFIG_NO_EXCEPTIONS
- assert( pos <= size() );
-#else
- if ( pos > size() )
- {
- throw std::out_of_range("nonstd::string_view::substr()");
- }
-#endif
- return basic_string_view( data() + pos, (std::min)( n, size() - pos ) );
- }
-
- // compare(), 6x:
-
- nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1)
- {
-#if nssv_CPP17_OR_GREATER
- if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
-#else
- if ( const int result = detail::compare( data(), other.data(), (std::min)( size(), other.size() ) ) )
-#endif
- {
- return result;
- }
-
- return size() == other.size() ? 0 : size() < other.size() ? -1 : 1;
- }
-
- nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2)
- {
- return substr( pos1, n1 ).compare( other );
- }
-
- nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3)
- {
- return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) );
- }
-
- nssv_constexpr int compare( CharT const * s ) const // (4)
- {
- return compare( basic_string_view( s ) );
- }
-
- nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5)
- {
- return substr( pos1, n1 ).compare( basic_string_view( s ) );
- }
-
- nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6)
- {
- return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) );
- }
-
- // 24.4.2.7 Searching:
-
- // starts_with(), 3x, since C++20:
-
- nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1)
- {
- return size() >= v.size() && compare( 0, v.size(), v ) == 0;
- }
-
- nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2)
- {
- return starts_with( basic_string_view( &c, 1 ) );
- }
-
- nssv_constexpr bool starts_with( CharT const * s ) const // (3)
- {
- return starts_with( basic_string_view( s ) );
- }
-
- // ends_with(), 3x, since C++20:
-
- nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1)
- {
- return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0;
- }
-
- nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2)
- {
- return ends_with( basic_string_view( &c, 1 ) );
- }
-
- nssv_constexpr bool ends_with( CharT const * s ) const // (3)
- {
- return ends_with( basic_string_view( s ) );
- }
-
- // find(), 4x:
-
- nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
- {
- return assert( v.size() == 0 || v.data() != nssv_nullptr )
- , pos >= size()
- ? npos
- : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
- }
-
- nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
- {
- return find( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
- {
- return find( basic_string_view( s, n ), pos );
- }
-
- nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
- {
- return find( basic_string_view( s ), pos );
- }
-
- // rfind(), 4x:
-
- nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
- {
- if ( size() < v.size() )
- {
- return npos;
- }
-
- if ( v.empty() )
- {
- return (std::min)( size(), pos );
- }
-
- const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size();
- const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq );
-
- return result != last ? size_type( result - cbegin() ) : npos;
- }
-
- nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
- {
- return rfind( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3)
- {
- return rfind( basic_string_view( s, n ), pos );
- }
-
- nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4)
- {
- return rfind( basic_string_view( s ), pos );
- }
-
- // find_first_of(), 4x:
-
- nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
- {
- return pos >= size()
- ? npos
- : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
- }
-
- nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
- {
- return find_first_of( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3)
- {
- return find_first_of( basic_string_view( s, n ), pos );
- }
-
- nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4)
- {
- return find_first_of( basic_string_view( s ), pos );
- }
-
- // find_last_of(), 4x:
-
- nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
- {
- return empty()
- ? npos
- : pos >= size()
- ? find_last_of( v, size() - 1 )
- : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) );
- }
-
- nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
- {
- return find_last_of( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3)
- {
- return find_last_of( basic_string_view( s, count ), pos );
- }
-
- nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4)
- {
- return find_last_of( basic_string_view( s ), pos );
- }
-
- // find_first_not_of(), 4x:
-
- nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
- {
- return pos >= size()
- ? npos
- : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) );
- }
-
- nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
- {
- return find_first_not_of( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
- {
- return find_first_not_of( basic_string_view( s, count ), pos );
- }
-
- nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4)
- {
- return find_first_not_of( basic_string_view( s ), pos );
- }
-
- // find_last_not_of(), 4x:
-
- nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1)
- {
- return empty()
- ? npos
- : pos >= size()
- ? find_last_not_of( v, size() - 1 )
- : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) );
- }
-
- nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2)
- {
- return find_last_not_of( basic_string_view( &c, 1 ), pos );
- }
-
- nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3)
- {
- return find_last_not_of( basic_string_view( s, count ), pos );
- }
-
- nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4)
- {
- return find_last_not_of( basic_string_view( s ), pos );
- }
-
- // Constants:
-
-#if nssv_CPP17_OR_GREATER
- static nssv_constexpr size_type npos = size_type(-1);
-#elif nssv_CPP11_OR_GREATER
- enum : size_type { npos = size_type(-1) };
-#else
- enum { npos = size_type(-1) };
-#endif
-
-private:
- struct not_in_view
- {
- const basic_string_view v;
-
- nssv_constexpr explicit not_in_view( basic_string_view v_ ) : v( v_ ) {}
-
- nssv_constexpr bool operator()( CharT c ) const
- {
- return npos == v.find_first_of( c );
- }
- };
-
- nssv_constexpr size_type to_pos( const_iterator it ) const
- {
- return it == cend() ? npos : size_type( it - cbegin() );
- }
-
- nssv_constexpr size_type to_pos( const_reverse_iterator it ) const
- {
- return it == crend() ? npos : size_type( crend() - it - 1 );
- }
-
- nssv_constexpr const_reference data_at( size_type pos ) const
- {
-#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 )
- return data_[pos];
-#else
- return assert( pos < size() ), data_[pos];
-#endif
- }
-
-private:
- const_pointer data_;
- size_type size_;
-
-public:
-#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-
- template< class Allocator >
- basic_string_view( std::basic_string<CharT, Traits, Allocator> const & s ) nssv_noexcept
- : data_( s.data() )
- , size_( s.size() )
- {}
-
-#if nssv_HAVE_EXPLICIT_CONVERSION
-
- template< class Allocator >
- explicit operator std::basic_string<CharT, Traits, Allocator>() const
- {
- return to_string( Allocator() );
- }
-
-#endif // nssv_HAVE_EXPLICIT_CONVERSION
-
-#if nssv_CPP11_OR_GREATER
-
- template< class Allocator = std::allocator<CharT> >
- std::basic_string<CharT, Traits, Allocator>
- to_string( Allocator const & a = Allocator() ) const
- {
- return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
- }
-
-#else
-
- std::basic_string<CharT, Traits>
- to_string() const
- {
- return std::basic_string<CharT, Traits>( begin(), end() );
- }
-
- template< class Allocator >
- std::basic_string<CharT, Traits, Allocator>
- to_string( Allocator const & a ) const
- {
- return std::basic_string<CharT, Traits, Allocator>( begin(), end(), a );
- }
-
-#endif // nssv_CPP11_OR_GREATER
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS
-};
-
-//
-// Non-member functions:
-//
-
-// 24.4.3 Non-member comparison functions:
-// lexicographically compare two string views (function template):
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator== (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator!= (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator< (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator<= (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator> (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits >
-nssv_constexpr bool operator>= (
- basic_string_view <CharT, Traits> lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-// Let S be basic_string_view<CharT, Traits>, and sv be an instance of S.
-// Implementations shall provide sufficient additional overloads marked
-// constexpr and noexcept so that an object t with an implicit conversion
-// to S can be compared according to Table 67.
-
-#if ! nssv_CPP11_OR_GREATER || nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 )
-
-// accomodate for older compilers:
-
-// ==
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
- basic_string_view<CharT, Traits> lhs,
- CharT const * rhs ) nssv_noexcept
-{ return lhs.size() == detail::length( rhs ) && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
- CharT const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return detail::length( lhs ) == rhs.size() && rhs.compare( lhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator==(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-// !=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
- basic_string_view<CharT, Traits> lhs,
- char const * rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
- char const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator!=(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-// <
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
- basic_string_view<CharT, Traits> lhs,
- char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
- char const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) > 0; }
-
-// <=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
- basic_string_view<CharT, Traits> lhs,
- char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
- char const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator<=(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) >= 0; }
-
-// >
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
- basic_string_view<CharT, Traits> lhs,
- char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
- char const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) < 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) < 0; }
-
-// >=
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
- basic_string_view<CharT, Traits> lhs,
- char const * rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
- char const * lhs,
- basic_string_view<CharT, Traits> rhs ) nssv_noexcept
-{ return rhs.compare( lhs ) <= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
- basic_string_view<CharT, Traits> lhs,
- std::basic_string<CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits>
-nssv_constexpr bool operator>=(
- std::basic_string<CharT, Traits> rhs,
- basic_string_view<CharT, Traits> lhs ) nssv_noexcept
-{ return rhs.compare( lhs ) <= 0; }
-
-#else // newer compilers:
-
-#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view<T,U> >::type
-
-#if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 )
-# define nssv_MSVC_ORDER(x) , int=x
-#else
-# define nssv_MSVC_ORDER(x) /*, int=x*/
-#endif
-
-// ==
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator==(
- basic_string_view <CharT, Traits> lhs,
- nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator==(
- nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs,
- basic_string_view <CharT, Traits> rhs ) nssv_noexcept
-{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; }
-
-// !=
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator!= (
- basic_string_view < CharT, Traits > lhs,
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator!= (
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
- basic_string_view < CharT, Traits > rhs ) nssv_noexcept
-{ return !( lhs == rhs ); }
-
-// <
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator< (
- basic_string_view < CharT, Traits > lhs,
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator< (
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
- basic_string_view < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) < 0; }
-
-// <=
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator<= (
- basic_string_view < CharT, Traits > lhs,
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator<= (
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
- basic_string_view < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) <= 0; }
-
-// >
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator> (
- basic_string_view < CharT, Traits > lhs,
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator> (
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
- basic_string_view < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) > 0; }
-
-// >=
-
-template< class CharT, class Traits nssv_MSVC_ORDER(1) >
-nssv_constexpr bool operator>= (
- basic_string_view < CharT, Traits > lhs,
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-template< class CharT, class Traits nssv_MSVC_ORDER(2) >
-nssv_constexpr bool operator>= (
- nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs,
- basic_string_view < CharT, Traits > rhs ) nssv_noexcept
-{ return lhs.compare( rhs ) >= 0; }
-
-#undef nssv_MSVC_ORDER
-#undef nssv_BASIC_STRING_VIEW_I
-
-#endif // compiler-dependent approach to comparisons
-
-// 24.4.4 Inserters and extractors:
-
-namespace detail {
-
-template< class Stream >
-void write_padding( Stream & os, std::streamsize n )
-{
- for ( std::streamsize i = 0; i < n; ++i )
- os.rdbuf()->sputc( os.fill() );
-}
-
-template< class Stream, class View >
-Stream & write_to_stream( Stream & os, View const & sv )
-{
- typename Stream::sentry sentry( os );
-
- if ( !os )
- return os;
-
- const std::streamsize length = static_cast<std::streamsize>( sv.length() );
-
- // Whether, and how, to pad:
- const bool pad = ( length < os.width() );
- const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right;
-
- if ( left_pad )
- write_padding( os, os.width() - length );
-
- // Write span characters:
- os.rdbuf()->sputn( sv.begin(), length );
-
- if ( pad && !left_pad )
- write_padding( os, os.width() - length );
-
- // Reset output stream width:
- os.width( 0 );
-
- return os;
-}
-
-} // namespace detail
-
-template< class CharT, class Traits >
-std::basic_ostream<CharT, Traits> &
-operator<<(
- std::basic_ostream<CharT, Traits>& os,
- basic_string_view <CharT, Traits> sv )
-{
- return detail::write_to_stream( os, sv );
-}
-
-// Several typedefs for common character types are provided:
-
-typedef basic_string_view<char> string_view;
-typedef basic_string_view<wchar_t> wstring_view;
-#if nssv_HAVE_WCHAR16_T
-typedef basic_string_view<char16_t> u16string_view;
-typedef basic_string_view<char32_t> u32string_view;
-#endif
-
-}} // namespace nonstd::sv_lite
-
-//
-// 24.4.6 Suffix for basic_string_view literals:
-//
-
-#if nssv_HAVE_USER_DEFINED_LITERALS
-
-namespace nonstd {
-nssv_inline_ns namespace literals {
-nssv_inline_ns namespace string_view_literals {
-
-#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
-
-nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1)
-{
- return nonstd::sv_lite::string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
-{
- return nonstd::sv_lite::u16string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
-{
- return nonstd::sv_lite::u32string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
-{
- return nonstd::sv_lite::wstring_view{ str, len };
-}
-
-#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS
-
-#if nssv_CONFIG_USR_SV_OPERATOR
-
-nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1)
-{
- return nonstd::sv_lite::string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2)
-{
- return nonstd::sv_lite::u16string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3)
-{
- return nonstd::sv_lite::u32string_view{ str, len };
-}
-
-nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4)
-{
- return nonstd::sv_lite::wstring_view{ str, len };
-}
-
-#endif // nssv_CONFIG_USR_SV_OPERATOR
-
-}}} // namespace nonstd::literals::string_view_literals
-
-#endif
-
-//
-// Extensions for std::string:
-//
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-namespace nonstd {
-namespace sv_lite {
-
-// Exclude MSVC 14 (19.00): it yields ambiguous to_string():
-
-#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140
-
-template< class CharT, class Traits, class Allocator = std::allocator<CharT> >
-std::basic_string<CharT, Traits, Allocator>
-to_string( basic_string_view<CharT, Traits> v, Allocator const & a = Allocator() )
-{
- return std::basic_string<CharT,Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-#else
-
-template< class CharT, class Traits >
-std::basic_string<CharT, Traits>
-to_string( basic_string_view<CharT, Traits> v )
-{
- return std::basic_string<CharT, Traits>( v.begin(), v.end() );
-}
-
-template< class CharT, class Traits, class Allocator >
-std::basic_string<CharT, Traits, Allocator>
-to_string( basic_string_view<CharT, Traits> v, Allocator const & a )
-{
- return std::basic_string<CharT, Traits, Allocator>( v.begin(), v.end(), a );
-}
-
-#endif // nssv_CPP11_OR_GREATER
-
-template< class CharT, class Traits, class Allocator >
-basic_string_view<CharT, Traits>
-to_string_view( std::basic_string<CharT, Traits, Allocator> const & s )
-{
- return basic_string_view<CharT, Traits>( s.data(), s.size() );
-}
-
-}} // namespace nonstd::sv_lite
-
-#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-
-//
-// make types and algorithms available in namespace nonstd:
-//
-
-namespace nonstd {
-
-using sv_lite::basic_string_view;
-using sv_lite::string_view;
-using sv_lite::wstring_view;
-
-#if nssv_HAVE_WCHAR16_T
-using sv_lite::u16string_view;
-#endif
-#if nssv_HAVE_WCHAR32_T
-using sv_lite::u32string_view;
-#endif
-
-// literal "sv"
-
-using sv_lite::operator==;
-using sv_lite::operator!=;
-using sv_lite::operator<;
-using sv_lite::operator<=;
-using sv_lite::operator>;
-using sv_lite::operator>=;
-
-using sv_lite::operator<<;
-
-#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS
-using sv_lite::to_string;
-using sv_lite::to_string_view;
-#endif
-
-} // namespace nonstd
-
-// 24.4.5 Hash support (C++11):
-
-// Note: The hash value of a string view object is equal to the hash value of
-// the corresponding string object.
-
-#if nssv_HAVE_STD_HASH
-
-#include <functional>
-
-namespace std {
-
-template<>
-struct hash< nonstd::string_view >
-{
-public:
- std::size_t operator()( nonstd::string_view v ) const nssv_noexcept
- {
- return std::hash<std::string>()( std::string( v.data(), v.size() ) );
- }
-};
-
-template<>
-struct hash< nonstd::wstring_view >
-{
-public:
- std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept
- {
- return std::hash<std::wstring>()( std::wstring( v.data(), v.size() ) );
- }
-};
-
-template<>
-struct hash< nonstd::u16string_view >
-{
-public:
- std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept
- {
- return std::hash<std::u16string>()( std::u16string( v.data(), v.size() ) );
- }
-};
-
-template<>
-struct hash< nonstd::u32string_view >
-{
-public:
- std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept
- {
- return std::hash<std::u32string>()( std::u32string( v.data(), v.size() ) );
- }
-};
-
-} // namespace std
-
-#endif // nssv_HAVE_STD_HASH
-
-nssv_RESTORE_WARNINGS()
-
-#endif // nssv_HAVE_STD_STRING_VIEW
-#endif // NONSTD_SV_LITE_H_INCLUDED
-// 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.
//
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;
} 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);
#include <assertions.hpp>
#include <third_party/fmt/core.h>
-#include <third_party/nonstd/string_view.hpp>
+
+#include <string_view>
namespace util {
// 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);
Iterator operator++();
bool operator!=(const Iterator& other) const;
- nonstd::string_view operator*() const;
+ std::string_view operator*() const;
private:
const Tokenizer& m_tokenizer;
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)
if (start_pos == 0) {
advance(true);
} else {
- DEBUG_ASSERT(start_pos == nonstd::string_view::npos);
+ DEBUG_ASSERT(start_pos == std::string_view::npos);
}
}
inline Tokenizer::Iterator
Tokenizer::end()
{
- return Iterator(*this, nonstd::string_view::npos);
+ return Iterator(*this, std::string_view::npos);
}
} // namespace util
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] == ':'
}
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) {
}
std::vector<std::string>
-split_path_list(nonstd::string_view path_list)
+split_path_list(std::string_view path_list)
{
return Util::split_into_strings(path_list, k_path_delimiter);
}
std::string
-to_absolute_path(nonstd::string_view path)
+to_absolute_path(std::string_view path)
{
if (util::is_absolute_path(path)) {
return std::string(path);
}
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
#pragma once
-#include <third_party/nonstd/string_view.hpp>
-
#include <string>
+#include <string_view>
#include <vector>
namespace util {
// --- Interface ---
// Return whether `path` is absolute.
-bool is_absolute_path(nonstd::string_view path);
+bool is_absolute_path(std::string_view path);
// Return whether `path` includes at least one directory separator.
-bool is_full_path(nonstd::string_view path);
+bool is_full_path(std::string_view path);
// Return whether `path` starts with `prefix` considering path specifics on
// Windows
-bool path_starts_with(nonstd::string_view path, nonstd::string_view prefix);
+bool path_starts_with(std::string_view path, std::string_view prefix);
// Split a list of paths (such as the content of $PATH on Unix platforms or
// %PATH% on Windows platforms) into paths.
-std::vector<std::string> split_path_list(nonstd::string_view path_list);
+std::vector<std::string> split_path_list(std::string_view path_list);
// Make `path` an absolute path.
-std::string to_absolute_path(nonstd::string_view path);
+std::string to_absolute_path(std::string_view path);
// Make `path` an absolute path, but do not include Windows drive.
-std::string to_absolute_path_no_drive(nonstd::string_view path);
+std::string to_absolute_path_no_drive(std::string_view path);
// --- Inline implementations ---
inline bool
-is_full_path(const nonstd::string_view path)
+is_full_path(const std::string_view path)
{
#ifdef _WIN32
- if (path.find('\\') != nonstd::string_view::npos) {
+ if (path.find('\\') != std::string_view::npos) {
return true;
}
#endif
- return path.find('/') != nonstd::string_view::npos;
+ return path.find('/') != std::string_view::npos;
}
} // namespace util
-// 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.
//
#include <assertions.hpp>
#include <fmtmacros.hpp>
+#include <algorithm>
#include <cctype>
#include <iostream>
parse_signed(const std::string& value,
const std::optional<int64_t> min_value,
const std::optional<int64_t> max_value,
- const nonstd::string_view description)
+ const std::string_view description)
{
const std::string stripped_value = strip_whitespace(value);
parse_unsigned(const std::string& value,
const std::optional<uint64_t> min_value,
const std::optional<uint64_t> max_value,
- const nonstd::string_view description,
+ const std::string_view description,
const int base)
{
const std::string stripped_value = strip_whitespace(value);
}
nonstd::expected<std::string, std::string>
-percent_decode(nonstd::string_view string)
+percent_decode(std::string_view string)
{
const auto from_hex = [](const char digit) {
return static_cast<uint8_t>(
}
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);
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;
}
}
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);
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());
return result;
}
-std::pair<nonstd::string_view, std::optional<nonstd::string_view>>
-split_once(const nonstd::string_view string, const char split_char)
+std::pair<std::string_view, std::optional<std::string_view>>
+split_once(const std::string_view string, const char split_char)
{
const size_t sep_pos = string.find(split_char);
- if (sep_pos == nonstd::string_view::npos) {
+ if (sep_pos == std::string_view::npos) {
return std::make_pair(string, std::nullopt);
} else {
return std::make_pair(string.substr(0, sep_pos),
}
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);
#pragma once
#include <third_party/nonstd/expected.hpp>
-#include <third_party/nonstd/string_view.hpp>
#include <sys/stat.h> // for mode_t
#include <cstring>
#include <optional>
#include <string>
+#include <string_view>
#include <utility>
namespace util {
// --- Interface ---
// Return true if `suffix` is a suffix of `string`.
-bool ends_with(nonstd::string_view string, nonstd::string_view suffix);
+bool ends_with(std::string_view string, std::string_view suffix);
// Join stringified elements of `container` delimited by `delimiter` into a
// string. There must exist an `std::string to_string(T::value_type)` function.
template<typename T>
-std::string join(const T& container, const nonstd::string_view delimiter);
+std::string join(const T& container, const std::string_view delimiter);
// Join stringified elements between input iterators `begin` and `end` delimited
// by `delimiter` into a string. There must exist an `std::string
// to_string(T::value_type)` function.
template<typename T>
std::string
-join(const T& begin, const T& end, const nonstd::string_view delimiter);
+join(const T& begin, const T& end, const std::string_view delimiter);
// Parse a string into a double.
//
parse_signed(const std::string& value,
std::optional<int64_t> min_value = std::nullopt,
std::optional<int64_t> max_value = std::nullopt,
- nonstd::string_view description = "integer");
+ std::string_view description = "integer");
// Parse `value` (an octal integer).
nonstd::expected<mode_t, std::string> parse_umask(const std::string& value);
parse_unsigned(const std::string& value,
std::optional<uint64_t> min_value = std::nullopt,
std::optional<uint64_t> max_value = std::nullopt,
- nonstd::string_view description = "integer",
+ std::string_view description = "integer",
int base = 10);
// Percent-decode[1] `string`.
//
// [1]: https://en.wikipedia.org/wiki/Percent-encoding
nonstd::expected<std::string, std::string>
-percent_decode(nonstd::string_view string);
+percent_decode(std::string_view string);
// Replace the all occurrences of `from` to `to` in `string`.
-std::string replace_all(nonstd::string_view string,
- nonstd::string_view from,
- nonstd::string_view to);
+std::string replace_all(std::string_view string,
+ std::string_view from,
+ std::string_view to);
// Replace the first occurrence of `from` to `to` in `string`.
-std::string replace_first(nonstd::string_view string,
- nonstd::string_view from,
- nonstd::string_view to);
+std::string replace_first(std::string_view string,
+ std::string_view from,
+ std::string_view to);
// Split `string` into two parts using `split_char` as the delimiter. The second
// part will be `nullopt` if there is no `split_char` in `string.`
-std::pair<nonstd::string_view, std::optional<nonstd::string_view>>
-split_once(nonstd::string_view string, char split_char);
+std::pair<std::string_view, std::optional<std::string_view>>
+split_once(std::string_view string, char split_char);
// Return true if `prefix` is a prefix of `string`.
-bool starts_with(const char* string, nonstd::string_view prefix);
+bool starts_with(const char* string, std::string_view prefix);
// Return true if `prefix` is a prefix of `string`.
-bool starts_with(nonstd::string_view string, nonstd::string_view prefix);
+bool starts_with(std::string_view string, std::string_view prefix);
// Strip whitespace from left and right side of a string.
-[[nodiscard]] std::string strip_whitespace(nonstd::string_view string);
+[[nodiscard]] std::string strip_whitespace(std::string_view string);
-// Convert `string` to a string. This function is used when joining
+// Convert `value` to a string. This function is used when joining
// `std::string`s with `util::join`.
-std::string to_string(const std::string& string);
+template<typename T> std::string to_string(const T& value);
// --- Inline implementations ---
inline bool
-ends_with(const nonstd::string_view string, const nonstd::string_view suffix)
+ends_with(const std::string_view string, const std::string_view suffix)
{
- return string.ends_with(suffix);
+ return string.length() >= suffix.length()
+ && string.compare(
+ string.length() - suffix.length(), std::string_view::npos, suffix)
+ == 0;
}
template<typename T>
inline std::string
-join(const T& container, const nonstd::string_view delimiter)
+join(const T& container, const std::string_view delimiter)
{
return join(container.begin(), container.end(), delimiter);
}
template<typename T>
inline std::string
-join(const T& begin, const T& end, const nonstd::string_view delimiter)
+join(const T& begin, const T& end, const std::string_view delimiter)
{
std::string result;
for (auto it = begin; it != end; ++it) {
}
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.
}
inline bool
-starts_with(const nonstd::string_view string, const nonstd::string_view prefix)
+starts_with(const std::string_view string, const std::string_view prefix)
{
- return string.starts_with(prefix);
+ return string.substr(0, prefix.size()) == prefix;
}
-// Convert `string` to `string`. This is used by util::join.
+template<typename T>
+inline std::string
+to_string(const T& t)
+{
+ using std::to_string;
+ return to_string(std::forward<T>(t));
+}
+
+template<>
inline std::string
to_string(const std::string& string)
{
- return string;
+ return std::string(string);
+}
+
+template<>
+inline std::string
+to_string(const std::string_view& sv)
+{
+ return std::string(sv);
}
} // namespace util
test_AtomicFile.cpp
test_Config.cpp
test_Depfile.cpp
- test_FormatNonstdStringView.cpp
test_Hash.cpp
test_Lockfile.cpp
test_NullCompression.cpp
+++ /dev/null
-// 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();
-// 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.
//
#include "third_party/doctest.h"
-using nonstd::string_view;
using TestUtil::TestContext;
TEST_SUITE_BEGIN("hashutil");
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"
"#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__";
#include "third_party/doctest.h"
+#include <ostream> // https://github.com/doctest/doctest/issues/618
+
TEST_CASE("util::Tokenizer")
{
using Mode = util::Tokenizer::Mode;
#include <third_party/doctest.h>
+#include <ostream> // https://github.com/doctest/doctest/issues/618
+
TEST_CASE("util::is_absolute_path")
{
#ifdef _WIN32
#include <vector>
static bool
-operator==(
- std::pair<nonstd::string_view, std::optional<nonstd::string_view>> left,
- std::pair<nonstd::string_view, std::optional<nonstd::string_view>> right)
+operator==(std::pair<std::string_view, std::optional<std::string_view>> left,
+ std::pair<std::string_view, std::optional<std::string_view>> right)
{
return left.first == right.first && left.second == right.second;
}
CHECK(util::join(v.begin() + 1, v.end(), "|") == " b |c|");
}
{
- std::vector<nonstd::string_view> v{"1", "2"};
+ std::vector<std::string_view> v{"1", "2"};
CHECK(util::join(v, " ") == "1 2");
}
}