Use std::string_view and fmtlib across all libraries (#3402)

- Twine, StringRef, Format, and NativeFormatting have been removed
- Logging now uses fmtlib style formatting
- Nearly all uses of wpi::outs/errs have been replaced with fmt::print() or
std::puts()/std::fputs() (for unformatted strings).
- A wpi/fmt/raw_ostream.h header has been added to enable
fmt::print() with wpi::raw_ostream
This commit is contained in:
Peter Johnson
2021-06-06 16:13:58 -07:00
committed by GitHub
parent 4f1cecb8e7
commit b2c3b2dd8e
441 changed files with 5061 additions and 9749 deletions

View File

@@ -7,26 +7,26 @@
#include <cstddef>
#include <string>
#include "wpi/StringRef.h"
#include <string_view>
namespace wpi {
template <typename T>
class SmallVectorImpl;
class raw_ostream;
size_t Base64Decode(raw_ostream& os, StringRef encoded);
size_t Base64Decode(raw_ostream& os, std::string_view encoded);
size_t Base64Decode(StringRef encoded, std::string* plain);
size_t Base64Decode(std::string_view encoded, std::string* plain);
StringRef Base64Decode(StringRef encoded, size_t* num_read,
SmallVectorImpl<char>& buf);
std::string_view Base64Decode(std::string_view encoded, size_t* num_read,
SmallVectorImpl<char>& buf);
void Base64Encode(raw_ostream& os, StringRef plain);
void Base64Encode(raw_ostream& os, std::string_view plain);
void Base64Encode(StringRef plain, std::string* encoded);
void Base64Encode(std::string_view plain, std::string* encoded);
StringRef Base64Encode(StringRef plain, SmallVectorImpl<char>& buf);
std::string_view Base64Encode(std::string_view plain,
SmallVectorImpl<char>& buf);
} // namespace wpi

View File

@@ -91,10 +91,10 @@
#define LLVM_SUPPORT_CONVERTUTF_H
#include "wpi/ArrayRef.h"
#include "wpi/StringRef.h"
#include <cstddef>
#include <string>
#include <string_view>
#include <system_error>
// Wrap everything in namespace wpi so that programs can link with wpiutil and
@@ -243,15 +243,15 @@ bool convertUTF16ToUTF8String(ArrayRef<UTF16> SrcUTF16,
*
* \returns true on success
*/
bool convertUTF8ToUTF16String(StringRef SrcUTF8,
bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
SmallVectorImpl<UTF16> &DstUTF16);
#if defined(_WIN32)
namespace sys {
namespace windows {
std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
std::error_code UTF8ToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
/// Convert to UTF16 from the current code page used in the system
std::error_code CurCPToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
SmallVectorImpl<char> &utf8);
/// Convert from UTF16 to the current code page used in the system

View File

@@ -6,8 +6,7 @@
#define WPIUTIL_WPI_DEMANGLE_H_
#include <string>
#include "wpi/Twine.h"
#include <string_view>
namespace wpi {
@@ -17,7 +16,7 @@ namespace wpi {
* @param mangledSymbol the mangled symbol.
* @return The demangled symbol, or mangledSymbol if demangling fails.
*/
std::string Demangle(const Twine& mangledSymbol);
std::string Demangle(std::string_view mangledSymbol);
} // namespace wpi

View File

@@ -16,11 +16,11 @@
#include "wpi/ArrayRef.h"
#include "wpi/Hashing.h"
#include "wpi/StringRef.h"
#include "wpi/PointerLikeTypeTraits.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <utility>
namespace wpi {
@@ -206,26 +206,26 @@ struct DenseMapInfo<std::pair<T, U>> {
}
};
// Provide DenseMapInfo for StringRefs.
template <> struct DenseMapInfo<StringRef> {
static inline StringRef getEmptyKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
// Provide DenseMapInfo for std::string_view.
template <> struct DenseMapInfo<std::string_view> {
static inline std::string_view getEmptyKey() {
return std::string_view(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
0);
}
static inline StringRef getTombstoneKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
static inline std::string_view getTombstoneKey() {
return std::string_view(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
0);
}
static unsigned getHashValue(StringRef Val) {
static unsigned getHashValue(std::string_view Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val));
}
static bool isEqual(StringRef LHS, StringRef RHS) {
static bool isEqual(std::string_view LHS, std::string_view RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
if (RHS.data() == getTombstoneKey().data())

File diff suppressed because it is too large Load Diff

View File

@@ -17,11 +17,9 @@
#include "wpi/Compiler.h"
#include <string>
#include <string_view>
namespace wpi {
class StringRef;
class Twine;
/// An error handler callback.
typedef void (*fatal_error_handler_t)(void *user_data,
const std::string& reason,
@@ -73,9 +71,7 @@ LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason,
bool gen_crash_diag = true);
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason,
bool gen_crash_diag = true);
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason,
bool gen_crash_diag = true);
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason,
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(std::string_view reason,
bool gen_crash_diag = true);
/// Installs a new bad alloc error handler that should be used whenever a

View File

@@ -1,279 +0,0 @@
//===- llvm/Support/ErrorOr.h - Error Smart Pointer -------------*- C++ -*-===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// Provides ErrorOr<T> smart pointer.
///
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_ERROROR_H
#define WPIUTIL_WPI_ERROROR_H
#include "wpi/AlignOf.h"
#include <cassert>
#include <system_error>
#include <type_traits>
#include <utility>
namespace wpi {
/// Represents either an error or a value T.
///
/// ErrorOr<T> is a pointer-like class that represents the result of an
/// operation. The result is either an error, or a value of type T. This is
/// designed to emulate the usage of returning a pointer where nullptr indicates
/// failure. However instead of just knowing that the operation failed, we also
/// have an error_code and optional user data that describes why it failed.
///
/// It is used like the following.
/// \code
/// ErrorOr<Buffer> getBuffer();
///
/// auto buffer = getBuffer();
/// if (error_code ec = buffer.getError())
/// return ec;
/// buffer->write("adena");
/// \endcode
///
///
/// Implicit conversion to bool returns true if there is a usable value. The
/// unary * and -> operators provide pointer like access to the value. Accessing
/// the value when there is an error has undefined behavior.
///
/// When T is a reference type the behavior is slightly different. The reference
/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
/// there is special handling to make operator -> work as if T was not a
/// reference.
///
/// T cannot be a rvalue reference.
template<class T>
class ErrorOr {
template <class OtherT> friend class ErrorOr;
static const bool isRef = std::is_reference<T>::value;
using wrap = std::reference_wrapper<typename std::remove_reference<T>::type>;
public:
using storage_type = typename std::conditional<isRef, wrap, T>::type;
private:
using reference = typename std::remove_reference<T>::type &;
using const_reference = const typename std::remove_reference<T>::type &;
using pointer = typename std::remove_reference<T>::type *;
using const_pointer = const typename std::remove_reference<T>::type *;
public:
template <class E>
ErrorOr(E ErrorCode,
typename std::enable_if<std::is_error_code_enum<E>::value ||
std::is_error_condition_enum<E>::value,
void *>::type = nullptr)
: HasError(true) {
new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
}
ErrorOr(std::error_code EC) : HasError(true) {
new (getErrorStorage()) std::error_code(EC);
}
template <class OtherT>
ErrorOr(OtherT &&Val,
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
* = nullptr)
: HasError(false) {
new (getStorage()) storage_type(std::forward<OtherT>(Val));
}
ErrorOr(const ErrorOr &Other) {
copyConstruct(Other);
}
template <class OtherT>
ErrorOr(
const ErrorOr<OtherT> &Other,
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
nullptr) {
copyConstruct(Other);
}
template <class OtherT>
explicit ErrorOr(
const ErrorOr<OtherT> &Other,
typename std::enable_if<
!std::is_convertible<OtherT, const T &>::value>::type * = nullptr) {
copyConstruct(Other);
}
ErrorOr(ErrorOr &&Other) {
moveConstruct(std::move(Other));
}
template <class OtherT>
ErrorOr(
ErrorOr<OtherT> &&Other,
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
nullptr) {
moveConstruct(std::move(Other));
}
// This might eventually need SFINAE but it's more complex than is_convertible
// & I'm too lazy to write it right now.
template <class OtherT>
explicit ErrorOr(
ErrorOr<OtherT> &&Other,
typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
nullptr) {
moveConstruct(std::move(Other));
}
ErrorOr &operator=(const ErrorOr &Other) {
copyAssign(Other);
return *this;
}
ErrorOr &operator=(ErrorOr &&Other) {
moveAssign(std::move(Other));
return *this;
}
~ErrorOr() {
if (!HasError)
getStorage()->~storage_type();
}
/// Return false if there is an error.
explicit operator bool() const {
return !HasError;
}
reference get() { return *getStorage(); }
const_reference get() const { return const_cast<ErrorOr<T> *>(this)->get(); }
std::error_code getError() const {
return HasError ? *getErrorStorage() : std::error_code();
}
pointer operator ->() {
return toPointer(getStorage());
}
const_pointer operator->() const { return toPointer(getStorage()); }
reference operator *() {
return *getStorage();
}
const_reference operator*() const { return *getStorage(); }
private:
template <class OtherT>
void copyConstruct(const ErrorOr<OtherT> &Other) {
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (getStorage()) storage_type(*Other.getStorage());
} else {
// Get other's error.
HasError = true;
new (getErrorStorage()) std::error_code(Other.getError());
}
}
template <class T1>
static bool compareThisIfSameType(const T1 &a, const T1 &b) {
return &a == &b;
}
template <class T1, class T2>
static bool compareThisIfSameType(const T1 &a, const T2 &b) {
return false;
}
template <class OtherT>
void copyAssign(const ErrorOr<OtherT> &Other) {
if (compareThisIfSameType(*this, Other))
return;
this->~ErrorOr();
new (this) ErrorOr(Other);
}
template <class OtherT>
void moveConstruct(ErrorOr<OtherT> &&Other) {
if (!Other.HasError) {
// Get the other value.
HasError = false;
new (getStorage()) storage_type(std::move(*Other.getStorage()));
} else {
// Get other's error.
HasError = true;
new (getErrorStorage()) std::error_code(Other.getError());
}
}
template <class OtherT>
void moveAssign(ErrorOr<OtherT> &&Other) {
if (compareThisIfSameType(*this, Other))
return;
this->~ErrorOr();
new (this) ErrorOr(std::move(Other));
}
pointer toPointer(pointer Val) {
return Val;
}
const_pointer toPointer(const_pointer Val) const { return Val; }
pointer toPointer(wrap *Val) {
return &Val->get();
}
const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
}
const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<const storage_type*>(TStorage.buffer);
}
std::error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
return reinterpret_cast<std::error_code *>(ErrorStorage.buffer);
}
const std::error_code *getErrorStorage() const {
return const_cast<ErrorOr<T> *>(this)->getErrorStorage();
}
union {
AlignedCharArrayUnion<storage_type> TStorage;
AlignedCharArrayUnion<std::error_code> ErrorStorage;
};
bool HasError : 1;
};
template <class T, class E>
typename std::enable_if<std::is_error_code_enum<E>::value ||
std::is_error_condition_enum<E>::value,
bool>::type
operator==(const ErrorOr<T> &Err, E Code) {
return Err.getError() == Code;
}
} // end namespace wpi
#endif // LLVM_SUPPORT_ERROROR_H

View File

@@ -1,265 +0,0 @@
//===- Format.h - Efficient printf-style formatting for streams -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the format() function, which can be used with other
// LLVM subsystems to provide printf-style formatting. This gives all the power
// and risk of printf. This can be used like this (with raw_ostreams as an
// example):
//
// OS << "mynumber: " << format("%4.5f", 1234.412) << '\n';
//
// Or if you prefer:
//
// OS << format("mynumber: %4.5f\n", 1234.412);
//
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_FORMAT_H
#define WPIUTIL_WPI_FORMAT_H
#include "wpi/ArrayRef.h"
#include "wpi/StringRef.h"
#include <cassert>
#include <cstdint>
#include <cstdio>
#include <optional>
#include <tuple>
#include <utility>
namespace wpi {
/// This is a helper class used for handling formatted output. It is the
/// abstract base class of a templated derived class.
class format_object_base {
protected:
const char *Fmt;
~format_object_base() = default; // Disallow polymorphic deletion.
format_object_base(const format_object_base &) = default;
virtual void home(); // Out of line virtual method.
/// Call snprintf() for this object, on the given buffer and size.
virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
public:
format_object_base(const char *fmt) : Fmt(fmt) {}
/// Format the object into the specified buffer. On success, this returns
/// the length of the formatted string. If the buffer is too small, this
/// returns a length to retry with, which will be larger than BufferSize.
unsigned print(char *Buffer, unsigned BufferSize) const {
assert(BufferSize && "Invalid buffer size!");
// Print the string, leaving room for the terminating null.
int N = snprint(Buffer, BufferSize);
// VC++ and old GlibC return negative on overflow, just double the size.
if (N < 0)
return BufferSize * 2;
// Other implementations yield number of bytes needed, not including the
// final '\0'.
if (unsigned(N) >= BufferSize)
return N + 1;
// Otherwise N is the length of output (not including the final '\0').
return N;
}
};
/// These are templated helper classes used by the format function that
/// capture the object to be formatted and the format string. When actually
/// printed, this synthesizes the string into a temporary buffer provided and
/// returns whether or not it is big enough.
// Helper to validate that format() parameters are scalars or pointers.
template <typename... Args> struct validate_format_parameters;
template <typename Arg, typename... Args>
struct validate_format_parameters<Arg, Args...> {
static_assert(std::is_scalar<Arg>::value,
"format can't be used with non fundamental / non pointer type");
validate_format_parameters() { validate_format_parameters<Args...>(); }
};
template <> struct validate_format_parameters<> {};
template <typename... Ts>
class format_object final : public format_object_base {
std::tuple<Ts...> Vals;
template <std::size_t... Is>
int snprint_tuple(char *Buffer, unsigned BufferSize,
std::index_sequence<Is...>) const {
#ifdef _MSC_VER
return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
#else
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif
}
public:
format_object(const char *fmt, const Ts &... vals)
: format_object_base(fmt), Vals(vals...) {
validate_format_parameters<Ts...>();
}
int snprint(char *Buffer, unsigned BufferSize) const override {
return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>());
}
};
/// These are helper functions used to produce formatted output. They use
/// template type deduction to construct the appropriate instance of the
/// format_object class to simplify their construction.
///
/// This is typically used like:
/// \code
/// OS << format("%0.4f", myfloat) << '\n';
/// \endcode
template <typename... Ts>
inline format_object<Ts...> format(const char *Fmt, const Ts &... Vals) {
return format_object<Ts...>(Fmt, Vals...);
}
/// This is a helper class for left_justify, right_justify, and center_justify.
class FormattedString {
public:
enum Justification { JustifyNone, JustifyLeft, JustifyRight, JustifyCenter };
FormattedString(StringRef S, unsigned W, Justification J)
: Str(S), Width(W), Justify(J) {}
private:
StringRef Str;
unsigned Width;
Justification Justify;
friend class raw_ostream;
};
/// left_justify - append spaces after string so total output is
/// \p Width characters. If \p Str is larger that \p Width, full string
/// is written with no padding.
inline FormattedString left_justify(StringRef Str, unsigned Width) {
return FormattedString(Str, Width, FormattedString::JustifyLeft);
}
/// right_justify - add spaces before string so total output is
/// \p Width characters. If \p Str is larger that \p Width, full string
/// is written with no padding.
inline FormattedString right_justify(StringRef Str, unsigned Width) {
return FormattedString(Str, Width, FormattedString::JustifyRight);
}
/// center_justify - add spaces before and after string so total output is
/// \p Width characters. If \p Str is larger that \p Width, full string
/// is written with no padding.
inline FormattedString center_justify(StringRef Str, unsigned Width) {
return FormattedString(Str, Width, FormattedString::JustifyCenter);
}
/// This is a helper class used for format_hex() and format_decimal().
class FormattedNumber {
uint64_t HexValue;
int64_t DecValue;
unsigned Width;
bool Hex;
bool Upper;
bool HexPrefix;
friend class raw_ostream;
public:
FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U,
bool Prefix)
: HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U),
HexPrefix(Prefix) {}
};
/// format_hex - Output \p N as a fixed width hexadecimal. If number will not
/// fit in width, full number is still printed. Examples:
/// OS << format_hex(255, 4) => 0xff
/// OS << format_hex(255, 4, true) => 0xFF
/// OS << format_hex(255, 6) => 0x00ff
/// OS << format_hex(255, 2) => 0xff
inline FormattedNumber format_hex(uint64_t N, unsigned Width,
bool Upper = false) {
assert(Width <= 18 && "hex width must be <= 18");
return FormattedNumber(N, 0, Width, true, Upper, true);
}
/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not
/// prepend '0x' to the outputted string. If number will not fit in width,
/// full number is still printed. Examples:
/// OS << format_hex_no_prefix(255, 2) => ff
/// OS << format_hex_no_prefix(255, 2, true) => FF
/// OS << format_hex_no_prefix(255, 4) => 00ff
/// OS << format_hex_no_prefix(255, 1) => ff
inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width,
bool Upper = false) {
assert(Width <= 16 && "hex width must be <= 16");
return FormattedNumber(N, 0, Width, true, Upper, false);
}
/// format_decimal - Output \p N as a right justified, fixed-width decimal. If
/// number will not fit in width, full number is still printed. Examples:
/// OS << format_decimal(0, 5) => " 0"
/// OS << format_decimal(255, 5) => " 255"
/// OS << format_decimal(-1, 3) => " -1"
/// OS << format_decimal(12345, 3) => "12345"
inline FormattedNumber format_decimal(int64_t N, unsigned Width) {
return FormattedNumber(0, N, Width, false, false, false);
}
class FormattedBytes {
ArrayRef<uint8_t> Bytes;
// If not nullopt, display offsets for each line relative to starting value.
std::optional<uint64_t> FirstByteOffset;
uint32_t IndentLevel; // Number of characters to indent each line.
uint32_t NumPerLine; // Number of bytes to show per line.
uint8_t ByteGroupSize; // How many hex bytes are grouped without spaces
bool Upper; // Show offset and hex bytes as upper case.
bool ASCII; // Show the ASCII bytes for the hex bytes to the right.
friend class raw_ostream;
public:
FormattedBytes(ArrayRef<uint8_t> B, uint32_t IL, std::optional<uint64_t> O,
uint32_t NPL, uint8_t BGS, bool U, bool A)
: Bytes(B), FirstByteOffset(O), IndentLevel(IL), NumPerLine(NPL),
ByteGroupSize(BGS), Upper(U), ASCII(A) {
if (ByteGroupSize > NumPerLine)
ByteGroupSize = NumPerLine;
}
};
inline FormattedBytes
format_bytes(ArrayRef<uint8_t> Bytes, std::optional<uint64_t> FirstByteOffset = std::nullopt,
uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
uint32_t IndentLevel = 0, bool Upper = false) {
return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
ByteGroupSize, Upper, false);
}
inline FormattedBytes
format_bytes_with_ascii(ArrayRef<uint8_t> Bytes,
std::optional<uint64_t> FirstByteOffset = std::nullopt,
uint32_t NumPerLine = 16, uint8_t ByteGroupSize = 4,
uint32_t IndentLevel = 0, bool Upper = false) {
return FormattedBytes(Bytes, IndentLevel, FirstByteOffset, NumPerLine,
ByteGroupSize, Upper, true);
}
} // end namespace wpi
#endif

View File

