Use wpi::span instead of wpi::ArrayRef across all libraries (#3414)

- Remove ArrayRef.h
- Add SpanExtras.h for a couple of convenience functions
This commit is contained in:
Peter Johnson
2021-06-06 19:51:14 -07:00
committed by GitHub
parent 2abbbd9e70
commit 64f5413253
167 changed files with 974 additions and 1433 deletions

View File

@@ -1,586 +0,0 @@
//===- ArrayRef.h - Array 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_ARRAYREF_H
#define WPIUTIL_WPI_ARRAYREF_H
#include "wpi/Hashing.h"
#include "wpi/SmallVector.h"
#include "wpi/STLExtras.h"
#include "wpi/Compiler.h"
#include "wpi/span.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <optional>
#include <type_traits>
#include <vector>
#if __cplusplus >= 202002L && __has_include(<span>)
#include <span>
#endif
namespace wpi {
/// ArrayRef - Represent a constant reference to an array (0 or more elements
/// consecutively in memory), i.e. a start pointer and a length. It allows
/// various APIs to take consecutive elements easily and conveniently.
///
/// This class does not own the underlying data, it is expected to be used in
/// situations where the data resides in some other buffer, whose lifetime
/// extends past that of the ArrayRef. For this reason, it is not in general
/// safe to store an ArrayRef.
///
/// This is intended to be trivially copyable, so it should be passed by
/// value.
template<typename T>
class LLVM_NODISCARD ArrayRef {
public:
using iterator = const T *;
using const_iterator = const T *;
using size_type = size_t;
using reverse_iterator = std::reverse_iterator<iterator>;
using value_type = T;
private:
/// The start of the array, in an external buffer.
const T *Data = nullptr;
/// The number of elements.
size_type Length = 0;
public:
/// @name Constructors
/// @{
/// Construct an empty ArrayRef.
/*implicit*/ ArrayRef() = default;
/// Construct an empty ArrayRef from nullopt.
/*implicit*/ ArrayRef(std::nullopt_t) {}
/// Construct an ArrayRef from a single element.
/*implicit*/ ArrayRef(const T &OneElt)
: Data(&OneElt), Length(1) {}
/// Construct an ArrayRef from a pointer and length.
/*implicit*/ ArrayRef(const T *data, size_t length)
: Data(data), Length(length) {}
/// Construct an ArrayRef from a range.
ArrayRef(const T *begin, const T *end)
: Data(begin), Length(end - begin) {}
/// Construct an ArrayRef from a SmallVector. This is templated in order to
/// avoid instantiating SmallVectorTemplateCommon<T> whenever we
/// copy-construct an ArrayRef.
template<typename U>
/*implicit*/ ArrayRef(const SmallVectorTemplateCommon<T, U> &Vec)
: Data(Vec.data()), Length(Vec.size()) {
}
/// Construct an ArrayRef from a std::vector.
template<typename A>
/*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
: Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a std::array
template <size_t N>
/*implicit*/ constexpr ArrayRef(const std::array<T, N> &Arr)
: Data(Arr.data()), Length(N) {}
/// Construct an ArrayRef from a C array.
template <size_t N>
/*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
/// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
/// ensure that only ArrayRefs of pointers can be converted.
template <typename U>
ArrayRef(
const ArrayRef<U *> &A,
typename std::enable_if<
std::is_convertible<U *const *, T const *>::value>::type * = nullptr)
: Data(A.data()), Length(A.size()) {}
/// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
/// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
/// whenever we copy-construct an ArrayRef.
template<typename U, typename DummyT>
/*implicit*/ ArrayRef(
const SmallVectorTemplateCommon<U *, DummyT> &Vec,
typename std::enable_if<
std::is_convertible<U *const *, T const *>::value>::type * = nullptr)
: Data(Vec.data()), Length(Vec.size()) {
}
/// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
/// to ensure that only vectors of pointers can be converted.
template<typename U, typename A>
ArrayRef(const std::vector<U *, A> &Vec,
typename std::enable_if<
std::is_convertible<U *const *, T const *>::value>::type* = 0)
: Data(Vec.data()), Length(Vec.size()) {}
#ifdef __cpp_lib_span
/// Construct an ArrayRef from std::span
/*implicit*/ ArrayRef(std::span<T> Span)
: Data(Span.data()), Length(Span.size()) {}
/// Construct an ArrayRef from std::span
/*implicit*/ ArrayRef(std::span<const T> Span)
: Data(Span.data()), Length(Span.size()) {}
#endif
/// Construct an ArrayRef from wpi::span
/*implicit*/ ArrayRef(span<T> Span)
: Data(Span.data()), Length(Span.size()) {}
/// Construct an ArrayRef from wpi::span
/*implicit*/ ArrayRef(span<const T> Span)
: Data(Span.data()), Length(Span.size()) {}
/// @}
/// @name Simple Operations
/// @{
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
/// empty - Check if the array is empty.
bool empty() const { return Length == 0; }
const T *data() const { return Data; }
/// size - Get the array size.
size_t size() const { return Length; }
/// front - Get the first element.
const T &front() const {
assert(!empty());
return Data[0];
}
/// back - Get the last element.
const T &back() const {
assert(!empty());
return Data[Length-1];
}
// copy - Allocate copy in Allocator and return ArrayRef<T> to it.
template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
T *Buff = A.template Allocate<T>(Length);
std::uninitialized_copy(begin(), end(), Buff);
return ArrayRef<T>(Buff, Length);
}
/// equals - Check for element-wise equality.
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
return false;
return std::equal(begin(), end(), RHS.begin());
}
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
ArrayRef<T> slice(size_t N, size_t M) const {
assert(N+M <= size() && "Invalid specifier");
return ArrayRef<T>(data()+N, M);
}
/// slice(n) - Chop off the first N elements of the array.
ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); }
/// Drop the first \p N elements of the array.
ArrayRef<T> drop_front(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return slice(N, size() - N);
}
/// Drop the last \p N elements of the array.
ArrayRef<T> drop_back(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return slice(0, size() - N);
}
/// Return a copy of *this with the first N elements satisfying the
/// given predicate removed.
template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const {
return ArrayRef<T>(find_if_not(*this, Pred), end());
}
/// Return a copy of *this with the first N elements not satisfying
/// the given predicate removed.
template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const {
return ArrayRef<T>(find_if(*this, Pred), end());
}
/// Return a copy of *this with only the first \p N elements.
ArrayRef<T> take_front(size_t N = 1) const {
if (N >= size())
return *this;
return drop_back(size() - N);
}
/// Return a copy of *this with only the last \p N elements.
ArrayRef<T> take_back(size_t N = 1) const {
if (N >= size())
return *this;
return drop_front(size() - N);
}
/// Return the first N elements of this Array that satisfy the given
/// predicate.
template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const {
return ArrayRef<T>(begin(), find_if_not(*this, Pred));
}
/// Return the first N elements of this Array that don't satisfy the
/// given predicate.
template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const {
return ArrayRef<T>(begin(), find_if(*this, Pred));
}
/// @}
/// @name Operator Overloads
/// @{
const T &operator[](size_t Index) const {
assert(Index < Length && "Invalid index!");
return Data[Index];
}
/// Disallow accidental assignment from a temporary.
///
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
operator=(U &&Temporary) = delete;
/// Disallow accidental assignment from a temporary.
///
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
operator=(std::initializer_list<U>) = delete;
/// @}
/// @name Expensive Operations
/// @{
std::vector<T> vec() const {
return std::vector<T>(Data, Data+Length);
}
/// @}
/// @name Conversion operators
/// @{
operator std::vector<T>() const {
return std::vector<T>(Data, Data+Length);
}
#ifdef __cpp_lib_span
operator std::span<const T>() const {
return std::span<const T>(Data, Length);
}
#endif
operator span<const T>() const {
return span<const T>(Data, Length);
}
/// @}
};
/// MutableArrayRef - Represent a mutable reference to an array (0 or more
/// elements consecutively in memory), i.e. a start pointer and a length. It
/// allows various APIs to take and modify consecutive elements easily and
/// conveniently.
///
/// This class does not own the underlying data, it is expected to be used in
/// situations where the data resides in some other buffer, whose lifetime
/// extends past that of the MutableArrayRef. For this reason, it is not in
/// general safe to store a MutableArrayRef.
///
/// This is intended to be trivially copyable, so it should be passed by
/// value.
template<typename T>
class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> {
public:
using iterator = T *;
using reverse_iterator = std::reverse_iterator<iterator>;
/// Construct an empty MutableArrayRef.
/*implicit*/ MutableArrayRef() = default;
/// Construct an empty MutableArrayRef from nullopt.
/*implicit*/ MutableArrayRef(std::nullopt_t) : ArrayRef<T>() {}
/// Construct an MutableArrayRef from a single element.
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
/// Construct an MutableArrayRef from a pointer and length.
/*implicit*/ MutableArrayRef(T *data, size_t length)
: ArrayRef<T>(data, length) {}
/// Construct an MutableArrayRef from a range.
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
/// Construct an MutableArrayRef from a SmallVector.
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
: ArrayRef<T>(Vec) {}
/// Construct a MutableArrayRef from a std::vector.
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
: ArrayRef<T>(Vec) {}
/// Construct an ArrayRef from a std::array
template <size_t N>
/*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr)
: ArrayRef<T>(Arr) {}
/// Construct an MutableArrayRef from a C array.
template <size_t N>
/*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
#ifdef __cpp_lib_span
/// Construct an ArrayRef from std::span
/*implicit*/ MutableArrayRef(std::span<T> Span) : ArrayRef<T>(Span) {}
#endif
/// Construct an ArrayRef from wpi::span
/*implicit*/ MutableArrayRef(span<T> Span) : ArrayRef<T>(Span) {}
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
iterator begin() const { return data(); }
iterator end() const { return data() + this->size(); }
reverse_iterator rbegin() const { return reverse_iterator(end()); }
reverse_iterator rend() const { return reverse_iterator(begin()); }
/// front - Get the first element.
T &front() const {
assert(!this->empty());
return data()[0];
}
/// back - Get the last element.
T &back() const {
assert(!this->empty());
return data()[this->size()-1];
}
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
MutableArrayRef<T> slice(size_t N, size_t M) const {
assert(N + M <= this->size() && "Invalid specifier");
return MutableArrayRef<T>(this->data() + N, M);
}
/// slice(n) - Chop off the first N elements of the array.
MutableArrayRef<T> slice(size_t N) const {
return slice(N, this->size() - N);
}
/// Drop the first \p N elements of the array.
MutableArrayRef<T> drop_front(size_t N = 1) const {
assert(this->size() >= N && "Dropping more elements than exist");
return slice(N, this->size() - N);
}
MutableArrayRef<T> drop_back(size_t N = 1) const {
assert(this->size() >= N && "Dropping more elements than exist");
return slice(0, this->size() - N);
}
/// Return a copy of *this with the first N elements satisfying the
/// given predicate removed.
template <class PredicateT>
MutableArrayRef<T> drop_while(PredicateT Pred) const {
return MutableArrayRef<T>(find_if_not(*this, Pred), end());
}
/// Return a copy of *this with the first N elements not satisfying
/// the given predicate removed.
template <class PredicateT>
MutableArrayRef<T> drop_until(PredicateT Pred) const {
return MutableArrayRef<T>(find_if(*this, Pred), end());
}
/// Return a copy of *this with only the first \p N elements.
MutableArrayRef<T> take_front(size_t N = 1) const {
if (N >= this->size())
return *this;
return drop_back(this->size() - N);
}
/// Return a copy of *this with only the last \p N elements.
MutableArrayRef<T> take_back(size_t N = 1) const {
if (N >= this->size())
return *this;
return drop_front(this->size() - N);
}
/// Return the first N elements of this Array that satisfy the given
/// predicate.
template <class PredicateT>
MutableArrayRef<T> take_while(PredicateT Pred) const {
return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));
}
/// Return the first N elements of this Array that don't satisfy the
/// given predicate.
template <class PredicateT>
MutableArrayRef<T> take_until(PredicateT Pred) const {
return MutableArrayRef<T>(begin(), find_if(*this, Pred));
}
/// @}
/// @name Operator Overloads
/// @{
T &operator[](size_t Index) const {
assert(Index < this->size() && "Invalid index!");
return data()[Index];
}
#ifdef __cpp_lib_span
operator std::span<T>() const {
return std::span<T>(data(), this->size());
}
#endif
operator span<T>() const {
return span<T>(data(), this->size());
}
};
/// This is a MutableArrayRef that owns its array.
template <typename T> class OwningArrayRef : public MutableArrayRef<T> {
public:
OwningArrayRef() = default;
OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {}
OwningArrayRef(ArrayRef<T> Data)
: MutableArrayRef<T>(new T[Data.size()], Data.size()) {
std::copy(Data.begin(), Data.end(), this->begin());
}
OwningArrayRef(OwningArrayRef &&Other) { *this = Other; }
OwningArrayRef &operator=(OwningArrayRef &&Other) {
delete[] this->data();
this->MutableArrayRef<T>::operator=(Other);
Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
return *this;
}
~OwningArrayRef() { delete[] this->data(); }
};
/// @name ArrayRef Convenience constructors
/// @{
/// Construct an ArrayRef from a single element.
template<typename T>
ArrayRef<T> makeArrayRef(const T &OneElt) {
return OneElt;
}
/// Construct an ArrayRef from a pointer and length.
template<typename T>
ArrayRef<T> makeArrayRef(const T *data, size_t length) {
return ArrayRef<T>(data, length);
}
/// Construct an ArrayRef from a range.
template<typename T>
ArrayRef<T> makeArrayRef(const T *begin, const T *end) {
return ArrayRef<T>(begin, end);
}
/// Construct an ArrayRef from a SmallVector.
template <typename T>
ArrayRef<T> makeArrayRef(const SmallVectorImpl<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a SmallVector.
template <typename T, unsigned N>
ArrayRef<T> makeArrayRef(const SmallVector<T, N> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a std::vector.
template<typename T>
ArrayRef<T> makeArrayRef(const std::vector<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from an ArrayRef (no-op) (const)
template <typename T> ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from an ArrayRef (no-op)
template <typename T> ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) {
return Vec;
}
/// Construct an ArrayRef from a C array.
template<typename T, size_t N>
ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
return ArrayRef<T>(Arr);
}
/// Construct a MutableArrayRef from a single element.
template<typename T>
MutableArrayRef<T> makeMutableArrayRef(T &OneElt) {
return OneElt;
}
/// Construct a MutableArrayRef from a pointer and length.
template<typename T>
MutableArrayRef<T> makeMutableArrayRef(T *data, size_t length) {
return MutableArrayRef<T>(data, length);
}
/// @}
/// @name ArrayRef Comparison Operators
/// @{
template<typename T>
inline bool operator==(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return LHS.equals(RHS);
}
template<typename T>
inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return !(LHS == RHS);
}
/// @}
// ArrayRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <typename T> struct isPodLike<ArrayRef<T>> {
static const bool value = true;
};
template <typename T> hash_code hash_value(ArrayRef<T> S) {
return hash_combine_range(S.begin(), S.end());
}
} // end namespace wpi
#endif // LLVM_ADT_ARRAYREF_H