@@ -53,6 +53,7 @@
#include <cassert>
#include <cstring>
#include <string>
#include <string_view>
#include <utility>
#ifdef _WIN32
@@ -660,6 +661,11 @@ hash_code hash_value(const std::basic_string<T> &arg) {
return hash_combine_range(arg.begin(), arg.end());
}
template <typename T>
hash_code hash_value(const std::basic_string_view<T> &arg) {
return hash_combine_range(arg.begin(), arg.end());
}
} // namespace wpi
#ifdef _WIN32

View File

@@ -7,9 +7,10 @@
#include <stdint.h>
#include <string_view>
#include "wpi/Signal.h"
#include "wpi/SmallString.h"
#include "wpi/StringRef.h"
#include "wpi/http_parser.h"
namespace wpi {
@@ -58,9 +59,10 @@ class HttpParser {
* @param in input data
* @return Trailing input data after the parse.
*/
StringRef Execute(StringRef in) {
return in.drop_front(
std::string_view Execute(std::string_view in) {
in.remove_prefix(
http_parser_execute(&m_parser, &m_settings, in.data(), in.size()));
return in;
}
/**
@@ -136,7 +138,7 @@ class HttpParser {
/**
* Get URL. Valid in and after the url callback has been called.
*/
StringRef GetUrl() const { return m_urlBuf; }
std::string_view GetUrl() const { return m_urlBuf.str(); }
/**
* Message begin callback.
@@ -148,7 +150,7 @@ class HttpParser {
*
* The parameter to the callback is the complete URL string.
*/
sig::Signal<StringRef> url;
sig::Signal<std::string_view> url;
/**
* Status callback.
@@ -156,14 +158,14 @@ class HttpParser {
* The parameter to the callback is the complete status string.
* GetStatusCode() can be used to get the numeric status code.
*/
sig::Signal<StringRef> status;
sig::Signal<std::string_view> status;
/**
* Header field callback.
*
* The parameters to the callback are the field name and field value.
*/
sig::Signal<StringRef, StringRef> header;
sig::Signal<std::string_view, std::string_view> header;
/**
* Headers complete callback.
@@ -183,7 +185,7 @@ class HttpParser {
* multiple times arbitrarily (e.g. it's possible that it may be called with
* just a few characters at a time).
*/
sig::Signal<StringRef, bool> body;
sig::Signal<std::string_view, bool> body;
/**
* Headers complete callback.

View File

@@ -6,11 +6,10 @@
#define WPIUTIL_WPI_HTTPSERVERCONNECTION_H_
#include <memory>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/HttpParser.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
#include "wpi/uv/Stream.h"
namespace wpi {
@@ -64,9 +63,9 @@ class HttpServerConnection {
* be set to false.
* @param extra Extra HTTP headers to send, including final "\r\n"
*/
virtual void BuildHeader(raw_ostream& os, int code, const Twine& codeText,
const Twine& contentType, uint64_t contentLength,
const Twine& extra = Twine{});
virtual void BuildHeader(raw_ostream& os, int code, std::string_view codeText,
std::string_view contentType, uint64_t contentLength,
std::string_view extra = {});
/**
* Send data to client.
@@ -91,9 +90,10 @@ class HttpServerConnection {
* @param content Response message content
* @param extraHeader Extra HTTP headers to send, including final "\r\n"
*/
virtual void SendResponse(int code, const Twine& codeText,
const Twine& contentType, StringRef content,
const Twine& extraHeader = Twine{});
virtual void SendResponse(int code, std::string_view codeText,
std::string_view contentType,
std::string_view content,
std::string_view extraHeader = {});
/**
* Send HTTP response from static data, along with other header information
@@ -109,10 +109,10 @@ class HttpServerConnection {
* @param gzipped True if content is gzip compressed
* @param extraHeader Extra HTTP headers to send, including final "\r\n"
*/
virtual void SendStaticResponse(int code, const Twine& codeText,
const Twine& contentType, StringRef content,
bool gzipped,
const Twine& extraHeader = Twine{});
virtual void SendStaticResponse(int code, std::string_view codeText,
std::string_view contentType,
std::string_view content, bool gzipped,
std::string_view extraHeader = {});
/**
* Send error header and message.
@@ -123,7 +123,7 @@ class HttpServerConnection {
* @param code HTTP error code (e.g. 404)
* @param message Additional message text
*/
virtual void SendError(int code, const Twine& message = Twine{});
virtual void SendError(int code, std::string_view message = {});
/** The HTTP request. */
HttpParser m_request{HttpParser::kRequest};

View File

@@ -9,6 +9,7 @@
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
@@ -17,8 +18,6 @@
#include "wpi/SmallString.h"
#include "wpi/SmallVector.h"
#include "wpi/StringMap.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
#include "wpi/raw_istream.h"
#include "wpi/raw_socket_istream.h"
#include "wpi/raw_socket_ostream.h"
@@ -29,15 +28,15 @@ namespace wpi {
// @param buf Buffer for output
// @param error Set to true if an error occurred
// @return Escaped string
StringRef UnescapeURI(const Twine& str, SmallVectorImpl<char>& buf,
bool* error);
std::string_view UnescapeURI(std::string_view str, SmallVectorImpl<char>& buf,
bool* error);
// Escape a string with %xx-encoding.
// @param buf Buffer for output
// @param spacePlus If true, encodes spaces to '+' rather than "%20"
// @return Escaped string
StringRef EscapeURI(const Twine& str, SmallVectorImpl<char>& buf,
bool spacePlus = true);
std::string_view EscapeURI(std::string_view str, SmallVectorImpl<char>& buf,
bool spacePlus = true);
// Parse a set of HTTP headers. Saves just the Content-Type and Content-Length
// fields.
@@ -55,7 +54,7 @@ bool ParseHttpHeaders(raw_istream& is, SmallVectorImpl<char>* contentType,
// @param saveBuf If not null, all scanned characters up to but not including
// the boundary are saved to this string
// @return False if error occurred on input stream, true if boundary found.
bool FindMultipartBoundary(wpi::raw_istream& is, StringRef boundary,
bool FindMultipartBoundary(wpi::raw_istream& is, std::string_view boundary,
std::string* saveBuf);
/**
@@ -77,7 +76,7 @@ class HttpQueryMap {
*
* @param query query string
*/
explicit HttpQueryMap(StringRef query);
explicit HttpQueryMap(std::string_view query);
/**
* Gets an element of the query string. Both the name and the returned
@@ -88,11 +87,11 @@ class HttpQueryMap {
* @return Optional unescaped value. Returns an empty optional if the
* name is not present in the query map.
*/
std::optional<StringRef> Get(StringRef name,
SmallVectorImpl<char>& buf) const;
std::optional<std::string_view> Get(std::string_view name,
SmallVectorImpl<char>& buf) const;
private:
StringMap<StringRef> m_elems;
StringMap<std::string_view> m_elems;
};
class HttpPathRef;
@@ -120,7 +119,7 @@ class HttpPath {
* Constructs a HTTP path from an escaped path string. Makes a copy of the
* path, so it's safe to be a temporary.
*/
explicit HttpPath(StringRef path);
explicit HttpPath(std::string_view path);
/**
* Evaluates to true if the path is not empty.
@@ -143,11 +142,15 @@ class HttpPath {
* @param match match list
* @return True if path equals match list
*/
bool equals(std::initializer_list<StringRef> match) const {
bool equals(std::initializer_list<std::string_view> match) const {
return equals(0, makeArrayRef(match.begin(), match.end()));
}
bool equals(ArrayRef<StringRef> match) const { return equals(0, match); }
bool equals(StringRef match) const { return equals(0, makeArrayRef(match)); }
bool equals(ArrayRef<std::string_view> match) const {
return equals(0, match);
}
bool equals(std::string_view match) const {
return equals(0, makeArrayRef(match));
}
/**
* Returns true if the elements of the path starting at the "start" element
@@ -157,16 +160,17 @@ class HttpPath {
* @param match match list
* @return True if match
*/
bool equals(size_t start, std::initializer_list<StringRef> match) const {
bool equals(size_t start,
std::initializer_list<std::string_view> match) const {
return equals(start, makeArrayRef(match.begin(), match.end()));
}
bool equals(size_t start, ArrayRef<StringRef> match) const {
bool equals(size_t start, ArrayRef<std::string_view> match) const {
if (m_pathEnds.size() != (start + match.size())) {
return false;
}
return startswith(start, match);
}
bool equals(size_t start, StringRef match) const {
bool equals(size_t start, std::string_view match) const {
return equals(start, makeArrayRef(match));
}
@@ -177,13 +181,13 @@ class HttpPath {
* @param match match list
* @return True if path starts with match list
*/
bool startswith(std::initializer_list<StringRef> match) const {
bool startswith(std::initializer_list<std::string_view> match) const {
return startswith(0, makeArrayRef(match.begin(), match.end()));
}
bool startswith(ArrayRef<StringRef> match) const {
bool startswith(ArrayRef<std::string_view> match) const {
return startswith(0, match);
}
bool startswith(StringRef match) const {
bool startswith(std::string_view match) const {
return startswith(0, makeArrayRef(match));
}
@@ -195,22 +199,21 @@ class HttpPath {
* @param match match list
* @return True if path starting at the start element matches the match list
*/
bool startswith(size_t start, std::initializer_list<StringRef> match) const {
bool startswith(size_t start,
std::initializer_list<std::string_view> match) const {
return startswith(start, makeArrayRef(match.begin(), match.end()));
}
bool startswith(size_t start, ArrayRef<StringRef> match) const;
bool startswith(size_t start, ArrayRef<std::string_view> match) const;
bool startswith(size_t start, StringRef match) const {
bool startswith(size_t start, std::string_view match) const {
return startswith(start, makeArrayRef(match));
}
/**
* Gets a single element of the path.
*/
StringRef operator[](size_t n) const {
return m_pathBuf.slice(n == 0 ? 0 : m_pathEnds[n - 1], m_pathEnds[n]);
}
std::string_view operator[](size_t n) const;
/**
* Returns a path reference with the first N elements of the path removed.
@@ -236,44 +239,50 @@ class HttpPathRef {
bool empty() const { return m_path && m_path->size() == m_start; }
size_t size() const { return m_path ? m_path->size() - m_start : 0; }
bool equals(std::initializer_list<StringRef> match) const {
bool equals(std::initializer_list<std::string_view> match) const {
return equals(0, makeArrayRef(match.begin(), match.end()));
}
bool equals(ArrayRef<StringRef> match) const { return equals(0, match); }
bool equals(StringRef match) const { return equals(0, makeArrayRef(match)); }
bool equals(ArrayRef<std::string_view> match) const {
return equals(0, match);
}
bool equals(std::string_view match) const {
return equals(0, makeArrayRef(match));
}
bool equals(size_t start, std::initializer_list<StringRef> match) const {
bool equals(size_t start,
std::initializer_list<std::string_view> match) const {
return equals(start, makeArrayRef(match.begin(), match.end()));
}
bool equals(size_t start, ArrayRef<StringRef> match) const {
bool equals(size_t start, ArrayRef<std::string_view> match) const {
return m_path ? m_path->equals(m_start + start, match) : false;
}
bool equals(size_t start, StringRef match) const {
bool equals(size_t start, std::string_view match) const {
return equals(start, makeArrayRef(match));
}
bool startswith(std::initializer_list<StringRef> match) const {
bool startswith(std::initializer_list<std::string_view> match) const {
return startswith(0, makeArrayRef(match.begin(), match.end()));
}
bool startswith(ArrayRef<StringRef> match) const {
bool startswith(ArrayRef<std::string_view> match) const {
return startswith(0, match);
}
bool startswith(StringRef match) const {
bool startswith(std::string_view match) const {
return startswith(0, makeArrayRef(match));
}
bool startswith(size_t start, std::initializer_list<StringRef> match) const {
bool startswith(size_t start,
std::initializer_list<std::string_view> match) const {
return startswith(start, makeArrayRef(match.begin(), match.end()));
}
bool startswith(size_t start, ArrayRef<StringRef> match) const {
bool startswith(size_t start, ArrayRef<std::string_view> match) const {
return m_path ? m_path->startswith(m_start + start, match) : false;
}
bool startswith(size_t start, StringRef match) const {
bool startswith(size_t start, std::string_view match) const {
return startswith(start, makeArrayRef(match));
}
StringRef operator[](size_t n) const {
return m_path ? m_path->operator[](m_start + n) : StringRef{};
std::string_view operator[](size_t n) const {
return m_path ? m_path->operator[](m_start + n) : std::string_view{};
}
HttpPathRef drop_front(size_t n) const {
return m_path ? m_path->drop_front(m_start + n) : HttpPathRef{};
@@ -287,7 +296,7 @@ class HttpPathRef {
class HttpLocation {
public:
HttpLocation() = default;
HttpLocation(const Twine& url_, bool* error, std::string* errorMsg);
HttpLocation(std::string_view url_, bool* error, std::string* errorMsg);
std::string url; // retain copy
std::string user; // unescaped
@@ -312,13 +321,13 @@ class HttpRequest {
template <typename T>
HttpRequest(const HttpLocation& loc, const T& extraParams);
HttpRequest(const HttpLocation& loc, StringRef path_)
HttpRequest(const HttpLocation& loc, std::string_view path_)
: host{loc.host}, port{loc.port}, path{path_} {
SetAuth(loc);
}
template <typename T>
HttpRequest(const HttpLocation& loc, StringRef path_, const T& params)
HttpRequest(const HttpLocation& loc, std::string_view path_, const T& params)
: host{loc.host}, port{loc.port} {
SetPath(path_, params);
SetAuth(loc);
@@ -332,18 +341,18 @@ class HttpRequest {
private:
void SetAuth(const HttpLocation& loc);
template <typename T>
void SetPath(StringRef path_, const T& params);
void SetPath(std::string_view path_, const T& params);
template <typename T>
static StringRef GetFirst(const T& elem) {
static std::string_view GetFirst(const T& elem) {
return elem.first;
}
template <typename T>
static StringRef GetFirst(const StringMapEntry<T>& elem) {
static std::string_view GetFirst(const StringMapEntry<T>& elem) {
return elem.getKey();
}
template <typename T>
static StringRef GetSecond(const T& elem) {
static std::string_view GetSecond(const T& elem) {
return elem.second;
}
};
@@ -368,14 +377,15 @@ class HttpConnection {
class HttpMultipartScanner {
public:
explicit HttpMultipartScanner(StringRef boundary, bool saveSkipped = false) {
explicit HttpMultipartScanner(std::string_view boundary,
bool saveSkipped = false) {
Reset(saveSkipped);
SetBoundary(boundary);
}
// Change the boundary. This is only safe to do when IsDone() is true (or
// immediately after construction).
void SetBoundary(StringRef boundary);
void SetBoundary(std::string_view boundary);
// Reset the scanner. This allows reuse of internal buffers.
void Reset(bool saveSkipped = false);
@@ -384,14 +394,14 @@ class HttpMultipartScanner {
// is true.
// @param in input data
// @return the input not consumed; empty if all input consumed
StringRef Execute(StringRef in);
std::string_view Execute(std::string_view in);
// Returns true when the boundary has been found.
bool IsDone() const { return m_state == kDone; }
// Get the skipped data. Will be empty if saveSkipped was false.
StringRef GetSkipped() const {
return m_saveSkipped ? StringRef{m_buf} : StringRef{};
std::string_view GetSkipped() const {
return m_saveSkipped ? std::string_view{m_buf} : std::string_view{};
}
private:

View File

@@ -18,7 +18,7 @@ inline HttpPathRef HttpPath::drop_front(size_t n) const {
template <typename T>
HttpRequest::HttpRequest(const HttpLocation& loc, const T& extraParams)
: host{loc.host}, port{loc.port} {
StringMap<StringRef> params;
StringMap<std::string_view> params;
for (const auto& p : loc.params) {
params.insert(std::make_pair(GetFirst(p), GetSecond(p)));
}
@@ -30,7 +30,7 @@ HttpRequest::HttpRequest(const HttpLocation& loc, const T& extraParams)
}
template <typename T>
void HttpRequest::SetPath(StringRef path_, const T& params) {
void HttpRequest::SetPath(std::string_view path_, const T& params) {
// Build location including query string
raw_svector_ostream pathOs{path};
pathOs << path_;

View File

@@ -8,11 +8,11 @@
#include <initializer_list>
#include <memory>
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/HttpServerConnection.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/WebSocket.h"
#include "wpi/WebSocketServer.h"
#include "wpi/uv/Stream.h"
@@ -36,7 +36,7 @@ class HttpWebSocketServerConnection
* @param protocols Acceptable subprotocols
*/
HttpWebSocketServerConnection(std::shared_ptr<uv::Stream> stream,
ArrayRef<StringRef> protocols);
ArrayRef<std::string_view> protocols);
/**
* Constructor.
@@ -44,8 +44,9 @@ class HttpWebSocketServerConnection
* @param stream network stream
* @param protocols Acceptable subprotocols
*/
HttpWebSocketServerConnection(std::shared_ptr<uv::Stream> stream,
std::initializer_list<StringRef> protocols)
HttpWebSocketServerConnection(
std::shared_ptr<uv::Stream> stream,
std::initializer_list<std::string_view> protocols)
: HttpWebSocketServerConnection(
stream, makeArrayRef(protocols.begin(), protocols.end())) {}
@@ -59,7 +60,7 @@ class HttpWebSocketServerConnection
*
* @param protocol negotiated subprotocol
*/
virtual bool IsValidWsUpgrade(StringRef protocol) { return true; }
virtual bool IsValidWsUpgrade(std::string_view protocol) { return true; }
/**
* Process an incoming WebSocket upgrade. This is called after the header

View File

@@ -13,15 +13,16 @@ namespace wpi {
template <typename Derived>
HttpWebSocketServerConnection<Derived>::HttpWebSocketServerConnection(
std::shared_ptr<uv::Stream> stream, ArrayRef<StringRef> protocols)
std::shared_ptr<uv::Stream> stream, ArrayRef<std::string_view> protocols)
: HttpServerConnection{stream},
m_helper{m_request},
m_protocols{protocols.begin(), protocols.end()} {
// Handle upgrade event
m_helper.upgrade.connect([this] {
// Negotiate sub-protocol
SmallVector<StringRef, 2> protocols{m_protocols.begin(), m_protocols.end()};
StringRef protocol = m_helper.MatchProtocol(protocols).second;
SmallVector<std::string_view, 2> protocols{m_protocols.begin(),
m_protocols.end()};
std::string_view protocol = m_helper.MatchProtocol(protocols).second;
// Check that the upgrade is valid
if (!IsValidWsUpgrade(protocol)) {

View File

@@ -8,8 +8,7 @@
#include <functional>
#include <utility>
#include "wpi/SmallString.h"
#include "wpi/raw_ostream.h"
#include "fmt/format.h"
namespace wpi {
@@ -40,12 +39,19 @@ class Logger {
void set_min_level(unsigned int level) { m_min_level = level; }
unsigned int min_level() const { return m_min_level; }
void DoLog(unsigned int level, const char* file, unsigned int line,
const char* msg);
void LogV(unsigned int level, const char* file, unsigned int line,
fmt::string_view format, fmt::format_args args);
template <typename S, typename... Args>
void Log(unsigned int level, const char* file, unsigned int line,
const char* msg) {
if (!m_func || level < m_min_level) {
return;
const S& format, Args&&... args) {
if (m_func && level >= m_min_level) {
LogV(level, file, line, format,
fmt::make_args_checked<Args...>(format, args...));
}
m_func(level, file, line, msg);
}
bool HasLogger() const { return m_func != nullptr; }
@@ -55,44 +61,43 @@ class Logger {
unsigned int m_min_level = 20;
};
#define WPI_LOG(logger_inst, level, x) \
do { \
::wpi::Logger& WPI_logger_ = logger_inst; \
if (WPI_logger_.min_level() <= static_cast<unsigned int>(level) && \
WPI_logger_.HasLogger()) { \
::wpi::SmallString<128> log_buf_; \
::wpi::raw_svector_ostream log_os_{log_buf_}; \
log_os_ << x; \
WPI_logger_.Log(level, __FILE__, __LINE__, log_buf_.c_str()); \
} \
} while (0)
#define WPI_LOG(logger_inst, level, format, ...) \
logger_inst.Log(level, __FILE__, __LINE__, FMT_STRING(format), __VA_ARGS__)
#define WPI_ERROR(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_ERROR, x)
#define WPI_WARNING(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_WARNING, x)
#define WPI_INFO(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_INFO, x)
#define WPI_ERROR(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_ERROR, format, __VA_ARGS__)
#define WPI_WARNING(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_WARNING, format, __VA_ARGS__)
#define WPI_INFO(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_INFO, format, __VA_ARGS__)
#ifdef NDEBUG
#define WPI_DEBUG(inst, x) \
do { \
#define WPI_DEBUG(inst, format, ...) \
do { \
} while (0)
#define WPI_DEBUG1(inst, x) \
do { \
#define WPI_DEBUG1(inst, format, ...) \
do { \
} while (0)
#define WPI_DEBUG2(inst, x) \
do { \
#define WPI_DEBUG2(inst, format, ...) \
do { \
} while (0)
#define WPI_DEBUG3(inst, x) \
do { \
#define WPI_DEBUG3(inst, format, ...) \
do { \
} while (0)
#define WPI_DEBUG4(inst, x) \
do { \
#define WPI_DEBUG4(inst, format, ...) \
do { \
} while (0)
#else
#define WPI_DEBUG(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG, x)
#define WPI_DEBUG1(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG1, x)
#define WPI_DEBUG2(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG2, x)
#define WPI_DEBUG3(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG3, x)
#define WPI_DEBUG4(inst, x) WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG4, x)
#define WPI_DEBUG(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG, format, __VA_ARGS__)
#define WPI_DEBUG1(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG1, format, __VA_ARGS__)
#define WPI_DEBUG2(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG2, format, __VA_ARGS__)
#define WPI_DEBUG3(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG3, format, __VA_ARGS__)
#define WPI_DEBUG4(inst, format, ...) \
WPI_LOG(inst, ::wpi::WPI_LOG_DEBUG4, format, __VA_ARGS__)
#endif
} // namespace wpi

View File

@@ -5,11 +5,11 @@
#ifndef WPIUTIL_WPI_MIMETYPES_H_
#define WPIUTIL_WPI_MIMETYPES_H_
#include "wpi/StringRef.h"
#include <string_view>
namespace wpi {
StringRef MimeTypeFromPath(StringRef path);
std::string_view MimeTypeFromPath(std::string_view path);
} // namespace wpi

View File

@@ -1,49 +0,0 @@
//===- NativeFormatting.h - Low level formatting helpers ---------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_NATIVE_FORMATTING_H
#define WPIUTIL_WPI_NATIVE_FORMATTING_H
#include "wpi/raw_ostream.h"
#include <cstdint>
#include <optional>
namespace wpi {
enum class FloatStyle { Exponent, ExponentUpper, Fixed, Percent };
enum class IntegerStyle {
Integer,
Number,
};
enum class HexPrintStyle { Upper, Lower, PrefixUpper, PrefixLower };
size_t getDefaultPrecision(FloatStyle Style);
bool isPrefixedHexStyle(HexPrintStyle S);
void write_integer(raw_ostream &S, unsigned int N, size_t MinDigits,
IntegerStyle Style);
void write_integer(raw_ostream &S, int N, size_t MinDigits, IntegerStyle Style);
void write_integer(raw_ostream &S, unsigned long N, size_t MinDigits,
IntegerStyle Style);
void write_integer(raw_ostream &S, long N, size_t MinDigits,
IntegerStyle Style);
void write_integer(raw_ostream &S, unsigned long long N, size_t MinDigits,
IntegerStyle Style);
void write_integer(raw_ostream &S, long long N, size_t MinDigits,
IntegerStyle Style);
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style,
std::optional<size_t> Width = std::nullopt);
void write_double(raw_ostream &S, double D, FloatStyle Style,
std::optional<size_t> Precision = std::nullopt);
}
#endif

View File

@@ -6,8 +6,7 @@
#define WPIUTIL_WPI_NETWORKSTREAM_H_
#include <cstddef>
#include "wpi/StringRef.h"
#include <string_view>
namespace wpi {
@@ -28,7 +27,7 @@ class NetworkStream {
int timeout = 0) = 0;
virtual void close() = 0;
virtual StringRef getPeerIP() const = 0;
virtual std::string_view getPeerIP() const = 0;
virtual int getPeerPort() const = 0;
virtual void setNoDelay() = 0;

View File

@@ -8,8 +8,7 @@
#pragma once
#include <memory>
#include "wpi/Twine.h"
#include <string_view>
namespace wpi {
@@ -38,7 +37,8 @@ class PortForwarder {
* @param remoteHost remote IP address / DNS name
* @param remotePort remote port number
*/
void Add(unsigned int port, const Twine& remoteHost, unsigned int remotePort);
void Add(unsigned int port, std::string_view remoteHost,
unsigned int remotePort);
/**
* Stop TCP forwarding on a port.

View File

@@ -15,8 +15,8 @@
#define WPIUTIL_WPI_SMALLSTRING_H
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include <cstddef>
#include <string_view>
namespace wpi {
@@ -28,8 +28,9 @@ public:
/// Default ctor - Initialize to empty.
SmallString() = default;
/// Initialize from a StringRef.
SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
/// Initialize from a std::string_view.
SmallString(std::string_view S)
: SmallVector<char, InternalLen>(S.begin(), S.end()) {}
/// Initialize with a range.
template<typename ItTy>
@@ -54,8 +55,8 @@ public:
SmallVectorImpl<char>::append(S, E);
}
/// Assign from a StringRef.
void assign(StringRef RHS) {
/// Assign from a std::string_view.
void assign(std::string_view RHS) {
this->clear();
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
@@ -80,8 +81,8 @@ public:
SmallVectorImpl<char>::append(NumInputs, Elt);
}
/// Append from a StringRef.
void append(StringRef RHS) {
/// Append from a std::string_view.
void append(std::string_view RHS) {
SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
}
@@ -94,48 +95,12 @@ public:
/// @name String Comparison
/// @{
/// Check for string equality. This is more efficient than compare() when
/// the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
return str().equals(RHS);
}
/// Check for string equality, ignoring case.
bool equals_lower(StringRef RHS) const {
return str().equals_lower(RHS);
}
/// Compare two strings; the result is -1, 0, or 1 if this string is
/// lexicographically less than, equal to, or greater than the \p RHS.
int compare(StringRef RHS) const {
int compare(std::string_view RHS) const {
return str().compare(RHS);
}
/// compare_lower - Compare two strings, ignoring case.
int compare_lower(StringRef RHS) const {
return str().compare_lower(RHS);
}
/// compare_numeric - Compare two strings, treating sequences of digits as
/// numbers.
int compare_numeric(StringRef RHS) const {
return str().compare_numeric(RHS);
}
/// @}
/// @name String Predicates
/// @{
/// startswith - Check if this string starts with the given \p Prefix.
bool startswith(StringRef Prefix) const {
return str().startswith(Prefix);
}
/// endswith - Check if this string ends with the given \p Suffix.
bool endswith(StringRef Suffix) const {
return str().endswith(Suffix);
}
/// @}
/// @name String Searching
/// @{
@@ -152,7 +117,7 @@ public:
///
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
size_t find(StringRef Str, size_t From = 0) const {
size_t find(std::string_view Str, size_t From = 0) const {
return str().find(Str, From);
}
@@ -160,7 +125,7 @@ public:
///
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
size_t rfind(char C, size_t From = StringRef::npos) const {
size_t rfind(char C, size_t From = std::string_view::npos) const {
return str().rfind(C, From);
}
@@ -168,7 +133,7 @@ public:
///
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
size_t rfind(StringRef Str) const {
size_t rfind(std::string_view Str) const {
return str().rfind(Str);
}
@@ -182,7 +147,7 @@ public:
/// not found.
///
/// Complexity: O(size() + Chars.size())
size_t find_first_of(StringRef Chars, size_t From = 0) const {
size_t find_first_of(std::string_view Chars, size_t From = 0) const {
return str().find_first_of(Chars, From);
}
@@ -196,13 +161,13 @@ public:
/// \p Chars, or npos if not found.
///
/// Complexity: O(size() + Chars.size())
size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
size_t find_first_not_of(std::string_view Chars, size_t From = 0) const {
return str().find_first_not_of(Chars, From);
}
/// Find the last character in the string that is \p C, or npos if not
/// found.
size_t find_last_of(char C, size_t From = StringRef::npos) const {
size_t find_last_of(char C, size_t From = std::string_view::npos) const {
return str().find_last_of(C, From);
}
@@ -211,25 +176,10 @@ public:
///
/// Complexity: O(size() + Chars.size())
size_t find_last_of(
StringRef Chars, size_t From = StringRef::npos) const {
std::string_view Chars, size_t From = std::string_view::npos) const {
return str().find_last_of(Chars, From);
}
/// @}
/// @name Helpful Algorithms
/// @{
/// Return the number of occurrences of \p C in the string.
size_t count(char C) const {
return str().count(C);
}
/// Return the number of non-overlapped occurrences of \p Str in the
/// string.
size_t count(StringRef Str) const {
return str().count(Str);
}
/// @}
/// @name Substring Operations
/// @{
@@ -243,28 +193,17 @@ public:
/// \param N The number of characters to included in the substring. If \p N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \p Start) will be returned.
StringRef substr(size_t Start, size_t N = StringRef::npos) const {
std::string_view substr(size_t Start, size_t N = std::string_view::npos) const {
return str().substr(Start, N);
}
/// Return a reference to the substring from [Start, End).
///
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End The index following the last character to include in the
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \p Start) will be returned.
StringRef slice(size_t Start, size_t End) const {
return str().slice(Start, End);
}
// Extra methods.
/// Explicit conversion to StringRef.
StringRef str() const { return StringRef(this->begin(), this->size()); }
/// Explicit conversion to std::string_view.
std::string_view str() const { return {this->begin(), this->size()}; }
/// Explicit conversion to std::string.
std::string string() const { return {this->begin(), this->size()}; }
// TODO: Make this const, if it's safe...
const char* c_str() {
@@ -273,16 +212,19 @@ public:
return this->data();
}
/// Implicit conversion to StringRef.
operator StringRef() const { return str(); }
/// Implicit conversion to std::string_view.
operator std::string_view() const { return str(); }
/// Implicit conversion to std::string.
operator std::string() const { return string(); }
// Extra operators.
const SmallString &operator=(StringRef RHS) {
const SmallString &operator=(std::string_view RHS) {
this->clear();
return *this += RHS;
}
SmallString &operator+=(StringRef RHS) {
SmallString &operator+=(std::string_view RHS) {
this->append(RHS.begin(), RHS.end());
return *this;
}

View File

@@ -15,7 +15,6 @@
#define WPIUTIL_WPI_STRINGMAP_H
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/iterator.h"
#include "wpi/iterator_range.h"
#include "wpi/MemAlloc.h"
@@ -29,6 +28,7 @@
#include <cstring>
#include <initializer_list>
#include <iterator>
#include <string_view>
#include <utility>
namespace wpi {
@@ -82,12 +82,12 @@ protected:
/// specified bucket will be non-null. Otherwise, it will be null. In either
/// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string.
unsigned LookupBucketFor(StringRef Key);
unsigned LookupBucketFor(std::string_view Key);
/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key. Otherwise return -1.
/// This does not modify the map.
int FindKey(StringRef Key) const;
int FindKey(std::string_view Key) const;
/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
/// delete it. This aborts if the value isn't in the table.
@@ -95,7 +95,7 @@ protected:
/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null.
StringMapEntryBase *RemoveKey(StringRef Key);
StringMapEntryBase *RemoveKey(std::string_view Key);
/// Allocate the table with the specified number of buckets and otherwise
/// setup the map as empty.
@@ -137,8 +137,8 @@ public:
: StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
StringMapEntry(StringMapEntry &E) = delete;
StringRef getKey() const {
return StringRef(getKeyData(), getKeyLength());
std::string_view getKey() const {
return {getKeyData(), getKeyLength()};
}
const ValueTy &getValue() const { return second; }
@@ -151,12 +151,12 @@ public:
/// StringMapEntry object.
const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
std::string_view first() const { return {getKeyData(), getKeyLength()}; }
/// Create a StringMapEntry for the specified key construct the value using
/// \p InitiVals.
template <typename... InitTy>
static StringMapEntry *Create(StringRef Key, InitTy &&... InitVals) {
static StringMapEntry *Create(std::string_view Key, InitTy &&... InitVals) {
size_t KeyLength = Key.size();
// Allocate a new item with space for the string at the end and a null
@@ -177,7 +177,7 @@ public:
return NewItem;
}
static StringMapEntry *Create(StringRef Key) {
static StringMapEntry *Create(std::string_view Key) {
return Create(Key, ValueTy());
}
@@ -212,7 +212,7 @@ public:
explicit StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
StringMap(std::initializer_list<std::pair<std::string_view, ValueTy>> List)
: StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
for (const auto &P : List) {
insert(P);
@@ -302,13 +302,13 @@ public:
StringMapKeyIterator<ValueTy>(end()));
}
iterator find(StringRef Key) {
iterator find(std::string_view Key) {
int Bucket = FindKey(Key);
if (Bucket == -1) return end();
return iterator(TheTable+Bucket, true);
}
const_iterator find(StringRef Key) const {
const_iterator find(std::string_view Key) const {
int Bucket = FindKey(Key);
if (Bucket == -1) return end();
return const_iterator(TheTable+Bucket, true);
@@ -316,7 +316,7 @@ public:
/// lookup - Return the entry for the specified key, or a default
/// constructed value if no such entry exists.
ValueTy lookup(StringRef Key) const {
ValueTy lookup(std::string_view Key) const {
const_iterator it = find(Key);
if (it != end())
return it->second;
@@ -325,10 +325,10 @@ public:
/// Lookup the ValueTy for the \p Key, or create a default constructed value
/// if the key is not in the map.
ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
ValueTy &operator[](std::string_view Key) { return try_emplace(Key).first->second; }
/// count - Return 1 if the element is in the map, 0 otherwise.
size_type count(StringRef Key) const {
size_type count(std::string_view Key) const {
return find(Key) == end() ? 0 : 1;
}
@@ -355,7 +355,7 @@ public:
/// isn't already in the map. The bool component of the returned pair is true
/// if and only if the insertion takes place, and the iterator component of
/// the pair points to the element with key equivalent to the key of the pair.
std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
std::pair<iterator, bool> insert(std::pair<std::string_view, ValueTy> KV) {
return try_emplace(KV.first, std::move(KV.second));
}
@@ -364,7 +364,7 @@ public:
/// if and only if the insertion takes place, and the iterator component of
/// the pair points to the element with key equivalent to the key of the pair.
template <typename... ArgsTy>
std::pair<iterator, bool> try_emplace(StringRef Key, ArgsTy &&... Args) {
std::pair<iterator, bool> try_emplace(std::string_view Key, ArgsTy &&... Args) {
unsigned BucketNo = LookupBucketFor(Key);
StringMapEntryBase *&Bucket = TheTable[BucketNo];
if (Bucket && Bucket != getTombstoneVal())
@@ -411,7 +411,7 @@ public:
V.Destroy();
}
bool erase(StringRef Key) {
bool erase(std::string_view Key) {
iterator I = find(Key);
if (I == end()) return false;
erase(I);
@@ -524,23 +524,23 @@ template <typename ValueTy>
class StringMapKeyIterator
: public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
StringMapConstIterator<ValueTy>,
std::forward_iterator_tag, StringRef> {
std::forward_iterator_tag, std::string_view> {
using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
StringMapConstIterator<ValueTy>,
std::forward_iterator_tag, StringRef>;
std::forward_iterator_tag, std::string_view>;
public:
StringMapKeyIterator() = default;
explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
: base(std::move(Iter)) {}
StringRef &operator*() {
std::string_view &operator*() {
Key = this->wrapped()->getKey();
return Key;
}
private:
StringRef Key;
std::string_view Key;
};
template <typename ValueTy>
@@ -594,13 +594,13 @@ bool operator<(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
if (&lhs == &rhs) return false;
// copy into vectors and sort by key
SmallVector<StringRef, 16> lhs_keys;
SmallVector<std::string_view, 16> lhs_keys;
lhs_keys.reserve(lhs.size());
for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
lhs_keys.push_back(i->getKey());
std::sort(lhs_keys.begin(), lhs_keys.end());
SmallVector<StringRef, 16> rhs_keys;
SmallVector<std::string_view, 16> rhs_keys;
rhs_keys.reserve(rhs.size());
for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
rhs_keys.push_back(i->getKey());

View File

@@ -1,956 +0,0 @@
//===- StringRef.h - Constant String Reference Wrapper ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_STRINGREF_H
#define WPIUTIL_WPI_STRINGREF_H
#include "wpi/STLExtras.h"
#include "wpi/iterator_range.h"
#include "wpi/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iosfwd>
#include <limits>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
namespace wpi {
class hash_code;
template <typename T> class SmallVectorImpl;
class StringRef;
/// Helper functions for StringRef::getAsInteger.
bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
unsigned long long &Result) noexcept;
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result) noexcept;
bool consumeUnsignedInteger(StringRef &Str, unsigned Radix,
unsigned long long &Result) noexcept;
bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result) noexcept;
/// StringRef - Represent a constant reference to a string, i.e. a character
/// array and a length, which need not be null terminated.
///
/// This class does not own the string data, it is expected to be used in
/// situations where the character data resides in some other buffer, whose
/// lifetime extends past that of the StringRef. For this reason, it is not in
/// general safe to store a StringRef.
class StringRef {
public:
static const size_t npos = ~size_t(0);
using iterator = const char *;
using const_iterator = const char *;
using size_type = size_t;
private:
/// The start of the string, in an external buffer.
const char *Data = nullptr;
/// The length of the string.
size_t Length = 0;
// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
LLVM_ATTRIBUTE_ALWAYS_INLINE
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) noexcept {
if (Length == 0) { return 0; }
return ::memcmp(Lhs,Rhs,Length);
}
public:
/// @name Constructors
/// @{
/// Construct an empty string ref.
/*implicit*/ StringRef() = default;
/// Disable conversion from nullptr. This prevents things like
/// if (S == nullptr)
StringRef(std::nullptr_t) = delete;
/// Construct a string ref from a cstring.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const char *Str) noexcept
: Data(Str), Length(Str ? ::strlen(Str) : 0) {}
/// Construct a string ref from a pointer and length.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ constexpr StringRef(const char *data, size_t length) noexcept
: Data(data), Length(length) {}
/// Construct a string ref from an std::string.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const std::string &Str) noexcept
: Data(Str.data()), Length(Str.length()) {}
/// Construct a string ref from an std::string_view.
/*implicit*/ constexpr StringRef(std::string_view Str)
: Data(Str.data()), Length(Str.size()) {}
static StringRef withNullAsEmpty(const char *data) noexcept {
return StringRef(data ? data : "");
}
/// @}
/// @name Iterators
/// @{
iterator begin() const noexcept { return Data; }
iterator end() const noexcept { return Data + Length; }
const unsigned char *bytes_begin() const noexcept {
return reinterpret_cast<const unsigned char *>(begin());
}
const unsigned char *bytes_end() const noexcept {
return reinterpret_cast<const unsigned char *>(end());
}
iterator_range<const unsigned char *> bytes() const noexcept {
return make_range(bytes_begin(), bytes_end());
}
/// @}
/// @name String Operations
/// @{
/// data - Get a pointer to the start of the string (which may not be null
/// terminated).
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
const char *data() const noexcept { return Data; }
/// empty - Check if the string is empty.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool empty() const noexcept { return Length == 0; }
/// size - Get the string size.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t size() const noexcept { return Length; }
/// front - Get the first character in the string.
LLVM_NODISCARD
char front() const noexcept {
assert(!empty());
return Data[0];
}
/// back - Get the last character in the string.
LLVM_NODISCARD
char back() const noexcept {
assert(!empty());
return Data[Length-1];
}
// copy - Allocate copy in Allocator and return StringRef to it.
template <typename Allocator>
LLVM_NODISCARD StringRef copy(Allocator &A) const {
// Don't request a length 0 copy from the allocator.
if (empty())
return StringRef();
char *S = A.template Allocate<char>(Length);
std::copy(begin(), end(), S);
return StringRef(S, Length);
}
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool equals(StringRef RHS) const noexcept {
return (Length == RHS.Length &&
compareMemory(Data, RHS.Data, RHS.Length) == 0);
}
/// equals_lower - Check for string equality, ignoring case.
LLVM_NODISCARD
bool equals_lower(StringRef RHS) const noexcept {
return Length == RHS.Length && compare_lower(RHS) == 0;
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \p RHS.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
int compare(StringRef RHS) const noexcept {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, (std::min)(Length, RHS.Length)))
return Res < 0 ? -1 : 1;
// Otherwise the prefixes match, so we only need to check the lengths.
if (Length == RHS.Length)
return 0;
return Length < RHS.Length ? -1 : 1;
}
/// compare_lower - Compare two strings, ignoring case.
LLVM_NODISCARD
int compare_lower(StringRef RHS) const noexcept;
/// compare_numeric - Compare two strings, treating sequences of digits as
/// numbers.
LLVM_NODISCARD
int compare_numeric(StringRef RHS) const noexcept;
/// str - Get the contents as an std::string.
LLVM_NODISCARD
std::string str() const {
if (!Data) return std::string();
return std::string(Data, Length);
}
/// @}
/// @name Operator Overloads
/// @{
LLVM_NODISCARD
char operator[](size_t Index) const noexcept {
assert(Index < Length && "Invalid index!");
return Data[Index];
}
/// Disallow accidental assignment from a temporary std::string.
///
/// The declaration here is extra complicated so that `stringRef = {}`
/// and `stringRef = "abc"` continue to select the move assignment operator.
template <typename T>
typename std::enable_if<std::is_same<T, std::string>::value,
StringRef>::type &
operator=(T &&Str) = delete;
/// @}
/// @name Type Conversions
/// @{
operator std::string() const {
return str();
}
operator std::string_view() const {
return std::string_view(data(), size());
}
/// @}
/// @name String Predicates
/// @{
/// Check if this string starts with the given \p Prefix.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool startswith(StringRef Prefix) const noexcept {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
}
/// Check if this string starts with the given \p Prefix, ignoring case.
LLVM_NODISCARD
bool startswith_lower(StringRef Prefix) const noexcept;
/// Check if this string ends with the given \p Suffix.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool endswith(StringRef Suffix) const noexcept {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
}
/// Check if this string ends with the given \p Suffix, ignoring case.
LLVM_NODISCARD
bool endswith_lower(StringRef Suffix) const noexcept;
/// @}
/// @name String Searching
/// @{
/// Search for the first character \p C in the string.
///
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t find(char C, size_t From = 0) const noexcept {
size_t FindBegin = (std::min)(From, Length);
if (FindBegin < Length) { // Avoid calling memchr with nullptr.
// Just forward to memchr, which is faster than a hand-rolled loop.
if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin))
return static_cast<const char *>(P) - Data;
}
return npos;
}
/// Search for the first character \p C in the string, ignoring case.
///
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
LLVM_NODISCARD
size_t find_lower(char C, size_t From = 0) const noexcept;
/// Search for the first character satisfying the predicate \p F
///
/// \returns The index of the first character satisfying \p F starting from
/// \p From, or npos if not found.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t find_if(function_ref<bool(char)> F, size_t From = 0) const noexcept {
StringRef S = drop_front(From);
while (!S.empty()) {
if (F(S.front()))
return size() - S.size();
S = S.drop_front();
}
return npos;
}
/// Search for the first character not satisfying the predicate \p F
///
/// \returns The index of the first character not satisfying \p F starting
/// from \p From, or npos if not found.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const noexcept {
return find_if([F](char c) { return !F(c); }, From);
}
/// Search for the first string \p Str in the string.
///
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
LLVM_NODISCARD
size_t find(StringRef Str, size_t From = 0) const noexcept;
/// Search for the first string \p Str in the string, ignoring case.
///
/// \returns The index of the first occurrence of \p Str, or npos if not
/// found.
LLVM_NODISCARD
size_t find_lower(StringRef Str, size_t From = 0) const noexcept;
/// Search for the last character \p C in the string.
///
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
LLVM_NODISCARD
size_t rfind(char C, size_t From = npos) const noexcept {
From = (std::min)(From, Length);
size_t i = From;
while (i != 0) {
--i;
if (Data[i] == C)
return i;
}
return npos;
}
/// Search for the last character \p C in the string, ignoring case.
///
/// \returns The index of the last occurrence of \p C, or npos if not
/// found.
LLVM_NODISCARD
size_t rfind_lower(char C, size_t From = npos) const noexcept;
/// Search for the last string \p Str in the string.
///
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
LLVM_NODISCARD
size_t rfind(StringRef Str) const noexcept;
/// Search for the last string \p Str in the string, ignoring case.
///
/// \returns The index of the last occurrence of \p Str, or npos if not
/// found.
LLVM_NODISCARD
size_t rfind_lower(StringRef Str) const noexcept;
/// Find the first character in the string that is \p C, or npos if not
/// found. Same as find.
LLVM_NODISCARD
size_t find_first_of(char C, size_t From = 0) const noexcept {
return find(C, From);
}
/// Find the first character in the string that is in \p Chars, or npos if
/// not found.
///
/// Complexity: O(size() + Chars.size())
LLVM_NODISCARD
size_t find_first_of(StringRef Chars, size_t From = 0) const noexcept;
/// Find the first character in the string that is not \p C or npos if not
/// found.
LLVM_NODISCARD
size_t find_first_not_of(char C, size_t From = 0) const noexcept;
/// Find the first character in the string that is not in the string
/// \p Chars, or npos if not found.
///
/// Complexity: O(size() + Chars.size())
LLVM_NODISCARD
size_t find_first_not_of(StringRef Chars, size_t From = 0) const noexcept;
/// Find the last character in the string that is \p C, or npos if not
/// found.
LLVM_NODISCARD
size_t find_last_of(char C, size_t From = npos) const noexcept {
return rfind(C, From);
}
/// Find the last character in the string that is in \p C, or npos if not
/// found.
///
/// Complexity: O(size() + Chars.size())
LLVM_NODISCARD
size_t find_last_of(StringRef Chars, size_t From = npos) const noexcept;
/// Find the last character in the string that is not \p C, or npos if not
/// found.
LLVM_NODISCARD
size_t find_last_not_of(char C, size_t From = npos) const noexcept;
/// Find the last character in the string that is not in \p Chars, or
/// npos if not found.
///
/// Complexity: O(size() + Chars.size())
LLVM_NODISCARD
size_t find_last_not_of(StringRef Chars, size_t From = npos) const noexcept;
/// Return true if the given string is a substring of *this, and false
/// otherwise.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool contains(StringRef Other) const noexcept { return find(Other) != npos; }
/// Return true if the given character is contained in *this, and false
/// otherwise.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool contains(char C) const noexcept { return find_first_of(C) != npos; }
/// Return true if the given string is a substring of *this, and false
/// otherwise.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool contains_lower(StringRef Other) const noexcept {
return find_lower(Other) != npos;
}
/// Return true if the given character is contained in *this, and false
/// otherwise.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool contains_lower(char C) const noexcept { return find_lower(C) != npos; }
/// @}
/// @name Helpful Algorithms
/// @{
/// Return the number of occurrences of \p C in the string.
LLVM_NODISCARD
size_t count(char C) const noexcept {
size_t Count = 0;
for (size_t i = 0, e = Length; i != e; ++i)
if (Data[i] == C)
++Count;
return Count;
}
/// Return the number of non-overlapped occurrences of \p Str in
/// the string.
size_t count(StringRef Str) const noexcept;
/// Parse the current string as an integer of the specified radix. If
/// \p Radix is specified as zero, this does radix autosensing using
/// extended C rules: 0 is octal, 0x is hex, 0b is binary.
///
/// If the string is invalid or if only a subset of the string is valid,
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
template <typename T>
typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const noexcept {
long long LLVal;
if (getAsSignedInteger(*this, Radix, LLVal) ||
static_cast<T>(LLVal) != LLVal)
return true;
Result = LLVal;
return false;
}
template <typename T>
typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const noexcept {
unsigned long long ULLVal;
// The additional cast to unsigned long long is required to avoid the
// Visual C++ warning C4805: '!=' : unsafe mix of type 'bool' and type
// 'unsigned __int64' when instantiating getAsInteger with T = bool.
if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
return true;
Result = ULLVal;
return false;
}
/// Parse the current string as an integer of the specified radix. If
/// \p Radix is specified as zero, this does radix autosensing using
/// extended C rules: 0 is octal, 0x is hex, 0b is binary.
///
/// If the string does not begin with a number of the specified radix,
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
/// The portion of the string representing the discovered numeric value
/// is removed from the beginning of the string.
template <typename T>
typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
consumeInteger(unsigned Radix, T &Result) noexcept {
long long LLVal;
if (consumeSignedInteger(*this, Radix, LLVal) ||
static_cast<long long>(static_cast<T>(LLVal)) != LLVal)
return true;
Result = LLVal;
return false;
}
template <typename T>
typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
consumeInteger(unsigned Radix, T &Result) noexcept {
unsigned long long ULLVal;
if (consumeUnsignedInteger(*this, Radix, ULLVal) ||
static_cast<unsigned long long>(static_cast<T>(ULLVal)) != ULLVal)
return true;
Result = ULLVal;
return false;
}
/// @}
/// @name String Operations
/// @{
// Convert the given ASCII string to lowercase.
LLVM_NODISCARD
std::string lower() const;
/// Convert the given ASCII string to uppercase.
LLVM_NODISCARD
std::string upper() const;
/// @}
/// @name Substring Operations
/// @{
/// Return a reference to the substring from [Start, Start + N).
///
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \p Start) will be returned.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef substr(size_t Start, size_t N = npos) const noexcept {
Start = (std::min)(Start, Length);
return StringRef(Data + Start, (std::min)(N, Length - Start));
}
/// Return a StringRef equal to 'this' but with only the first \p N
/// elements remaining. If \p N is greater than the length of the
/// string, the entire string is returned.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef take_front(size_t N = 1) const noexcept {
if (N >= size())
return *this;
return drop_back(size() - N);
}
/// Return a StringRef equal to 'this' but with only the last \p N
/// elements remaining. If \p N is greater than the length of the
/// string, the entire string is returned.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef take_back(size_t N = 1) const noexcept {
if (N >= size())
return *this;
return drop_front(size() - N);
}
/// Return the longest prefix of 'this' such that every character
/// in the prefix satisfies the given predicate.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef take_while(function_ref<bool(char)> F) const noexcept {
return substr(0, find_if_not(F));
}
/// Return the longest prefix of 'this' such that no character in
/// the prefix satisfies the given predicate.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef take_until(function_ref<bool(char)> F) const noexcept {
return substr(0, find_if(F));
}
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_front(size_t N = 1) const noexcept {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
}
/// Return a StringRef equal to 'this' but with the last \p N elements
/// dropped.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_back(size_t N = 1) const noexcept {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
}
/// Return a StringRef equal to 'this', but with all characters satisfying
/// the given predicate dropped from the beginning of the string.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_while(function_ref<bool(char)> F) const noexcept {
return substr(find_if_not(F));
}
/// Return a StringRef equal to 'this', but with all characters not
/// satisfying the given predicate dropped from the beginning of the string.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_until(function_ref<bool(char)> F) const noexcept {
return substr(find_if(F));
}
/// Returns true if this StringRef has the given prefix and removes that
/// prefix.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool consume_front(StringRef Prefix) noexcept {
if (!startswith(Prefix))
return false;
*this = drop_front(Prefix.size());
return true;
}
/// Returns true if this StringRef has the given suffix and removes that
/// suffix.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool consume_back(StringRef Suffix) noexcept {
if (!endswith(Suffix))
return false;
*this = drop_back(Suffix.size());
return true;
}
/// Return a reference to the substring from [Start, End).
///
/// \param Start The index of the starting character in the substring; if
/// the index is npos or greater than the length of the string then the
/// empty substring will be returned.
///
/// \param End The index following the last character to include in the
/// substring. If this is npos or exceeds the number of characters
/// remaining in the string, the string suffix (starting with \p Start)
/// will be returned. If this is less than \p Start, an empty string will
/// be returned.
LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef slice(size_t Start, size_t End) const noexcept {
Start = (std::min)(Start, Length);
End = (std::min)((std::max)(Start, End), Length);
return StringRef(Data + Start, End - Start);
}
/// Split into two substrings around the first occurrence of a separator
/// character.
///
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator The character to split on.
/// \returns The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> split(char Separator) const {
return split(StringRef(&Separator, 1));
}
/// Split into two substrings around the first occurrence of a separator
/// string.
///
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// maximal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The string to split on.
/// \return - The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> split(StringRef Separator) const {
size_t Idx = find(Separator);
if (Idx == npos)
return std::make_pair(*this, StringRef());
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
/// Split into two substrings around the last occurrence of a separator
/// string.
///
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// minimal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The string to split on.
/// \return - The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> rsplit(StringRef Separator) const {
size_t Idx = rfind(Separator);
if (Idx == npos)
return std::make_pair(*this, StringRef());
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
/// Split into substrings around the occurrences of a separator string.
///
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
/// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
/// elements are added to A.
/// If \p KeepEmpty is false, empty strings are not added to \p A. They
/// still count when considering \p MaxSplit
/// An useful invariant is that
/// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
///
/// \param A - Where to put the substrings.
/// \param Separator - The string to split on.
/// \param MaxSplit - The maximum number of times the string is split.
/// \param KeepEmpty - True if empty substring should be added.
void split(SmallVectorImpl<StringRef> &A,
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
/// Split into substrings around the occurrences of a separator character.
///
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
/// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
/// elements are added to A.
/// If \p KeepEmpty is false, empty strings are not added to \p A. They
/// still count when considering \p MaxSplit
/// An useful invariant is that
/// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
///
/// \param A - Where to put the substrings.
/// \param Separator - The string to split on.
/// \param MaxSplit - The maximum number of times the string is split.
/// \param KeepEmpty - True if empty substring should be added.
void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
/// Split into two substrings around the last occurrence of a separator
/// character.
///
/// If \p Separator is in the string, then the result is a pair (LHS, RHS)
/// such that (*this == LHS + Separator + RHS) is true and RHS is
/// minimal. If \p Separator is not in the string, then the result is a
/// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
///
/// \param Separator - The character to split on.
/// \return - The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> rsplit(char Separator) const {
return rsplit(StringRef(&Separator, 1));
}
/// Return string with consecutive \p Char characters starting from the
/// the left removed.
LLVM_NODISCARD
StringRef ltrim(char Char) const noexcept {
return drop_front((std::min)(Length, find_first_not_of(Char)));
}
/// Return string with consecutive characters in \p Chars starting from
/// the left removed.
LLVM_NODISCARD
StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const noexcept {
return drop_front((std::min)(Length, find_first_not_of(Chars)));
}
/// Return string with consecutive \p Char characters starting from the
/// right removed.
LLVM_NODISCARD
StringRef rtrim(char Char) const noexcept {
return drop_back(size() - (std::min)(Length, find_last_not_of(Char) + 1));
}
/// Return string with consecutive characters in \p Chars starting from
/// the right removed.
LLVM_NODISCARD
StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const noexcept {
return drop_back(size() - (std::min)(Length, find_last_not_of(Chars) + 1));
}
/// Return string with consecutive \p Char characters starting from the
/// left and right removed.
LLVM_NODISCARD
StringRef trim(char Char) const noexcept {
return ltrim(Char).rtrim(Char);
}
/// Return string with consecutive characters in \p Chars starting from
/// the left and right removed.
LLVM_NODISCARD
StringRef trim(StringRef Chars = " \t\n\v\f\r") const noexcept {
return ltrim(Chars).rtrim(Chars);
}
/// @}
};
/// A wrapper around a string literal that serves as a proxy for constructing
/// global tables of StringRefs with the length computed at compile time.
/// In order to avoid the invocation of a global constructor, StringLiteral
/// should *only* be used in a constexpr context, as such:
///
/// constexpr StringLiteral S("test");
///
class StringLiteral : public StringRef {
private:
constexpr StringLiteral(const char *Str, size_t N) : StringRef(Str, N) {
}
public:
template <size_t N>
constexpr StringLiteral(const char (&Str)[N])
#if defined(__clang__) && __has_attribute(enable_if)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgcc-compat"
__attribute((enable_if(__builtin_strlen(Str) == N - 1,
"invalid string literal")))
#pragma clang diagnostic pop
#endif
: StringRef(Str, N - 1) {
}
// Explicit construction for strings like "foo\0bar".
template <size_t N>
static constexpr StringLiteral withInnerNUL(const char (&Str)[N]) {
return StringLiteral(Str, N - 1);
}
};
/// @name StringRef Comparison Operators
/// @{
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool operator==(StringRef LHS, StringRef RHS) noexcept {
return LHS.equals(RHS);
}
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool operator!=(StringRef LHS, StringRef RHS) noexcept {
return !(LHS == RHS);
}
inline bool operator<(StringRef LHS, StringRef RHS) noexcept {
return LHS.compare(RHS) == -1;
}
inline bool operator<=(StringRef LHS, StringRef RHS) noexcept {
return LHS.compare(RHS) != 1;
}
inline bool operator>(StringRef LHS, StringRef RHS) noexcept {
return LHS.compare(RHS) == 1;
}
inline bool operator>=(StringRef LHS, StringRef RHS) noexcept {
return LHS.compare(RHS) != -1;
}
inline bool operator==(StringRef LHS, const char *RHS) noexcept {
return LHS.equals(StringRef(RHS));
}
inline bool operator!=(StringRef LHS, const char *RHS) noexcept {
return !(LHS == StringRef(RHS));
}
inline bool operator<(StringRef LHS, const char *RHS) noexcept {
return LHS.compare(StringRef(RHS)) == -1;
}
inline bool operator<=(StringRef LHS, const char *RHS) noexcept {
return LHS.compare(StringRef(RHS)) != 1;
}
inline bool operator>(StringRef LHS, const char *RHS) noexcept {
return LHS.compare(StringRef(RHS)) == 1;
}
inline bool operator>=(StringRef LHS, const char *RHS) noexcept {
return LHS.compare(StringRef(RHS)) != -1;
}
inline bool operator==(const char *LHS, StringRef RHS) noexcept {
return StringRef(LHS).equals(RHS);
}
inline bool operator!=(const char *LHS, StringRef RHS) noexcept {
return !(StringRef(LHS) == RHS);
}
inline bool operator<(const char *LHS, StringRef RHS) noexcept {
return StringRef(LHS).compare(RHS) == -1;
}
inline bool operator<=(const char *LHS, StringRef RHS) noexcept {
return StringRef(LHS).compare(RHS) != 1;
}
inline bool operator>(const char *LHS, StringRef RHS) noexcept {
return StringRef(LHS).compare(RHS) == 1;
}
inline bool operator>=(const char *LHS, StringRef RHS) noexcept {
return StringRef(LHS).compare(RHS) != -1;
}
inline std::string &operator+=(std::string &buffer, StringRef string) {
return buffer.append(string.data(), string.size());
}
std::ostream &operator<<(std::ostream &os, StringRef string);
/// @}
/// Compute a hash_code for a StringRef.
LLVM_NODISCARD
hash_code hash_value(StringRef S);
// StringRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };
} // end namespace wpi
#endif // LLVM_ADT_STRINGREF_H