View File

@@ -90,7 +90,7 @@
#ifndef LLVM_SUPPORT_CONVERTUTF_H
#define LLVM_SUPPORT_CONVERTUTF_H
#include "wpi/ArrayRef.h"
#include "wpi/span.h"
#include <cstddef>
#include <string>
@@ -102,6 +102,9 @@
namespace wpi {
template <typename T>
class SmallVectorImpl;
/* ---------------------------------------------------------------------
The following 4 definitions are compiler-specific.
The C standard does not guarantee that wchar_t has at least
@@ -228,14 +231,14 @@ static inline ConversionResult convertUTF8Sequence(const UTF8 **source,
* Returns true if a blob of text starts with a UTF-16 big or little endian byte
* order mark.
*/
bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
/**
* Converts a UTF-16 string into a UTF-8 string.
*
* \returns true on success
*/
bool convertUTF16ToUTF8String(ArrayRef<UTF16> SrcUTF16,
bool convertUTF16ToUTF8String(span<const UTF16> SrcUTF16,
SmallVectorImpl<char> &DstUTF8);
/**

View File

@@ -14,9 +14,9 @@
#ifndef WPIUTIL_WPI_DENSEMAPINFO_H
#define WPIUTIL_WPI_DENSEMAPINFO_H
#include "wpi/ArrayRef.h"
#include "wpi/Hashing.h"
#include "wpi/PointerLikeTypeTraits.h"
#include "wpi/span.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -234,26 +234,26 @@ template <> struct DenseMapInfo<std::string_view> {
}
};
// Provide DenseMapInfo for ArrayRefs.
template <typename T> struct DenseMapInfo<ArrayRef<T>> {
static inline ArrayRef<T> getEmptyKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
size_t(0));
// Provide DenseMapInfo for spans.
template <typename T> struct DenseMapInfo<span<T>> {
static inline span<T> getEmptyKey() {
return span<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
size_t(0));
}
static inline ArrayRef<T> getTombstoneKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
size_t(0));
static inline span<T> getTombstoneKey() {
return span<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
size_t(0));
}
static unsigned getHashValue(ArrayRef<T> Val) {
static unsigned getHashValue(span<T> 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(ArrayRef<T> LHS, ArrayRef<T> RHS) {
static bool isEqual(span<T> LHS, span<T> RHS) {
if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data();
if (RHS.data() == getTombstoneKey().data())

View File

@@ -8,8 +8,8 @@
#include <memory>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/HttpParser.h"
#include "wpi/span.h"
#include "wpi/uv/Stream.h"
namespace wpi {
@@ -78,7 +78,7 @@ class HttpServerConnection {
* is desired, call m_stream.Write() directly instead.
* @param closeAfter close the connection after the write completes
*/
void SendData(ArrayRef<uv::Buffer> bufs, bool closeAfter = false);
void SendData(span<const uv::Buffer> bufs, bool closeAfter = false);
/**
* Send HTTP response, along with other header information like mimetype.

View File

@@ -13,7 +13,6 @@
#include <utility>
#include <vector>
#include "wpi/ArrayRef.h"
#include "wpi/NetworkStream.h"
#include "wpi/SmallString.h"
#include "wpi/SmallVector.h"
@@ -21,6 +20,7 @@
#include "wpi/raw_istream.h"
#include "wpi/raw_socket_istream.h"
#include "wpi/raw_socket_ostream.h"
#include "wpi/span.h"
namespace wpi {
@@ -143,14 +143,12 @@ class HttpPath {
* @return True if path equals match list
*/
bool equals(std::initializer_list<std::string_view> match) const {
return equals(0, makeArrayRef(match.begin(), match.end()));
return equals(0, {match.begin(), match.end()});
}
bool equals(ArrayRef<std::string_view> match) const {
bool equals(span<const std::string_view> match) const {
return equals(0, match);
}
bool equals(std::string_view match) const {
return equals(0, makeArrayRef(match));
}
bool equals(std::string_view match) const { return equals(0, {match}); }
/**
* Returns true if the elements of the path starting at the "start" element
@@ -162,16 +160,16 @@ class HttpPath {
*/
bool equals(size_t start,
std::initializer_list<std::string_view> match) const {
return equals(start, makeArrayRef(match.begin(), match.end()));
return equals(start, {match.begin(), match.end()});
}
bool equals(size_t start, ArrayRef<std::string_view> match) const {
bool equals(size_t start, span<const std::string_view> match) const {
if (m_pathEnds.size() != (start + match.size())) {
return false;
}
return startswith(start, match);
}
bool equals(size_t start, std::string_view match) const {
return equals(start, makeArrayRef(match));
return equals(start, {match});
}
/**
@@ -182,13 +180,13 @@ class HttpPath {
* @return True if path starts with match list
*/
bool startswith(std::initializer_list<std::string_view> match) const {
return startswith(0, makeArrayRef(match.begin(), match.end()));
return startswith(0, {match.begin(), match.end()});
}
bool startswith(ArrayRef<std::string_view> match) const {
bool startswith(span<const std::string_view> match) const {
return startswith(0, match);
}
bool startswith(std::string_view match) const {
return startswith(0, makeArrayRef(match));
return startswith(0, {match});
}
/**
@@ -201,13 +199,13 @@ class HttpPath {
*/
bool startswith(size_t start,
std::initializer_list<std::string_view> match) const {
return startswith(start, makeArrayRef(match.begin(), match.end()));
return startswith(start, {match.begin(), match.end()});
}
bool startswith(size_t start, ArrayRef<std::string_view> match) const;
bool startswith(size_t start, span<const std::string_view> match) const;
bool startswith(size_t start, std::string_view match) const {
return startswith(start, makeArrayRef(match));
return startswith(start, {match});
}
/**
@@ -240,45 +238,43 @@ class HttpPathRef {
size_t size() const { return m_path ? m_path->size() - m_start : 0; }
bool equals(std::initializer_list<std::string_view> match) const {
return equals(0, makeArrayRef(match.begin(), match.end()));
return equals(0, {match.begin(), match.end()});
}
bool equals(ArrayRef<std::string_view> match) const {
bool equals(span<const std::string_view> match) const {
return equals(0, match);
}
bool equals(std::string_view match) const {
return equals(0, makeArrayRef(match));
}
bool equals(std::string_view match) const { return equals(0, {match}); }
bool equals(size_t start,
std::initializer_list<std::string_view> match) const {
return equals(start, makeArrayRef(match.begin(), match.end()));
return equals(start, {match.begin(), match.end()});
}
bool equals(size_t start, ArrayRef<std::string_view> match) const {
bool equals(size_t start, span<const std::string_view> match) const {
return m_path ? m_path->equals(m_start + start, match) : false;
}
bool equals(size_t start, std::string_view match) const {
return equals(start, makeArrayRef(match));
return equals(start, {match});
}
bool startswith(std::initializer_list<std::string_view> match) const {
return startswith(0, makeArrayRef(match.begin(), match.end()));
return startswith(0, {match.begin(), match.end()});
}
bool startswith(ArrayRef<std::string_view> match) const {
bool startswith(span<const std::string_view> match) const {
return startswith(0, match);
}
bool startswith(std::string_view match) const {
return startswith(0, makeArrayRef(match));
return startswith(0, {match});
}
bool startswith(size_t start,
std::initializer_list<std::string_view> match) const {
return startswith(start, makeArrayRef(match.begin(), match.end()));
return startswith(start, {match.begin(), match.end()});
}
bool startswith(size_t start, ArrayRef<std::string_view> match) const {
bool startswith(size_t start, span<const std::string_view> match) const {
return m_path ? m_path->startswith(m_start + start, match) : false;
}
bool startswith(size_t start, std::string_view match) const {
return startswith(start, makeArrayRef(match));
return startswith(start, {match});
}
std::string_view operator[](size_t n) const {

View File

@@ -10,11 +10,11 @@
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/HttpServerConnection.h"
#include "wpi/SmallVector.h"
#include "wpi/WebSocket.h"
#include "wpi/WebSocketServer.h"
#include "wpi/span.h"
#include "wpi/uv/Stream.h"
namespace wpi {
@@ -36,7 +36,7 @@ class HttpWebSocketServerConnection
* @param protocols Acceptable subprotocols
*/
HttpWebSocketServerConnection(std::shared_ptr<uv::Stream> stream,
ArrayRef<std::string_view> protocols);
span<const std::string_view> protocols);
/**
* Constructor.
@@ -47,8 +47,8 @@ class HttpWebSocketServerConnection
HttpWebSocketServerConnection(
std::shared_ptr<uv::Stream> stream,
std::initializer_list<std::string_view> protocols)
: HttpWebSocketServerConnection(
stream, makeArrayRef(protocols.begin(), protocols.end())) {}
: HttpWebSocketServerConnection(stream,
{protocols.begin(), protocols.end()}) {}
protected:
/**

View File

@@ -13,7 +13,7 @@ namespace wpi {
template <typename Derived>
HttpWebSocketServerConnection<Derived>::HttpWebSocketServerConnection(
std::shared_ptr<uv::Stream> stream, ArrayRef<std::string_view> protocols)
std::shared_ptr<uv::Stream> stream, span<const std::string_view> protocols)
: HttpServerConnection{stream},
m_helper{m_request},
m_protocols{protocols.begin(), protocols.end()} {

View File

@@ -0,0 +1,27 @@
// 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.
#pragma once
#include <cassert>
#include "wpi/span.h"
namespace wpi {
/// Drop the first \p N elements of the array.
template <typename T>
constexpr span<T> drop_front(span<T> in, typename span<T>::size_type n = 1) {
assert(in.size() >= n && "Dropping more elements than exist");
return in.subspan(n, in.size() - n);
}
/// Drop the last \p N elements of the array.
template <typename T>
constexpr span<T> drop_back(span<T> in, typename span<T>::size_type n = 1) {
assert(in.size() >= n && "Dropping more elements than exist");
return in.subspan(0, in.size() - n);
}
} // namespace wpi

View File

@@ -27,8 +27,8 @@
#include <memory>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/NetworkStream.h"
#include "wpi/span.h"
namespace wpi {
@@ -40,7 +40,7 @@ class TCPConnector {
Logger& logger,
int timeout = 0);
static std::unique_ptr<NetworkStream> connect_parallel(
ArrayRef<std::pair<const char*, int>> servers, Logger& logger,
span<const std::pair<const char*, int>> servers, Logger& logger,
int timeout = 0);
};

View File

@@ -8,9 +8,9 @@
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/mutex.h"
#include "wpi/span.h"
namespace wpi {
@@ -36,7 +36,7 @@ class UDPClient {
int start(int port);
void shutdown();
// The passed in address MUST be a resolved IP address.
int send(ArrayRef<uint8_t> data, std::string_view server, int port);
int send(span<const 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,

View File

@@ -14,9 +14,9 @@
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/SmallVector.h"
#include "wpi/span.h"
#include "wpi/uv/Buffer.h"
#include "wpi/uv/Error.h"
#include "wpi/uv/Timer.h"
@@ -78,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<std::string_view, std::string_view>> extraHeaders;
span<const std::pair<std::string_view, std::string_view>> extraHeaders;
};
/**
@@ -93,7 +93,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
*/
static std::shared_ptr<WebSocket> CreateClient(
uv::Stream& stream, std::string_view uri, std::string_view host,
ArrayRef<std::string_view> protocols = {},
span<const std::string_view> protocols = {},
const ClientOptions& options = {});
/**
@@ -110,8 +110,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
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()),
return CreateClient(stream, uri, host, {protocols.begin(), protocols.end()},
options);
}
@@ -182,23 +181,41 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param data UTF-8 encoded data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendText(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
void SendText(span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kFlagFin | kOpText, data, callback);
}
/**
* Send a text message.
* @param data UTF-8 encoded data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendText(std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendText({data.begin(), data.end()}, callback);
}
/**
* Send a binary message.
* @param data Data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendBinary(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
void SendBinary(span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kFlagFin | kOpBinary, data, callback);
}
/**
* Send a binary message.
* @param data Data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendBinary(std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendBinary({data.begin(), data.end()}, callback);
}
/**
* Send a text message fragment. This must be followed by one or more
* SendFragment() calls, where the last one has fin=True, to complete the
@@ -207,11 +224,24 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param callback Callback which is invoked when the write completes.
*/
void SendTextFragment(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kOpText, data, callback);
}
/**
* Send a text message fragment. This must be followed by one or more
* SendFragment() calls, where the last one has fin=True, to complete the
* message.
* @param data UTF-8 encoded data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendTextFragment(
std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendTextFragment({data.begin(), data.end()}, callback);
}
/**
* Send a text message fragment. This must be followed by one or more
* SendFragment() calls, where the last one has fin=True, to complete the
@@ -220,11 +250,24 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param callback Callback which is invoked when the write completes.
*/
void SendBinaryFragment(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kOpBinary, data, callback);
}
/**
* Send a text message fragment. This must be followed by one or more
* SendFragment() calls, where the last one has fin=True, to complete the
* message.
* @param data Data to send
* @param callback Callback which is invoked when the write completes.
*/
void SendBinaryFragment(
std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendBinaryFragment({data.begin(), data.end()}, callback);
}
/**
* Send a continuation frame. This is used to send additional parts of a
* message started with SendTextFragment() or SendBinaryFragment().
@@ -232,19 +275,30 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param fin Set to true if this is the final fragment of the message
* @param callback Callback which is invoked when the write completes.
*/
void SendFragment(
ArrayRef<uv::Buffer> data, bool fin,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
void SendFragment(span<const uv::Buffer> data, bool fin,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kOpCont | (fin ? kFlagFin : 0), data, callback);
}
/**
* Send a continuation frame. This is used to send additional parts of a
* message started with SendTextFragment() or SendBinaryFragment().
* @param data Data to send
* @param fin Set to true if this is the final fragment of the message
* @param callback Callback which is invoked when the write completes.
*/
void SendFragment(std::initializer_list<uv::Buffer> data, bool fin,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendFragment({data.begin(), data.end()}, fin, callback);
}
/**
* Send a ping frame with no data.
* @param callback Optional callback which is invoked when the ping frame
* write completes.
*/
void SendPing(std::function<void(uv::Error)> callback = nullptr) {
SendPing(ArrayRef<uv::Buffer>{}, [callback](auto bufs, uv::Error err) {
SendPing({}, [callback](auto bufs, uv::Error err) {
if (callback) {
callback(err);
}
@@ -257,19 +311,29 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param callback Callback which is invoked when the ping frame
* write completes.
*/
void SendPing(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
void SendPing(span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kFlagFin | kOpPing, data, callback);
}
/**
* Send a ping frame.
* @param data Data to send in the ping frame
* @param callback Callback which is invoked when the ping frame
* write completes.
*/
void SendPing(std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendPing({data.begin(), data.end()}, callback);
}
/**
* Send a pong frame with no data.
* @param callback Optional callback which is invoked when the pong frame
* write completes.
*/
void SendPong(std::function<void(uv::Error)> callback = nullptr) {
SendPong(ArrayRef<uv::Buffer>{}, [callback](auto bufs, uv::Error err) {
SendPong({}, [callback](auto bufs, uv::Error err) {
if (callback) {
callback(err);
}
@@ -282,12 +346,22 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* @param callback Callback which is invoked when the pong frame
* write completes.
*/
void SendPong(
ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback) {
void SendPong(span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
Send(kFlagFin | kOpPong, data, callback);
}
/**
* Send a pong frame.
* @param data Data to send in the pong frame
* @param callback Callback which is invoked when the pong frame
* write completes.
*/
void SendPong(std::initializer_list<uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback) {
SendPong({data.begin(), data.end()}, callback);
}
/**
* Fail the connection.
*/
@@ -339,17 +413,17 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
* The first parameter is the data, the second parameter is true if the
* data is the last fragment of the message.
*/
sig::Signal<ArrayRef<uint8_t>, bool> binary;
sig::Signal<span<const uint8_t>, bool> binary;
/**
* Ping event. Emitted when a ping message is received.
*/
sig::Signal<ArrayRef<uint8_t>> ping;
sig::Signal<span<const uint8_t>> ping;
/**
* Pong event. Emitted when a pong message is received.
*/
sig::Signal<ArrayRef<uint8_t>> pong;
sig::Signal<span<const uint8_t>> pong;
private:
// user data
@@ -382,7 +456,7 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
std::unique_ptr<ClientHandshakeData> m_clientHandshake;
void StartClient(std::string_view uri, std::string_view host,
ArrayRef<std::string_view> protocols,
span<const std::string_view> protocols,
const ClientOptions& options);
void StartServer(std::string_view key, std::string_view version,
std::string_view protocol);
@@ -390,9 +464,8 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
void SetClosed(uint16_t code, std::string_view reason, bool failed = false);
void Shutdown();
void HandleIncoming(uv::Buffer& buf, size_t size);
void Send(
uint8_t opcode, ArrayRef<uv::Buffer> data,
std::function<void(MutableArrayRef<uv::Buffer>, uv::Error)> callback);
void Send(uint8_t opcode, span<const uv::Buffer> data,
std::function<void(span<uv::Buffer>, uv::Error)> callback);
};
} // namespace wpi

View File

@@ -12,12 +12,12 @@
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/HttpParser.h"
#include "wpi/Signal.h"
#include "wpi/SmallString.h"
#include "wpi/SmallVector.h"
#include "wpi/WebSocket.h"
#include "wpi/span.h"
namespace wpi {
@@ -53,7 +53,7 @@ class WebSocketServerHelper {
* is empty.
*/
std::pair<bool, std::string_view> MatchProtocol(
ArrayRef<std::string_view> protocols);
span<const std::string_view> protocols);
/**
* Try to find a match to the list of sub-protocols provided by the client.
@@ -66,7 +66,7 @@ class WebSocketServerHelper {
*/
std::pair<bool, std::string_view> MatchProtocol(
std::initializer_list<std::string_view> protocols) {
return MatchProtocol(makeArrayRef(protocols.begin(), protocols.end()));
return MatchProtocol({protocols.begin(), protocols.end()});
}
/**
@@ -122,7 +122,7 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
/**
* Private constructor.
*/
WebSocketServer(uv::Stream& stream, ArrayRef<std::string_view> protocols,
WebSocketServer(uv::Stream& stream, span<const std::string_view> protocols,
ServerOptions options, const private_init&);
/**
@@ -135,7 +135,7 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
* @param options Handshake options
*/
static std::shared_ptr<WebSocketServer> Create(
uv::Stream& stream, ArrayRef<std::string_view> protocols = {},
uv::Stream& stream, span<const std::string_view> protocols = {},
const ServerOptions& options = {});
/**
@@ -150,8 +150,7 @@ class WebSocketServer : public std::enable_shared_from_this<WebSocketServer> {
static std::shared_ptr<WebSocketServer> Create(
uv::Stream& stream, std::initializer_list<std::string_view> protocols,
const ServerOptions& options = {}) {
return Create(stream, makeArrayRef(protocols.begin(), protocols.end()),
options);
return Create(stream, {protocols.begin(), protocols.end()}, options);
}
/**

View File

@@ -14,7 +14,6 @@
#include <utility>
#include <vector>
#include "wpi/ArrayRef.h"
#include "wpi/ConvertUTF.h"
#include "wpi/SafeThread.h"
#include "wpi/SmallString.h"
@@ -23,6 +22,7 @@
#include "wpi/deprecated.h"
#include "wpi/mutex.h"
#include "wpi/raw_ostream.h"
#include "wpi/span.h"
/** Java Native Interface (JNI) utility functions */
namespace wpi::java {
@@ -137,7 +137,7 @@ class JStringRef {
jsize size = env->GetStringLength(str);
const jchar* chars = env->GetStringCritical(str, nullptr);
if (chars) {
convertUTF16ToUTF8String(makeArrayRef(chars, size), m_str);
convertUTF16ToUTF8String(wpi::span<const jchar>(chars, size), m_str);
env->ReleaseStringCritical(str, chars);
}
} else {
@@ -185,13 +185,13 @@ class JArrayRefBase : public JArrayRefInner<JArrayRefBase<T>, T> {
public:
explicit operator bool() const { return this->m_elements != nullptr; }
operator ArrayRef<T>() const { return array(); } // NOLINT
operator span<const T>() const { return array(); } // NOLINT
ArrayRef<T> array() const {
span<const T> array() const {
if (!this->m_elements) {
return {};
}
return ArrayRef<T>{this->m_elements, this->m_size};
return {this->m_elements, this->m_size};
}
JArrayRefBase(const JArrayRefBase&) = delete;
@@ -342,7 +342,7 @@ namespace detail {
template <typename T,
bool = (std::is_integral<T>::value && sizeof(jint) == sizeof(T))>
struct ConvertIntArray {
static jintArray ToJava(JNIEnv* env, ArrayRef<T> arr) {
static jintArray ToJava(JNIEnv* env, span<const T> arr) {
jintArray jarr = env->NewIntArray(arr.size());
if (!jarr) {
return nullptr;
@@ -363,7 +363,7 @@ struct ConvertIntArray {
// Fast path (use SetIntArrayRegion)
template <typename T>
struct ConvertIntArray<T, true> {
static jintArray ToJava(JNIEnv* env, ArrayRef<T> arr) {
static jintArray ToJava(JNIEnv* env, span<const T> arr) {
jintArray jarr = env->NewIntArray(arr.size());
if (!jarr) {
return nullptr;
@@ -376,9 +376,14 @@ struct ConvertIntArray<T, true> {
} // namespace detail
// Convert an ArrayRef to a jintArray.
// Convert an span to a jintArray.
template <typename T>
inline jintArray MakeJIntArray(JNIEnv* env, ArrayRef<T> arr) {
inline jintArray MakeJIntArray(JNIEnv* env, span<const T> arr) {
return detail::ConvertIntArray<T>::ToJava(env, arr);
}
template <typename T>
inline jintArray MakeJIntArray(JNIEnv* env, span<T> arr) {
return detail::ConvertIntArray<T>::ToJava(env, arr);
}
@@ -408,7 +413,7 @@ inline jbyteArray MakeJByteArray(JNIEnv* env, std::string_view str) {
}
// Convert an array of integers into a jbooleanArray.
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, ArrayRef<int> arr) {
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const int> arr) {
jbooleanArray jarr = env->NewBooleanArray(arr.size());
if (!jarr) {
return nullptr;
@@ -426,7 +431,7 @@ inline jbooleanArray MakeJBooleanArray(JNIEnv* env, ArrayRef<int> arr) {
}
// Convert an array of booleans into a jbooleanArray.
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, ArrayRef<bool> arr) {
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const bool> arr) {
jbooleanArray jarr = env->NewBooleanArray(arr.size());
if (!jarr) {
return nullptr;
@@ -445,14 +450,14 @@ inline jbooleanArray MakeJBooleanArray(JNIEnv* env, ArrayRef<bool> arr) {
// Other MakeJ*Array conversions.
#define WPI_JNI_MAKEJARRAY(T, F) \
inline T##Array MakeJ##F##Array(JNIEnv* env, ArrayRef<T> arr) { \
T##Array jarr = env->New##F##Array(arr.size()); \
if (!jarr) { \
return nullptr; \
} \
env->Set##F##ArrayRegion(jarr, 0, arr.size(), arr.data()); \
return jarr; \
#define WPI_JNI_MAKEJARRAY(T, F) \
inline T##Array MakeJ##F##Array(JNIEnv* env, span<const T> arr) { \
T##Array jarr = env->New##F##Array(arr.size()); \
if (!jarr) { \
return nullptr; \
} \
env->Set##F##ArrayRegion(jarr, 0, arr.size(), arr.data()); \
return jarr; \
}
WPI_JNI_MAKEJARRAY(jboolean, Boolean)
@@ -465,7 +470,7 @@ WPI_JNI_MAKEJARRAY(jdouble, Double)
#undef WPI_JNI_MAKEJARRAY
// Convert an array of std::string into a jarray of jstring.
inline jobjectArray MakeJStringArray(JNIEnv* env, ArrayRef<std::string> arr) {
inline jobjectArray MakeJStringArray(JNIEnv* env, span<const std::string> arr) {
static JClass stringCls{env, "java/lang/String"};
if (!stringCls) {
return nullptr;

View File

@@ -60,8 +60,8 @@ SOFTWARE.
#include <utility>
#include <vector> // vector
#include "wpi/ArrayRef.h"
#include "wpi/StringMap.h"
#include "wpi/span.h"
namespace wpi
{
@@ -1126,7 +1126,7 @@ struct external_constructor<value_t::array>
}
template<typename BasicJsonType, typename T>
static void construct(BasicJsonType& j, ArrayRef<T> arr)
static void construct(BasicJsonType& j, span<T> arr)
{
using std::begin;
using std::end;
@@ -7014,7 +7014,7 @@ class json
const parser_callback_t cb = nullptr,
const bool allow_exceptions = true);
static json parse(ArrayRef<uint8_t> arr,
static json parse(span<const uint8_t> arr,
const parser_callback_t cb = nullptr,
const bool allow_exceptions = true);
@@ -7027,7 +7027,7 @@ class json
static bool accept(std::string_view s);
static bool accept(ArrayRef<uint8_t> arr);
static bool accept(span<const uint8_t> arr);
static bool accept(raw_istream& i);
@@ -7205,8 +7205,8 @@ class json
@since version 2.0.9
*/
static std::vector<uint8_t> to_cbor(const json& j);
static ArrayRef<uint8_t> to_cbor(const json& j, std::vector<uint8_t>& buf);
static ArrayRef<uint8_t> to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf);
static span<uint8_t> to_cbor(const json& j, std::vector<uint8_t>& buf);
static span<uint8_t> to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf);
static void to_cbor(raw_ostream& os, const json& j);
/*!
@@ -7290,8 +7290,8 @@ class json
@since version 2.0.9
*/
static std::vector<uint8_t> to_msgpack(const json& j);
static ArrayRef<uint8_t> to_msgpack(const json& j, std::vector<uint8_t>& buf);
static ArrayRef<uint8_t> to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf);
static span<uint8_t> to_msgpack(const json& j, std::vector<uint8_t>& buf);
static span<uint8_t> to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf);
static void to_msgpack(raw_ostream& os, const json& j);
/*!
@@ -7377,10 +7377,10 @@ class json
static std::vector<uint8_t> to_ubjson(const json& j,
const bool use_size = false,
const bool use_type = false);
static ArrayRef<uint8_t> to_ubjson(const json& j, std::vector<uint8_t>& buf,
const bool use_size = false, const bool use_type = false);
static ArrayRef<uint8_t> to_ubjson(const json& j, SmallVectorImpl<uint8_t>& buf,
const bool use_size = false, const bool use_type = false);
static span<uint8_t> to_ubjson(const json& j, std::vector<uint8_t>& buf,
const bool use_size = false, const bool use_type = false);
static span<uint8_t> to_ubjson(const json& j, SmallVectorImpl<uint8_t>& buf,
const bool use_size = false, const bool use_type = false);
static void to_ubjson(raw_ostream& os, const json& j,
const bool use_size = false, const bool use_type = false);
@@ -7483,7 +7483,7 @@ class json
/*!
@copydoc from_cbor(raw_istream&, const bool)
*/
static json from_cbor(ArrayRef<uint8_t> arr, const bool strict = true);
static json from_cbor(span<const uint8_t> arr, const bool strict = true);
/*!
@brief create a JSON value from an input in MessagePack format
@@ -7564,7 +7564,7 @@ class json
/*!
@copydoc from_msgpack(raw_istream, const bool)
*/
static json from_msgpack(ArrayRef<uint8_t> arr, const bool strict = true);
static json from_msgpack(span<const uint8_t> arr, const bool strict = true);
/*!
@brief create a JSON value from an input in UBJSON format
@@ -7622,7 +7622,7 @@ class json
static json from_ubjson(raw_istream& is,
const bool strict = true);
static json from_ubjson(ArrayRef<uint8_t> arr, const bool strict = true);
static json from_ubjson(span<const uint8_t> arr, const bool strict = true);
/// @}

View File

@@ -14,8 +14,8 @@
#include <system_error>
#include <vector>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/span.h"
namespace wpi {
@@ -133,9 +133,9 @@ class raw_mem_istream : public raw_istream {
// not const as we don't want to allow temporaries
explicit raw_mem_istream(std::string& str)
: raw_mem_istream(str.data(), str.size()) {}
explicit raw_mem_istream(ArrayRef<char> mem)
explicit raw_mem_istream(span<const char> mem)
: raw_mem_istream(mem.data(), mem.size()) {}
explicit raw_mem_istream(ArrayRef<uint8_t> mem)
explicit raw_mem_istream(span<const uint8_t> mem)
: raw_mem_istream(reinterpret_cast<const char*>(mem.data()), mem.size()) {
}
explicit raw_mem_istream(const char* str)

View File

@@ -14,8 +14,8 @@
#ifndef WPIUTIL_WPI_RAW_OSTREAM_H
#define WPIUTIL_WPI_RAW_OSTREAM_H
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/span.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -159,7 +159,7 @@ public:
return *this;
}
raw_ostream &operator<<(ArrayRef<uint8_t> Arr) {
raw_ostream &operator<<(span<const uint8_t> Arr) {
// Inline fast path, particularly for arrays with a known length.
size_t Size = Arr.size();
@@ -573,8 +573,9 @@ public:
void flush() = delete;
/// Return an ArrayRef for the vector contents.
ArrayRef<uint8_t> array() { return ArrayRef<uint8_t>(OS.data(), OS.size()); }
/// Return an span for the vector contents.
span<uint8_t> array() { return {OS.data(), OS.size()}; }
span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
};
/// A raw_ostream that writes to a vector. This is a
@@ -606,8 +607,9 @@ public:
void flush() = delete;
/// Return a ArrayRef for the vector contents.
ArrayRef<uint8_t> array() { return ArrayRef<uint8_t>(OS.data(), OS.size()); }
/// Return a span for the vector contents.
span<uint8_t> array() { return {OS.data(), OS.size()}; }
span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
};

View File

@@ -5,11 +5,12 @@
#ifndef WPIUTIL_WPI_RAW_UV_OSTREAM_H_
#define WPIUTIL_WPI_RAW_UV_OSTREAM_H_
#include <functional>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/raw_ostream.h"
#include "wpi/span.h"
#include "wpi/uv/Buffer.h"
namespace wpi {
@@ -47,9 +48,9 @@ class raw_uv_ostream : public raw_ostream {
~raw_uv_ostream() override = default;
/**
* Returns an ArrayRef to the buffers.
* Returns an span to the buffers.
*/
ArrayRef<uv::Buffer> bufs() { return m_bufs; }
span<uv::Buffer> bufs() { return m_bufs; }
void flush() = delete;

View File

@@ -12,8 +12,8 @@
#include <string_view>
#include <utility>
#include "wpi/ArrayRef.h"
#include "wpi/SmallVector.h"
#include "wpi/span.h"
namespace wpi::uv {
@@ -32,7 +32,7 @@ class Buffer : public uv_buf_t {
}
/*implicit*/ Buffer(std::string_view str) // NOLINT
: Buffer{str.data(), str.size()} {}
/*implicit*/ Buffer(ArrayRef<uint8_t> arr) // NOLINT
/*implicit*/ Buffer(span<const uint8_t> arr) // NOLINT
: Buffer{reinterpret_cast<const char*>(arr.data()), arr.size()} {}
Buffer(char* base_, size_t len_) {
base = base_;
@@ -43,11 +43,11 @@ class Buffer : public uv_buf_t {
len = static_cast<decltype(len)>(len_);
}
ArrayRef<char> data() const { return ArrayRef<char>{base, len}; }
MutableArrayRef<char> data() { return MutableArrayRef<char>{base, len}; }
span<const char> data() const { return {base, len}; }
span<char> data() { return {base, len}; }
operator ArrayRef<char>() const { return data(); } // NOLINT
operator MutableArrayRef<char>() { return data(); } // NOLINT
operator span<const char>() const { return data(); } // NOLINT
operator span<char>() { return data(); } // NOLINT
static Buffer Allocate(size_t size) { return Buffer{new char[size], size}; }
@@ -57,7 +57,7 @@ class Buffer : public uv_buf_t {
return buf;
}
static Buffer Dup(ArrayRef<uint8_t> in) {
static Buffer Dup(span<const uint8_t> in) {
Buffer buf = Allocate(in.size());
std::memcpy(buf.base, in.begin(), in.size());
return buf;
@@ -131,7 +131,7 @@ class SimpleBufferPool {
* This is NOT safe to use with arbitrary buffers unless they were
* allocated with the same size as the buffer pool allocation size.
*/
void Release(MutableArrayRef<Buffer> bufs) {
void Release(span<Buffer> bufs) {
for (auto& buf : bufs) {
m_pool.emplace_back(buf.Move());
}

View File

@@ -12,9 +12,9 @@
#include <string>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/SmallVector.h"
#include "wpi/span.h"
#include "wpi/uv/Handle.h"
namespace wpi::uv {
@@ -232,12 +232,12 @@ class Process final : public HandleImpl<Process, uv_process_t> {
* @param options Process options
*/
static std::shared_ptr<Process> SpawnArray(Loop& loop, std::string_view file,
ArrayRef<Option> options);
span<const Option> options);
static std::shared_ptr<Process> SpawnArray(
Loop& loop, std::string_view file,
std::initializer_list<Option> options) {
return SpawnArray(loop, file, makeArrayRef(options.begin(), options.end()));
return SpawnArray(loop, file, {options.begin(), options.end()});
}
template <typename... Args>
@@ -261,7 +261,7 @@ class Process final : public HandleImpl<Process, uv_process_t> {
*/
static std::shared_ptr<Process> SpawnArray(const std::shared_ptr<Loop>& loop,
std::string_view file,
ArrayRef<Option> options) {
span<const Option> options) {
return SpawnArray(*loop, file, options);
}

View File

@@ -12,8 +12,8 @@
#include <initializer_list>
#include <memory>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/span.h"
#include "wpi/uv/Buffer.h"
#include "wpi/uv/Handle.h"
#include "wpi/uv/Request.h"
@@ -126,7 +126,7 @@ class Stream : public Handle {
* @param bufs The buffers to be written to the stream.
* @param req write request
*/
void Write(ArrayRef<Buffer> bufs, const std::shared_ptr<WriteReq>& req);
void Write(span<const Buffer> bufs, const std::shared_ptr<WriteReq>& req);
/**
* Write data to the stream.
@@ -146,7 +146,7 @@ class Stream : public Handle {
*/
void Write(std::initializer_list<Buffer> bufs,
const std::shared_ptr<WriteReq>& req) {
Write(makeArrayRef(bufs.begin(), bufs.end()), req);
Write({bufs.begin(), bufs.end()}, req);
}
/**
@@ -162,8 +162,8 @@ class Stream : public Handle {
* @param bufs The buffers to be written to the stream.
* @param callback Callback function to call when the write completes
*/
void Write(ArrayRef<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback);
void Write(span<const Buffer> bufs,
std::function<void(span<Buffer>, Error)> callback);
/**
* Write data to the stream.
@@ -179,8 +179,8 @@ class Stream : public Handle {
* @param callback Callback function to call when the write completes
*/
void Write(std::initializer_list<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback) {
Write(makeArrayRef(bufs.begin(), bufs.end()), callback);
std::function<void(span<Buffer>, Error)> callback) {
Write({bufs.begin(), bufs.end()}, callback);
}
/**
@@ -193,7 +193,7 @@ class Stream : public Handle {
* @param bufs The buffers to be written to the stream.
* @return Number of bytes written.
*/
int TryWrite(ArrayRef<Buffer> bufs);
int TryWrite(span<const Buffer> bufs);
/**
* Queue a write request if it can be completed immediately.
@@ -206,7 +206,7 @@ class Stream : public Handle {
* @return Number of bytes written.
*/
int TryWrite(std::initializer_list<Buffer> bufs) {
return TryWrite(makeArrayRef(bufs.begin(), bufs.end()));
return TryWrite({bufs.begin(), bufs.end()});
}
/**

View File

@@ -11,8 +11,8 @@
#include <memory>
#include <string_view>
#include "wpi/ArrayRef.h"
#include "wpi/Signal.h"
#include "wpi/span.h"
#include "wpi/uv/Handle.h"
#include "wpi/uv/Request.h"
@@ -230,15 +230,15 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be written to the stream.
* @param req write request
*/
void Send(const sockaddr& addr, ArrayRef<Buffer> bufs,
void Send(const sockaddr& addr, span<const Buffer> bufs,
const std::shared_ptr<UdpSendReq>& req);
void Send(const sockaddr_in& addr, ArrayRef<Buffer> bufs,
void Send(const sockaddr_in& addr, span<const Buffer> bufs,
const std::shared_ptr<UdpSendReq>& req) {
Send(reinterpret_cast<const sockaddr&>(addr), bufs, req);
}
void Send(const sockaddr_in6& addr, ArrayRef<Buffer> bufs,
void Send(const sockaddr_in6& addr, span<const Buffer> bufs,
const std::shared_ptr<UdpSendReq>& req) {
Send(reinterpret_cast<const sockaddr&>(addr), bufs, req);
}
@@ -250,7 +250,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be written to the stream.
* @param req write request
*/
void Send(ArrayRef<Buffer> bufs, const std::shared_ptr<UdpSendReq>& req);
void Send(span<const Buffer> bufs, const std::shared_ptr<UdpSendReq>& req);
/**
* Send data over the UDP socket. If the socket has not previously been bound
@@ -269,16 +269,16 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be sent.
* @param callback Callback function to call when the data has been sent.
*/
void Send(const sockaddr& addr, ArrayRef<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback);
void Send(const sockaddr& addr, span<const Buffer> bufs,
std::function<void(span<Buffer>, Error)> callback);
void Send(const sockaddr_in& addr, ArrayRef<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback) {
void Send(const sockaddr_in& addr, span<const Buffer> bufs,
std::function<void(span<Buffer>, Error)> callback) {
Send(reinterpret_cast<const sockaddr&>(addr), bufs, callback);
}
void Send(const sockaddr_in6& addr, ArrayRef<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback) {
void Send(const sockaddr_in6& addr, span<const Buffer> bufs,
std::function<void(span<Buffer>, Error)> callback) {
Send(reinterpret_cast<const sockaddr&>(addr), bufs, callback);
}
@@ -289,8 +289,8 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be written to the stream.
* @param callback Callback function to call when the data has been sent.
*/
void Send(ArrayRef<Buffer> bufs,
std::function<void(MutableArrayRef<Buffer>, Error)> callback);
void Send(span<const Buffer> bufs,
std::function<void(span<Buffer>, Error)> callback);
/**
* Same as Send(), but won't queue a send request if it can't be completed
@@ -301,7 +301,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be send.
* @return Number of bytes sent.
*/
int TrySend(const sockaddr& addr, ArrayRef<Buffer> bufs) {
int TrySend(const sockaddr& addr, span<const Buffer> bufs) {
int val = uv_udp_try_send(GetRaw(), bufs.data(),
static_cast<unsigned>(bufs.size()), &addr);
if (val < 0) {
@@ -311,11 +311,11 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
return val;
}
int TrySend(const sockaddr_in& addr, ArrayRef<Buffer> bufs) {
int TrySend(const sockaddr_in& addr, span<const Buffer> bufs) {
return TrySend(reinterpret_cast<const sockaddr&>(addr), bufs);
}
int TrySend(const sockaddr_in6& addr, ArrayRef<Buffer> bufs) {
int TrySend(const sockaddr_in6& addr, span<const Buffer> bufs) {
return TrySend(reinterpret_cast<const sockaddr&>(addr), bufs);
}
@@ -326,7 +326,7 @@ class Udp final : public HandleImpl<Udp, uv_udp_t> {
* @param bufs The buffers to be written to the stream.
* @return Number of bytes sent.
*/
int TrySend(ArrayRef<Buffer> bufs) {
int TrySend(span<const Buffer> bufs) {
int val = uv_udp_try_send(GetRaw(), bufs.data(),
static_cast<unsigned>(bufs.size()), nullptr);
if (val < 0) {