View File

@@ -27,6 +27,7 @@
#include <atomic>
#include <memory>
#include <string>
#include <string_view>
#include "wpi/NetworkAcceptor.h"
#include "wpi/TCPStream.h"
@@ -44,7 +45,7 @@ class TCPAcceptor : public NetworkAcceptor {
Logger& m_logger;
public:
TCPAcceptor(int port, const char* address, Logger& logger);
TCPAcceptor(int port, std::string_view address, Logger& logger);
~TCPAcceptor() override;
int start() override;

View File

@@ -26,6 +26,7 @@
#include <cstddef>
#include <string>
#include <string_view>
#include "wpi/NetworkStream.h"
@@ -50,7 +51,7 @@ class TCPStream : public NetworkStream {
int timeout = 0) override;
void close() final;
StringRef getPeerIP() const override;
std::string_view getPeerIP() const override;
int getPeerPort() const override;
void setNoDelay() override;
bool setBlocking(bool enabled) override;

View File

@@ -1,572 +0,0 @@
//===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef WPIUTIL_WPI_TWINE_H
#define WPIUTIL_WPI_TWINE_H
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/ErrorHandling.h"
#include <cassert>
#include <cstdint>
#include <string>
#include <string_view>
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 26495)
#endif
namespace wpi {
class raw_ostream;
/// Twine - A lightweight data structure for efficiently representing the
/// concatenation of temporary values as strings.
///
/// A Twine is a kind of rope, it represents a concatenated string using a
/// binary-tree, where the string is the preorder of the nodes. Since the
/// Twine can be efficiently rendered into a buffer when its result is used,
/// it avoids the cost of generating temporary values for intermediate string
/// results -- particularly in cases when the Twine result is never
/// required. By explicitly tracking the type of leaf nodes, we can also avoid
/// the creation of temporary strings for conversions operations (such as
/// appending an integer to a string).
///
/// A Twine is not intended for use directly and should not be stored, its
/// implementation relies on the ability to store pointers to temporary stack
/// objects which may be deallocated at the end of a statement. Twines should
/// only be used accepted as const references in arguments, when an API wishes
/// to accept possibly-concatenated strings.
///
/// Twines support a special 'null' value, which always concatenates to form
/// itself, and renders as an empty string. This can be returned from APIs to
/// effectively nullify any concatenations performed on the result.
///
/// \b Implementation
///
/// Given the nature of a Twine, it is not possible for the Twine's
/// concatenation method to construct interior nodes; the result must be
/// represented inside the returned value. For this reason a Twine object
/// actually holds two values, the left- and right-hand sides of a
/// concatenation. We also have nullary Twine objects, which are effectively
/// sentinel values that represent empty strings.
///
/// Thus, a Twine can effectively have zero, one, or two children. The \see
/// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
/// testing the number of children.
///
/// We maintain a number of invariants on Twine objects (FIXME: Why):
/// - Nullary twines are always represented with their Kind on the left-hand
/// side, and the Empty kind on the right-hand side.
/// - Unary twines are always represented with the value on the left-hand
/// side, and the Empty kind on the right-hand side.
/// - If a Twine has another Twine as a child, that child should always be
/// binary (otherwise it could have been folded into the parent).
///
/// These invariants are check by \see isValid().
///
/// \b Efficiency Considerations
///
/// The Twine is designed to yield efficient and small code for common
/// situations. For this reason, the concat() method is inlined so that
/// concatenations of leaf nodes can be optimized into stores directly into a
/// single stack allocated object.
///
/// In practice, not all compilers can be trusted to optimize concat() fully,
/// so we provide two additional methods (and accompanying operator+
/// overloads) to guarantee that particularly important cases (cstring plus
/// StringRef) codegen as desired.
class Twine {
/// NodeKind - Represent the type of an argument.
enum NodeKind : unsigned char {
/// An empty string; the result of concatenating anything with it is also
/// empty.
NullKind,
/// The empty string.
EmptyKind,
/// A pointer to a Twine instance.
TwineKind,
/// A pointer to a C string instance.
CStringKind,
/// A pointer to an std::string instance.
StdStringKind,
/// A pointer to a StringRef instance.
StringRefKind,
/// A pointer to a std::string_view instance.
StringViewKind,
/// A pointer to a SmallString instance.
SmallStringKind,
/// A char value, to render as a character.
CharKind,
/// An unsigned int value, to render as an unsigned decimal integer.
DecUIKind,
/// An int value, to render as a signed decimal integer.
DecIKind,
/// A pointer to an unsigned long value, to render as an unsigned decimal
/// integer.
DecULKind,
/// A pointer to a long value, to render as a signed decimal integer.
DecLKind,
/// A pointer to an unsigned long long value, to render as an unsigned
/// decimal integer.
DecULLKind,
/// A pointer to a long long value, to render as a signed decimal integer.
DecLLKind,
/// A pointer to a uint64_t value, to render as an unsigned hexadecimal
/// integer.
UHexKind
};
union Child
{
const Twine *twine;
const char *cString;
const std::string *stdString;
const StringRef *stringRef;
const std::string_view *stringView;
const SmallVectorImpl<char> *smallString;
char character;
unsigned int decUI;
int decI;
const unsigned long *decUL;
const long *decL;
const unsigned long long *decULL;
const long long *decLL;
const uint64_t *uHex;
};
/// LHS - The prefix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
Child LHS;
/// RHS - The suffix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
Child RHS;
/// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
NodeKind LHSKind = EmptyKind;
/// RHSKind - The NodeKind of the right hand side, \see getRHSKind().
NodeKind RHSKind = EmptyKind;
/// Construct a nullary twine; the kind must be NullKind or EmptyKind.
explicit Twine(NodeKind Kind) : LHSKind(Kind) {
assert(isNullary() && "Invalid kind!");
}
/// Construct a binary twine.
explicit Twine(const Twine &LHS, const Twine &RHS)
: LHSKind(TwineKind), RHSKind(TwineKind) {
this->LHS.twine = &LHS;
this->RHS.twine = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct a twine from explicit values.
explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
: LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
assert(isValid() && "Invalid twine!");
}
/// Check for the empty twine.
bool isEmpty() const {
return getLHSKind() == EmptyKind;
}
/// Check if this is a nullary twine (null or empty).
bool isNullary() const {
return isNull() || isEmpty();
}
/// Check if this is a unary twine.
bool isUnary() const {
return getRHSKind() == EmptyKind && !isNullary();
}
/// Check if this is a binary twine.
bool isBinary() const {
return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
}
/// Check if this is a valid twine (satisfying the invariants on
/// order and number of arguments).
bool isValid() const {
// Nullary twines always have Empty on the RHS.
if (isNullary() && getRHSKind() != EmptyKind)
return false;
// Null should never appear on the RHS.
if (getRHSKind() == NullKind)
return false;
// The RHS cannot be non-empty if the LHS is empty.
if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
return false;
#if 0 // causes spurious warnings
// A twine child should always be binary.
if (getLHSKind() == TwineKind &&
!LHS.twine->isBinary())
return false;
if (getRHSKind() == TwineKind &&
!RHS.twine->isBinary())
return false;
#endif
return true;
}
/// Get the NodeKind of the left-hand side.
NodeKind getLHSKind() const { return LHSKind; }
/// Get the NodeKind of the right-hand side.
NodeKind getRHSKind() const { return RHSKind; }
/// Print one child from a twine.
void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
/// Print the representation of one child from a twine.
void printOneChildRepr(raw_ostream &OS, Child Ptr,
NodeKind Kind) const;
public:
/// @name Constructors
/// @{
/// Construct from an empty string.
/*implicit*/ Twine() {
assert(isValid() && "Invalid twine!");
}
Twine(const Twine &) = default;
/// Construct from a C string.
///
/// We take care here to optimize "" into the empty twine -- this will be
/// optimized out for string constants. This allows Twine arguments have
/// default "" values, without introducing unnecessary string constants.
/*implicit*/ Twine(const char *Str) {
if (Str[0] != '\0') {
LHS.cString = Str;
LHSKind = CStringKind;
} else
LHSKind = EmptyKind;
assert(isValid() && "Invalid twine!");
}
/// Construct from an std::string.
/*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) {
LHS.stdString = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a StringRef.
/*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) {
LHS.stringRef = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a std::string_view.
/*implicit*/ Twine(const std::string_view &Str) : LHSKind(StringViewKind) {
LHS.stringView = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a SmallString.
/*implicit*/ Twine(const SmallVectorImpl<char> &Str)
: LHSKind(SmallStringKind) {
LHS.smallString = &Str;
assert(isValid() && "Invalid twine!");
}
/// Construct from a char.
explicit Twine(char Val) : LHSKind(CharKind) {
LHS.character = Val;
}
/// Construct from a signed char.
explicit Twine(signed char Val) : LHSKind(CharKind) {
LHS.character = static_cast<char>(Val);
}
/// Construct from an unsigned char.
explicit Twine(unsigned char Val) : LHSKind(CharKind) {
LHS.character = static_cast<char>(Val);
}
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(unsigned Val) : LHSKind(DecUIKind) {
LHS.decUI = Val;
}
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(int Val) : LHSKind(DecIKind) {
LHS.decI = Val;
}
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) {
LHS.decUL = &Val;
}
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long &Val) : LHSKind(DecLKind) {
LHS.decL = &Val;
}
/// Construct a twine to print \p Val as an unsigned decimal integer.
explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) {
LHS.decULL = &Val;
}
/// Construct a twine to print \p Val as a signed decimal integer.
explicit Twine(const long long &Val) : LHSKind(DecLLKind) {
LHS.decLL = &Val;
}
// FIXME: Unfortunately, to make sure this is as efficient as possible we
// need extra binary constructors from particular types. We can't rely on
// the compiler to be smart enough to fold operator+()/concat() down to the
// right thing. Yet.
/// Construct as the concatenation of a C string and a StringRef.
/*implicit*/ Twine(const char *LHS, const StringRef &RHS)
: LHSKind(CStringKind), RHSKind(StringRefKind) {
this->LHS.cString = LHS;
this->RHS.stringRef = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a StringRef and a C string.
/*implicit*/ Twine(const StringRef &LHS, const char *RHS)
: LHSKind(StringRefKind), RHSKind(CStringKind) {
this->LHS.stringRef = &LHS;
this->RHS.cString = RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a C string and a std::string_view.
/*implicit*/ Twine(const char *LHS, const std::string_view &RHS)
: LHSKind(CStringKind), RHSKind(StringViewKind) {
this->LHS.cString = LHS;
this->RHS.stringView = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a std::string_view and a C string.
/*implicit*/ Twine(const std::string_view &LHS, const char *RHS)
: LHSKind(StringViewKind), RHSKind(CStringKind) {
this->LHS.stringView = &LHS;
this->RHS.cString = RHS;
assert(isValid() && "Invalid twine!");
}
/// Since the intended use of twines is as temporary objects, assignments
/// when concatenating might cause undefined behavior or stack corruptions
Twine &operator=(const Twine &) = delete;
/// Create a 'null' string, which is an empty string that always
/// concatenates to form another empty string.
static Twine createNull() {
return Twine(NullKind);
}
/// @}
/// @name Numeric Conversions
/// @{
// Construct a twine to print \p Val as an unsigned hexadecimal integer.
static Twine utohexstr(const uint64_t &Val) {
Child LHS, RHS;
LHS.uHex = &Val;
RHS.twine = nullptr;
return Twine(LHS, UHexKind, RHS, EmptyKind);
}
/// @}
/// @name Predicate Operations
/// @{
/// Check for the null twine.
bool isNull() const {
return getLHSKind() == NullKind;
}
/// Check if this twine is trivially empty; a false return value does not
/// necessarily mean the twine is empty.
bool isTriviallyEmpty() const {
return isNullary();
}
/// Return true if this twine can be dynamically accessed as a single
/// StringRef value with getSingleStringRef().
bool isSingleStringRef() const {
if (getRHSKind() != EmptyKind) return false;
switch (getLHSKind()) {
case EmptyKind:
case CStringKind:
case StdStringKind:
case StringRefKind:
case StringViewKind:
case SmallStringKind:
case CharKind:
return true;
default:
return false;
}
}
/// @}
/// @name String Operations
/// @{
Twine concat(const Twine &Suffix) const;
/// @}
/// @name Output & Conversion.
/// @{
/// Return the twine contents as a std::string.
std::string str() const;
/// Append the concatenated string into the given SmallString or SmallVector.
void toVector(SmallVectorImpl<char> &Out) const;
/// This returns the twine as a single StringRef. This method is only valid
/// if isSingleStringRef() is true.
StringRef getSingleStringRef() const {
assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
switch (getLHSKind()) {
default:
// unreachable("Out of sync with isSingleStringRef");
return StringRef();
case EmptyKind: return StringRef();
case CStringKind: return StringRef(LHS.cString);
case StdStringKind: return StringRef(*LHS.stdString);
case StringRefKind: return *LHS.stringRef;
case StringViewKind: return StringRef(*LHS.stringView);
case SmallStringKind:
return StringRef(LHS.smallString->data(), LHS.smallString->size());
case CharKind: return StringRef(&LHS.character, 1);
}
}
/// This returns the twine as a single StringRef if it can be
/// represented as such. Otherwise the twine is written into the given
/// SmallVector and a StringRef to the SmallVector's data is returned.
StringRef toStringRef(SmallVectorImpl<char> &Out) const {
if (isSingleStringRef())
return getSingleStringRef();
toVector(Out);
return StringRef(Out.data(), Out.size());
}
/// This returns the twine as a single null terminated StringRef if it
/// can be represented as such. Otherwise the twine is written into the
/// given SmallVector and a StringRef to the SmallVector's data is returned.
///
/// The returned StringRef's size does not include the null terminator.
StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
/// Write the concatenated string represented by this twine to the
/// stream \p OS.
void print(raw_ostream &OS) const;
/// Dump the concatenated string represented by this twine to stderr.
void dump() const;
/// Write the representation of this twine to the stream \p OS.
void printRepr(raw_ostream &OS) const;
/// Dump the representation of this twine to stderr.
void dumpRepr() const;
/// @}
};
/// @name Twine Inline Implementations
/// @{
inline Twine Twine::concat(const Twine &Suffix) const {
// Concatenation with null is null.
if (isNull() || Suffix.isNull())
return Twine(NullKind);
// Concatenation with empty yields the other side.
if (isEmpty())
return Suffix;
if (Suffix.isEmpty())
return *this;
// Otherwise we need to create a new node, taking care to fold in unary
// twines.
Child NewLHS, NewRHS;
NewLHS.twine = this;
NewRHS.twine = &Suffix;
NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
if (isUnary()) {
NewLHS = LHS;
NewLHSKind = getLHSKind();
}
if (Suffix.isUnary()) {
NewRHS = Suffix.LHS;
NewRHSKind = Suffix.getLHSKind();
}
return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
}
inline Twine operator+(const Twine &LHS, const Twine &RHS) {
return LHS.concat(RHS);
}
/// Additional overload to guarantee simplified codegen; this is equivalent to
/// concat().
inline Twine operator+(const char *LHS, const StringRef &RHS) {
return Twine(LHS, RHS);
}
/// Additional overload to guarantee simplified codegen; this is equivalent to
/// concat().
inline Twine operator+(const StringRef &LHS, const char *RHS) {
return Twine(LHS, RHS);
}
inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
RHS.print(OS);
return OS;
}
/// @}
} // end namespace wpi
#ifdef _WIN32
#pragma warning(pop)
#endif
#endif // LLVM_ADT_TWINE_H

View File

@@ -6,11 +6,10 @@
#define WPIUTIL_WPI_UDPCLIENT_H_
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
#include "wpi/mutex.h"
namespace wpi {
@@ -25,7 +24,7 @@ class UDPClient {
public:
explicit UDPClient(Logger& logger);
UDPClient(const Twine& address, Logger& logger);
UDPClient(std::string_view address, Logger& logger);
UDPClient(const UDPClient& other) = delete;
UDPClient(UDPClient&& other);
~UDPClient();
@@ -37,8 +36,8 @@ class UDPClient {
int start(int port);
void shutdown();
// The passed in address MUST be a resolved IP address.
int send(ArrayRef<uint8_t> data, const Twine& server, int port);
int send(StringRef data, const Twine& server, int port);
int send(ArrayRef<uint8_t> data, std::string_view server, int port);
int send(std::string_view data, std::string_view server, int port);
int receive(uint8_t* data_received, int receive_len);
int receive(uint8_t* data_received, int receive_len,
SmallVectorImpl<char>* addr_received, int* port_received);

View File

@@ -5,7 +5,8 @@
#ifndef WPIUTIL_WPI_URLPARSER_H_
#define WPIUTIL_WPI_URLPARSER_H_
#include "wpi/StringRef.h"
#include <string_view>
#include "wpi/http_parser.h"
namespace wpi {
@@ -21,7 +22,7 @@ class UrlParser {
* @param in input
* @param isConnect
*/
UrlParser(StringRef in, bool isConnect) {
UrlParser(std::string_view in, bool isConnect) {
m_data = in;
http_parser_url_init(&m_url);
m_error = http_parser_parse_url(in.data(), in.size(), isConnect, &m_url);
@@ -50,41 +51,41 @@ class UrlParser {
return (m_url.field_set & (1 << UF_USERINFO)) != 0;
}
StringRef GetSchema() const {
std::string_view GetSchema() const {
return m_data.substr(m_url.field_data[UF_SCHEMA].off,
m_url.field_data[UF_SCHEMA].len);
}
StringRef GetHost() const {
std::string_view GetHost() const {
return m_data.substr(m_url.field_data[UF_HOST].off,
m_url.field_data[UF_HOST].len);
}
unsigned int GetPort() const { return m_url.port; }
StringRef GetPath() const {
std::string_view GetPath() const {
return m_data.substr(m_url.field_data[UF_PATH].off,
m_url.field_data[UF_PATH].len);
}
StringRef GetQuery() const {
std::string_view GetQuery() const {
return m_data.substr(m_url.field_data[UF_QUERY].off,
m_url.field_data[UF_QUERY].len);
}
StringRef GetFragment() const {
std::string_view GetFragment() const {
return m_data.substr(m_url.field_data[UF_FRAGMENT].off,
m_url.field_data[UF_FRAGMENT].len);
}
StringRef GetUserInfo() const {
std::string_view GetUserInfo() const {
return m_data.substr(m_url.field_data[UF_USERINFO].off,
m_url.field_data[UF_USERINFO].len);
}
private:
bool m_error;
StringRef m_data;
std::string_view m_data;
http_parser_url m_url;
};

View File

@@ -15,11 +15,8 @@
#ifndef WPIUTIL_WPI_VERSIONTUPLE_H
#define WPIUTIL_WPI_VERSIONTUPLE_H
#include "wpi/StringRef.h"
#include "wpi/raw_ostream.h"
#include <optional>
#include <string>
#include <tuple>
namespace wpi {
@@ -137,18 +134,7 @@ public:
friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
return !(X < Y);
}
/// Retrieve a string representation of the version number.
std::string getAsString() const;
/// Try to parse the given string as a version number.
/// \returns \c true if the string does not match the regular expression
/// [0-9]+(\.[0-9]+){0,3}
bool tryParse(StringRef string);
};
/// Print a version number.
raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V);
} // end namespace wpi
#endif // WPIUTIL_WPI_VERSIONTUPLE_H

View File

@@ -11,13 +11,12 @@
#include <initializer_list>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
#include "wpi/uv/Buffer.h"
#include "wpi/uv/Error.h"
#include "wpi/uv/Timer.h"
@@ -79,7 +78,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
uv::Timer::Time handshakeTimeout; // NOLINT
/** Additional headers to include in handshake. */
ArrayRef<std::pair<StringRef, StringRef>> extraHeaders;
ArrayRef<std::pair<std::string_view, std::string_view>> extraHeaders;
};
/**
@@ -93,9 +92,9 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param options Handshake options
*/
static std::shared_ptr<WebSocket> CreateClient(
uv::Stream& stream, const Twine& uri, const Twine& host,
ArrayRef<StringRef> protocols = ArrayRef<StringRef>{},
const ClientOptions& options = ClientOptions{});
uv::Stream& stream, std::string_view uri, std::string_view host,
ArrayRef<std::string_view> protocols = {},
const ClientOptions& options = {});
/**
* Starts a client connection by performing the initial client handshake.
@@ -108,9 +107,9 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param options Handshake options
*/
static std::shared_ptr<WebSocket> CreateClient(
uv::Stream& stream, const Twine& uri, const Twine& host,
std::initializer_list<StringRef> protocols,
const ClientOptions& options = ClientOptions{}) {
uv::Stream& stream, std::string_view uri, std::string_view host,
std::initializer_list<std::string_view> protocols,
const ClientOptions& options = {}) {
return CreateClient(stream, uri, host,
makeArrayRef(protocols.begin(), protocols.end()),
options);
@@ -130,8 +129,8 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* Sec-WebSocket-Protocol header field).
*/
static std::shared_ptr<WebSocket> CreateServer(
uv::Stream& stream, StringRef key, StringRef version,
StringRef protocol = StringRef{});
uv::Stream& stream, std::string_view key, std::string_view version,
std::string_view protocol = {});
/**
* Get connection state.
@@ -152,7 +151,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
/**
* Get the selected sub-protocol. Only valid in or after the open() event.
*/
StringRef GetProtocol() const { return m_protocol; }
std::string_view GetProtocol() const { return m_protocol; }
/**
* Set the maximum message size. Default is 128 KB. If configured to combine
@@ -176,7 +175,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param reason A human-readable string explaining why the connection is
* closing (optional).
*/
void Close(uint16_t code = 1005, const Twine& reason = Twine{});
void Close(uint16_t code = 1005, std::string_view reason = {});
/**
* Send a text message.
@@ -292,12 +291,12 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
/**
* Fail the connection.
*/
void Fail(uint16_t code = 1002, const Twine& reason = "protocol error");
void Fail(uint16_t code = 1002, std::string_view reason = "protocol error");
/**
* Forcibly close the connection.
*/
void Terminate(uint16_t code = 1006, const Twine& reason = "terminated");
void Terminate(uint16_t code = 1006, std::string_view reason = "terminated");
/**
* Gets user-defined data.
@@ -318,7 +317,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* Open event. Emitted when the connection is open and ready to communicate.
* The parameter is the selected subprotocol.
*/
sig::Signal<StringRef> open;
sig::Signal<std::string_view> open;
/**
* Close event. Emitted when the connection is closed. The first parameter
@@ -326,14 +325,14 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* has been closed. The second parameter is a human-readable string
* explaining the reason why the connection has been closed.
*/
sig::Signal<uint16_t, StringRef> closed;
sig::Signal<uint16_t, std::string_view> closed;
/**
* Text message event. Emitted when a text message is received.
* The first parameter is the data, the second parameter is true if the
* data is the last fragment of the message.
*/
sig::Signal<StringRef, bool> text;
sig::Signal<std::string_view, bool> text;
/**
* Binary message event. Emitted when a binary message is received.
@@ -382,11 +381,13 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
class ClientHandshakeData;
std::unique_ptr<ClientHandshakeData> m_clientHandshake;
void StartClient(const Twine& uri, const Twine& host,
ArrayRef<StringRef> protocols, const ClientOptions& options);
void StartServer(StringRef key, StringRef version, StringRef protocol);
void SendClose(uint16_t code, const Twine& reason);
void SetClosed(uint16_t code, const Twine& reason, bool failed = false);
void StartClient(std::string_view uri, std::string_view host,
ArrayRef<std::string_view> protocols,
const ClientOptions& options);
void StartServer(std::string_view key, std::string_view version,
std::string_view protocol);
void SendClose(uint16_t code, std::string_view reason);
void SetClosed(uint16_t code, std::string_view reason, bool failed = false);
void Shutdown();
void HandleIncoming(uv::Buffer& buf, size_t size);
void Send(

View File

@@ -9,6 +9,7 @@
#include <initializer_list>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
@@ -16,7 +17,6 @@
#include "wpi/Signal.h"
#include "wpi/SmallString.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/WebSocket.h"
namespace wpi {
@@ -52,7 +52,8 @@ class WebSocketServerHelper {
* Second item is the matched protocol if a match was made, otherwise
* is empty.
*/
std::pair<bool, StringRef> MatchProtocol(ArrayRef<StringRef> protocols);
std::pair<bool, std::string_view> MatchProtocol(
ArrayRef<std::string_view> protocols);
/**
* Try to find a match to the list of sub-protocols provided by the client.
@@ -63,8 +64,8 @@ class WebSocketServerHelper {
* Second item is the matched protocol if a match was made, otherwise
* is empty.
*/
std::pair<bool, StringRef> MatchProtocol(
std::initializer_list<StringRef> protocols) {
std::pair<bool, std::string_view> MatchProtocol(
std::initializer_list<std::string_view> protocols) {
return MatchProtocol(makeArrayRef(protocols.begin(), protocols.end()));
}
@@ -75,7 +76,7 @@ class WebSocketServerHelper {
* @param protocol The subprotocol to send to the client
*/
std::shared_ptr<WebSocket> Accept(uv::Stream& stream,
StringRef protocol = StringRef{}) {
std::string_view protocol = {}) {
return WebSocket::CreateServer(stream, m_key, m_version, protocol);
}
@@ -109,19 +110,19 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
* Checker for URL. Return true if URL should be accepted. By default all
* URLs are accepted.
*/
std::function<bool(StringRef)> checkUrl;
std::function<bool(std::string_view)> checkUrl;
/**
* Checker for Host header. Return true if Host should be accepted. By
* default all hosts are accepted.
*/
std::function<bool(StringRef)> checkHost;
std::function<bool(std::string_view)> checkHost;
};
/**
* Private constructor.
*/
WebSocketServer(uv::Stream& stream, ArrayRef<StringRef> protocols,
WebSocketServer(uv::Stream& stream, ArrayRef<std::string_view> protocols,
ServerOptions options, const private_init&);
/**
@@ -134,8 +135,8 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
* @param options Handshake options
*/
static std::shared_ptr<WebSocketServer> Create(
uv::Stream& stream, ArrayRef<StringRef> protocols = ArrayRef<StringRef>{},
const ServerOptions& options = ServerOptions{});
uv::Stream& stream, ArrayRef<std::string_view> protocols = {},
const ServerOptions& options = {});
/**
* Starts a dedicated WebSocket server on the provided connection. The
@@ -147,8 +148,8 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
* @param options Handshake options
*/
static std::shared_ptr<WebSocketServer> Create(
uv::Stream& stream, std::initializer_list<StringRef> protocols,
const ServerOptions& options = ServerOptions{}) {
uv::Stream& stream, std::initializer_list<std::string_view> protocols,
const ServerOptions& options = {}) {
return Create(stream, makeArrayRef(protocols.begin(), protocols.end()),
options);
}
@@ -156,7 +157,7 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
/**
* Connected event. First parameter is the URL, second is the websocket.
*/
sig::Signal<StringRef, WebSocket&> connected;
sig::Signal<std::string_view, WebSocket&> connected;
private:
uv::Stream& m_stream;
@@ -169,7 +170,7 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
sig::ScopedConnection m_errorConn;
sig::ScopedConnection m_endConn;
void Abort(uint16_t code, StringRef reason);
void Abort(uint16_t code, std::string_view reason);
};
} // namespace wpi

View File

@@ -0,0 +1,30 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#ifndef WPIUTIL_WPI_FMT_RAW_OSTREAM_H_
#define WPIUTIL_WPI_FMT_RAW_OSTREAM_H_
#include "fmt/format.h"
#include "wpi/raw_ostream.h"
FMT_BEGIN_NAMESPACE
inline void vprint(wpi::raw_ostream& os, string_view format_str,
fmt::format_args args) {
memory_buffer buffer;
detail::vformat_to(buffer, format_str, args);
os.write(buffer.data(), buffer.size());
}
/**
* Prints formatted data to the stream *os*.
*/
template <typename S, typename... Args>
void print(wpi::raw_ostream& os, const S& format_str, Args&&... args) {
vprint(os, format_str, fmt::make_args_checked<Args...>(format_str, args...));
}
FMT_END_NAMESPACE
#endif // WPIUTIL_WPI_FMT_RAW_OSTREAM_H_

View File

@@ -6,15 +6,14 @@
#define WPIUTIL_WPI_HOSTNAME_H_
#include <string>
#include "wpi/StringRef.h"
#include <string_view>
namespace wpi {
template <typename T>
class SmallVectorImpl;
std::string GetHostname();
StringRef GetHostname(SmallVectorImpl<char>& name);
std::string_view GetHostname(SmallVectorImpl<char>& name);
} // namespace wpi
#endif // WPIUTIL_WPI_HOSTNAME_H_

View File

@@ -9,6 +9,7 @@
#include <queue>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
@@ -18,7 +19,7 @@
#include "wpi/SafeThread.h"
#include "wpi/SmallString.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/StringExtras.h"
#include "wpi/deprecated.h"
#include "wpi/mutex.h"
#include "wpi/raw_ostream.h"
@@ -30,7 +31,7 @@ namespace wpi::java {
// in the stack trace not starting with excludeFuncPrefix (useful for e.g.
// finding the first user call to a series of library functions).
std::string GetJavaStackTrace(JNIEnv* env, std::string* func = nullptr,
StringRef excludeFuncPrefix = StringRef());
std::string_view excludeFuncPrefix = {});
// Finds a class and keep it as a global reference.
// Use with caution, as the destructor does NOT call DeleteGlobalRef due
@@ -148,8 +149,8 @@ class JStringRef {
m_str.pop_back();
}
operator StringRef() const { return m_str; } // NOLINT
StringRef str() const { return m_str; }
operator std::string_view() const { return m_str.str(); } // NOLINT
std::string_view str() const { return m_str.str(); }
const char* c_str() const { return m_str.data(); }
size_t size() const { return m_str.size(); }
@@ -163,18 +164,18 @@ namespace detail {
template <typename C, typename T>
class JArrayRefInner {};
// Specialization of JArrayRefBase to provide StringRef conversion.
// Specialization of JArrayRefBase to provide std::string_view conversion.
template <typename C>
class JArrayRefInner<C, jbyte> {
public:
operator StringRef() const { return str(); }
operator std::string_view() const { return str(); }
StringRef str() const {
std::string_view str() const {
auto arr = static_cast<const C*>(this)->array();
if (arr.empty()) {
return {};
}
return StringRef{reinterpret_cast<const char*>(arr.data()), arr.size()};
return {reinterpret_cast<const char*>(arr.data()), arr.size()};
}
};
@@ -326,7 +327,7 @@ WPI_JNI_JARRAYREF(jdouble, Double)
//
// Convert a UTF8 string into a jstring.
inline jstring MakeJString(JNIEnv* env, StringRef str) {
inline jstring MakeJString(JNIEnv* env, std::string_view str) {
SmallVector<UTF16, 128> chars;
convertUTF8ToUTF16String(str, chars);
return env->NewString(chars.begin(), chars.size());
@@ -395,8 +396,8 @@ inline jintArray MakeJIntArray(JNIEnv* env, const std::vector<T>& arr) {
return detail::ConvertIntArray<T>::ToJava(env, arr);
}
// Convert a StringRef into a jbyteArray.
inline jbyteArray MakeJByteArray(JNIEnv* env, StringRef str) {
// Convert a std::string_view into a jbyteArray.
inline jbyteArray MakeJByteArray(JNIEnv* env, std::string_view str) {
jbyteArray jarr = env->NewByteArray(str.size());
if (!jarr) {
return nullptr;
@@ -593,7 +594,7 @@ class JSingletonCallbackManager : public JCallbackManager<T> {
}
};
inline std::string GetJavaStackTrace(JNIEnv* env, StringRef skipPrefix) {
inline std::string GetJavaStackTrace(JNIEnv* env, std::string_view skipPrefix) {
// create a throwable
static JClass throwableCls(env, "java/lang/Throwable");
if (!throwableCls) {
@@ -657,7 +658,7 @@ inline std::string GetJavaStackTrace(JNIEnv* env, StringRef skipPrefix) {
// add a line to res
JStringRef elem(env, stackElementString);
if (!foundFirst) {
if (elem.str().startswith(skipPrefix)) {
if (wpi::starts_with(elem, skipPrefix)) {
continue;
}
foundFirst = true;
@@ -669,7 +670,7 @@ inline std::string GetJavaStackTrace(JNIEnv* env, StringRef skipPrefix) {
}
inline std::string GetJavaStackTrace(JNIEnv* env, std::string* func,
StringRef excludeFuncPrefix) {
std::string_view excludeFuncPrefix) {
// create a throwable
static JClass throwableCls(env, "java/lang/Throwable");
if (!throwableCls) {
@@ -740,7 +741,7 @@ inline std::string GetJavaStackTrace(JNIEnv* env, std::string* func,
if (i == 1) {
*func = elem.str();
} else if (i > 1 && !haveLoc && !excludeFuncPrefix.empty() &&
!elem.str().startswith(excludeFuncPrefix)) {
!wpi::starts_with(elem, excludeFuncPrefix)) {
*func = elem.str();
haveLoc = true;
}
@@ -769,7 +770,9 @@ class JException : public JClass {
env->Throw(static_cast<jthrowable>(exception));
}
void Throw(JNIEnv* env, StringRef msg) { Throw(env, MakeJString(env, msg)); }
void Throw(JNIEnv* env, std::string_view msg) {
Throw(env, MakeJString(env, msg));
}
explicit operator bool() const { return m_constructor; }

View File

@@ -54,6 +54,7 @@ SOFTWARE.
#include <memory> // allocator, shared_ptr, make_shared, addressof
#include <stdexcept> // runtime_error
#include <string> // string, char_traits, stoi, to_string
#include <string_view>
#include <tuple> // tuple, get, make_tuple
#include <type_traits>
#include <utility>
@@ -61,8 +62,6 @@ SOFTWARE.
#include "wpi/ArrayRef.h"
#include "wpi/StringMap.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
namespace wpi
{
@@ -239,7 +238,7 @@ template<class RealType, class CompatibleObjectType>
struct is_compatible_object_type_impl<true, RealType, CompatibleObjectType>
{
static constexpr auto value =
std::is_constructible<StringRef, typename CompatibleObjectType::key_type>::value and
std::is_constructible<std::string_view, typename CompatibleObjectType::key_type>::value and
std::is_constructible<typename RealType::mapped_type, typename CompatibleObjectType::mapped_type>::value;
};
@@ -269,7 +268,7 @@ struct is_compatible_array_type
std::conjunction<std::negation<std::is_same<void, CompatibleArrayType>>,
std::negation<is_compatible_object_type<
BasicJsonType, CompatibleArrayType>>,
std::negation<std::is_constructible<StringRef,
std::negation<std::is_constructible<std::string_view,
CompatibleArrayType>>,
std::negation<is_json_nested_type<BasicJsonType, CompatibleArrayType>>,
has_value_type<CompatibleArrayType>,
@@ -423,7 +422,7 @@ class exception : public std::exception
const int id;
protected:
exception(int id_, const Twine& what_arg);
exception(int id_, std::string_view what_arg);
private:
/// an exception object as storage for error messages
@@ -484,7 +483,7 @@ class parse_error : public exception
@param[in] what_arg the explanatory string
@return parse_error object
*/
static parse_error create(int id_, std::size_t byte_, const Twine& what_arg);
static parse_error create(int id_, std::size_t byte_, std::string_view what_arg);
/*!
@brief byte index of the parse error
@@ -498,7 +497,7 @@ class parse_error : public exception
const std::size_t byte;
private:
parse_error(int id_, std::size_t byte_, const Twine& what_arg)
parse_error(int id_, std::size_t byte_, std::string_view what_arg)
: exception(id_, what_arg), byte(byte_) {}
};
@@ -542,10 +541,11 @@ caught.,invalid_iterator}
class invalid_iterator : public exception
{
public:
static invalid_iterator create(int id_, const Twine& what_arg);
static invalid_iterator create(int id_, std::string_view what_arg);
static invalid_iterator create(int id_, std::string_view what_arg, std::string_view type_info);
private:
invalid_iterator(int id_, const Twine& what_arg)
invalid_iterator(int id_, std::string_view what_arg)
: exception(id_, what_arg) {}
};
@@ -590,10 +590,11 @@ caught.,type_error}
class type_error : public exception
{
public:
static type_error create(int id_, const Twine& what_arg);
static type_error create(int id_, std::string_view what_arg);
static type_error create(int id_, std::string_view what_arg, std::string_view type_info);
private:
type_error(int id_, const Twine& what_arg) : exception(id_, what_arg) {}
type_error(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
};
/*!
@@ -631,10 +632,10 @@ caught.,out_of_range}
class out_of_range : public exception
{
public:
static out_of_range create(int id_, const Twine& what_arg);
static out_of_range create(int id_, std::string_view what_arg);
private:
out_of_range(int id_, const Twine& what_arg) : exception(id_, what_arg) {}
out_of_range(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
};
/*!
@@ -664,10 +665,10 @@ caught.,other_error}
class other_error : public exception
{
public:
static other_error create(int id_, const Twine& what_arg);
static other_error create(int id_, std::string_view what_arg);
private:
other_error(int id_, const Twine& what_arg) : exception(id_, what_arg) {}
other_error(int id_, std::string_view what_arg) : exception(id_, what_arg) {}
};
///////////////////////////
@@ -760,7 +761,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
}
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be number, but is", j.type_name()));
}
}
@@ -769,7 +770,7 @@ void from_json(const BasicJsonType& j, bool& b)
{
if (JSON_UNLIKELY(not j.is_boolean()))
{
JSON_THROW(type_error::create(302, "type must be boolean, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be boolean, but is", j.type_name()));
}
b = *j.template get_ptr<const bool*>();
}
@@ -779,7 +780,7 @@ void from_json(const BasicJsonType& j, std::string& s)
{
if (JSON_UNLIKELY(not j.is_string()))
{
JSON_THROW(type_error::create(302, "type must be string, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be string, but is", j.type_name()));
}
s = *j.template get_ptr<const std::string*>();
}
@@ -816,7 +817,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr)
{
if (JSON_UNLIKELY(not j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be array, but is", j.type_name()));
}
arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
}
@@ -875,8 +876,7 @@ void from_json(const BasicJsonType& j, CompatibleArrayType& arr)
{
if (JSON_UNLIKELY(not j.is_array()))
{
JSON_THROW(type_error::create(302, "type must be array, but is " +
Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be array, but is", j.type_name()));
}
from_json_array_impl(j, arr, priority_tag<2> {});
@@ -888,7 +888,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::object_t& obj)
{
if (!j.is_object())
{
JSON_THROW(type_error::create(302, "type must be object, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be object, but is", j.type_name()));
}
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
@@ -904,7 +904,7 @@ void from_json(const BasicJsonType& j, CompatibleObjectType& obj)
{
if (JSON_UNLIKELY(not j.is_object()))
{
JSON_THROW(type_error::create(302, "type must be object, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be object, but is", j.type_name()));
}
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
@@ -965,7 +965,7 @@ void from_json(const BasicJsonType& j, ArithmeticType& val)
}
default:
JSON_THROW(type_error::create(302, "type must be number, but is " + Twine(j.type_name())));
JSON_THROW(type_error::create(302, "type must be number, but is", j.type_name()));
}
}
@@ -1053,7 +1053,7 @@ template<>
struct external_constructor<value_t::string>
{
template<typename BasicJsonType>
static void construct(BasicJsonType& j, StringRef s)
static void construct(BasicJsonType& j, std::string_view s)
{
j.m_type = value_t::string;
j.m_value = s;
@@ -1206,7 +1206,7 @@ void to_json(BasicJsonType& j, T b) noexcept
}
template<typename BasicJsonType, typename CompatibleString,
enable_if_t<std::is_constructible<StringRef, CompatibleString>::value, int> = 0>
enable_if_t<std::is_constructible<std::string_view, CompatibleString>::value, int> = 0>
void to_json(BasicJsonType& j, const CompatibleString& s)
{
external_constructor<value_t::string>::construct(j, s);
@@ -1283,7 +1283,7 @@ void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
}
template<typename BasicJsonType, typename T, std::size_t N,
enable_if_t<not std::is_constructible<StringRef, T (&)[N]>::value, int> = 0>
enable_if_t<not std::is_constructible<std::string_view, T (&)[N]>::value, int> = 0>
void to_json(BasicJsonType& j, T (&arr)[N])
{
external_constructor<value_t::array>::construct(j, arr);
@@ -2044,7 +2044,7 @@ class iter_impl
@brief return the key of an object iterator
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
StringRef key() const
std::string_view key() const
{
assert(m_object != nullptr);
@@ -2348,7 +2348,7 @@ class json_pointer
@since version 2.0.0
*/
explicit json_pointer(const Twine& s = {})
explicit json_pointer(std::string_view s = {})
: reference_tokens(split(s))
{}
@@ -2382,7 +2382,7 @@ class json_pointer
@throw out_of_range.404 if string @a s could not be converted to an integer
*/
static int array_index(const Twine& s);
static int array_index(std::string_view s);
private:
/*!
@@ -2490,7 +2490,7 @@ class json_pointer
@throw parse_error.107 if the pointer is not empty or begins with '/'
@throw parse_error.108 if character '~' is not followed by '0' or '1'
*/
static std::vector<std::string> split(const Twine& reference_string);
static std::vector<std::string> split(std::string_view reference_string);
/*!
@brief replace all occurrences of a substring by another string
@@ -2521,7 +2521,7 @@ class json_pointer
@note Empty objects or arrays are flattened to `null`.
*/
static void flatten(const Twine& reference_string,
static void flatten(std::string_view reference_string,
const json& value,
json& result);
@@ -2970,7 +2970,7 @@ class json
json_value(value_t t);
/// constructor for strings
json_value(StringRef value)
json_value(std::string_view value)
{
string = create<std::string>(value);
}
@@ -3576,8 +3576,7 @@ class json
}
default:
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " +
Twine(first.m_object->type_name())));
JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from", first.m_object->type_name()));
}
assert_invariant();
@@ -4162,7 +4161,7 @@ class json
return m_value.boolean;
}
JSON_THROW(type_error::create(302, "type must be boolean, but is " + Twine(type_name())));
JSON_THROW(type_error::create(302, "type must be boolean, but is", type_name()));
}
/// get a pointer to the value (object)
@@ -4271,7 +4270,7 @@ class json
return *ptr;
}
JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + Twine(obj.type_name())));
JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is", obj.type_name()));
}
public:
@@ -4716,7 +4715,7 @@ class json
written using `at()`. It also demonstrates the different exceptions that
can be thrown.,at__object_t_key_type}
*/
reference at(StringRef key);
reference at(std::string_view key);
/*!
@brief access specified object element with bounds checking
@@ -4748,7 +4747,7 @@ class json
`at()`. It also demonstrates the different exceptions that can be thrown.,
at__object_t_key_type_const}
*/
const_reference at(StringRef key) const;
const_reference at(std::string_view key) const;
/*!
@brief access specified array element
@@ -4825,7 +4824,7 @@ class json
@since version 1.0.0
*/
reference operator[](StringRef key);
reference operator[](std::string_view key);
/*!
@brief read-only access specified object element
@@ -4857,7 +4856,7 @@ class json
@since version 1.0.0
*/
const_reference operator[](StringRef key) const;
const_reference operator[](std::string_view key) const;
/*!
@brief access specified object element
@@ -4903,7 +4902,7 @@ class json
return m_value.object->operator[](key);
}
JSON_THROW(type_error::create(305, "cannot use operator[] with " + Twine(type_name())));
JSON_THROW(type_error::create(305, "cannot use operator[] with", type_name()));
}
/*!
@@ -4946,7 +4945,7 @@ class json
return m_value.object->find(key)->second;
}
JSON_THROW(type_error::create(305, "cannot use operator[] with " + Twine(type_name())));
JSON_THROW(type_error::create(305, "cannot use operator[] with", type_name()));
}
/*!
@@ -4999,7 +4998,7 @@ class json
*/
template<class ValueType, typename std::enable_if<
std::is_convertible<json_t, ValueType>::value, int>::type = 0>
ValueType value(StringRef key, const ValueType& default_value) const
ValueType value(std::string_view key, const ValueType& default_value) const
{
// at only works for objects
if (JSON_LIKELY(is_object()))
@@ -5014,14 +5013,14 @@ class json
return default_value;
}
JSON_THROW(type_error::create(306, "cannot use value() with " + Twine(type_name())));
JSON_THROW(type_error::create(306, "cannot use value() with", type_name()));
}
/*!
@brief overload for a default value of type const char*
@copydoc json::value(const typename object_t::key_type&, ValueType) const
*/
std::string value(StringRef key, const char* default_value) const
std::string value(std::string_view key, const char* default_value) const
{
return value(key, std::string(default_value));
}
@@ -5085,7 +5084,7 @@ class json
}
}
JSON_THROW(type_error::create(306, "cannot use value() with " + Twine(type_name())));
JSON_THROW(type_error::create(306, "cannot use value() with", type_name()));
}
/*!
@@ -5220,7 +5219,7 @@ class json
@sa @ref erase(IteratorType, IteratorType) -- removes the elements in
the given range
@sa @ref erase(StringRef) -- removes the element
@sa @ref erase(std::string_view) -- removes the element
from an object at the given key
@sa @ref erase(const size_type) -- removes the element from an array at
the given index
@@ -5278,7 +5277,7 @@ class json
}
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + Twine(type_name())));
JSON_THROW(type_error::create(307, "cannot use erase() with", type_name()));
}
}
@@ -5377,7 +5376,7 @@ class json
}
default:
JSON_THROW(type_error::create(307, "cannot use erase() with " + Twine(type_name())));
JSON_THROW(type_error::create(307, "cannot use erase() with", type_name()));
}
return result;
@@ -5412,7 +5411,7 @@ class json
@since version 1.0.0
*/
size_type erase(StringRef key);
size_type erase(std::string_view key);
/*!
@brief remove element from a JSON array given an index
@@ -5472,13 +5471,13 @@ class json
@since version 1.0.0
*/
iterator find(StringRef key);
iterator find(std::string_view key);
/*!
@brief find an element in a JSON object
@copydoc find(KeyT&&)
*/
const_iterator find(StringRef key) const;
const_iterator find(std::string_view key) const;
/*!
@brief returns the number of occurrences of a key in a JSON object
@@ -5501,7 +5500,7 @@ class json
@since version 1.0.0
*/
size_type count(StringRef key) const;
size_type count(std::string_view key) const;
/// @}
@@ -6113,7 +6112,7 @@ class json
// push_back only works for null objects or objects
if (JSON_UNLIKELY(not(is_null() or is_object())))
{
JSON_THROW(type_error::create(308, "cannot use push_back() with " + Twine(type_name())));
JSON_THROW(type_error::create(308, "cannot use push_back() with", type_name()));
}
// transform null object into an object
@@ -6203,7 +6202,7 @@ class json
// emplace_back only works for null objects or arrays
if (JSON_UNLIKELY(not(is_null() or is_array())))
{
JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + Twine(type_name())));
JSON_THROW(type_error::create(311, "cannot use emplace_back() with", type_name()));
}
// transform null object into an array
@@ -6246,12 +6245,12 @@ class json
@since version 2.0.8
*/
template<class... Args>
std::pair<iterator, bool> emplace(StringRef key, Args&& ... args)
std::pair<iterator, bool> emplace(std::string_view key, Args&& ... args)
{
// emplace only works for null objects or arrays
if (JSON_UNLIKELY(not(is_null() or is_object())))
{
JSON_THROW(type_error::create(311, "cannot use emplace() with " + Twine(type_name())));
JSON_THROW(type_error::create(311, "cannot use emplace() with", type_name()));
}
// transform null object into an object
@@ -6521,7 +6520,7 @@ class json
}
else
{
JSON_THROW(type_error::create(310, "cannot use swap() with " + Twine(type_name())));
JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
}
}
@@ -6554,7 +6553,7 @@ class json
}
else
{
JSON_THROW(type_error::create(310, "cannot use swap() with " + Twine(type_name())));
JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
}
}
@@ -6587,7 +6586,7 @@ class json
}
else
{
JSON_THROW(type_error::create(310, "cannot use swap() with " + Twine(type_name())));
JSON_THROW(type_error::create(310, "cannot use swap() with", type_name()));
}
}
@@ -7011,7 +7010,7 @@ class json
@since version 2.0.3 (contiguous containers)
*/
static json parse(StringRef s,
static json parse(std::string_view s,
const parser_callback_t cb = nullptr,
const bool allow_exceptions = true);
@@ -7026,7 +7025,7 @@ class json
const parser_callback_t cb = nullptr,
const bool allow_exceptions = true);
static bool accept(StringRef s);
static bool accept(std::string_view s);
static bool accept(ArrayRef<uint8_t> arr);
@@ -8074,7 +8073,7 @@ if no parse error occurred.
*/
inline wpi::json operator "" _json(const char* s, std::size_t n)
{
return wpi::json::parse(wpi::StringRef(s, n));
return wpi::json::parse(std::string_view(s, n));
}
/*!
@@ -8092,7 +8091,7 @@ object if no parse error occurred.
*/
inline wpi::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
{
return wpi::json::json_pointer(wpi::StringRef(s, n));
return wpi::json::json_pointer(std::string_view(s, n));
}
#ifndef WPI_JSON_IMPLEMENTATION

View File

@@ -10,13 +10,12 @@
#include <algorithm>
#include <cstddef>
#include <string>
#include <string_view>
#include <system_error>
#include <vector>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include "wpi/Twine.h"
namespace wpi {
@@ -100,7 +99,7 @@ class raw_istream {
// @param buf Buffer for output
// @param maxLen Maximum length
// @return Line
StringRef getline(SmallVectorImpl<char>& buf, int maxLen);
std::string_view getline(SmallVectorImpl<char>& buf, int maxLen);
virtual void close() = 0;
@@ -154,7 +153,7 @@ class raw_mem_istream : public raw_istream {
class raw_fd_istream : public raw_istream {
public:
raw_fd_istream(const Twine& filename, std::error_code& ec,
raw_fd_istream(std::string_view filename, std::error_code& ec,
size_t bufSize = 4096);
raw_fd_istream(int fd, bool shouldClose, size_t bufSize = 4096);
~raw_fd_istream() override;

View File

@@ -16,7 +16,6 @@
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -34,11 +33,6 @@ enum CreationDisposition : unsigned;
namespace wpi {
class format_object_base;
class FormattedString;
class FormattedNumber;
class FormattedBytes;
/// This class implements an extremely fast bulk output stream that can *only*
/// output to a stream. It does not support seeking, reopening, rewinding, line
/// buffered disciplines etc. It is a simple buffer that outputs
@@ -180,21 +174,6 @@ public:
return *this;
}
raw_ostream &operator<<(StringRef Str) {
// Inline fast path, particularly for strings with a known length.
size_t Size = Str.size();
// Make sure we can use the fast path.
if (Size > (size_t)(OutBufEnd - OutBufCur))
return write(Str.data(), Size);
if (Size) {
memcpy(OutBufCur, Str.data(), Size);
OutBufCur += Size;
}
return *this;
}
raw_ostream &operator<<(std::string_view Str) {
// Inline fast path, particularly for strings with a known length.
size_t Size = Str.size();
@@ -214,7 +193,7 @@ public:
// Inline fast path, particularly for constant strings where a sufficiently
// smart compiler will simplify strlen.
return this->operator<<(StringRef(Str));
return this->operator<<(std::string_view(Str));
}
raw_ostream &operator<<(const std::string &Str) {
@@ -235,28 +214,9 @@ public:
return write(Arr.data(), Arr.size());
}
raw_ostream &operator<<(unsigned long N);
raw_ostream &operator<<(long N);
raw_ostream &operator<<(unsigned long long N);
raw_ostream &operator<<(long long N);
raw_ostream &operator<<(const void *P);
raw_ostream &operator<<(unsigned int N) {
return this->operator<<(static_cast<unsigned long>(N));
}
raw_ostream &operator<<(int N) {
return this->operator<<(static_cast<long>(N));
}
raw_ostream &operator<<(double N);
/// Output \p N in hexadecimal, without any prefix or padding.
raw_ostream &write_hex(unsigned long long N);
/// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
/// satisfy wpi::isPrint into an escape sequence.
raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false);
raw_ostream &write(unsigned char C);
raw_ostream &write(const char *Ptr, size_t Size);
@@ -264,18 +224,6 @@ public:
return write(reinterpret_cast<const char *>(Ptr), Size);
}
// Formatted output, see the format() function in Support/Format.h.
raw_ostream &operator<<(const format_object_base &Fmt);
// Formatted output, see the leftJustify() function in Support/Format.h.
raw_ostream &operator<<(const FormattedString &);
// Formatted output, see the formatHex() function in Support/Format.h.
raw_ostream &operator<<(const FormattedNumber &);
// Formatted output, see the format_bytes() function in Support/Format.h.
raw_ostream &operator<<(const FormattedBytes &);
/// indent - Insert 'NumSpaces' spaces.
raw_ostream &indent(unsigned NumSpaces);
@@ -443,14 +391,14 @@ public:
/// As a special case, if Filename is "-", then the stream will use
/// STDOUT_FILENO instead of opening a file. This will not close the stdout
/// descriptor.
raw_fd_ostream(StringRef Filename, std::error_code &EC);
raw_fd_ostream(StringRef Filename, std::error_code &EC,
raw_fd_ostream(std::string_view Filename, std::error_code &EC);
raw_fd_ostream(std::string_view Filename, std::error_code &EC,
fs::CreationDisposition Disp);
raw_fd_ostream(StringRef Filename, std::error_code &EC,
raw_fd_ostream(std::string_view Filename, std::error_code &EC,
fs::FileAccess Access);
raw_fd_ostream(StringRef Filename, std::error_code &EC,
raw_fd_ostream(std::string_view Filename, std::error_code &EC,
fs::OpenFlags Flags);
raw_fd_ostream(StringRef Filename, std::error_code &EC,
raw_fd_ostream(std::string_view Filename, std::error_code &EC,
fs::CreationDisposition Disp, fs::FileAccess Access,
fs::OpenFlags Flags);
@@ -559,8 +507,8 @@ public:
void flush() = delete;
/// Return a StringRef for the vector contents.
StringRef str() { return StringRef(OS.data(), OS.size()); }
/// Return a std::string_view for the vector contents.
std::string_view str() { return std::string_view(OS.data(), OS.size()); }
};
/// A raw_ostream that writes to a vector. This is a
@@ -592,8 +540,8 @@ public:
void flush() = delete;
/// Return a StringRef for the vector contents.
StringRef str() { return StringRef(OS.data(), OS.size()); }
/// Return a std::string_view for the vector contents.
std::string_view str() { return std::string_view(OS.data(), OS.size()); }
};
/// A raw_ostream that writes to an SmallVector or SmallString. This is a
@@ -658,7 +606,7 @@ public:
void flush() = delete;
/// Return a StringRef for the vector contents.
/// Return a ArrayRef for the vector contents.
ArrayRef<uint8_t> array() { return ArrayRef<uint8_t>(OS.data(), OS.size()); }
};

View File

@@ -23,8 +23,7 @@
#include <stdint.h>
#include <string>
#include "wpi/StringRef.h"
#include <string_view>
namespace wpi {
template <typename T>
@@ -34,12 +33,12 @@ class raw_istream;
class SHA1 {
public:
SHA1();
void Update(StringRef s);
void Update(std::string_view s);
void Update(raw_istream& is);
std::string Final();
StringRef Final(SmallVectorImpl<char>& buf);
StringRef RawFinal(SmallVectorImpl<char>& buf);
static std::string FromFile(StringRef filename);
std::string_view Final(SmallVectorImpl<char>& buf);
std::string_view RawFinal(SmallVectorImpl<char>& buf);
static std::string FromFile(std::string_view filename);
private:
uint32_t digest[5];

View File

@@ -9,11 +9,11 @@
#include <cstring>
#include <initializer_list>
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/StringRef.h"
namespace wpi::uv {
@@ -30,7 +30,7 @@ class Buffer : public uv_buf_t {
base = oth.base;
len = oth.len;
}
/*implicit*/ Buffer(StringRef str) // NOLINT
/*implicit*/ Buffer(std::string_view str) // NOLINT
: Buffer{str.data(), str.size()} {}
/*implicit*/ Buffer(ArrayRef<uint8_t> arr) // NOLINT
: Buffer{reinterpret_cast<const char*>(arr.data()), arr.size()} {}
@@ -51,7 +51,7 @@ class Buffer : public uv_buf_t {
static Buffer Allocate(size_t size) { return Buffer{new char[size], size}; }
static Buffer Dup(StringRef in) {
static Buffer Dup(std::string_view in) {
Buffer buf = Allocate(in.size());
std::memcpy(buf.base, in.data(), in.size());
return buf;

View File

@@ -9,9 +9,9 @@
#include <memory>
#include <string>
#include <string_view>
#include "wpi/Signal.h"
#include "wpi/Twine.h"
#include "wpi/uv/Handle.h"
namespace wpi::uv {
@@ -51,7 +51,7 @@ class FsEvent final : public HandleImpl<FsEvent, uv_fs_event_t> {
* @param events Bitmask of event flags. Only UV_FS_EVENT_RECURSIVE is
* supported (and only on OSX and Windows).
*/
void Start(const Twine& path, unsigned int flags = 0);
void Start(std::string_view path, unsigned int flags = 0);
/**
* Stop watching for changes.

View File

@@ -9,9 +9,9 @@
#include <functional>
#include <memory>
#include <string_view>
#include "wpi/Signal.h"
#include "wpi/Twine.h"
#include "wpi/uv/Request.h"
namespace wpi::uv {
@@ -40,7 +40,7 @@ class GetAddrInfoReq : public RequestImpl<GetAddrInfoReq, uv_getaddrinfo_t> {
* request when the resolution completes. HandleError() is called on the
* request if any errors occur.
*
* Either node or service may be null (`Twine::createNull()`) but not both.
* Either node or service may be empty but not both.
*
* @param loop Event loop
* @param req request
@@ -50,7 +50,7 @@ class GetAddrInfoReq : public RequestImpl<GetAddrInfoReq, uv_getaddrinfo_t> {
* type constraints.
*/
void GetAddrInfo(Loop& loop, const std::shared_ptr<GetAddrInfoReq>& req,
const Twine& node, const Twine& service = Twine::createNull(),
std::string_view node, std::string_view service = {},
const addrinfo* hints = nullptr);
/**
@@ -58,7 +58,7 @@ void GetAddrInfo(Loop& loop, const std::shared_ptr<GetAddrInfoReq>& req,
* request when the resolution completes. HandleError() is called on the
* request if any errors occur.
*
* Either node or service may be null (`Twine::createNull()`) but not both.
* Either node or service may be empty but not both.
*
* @param loop Event loop
* @param req request
@@ -69,8 +69,7 @@ void GetAddrInfo(Loop& loop, const std::shared_ptr<GetAddrInfoReq>& req,
*/
inline void GetAddrInfo(const std::shared_ptr<Loop>& loop,
const std::shared_ptr<GetAddrInfoReq>& req,
const Twine& node,
const Twine& service = Twine::createNull(),
std::string_view node, std::string_view service = {},
const addrinfo* hints = nullptr) {
GetAddrInfo(*loop, req, node, service, hints);
}
@@ -80,7 +79,7 @@ inline void GetAddrInfo(const std::shared_ptr<Loop>& loop,
* completes, and errors are forwarded to the loop. This is a convenience
* wrapper.
*
* Either node or service may be null (`Twine::createNull()`) but not both.
* Either node or service may be empty but not both.
*
* @param loop Event loop
* @param callback Callback function to call when resolution completes
@@ -90,7 +89,7 @@ inline void GetAddrInfo(const std::shared_ptr<Loop>& loop,
* type constraints.
*/
void GetAddrInfo(Loop& loop, std::function<void(const addrinfo&)> callback,
const Twine& node, const Twine& service = Twine::createNull(),
std::string_view node, std::string_view service = {},
const addrinfo* hints = nullptr);
/**
@@ -98,7 +97,7 @@ void GetAddrInfo(Loop& loop, std::function<void(const addrinfo&)> callback,
* completes, and errors are forwarded to the loop. This is a convenience
* wrapper.
*
* Either node or service may be null (`Twine::createNull()`) but not both.
* Either node or service may be empty but not both.
*
* @param loop Event loop
* @param callback Callback function to call when resolution completes
@@ -109,8 +108,7 @@ void GetAddrInfo(Loop& loop, std::function<void(const addrinfo&)> callback,
*/
inline void GetAddrInfo(const std::shared_ptr<Loop>& loop,
std::function<void(const addrinfo&)> callback,
const Twine& node,
const Twine& service = Twine::createNull(),
std::string_view node, std::string_view service = {},
const addrinfo* hints = nullptr) {
GetAddrInfo(*loop, callback, node, service, hints);
}

View File

@@ -9,9 +9,9 @@
#include <functional>
#include <memory>
#include <string_view>
#include "wpi/Signal.h"
#include "wpi/Twine.h"
#include "wpi/uv/Request.h"
namespace wpi::uv {
@@ -105,7 +105,7 @@ inline void GetNameInfo(const std::shared_ptr<Loop>& loop,
* @param flags Optional flags to modify the behavior of `getnameinfo`.
*/
void GetNameInfo4(Loop& loop, const std::shared_ptr<GetNameInfoReq>& req,
const Twine& ip, unsigned int port, int flags = 0);
std::string_view ip, unsigned int port, int flags = 0);
/**
* Asynchronous IPv4 getnameinfo(3). HandleResolvedName() is called on the
@@ -120,7 +120,8 @@ void GetNameInfo4(Loop& loop, const std::shared_ptr<GetNameInfoReq>& req,
*/
inline void GetNameInfo4(const std::shared_ptr<Loop>& loop,
const std::shared_ptr<GetNameInfoReq>& req,
const Twine& ip, unsigned int port, int flags = 0) {
std::string_view ip, unsigned int port,
int flags = 0) {
return GetNameInfo4(*loop, req, ip, port, flags);
}
@@ -136,7 +137,7 @@ inline void GetNameInfo4(const std::shared_ptr<Loop>& loop,
*/
void GetNameInfo4(Loop& loop,
std::function<void(const char*, const char*)> callback,
const Twine& ip, unsigned int port, int flags = 0);
std::string_view ip, unsigned int port, int flags = 0);
/**
* Asynchronous IPv4 getnameinfo(3). The callback is called when the resolution
@@ -151,7 +152,8 @@ void GetNameInfo4(Loop& loop,
*/
inline void GetNameInfo4(const std::shared_ptr<Loop>& loop,
std::function<void(const char*, const char*)> callback,
const Twine& ip, unsigned int port, int flags = 0) {
std::string_view ip, unsigned int port,
int flags = 0) {
return GetNameInfo4(*loop, callback, ip, port, flags);
}
@@ -167,7 +169,7 @@ inline void GetNameInfo4(const std::shared_ptr<Loop>& loop,
* @param flags Optional flags to modify the behavior of `getnameinfo`.
*/
void GetNameInfo6(Loop& loop, const std::shared_ptr<GetNameInfoReq>& req,
const Twine& ip, unsigned int port, int flags = 0);
std::string_view ip, unsigned int port, int flags = 0);
/**
* Asynchronous IPv6 getnameinfo(3). HandleResolvedName() is called on the
@@ -182,7 +184,8 @@ void GetNameInfo6(Loop& loop, const std::shared_ptr<GetNameInfoReq>& req,
*/
inline void GetNameInfo6(const std::shared_ptr<Loop>& loop,
const std::shared_ptr<GetNameInfoReq>& req,
const Twine& ip, unsigned int port, int flags = 0) {
std::string_view ip, unsigned int port,
int flags = 0) {
GetNameInfo6(*loop, req, ip, port, flags);
}
@@ -199,7 +202,7 @@ inline void GetNameInfo6(const std::shared_ptr<Loop>& loop,
*/
void GetNameInfo6(Loop& loop,
std::function<void(const char*, const char*)> callback,
const Twine& ip, unsigned int port, int flags = 0);
std::string_view ip, unsigned int port, int flags = 0);
/**
* Asynchronous IPv6 getnameinfo(3). The callback is called when the resolution
@@ -214,7 +217,8 @@ void GetNameInfo6(Loop& loop,
*/
inline void GetNameInfo6(const std::shared_ptr<Loop>& loop,
std::function<void(const char*, const char*)> callback,
const Twine& ip, unsigned int port, int flags = 0) {
std::string_view ip, unsigned int port,
int flags = 0) {
return GetNameInfo6(*loop, callback, ip, port, flags);
}

View File

@@ -10,10 +10,10 @@
#include <cstdlib>
#include <functional>
#include <memory>
#include <string_view>
#include <utility>
#include "wpi/Signal.h"
#include "wpi/StringRef.h"
#include "wpi/uv/Buffer.h"
#include "wpi/uv/Error.h"
#include "wpi/uv/Loop.h"
@@ -50,7 +50,7 @@ class Handle : public std::enable_shared_from_this<Handle> {
/**
* Get the name of the type of the handle. E.g. "pipe" for pipe handles.
*/
StringRef GetTypeName() const noexcept {
std::string_view GetTypeName() const noexcept {
return uv_handle_type_name(m_uv_handle->type);
}

View File

@@ -10,8 +10,8 @@
#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include "wpi/Twine.h"
#include "wpi/uv/NetworkStream.h"
namespace wpi::uv {
@@ -119,7 +119,7 @@ class Pipe final : public NetworkStreamImpl<Pipe, uv_pipe_t> {
*
* @param name File path (Unix) or name (Windows).
*/
void Bind(const Twine& name);
void Bind(std::string_view name);
/**
* Connect to the Unix domain socket or the named pipe.
@@ -135,7 +135,8 @@ class Pipe final : public NetworkStreamImpl<Pipe, uv_pipe_t> {
* @param name File path (Unix) or name (Windows).
* @param req connection request
*/
void Connect(const Twine& name, const std::shared_ptr<PipeConnectReq>& req);
void Connect(std::string_view name,
const std::shared_ptr<PipeConnectReq>& req);
/**
* Connect to the Unix domain socket or the named pipe.
@@ -149,7 +150,7 @@ class Pipe final : public NetworkStreamImpl<Pipe, uv_pipe_t> {
* @param name File path (Unix) or name (Windows).
* @param callback Callback function to call when connection established
*/
void Connect(const Twine& name, std::function<void()> callback);
void Connect(std::string_view name, std::function<void()> callback);
/**
* Get the name of the Unix domain socket or the named pipe.

View File

@@ -10,11 +10,11 @@
#include <initializer_list>
#include <memory>
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/SmallVector.h"
#include "wpi/Twine.h"
#include "wpi/uv/Handle.h"
namespace wpi::uv {
@@ -35,9 +35,9 @@ class Process final : public HandleImpl<Process, uv_process_t> {
~Process() noexcept override = default;
/**
* Structure for Spawn() option temporaries. This is a reference type
* similar to StringRef, so if this value is stored outside of a temporary,
* be careful about overwriting what it points to.
* Structure for Spawn() option temporaries. This is a reference type, so if
* this value is stored outside of a temporary, be careful about overwriting
* what it points to.
*/
struct Option {
enum Type {
@@ -65,7 +65,7 @@ class Process final : public HandleImpl<Process, uv_process_t> {
m_data.str = arg.data();
}
/*implicit*/ Option(StringRef arg) // NOLINT
/*implicit*/ Option(std::string_view arg) // NOLINT
: m_strData(arg) {
m_data.str = m_strData.c_str();
}
@@ -75,11 +75,6 @@ class Process final : public HandleImpl<Process, uv_process_t> {
m_data.str = m_strData.c_str();
}
/*implicit*/ Option(const Twine& arg) // NOLINT
: m_strData(arg.str()) {
m_data.str = m_strData.c_str();
}
explicit Option(Type type) : m_type(type) {}
Type m_type = kArg;
@@ -105,9 +100,9 @@ class Process final : public HandleImpl<Process, uv_process_t> {
* environment is used.
* @param env environment variable
*/
static Option Env(const Twine& env) {
static Option Env(std::string_view env) {
Option o(Option::kEnv);
o.m_strData = env.str();
o.m_strData = env;
o.m_data.str = o.m_strData.c_str();
return o;
}
@@ -116,9 +111,9 @@ class Process final : public HandleImpl<Process, uv_process_t> {
* Set the current working directory for the subprocess.
* @param cwd current working directory
*/
static Option Cwd(const Twine& cwd) {
static Option Cwd(std::string_view cwd) {
Option o(Option::kCwd);
o.m_strData = cwd.str();
o.m_strData = cwd;
o.m_data.str = o.m_strData.c_str();
return o;
}
@@ -236,16 +231,17 @@ class Process final : public HandleImpl<Process, uv_process_t> {
* @param file Path pointing to the program to be executed
* @param options Process options
*/
static std::shared_ptr<Process> SpawnArray(Loop& loop, const Twine& file,
static std::shared_ptr<Process> SpawnArray(Loop& loop, std::string_view file,
ArrayRef<Option> options);
static std::shared_ptr<Process> SpawnArray(
Loop& loop, const Twine& file, std::initializer_list<Option> options) {
Loop& loop, std::string_view file,
std::initializer_list<Option> options) {
return SpawnArray(loop, file, makeArrayRef(options.begin(), options.end()));
}
template <typename... Args>
static std::shared_ptr<Process> Spawn(Loop& loop, const Twine& file,
static std::shared_ptr<Process> Spawn(Loop& loop, std::string_view file,
const Args&... options) {
return SpawnArray(loop, file, {options...});
}
@@ -264,20 +260,20 @@ class Process final : public HandleImpl<Process, uv_process_t> {
* @param options Process options
*/
static std::shared_ptr<Process> SpawnArray(const std::shared_ptr<Loop>& loop,
const Twine& file,
std::string_view file,
ArrayRef<Option> options) {
return SpawnArray(*loop, file, options);
}
static std::shared_ptr<Process> SpawnArray(
const std::shared_ptr<Loop>& loop, const Twine& file,
const std::shared_ptr<Loop>& loop, std::string_view file,
std::initializer_list<Option> options) {
return SpawnArray(*loop, file, options);
}
template <typename... Args>
static std::shared_ptr<Process> Spawn(const std::shared_ptr<Loop>& loop,
const Twine& file,
std::string_view file,
const Args&... options) {
return SpawnArray(*loop, file, {options...});
}

View File

@@ -10,8 +10,8 @@
#include <chrono>
#include <functional>
#include <memory>
#include <string_view>
#include "wpi/Twine.h"
#include "wpi/uv/NetworkStream.h"
namespace wpi::uv {
@@ -185,7 +185,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to bind.
* @param flags Optional additional flags.
*/
void Bind(const Twine& ip, unsigned int port, unsigned int flags = 0);
void Bind(std::string_view ip, unsigned int port, unsigned int flags = 0);
/**
* Bind the handle to an IPv6 address and port.
@@ -201,7 +201,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to bind.
* @param flags Optional additional flags.
*/
void Bind6(const Twine& ip, unsigned int port, unsigned int flags = 0);
void Bind6(std::string_view ip, unsigned int port, unsigned int flags = 0);
/**
* Get the current address to which the handle is bound.
@@ -281,7 +281,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to connect to.
* @param req connection request
*/
void Connect(const Twine& ip, unsigned int port,
void Connect(std::string_view ip, unsigned int port,
const std::shared_ptr<TcpConnectReq>& req);
/**
@@ -298,7 +298,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to connect to.
* @param callback Callback function to call when connection established
*/
void Connect(const Twine& ip, unsigned int port,
void Connect(std::string_view ip, unsigned int port,
std::function<void()> callback);
/**
@@ -317,7 +317,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to connect to.
* @param req connection request
*/
void Connect6(const Twine& ip, unsigned int port,
void Connect6(std::string_view ip, unsigned int port,
const std::shared_ptr<TcpConnectReq>& req);
/**
@@ -334,7 +334,7 @@ class Tcp final : public NetworkStreamImpl<Tcp, uv_tcp_t> {
* @param port The port to which to connect to.
* @param callback Callback function to call when connection established
*/
void Connect6(const Twine& ip, unsigned int port,
void Connect6(std::string_view ip, unsigned int port,
std::function<void()> callback);
private:

View File

@@ -9,10 +9,10 @@
#include <functional>
#include <memory>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/Twine.h"
#include "wpi/uv/Handle.h"
#include "wpi/uv/Request.h"
@@ -100,7 +100,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param port The port to which to bind.
* @param flags Optional additional flags.
*/
void Bind(const Twine& ip, unsigned int port, unsigned int flags = 0);
void Bind(std::string_view ip, unsigned int port, unsigned int flags = 0);
/**
* Bind the handle to an IPv6 address and port.
@@ -109,7 +109,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param port The port to which to bind.
* @param flags Optional additional flags.
*/
void Bind6(const Twine& ip, unsigned int port, unsigned int flags = 0);
void Bind6(std::string_view ip, unsigned int port, unsigned int flags = 0);
/**
* Associate the handle to a remote address and port, so every message sent
@@ -136,7 +136,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param ip The address to which to bind.
* @param port The port to which to bind.
*/
void Connect(const Twine& ip, unsigned int port);
void Connect(std::string_view ip, unsigned int port);
/**
* Associate the handle to an IPv6 address and port, so every message sent
@@ -146,7 +146,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param port The port to which to bind.
* @param flags Optional additional flags.
*/
void Connect6(const Twine& ip, unsigned int port);
void Connect6(std::string_view ip, unsigned int port);
/**
* Get the remote IP and port on connected UDP handles.
@@ -167,8 +167,8 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param interfaceAddr Interface address
* @param membership Should be UV_JOIN_GROUP or UV_LEAVE_GROUP
*/
void SetMembership(const Twine& multicastAddr, const Twine& interfaceAddr,
uv_membership membership);
void SetMembership(std::string_view multicastAddr,
std::string_view interfaceAddr, uv_membership membership);
/**
* Set IP multicast loop flag. Makes multicast packets loop back to local
@@ -194,7 +194,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
*
* @param interfaceAddr Interface address
*/
void SetMulticastInterface(const Twine& interfaceAddr);
void SetMulticastInterface(std::string_view interfaceAddr);
/**
* Set broadcast on or off.

View File

@@ -8,8 +8,7 @@
#include <uv.h>
#include <cstring>
#include "wpi/Twine.h"
#include <string_view>
namespace wpi::uv {
@@ -116,7 +115,7 @@ int AddrToName(const in6_addr& addr, T* ip) {
* @param addr Output binary structure
* @return Error (same as `uv_ip4_addr()`).
*/
int NameToAddr(const Twine& ip, unsigned int port, sockaddr_in* addr);
int NameToAddr(std::string_view ip, unsigned int port, sockaddr_in* addr);
/**
* Convert a string containing an IPv6 address to a binary structure.
@@ -125,7 +124,7 @@ int NameToAddr(const Twine& ip, unsigned int port, sockaddr_in* addr);
* @param addr Output binary structure
* @return Error (same as `uv_ip6_addr()`).
*/
int NameToAddr(const Twine& ip, unsigned int port, sockaddr_in6* addr);
int NameToAddr(std::string_view ip, unsigned int port, sockaddr_in6* addr);
/**
* Convert a string containing an IPv4 address to binary format.
@@ -133,7 +132,7 @@ int NameToAddr(const Twine& ip, unsigned int port, sockaddr_in6* addr);
* @param addr Output binary
* @return Error (same as `uv_inet_pton()`).
*/
int NameToAddr(const Twine& ip, in_addr* addr);
int NameToAddr(std::string_view ip, in_addr* addr);
/**
* Convert a string containing an IPv6 address to binary format.
@@ -141,7 +140,7 @@ int NameToAddr(const Twine& ip, in_addr* addr);
* @param addr Output binary
* @return Error (same as `uv_inet_pton()`).
*/
int NameToAddr(const Twine& ip, in6_addr* addr);
int NameToAddr(std::string_view ip, in6_addr* addr);
} // namespace wpi::uv