mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-02 02:51:42 +00:00
Upgrade to C++20 (#4239)
* Use explicit this capture required by C++20 * Use C++20 span * Replace wpi::numbers with std::numbers * Fix C++20 clang-tidy warning false positive in fmt * Remove ciso646 include since C++20 removed that header * Fix global-buffer-overflow asan warnings in ntcore tests * Add DIOSetProxy constructor to HAL * Upgrade MSVC compiler to 2022 * Bump native-utils to 2023.2.7 (changes to std=c++20) Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
This commit is contained in:
@@ -2952,7 +2952,7 @@ class format_string_checker {
|
||||
basic_string_view<Char> format_str, ErrorHandler eh)
|
||||
: context_(format_str, num_args, types_, eh),
|
||||
parse_funcs_{&parse_format_specs<Args, parse_context_type>...},
|
||||
types_{
|
||||
types_{ // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
|
||||
mapped_type_constant<Args,
|
||||
basic_format_context<Char*, Char>>::value...} {
|
||||
}
|
||||
|
||||
@@ -1384,7 +1384,7 @@ json json::from_cbor(raw_istream& is, const bool strict)
|
||||
return binary_reader(is).parse_cbor(strict);
|
||||
}
|
||||
|
||||
json json::from_cbor(span<const uint8_t> arr, const bool strict)
|
||||
json json::from_cbor(std::span<const uint8_t> arr, const bool strict)
|
||||
{
|
||||
raw_mem_istream is(arr);
|
||||
return from_cbor(is, strict);
|
||||
@@ -1395,7 +1395,7 @@ json json::from_msgpack(raw_istream& is, const bool strict)
|
||||
return binary_reader(is).parse_msgpack(strict);
|
||||
}
|
||||
|
||||
json json::from_msgpack(span<const uint8_t> arr, const bool strict)
|
||||
json json::from_msgpack(std::span<const uint8_t> arr, const bool strict)
|
||||
{
|
||||
raw_mem_istream is(arr);
|
||||
return from_msgpack(is, strict);
|
||||
@@ -1406,7 +1406,7 @@ json json::from_ubjson(raw_istream& is, const bool strict)
|
||||
return binary_reader(is).parse_ubjson(strict);
|
||||
}
|
||||
|
||||
json json::from_ubjson(span<const uint8_t> arr, const bool strict)
|
||||
json json::from_ubjson(std::span<const uint8_t> arr, const bool strict)
|
||||
{
|
||||
raw_mem_istream is(arr);
|
||||
return from_ubjson(is, strict);
|
||||
|
||||
@@ -813,7 +813,7 @@ void json::binary_writer::write_number(const NumberType n)
|
||||
std::reverse(vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
o << span{vec.data(), sizeof(NumberType)};
|
||||
o << std::span{vec.data(), sizeof(NumberType)};
|
||||
}
|
||||
|
||||
template<typename NumberType, typename std::enable_if<
|
||||
@@ -1004,7 +1004,7 @@ std::vector<uint8_t> json::to_cbor(const json& j)
|
||||
return result;
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_cbor(const json& j, std::vector<uint8_t>& buf)
|
||||
std::span<uint8_t> json::to_cbor(const json& j, std::vector<uint8_t>& buf)
|
||||
{
|
||||
buf.clear();
|
||||
raw_uvector_ostream os(buf);
|
||||
@@ -1012,7 +1012,7 @@ span<uint8_t> json::to_cbor(const json& j, std::vector<uint8_t>& buf)
|
||||
return os.array();
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf)
|
||||
std::span<uint8_t> json::to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf)
|
||||
{
|
||||
buf.clear();
|
||||
raw_usvector_ostream os(buf);
|
||||
@@ -1033,7 +1033,7 @@ std::vector<uint8_t> json::to_msgpack(const json& j)
|
||||
return result;
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_msgpack(const json& j, std::vector<uint8_t>& buf)
|
||||
std::span<uint8_t> json::to_msgpack(const json& j, std::vector<uint8_t>& buf)
|
||||
{
|
||||
buf.clear();
|
||||
raw_uvector_ostream os(buf);
|
||||
@@ -1041,7 +1041,7 @@ span<uint8_t> json::to_msgpack(const json& j, std::vector<uint8_t>& buf)
|
||||
return os.array();
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf)
|
||||
std::span<uint8_t> json::to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf)
|
||||
{
|
||||
buf.clear();
|
||||
raw_usvector_ostream os(buf);
|
||||
@@ -1064,7 +1064,7 @@ std::vector<uint8_t> json::to_ubjson(const json& j,
|
||||
return result;
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_ubjson(const json& j, std::vector<uint8_t>& buf,
|
||||
std::span<uint8_t> json::to_ubjson(const json& j, std::vector<uint8_t>& buf,
|
||||
const bool use_size, const bool use_type)
|
||||
{
|
||||
buf.clear();
|
||||
@@ -1073,7 +1073,7 @@ span<uint8_t> json::to_ubjson(const json& j, std::vector<uint8_t>& buf,
|
||||
return os.array();
|
||||
}
|
||||
|
||||
span<uint8_t> json::to_ubjson(const json& j, SmallVectorImpl<uint8_t>& buf,
|
||||
std::span<uint8_t> json::to_ubjson(const json& j, SmallVectorImpl<uint8_t>& buf,
|
||||
const bool use_size, const bool use_type)
|
||||
{
|
||||
buf.clear();
|
||||
|
||||
@@ -1921,11 +1921,11 @@ json json::parse(std::string_view s,
|
||||
const parser_callback_t cb,
|
||||
const bool allow_exceptions)
|
||||
{
|
||||
raw_mem_istream is(span<const char>(s.data(), s.size()));
|
||||
raw_mem_istream is(std::span<const char>(s.data(), s.size()));
|
||||
return parse(is, cb, allow_exceptions);
|
||||
}
|
||||
|
||||
json json::parse(span<const uint8_t> arr,
|
||||
json json::parse(std::span<const uint8_t> arr,
|
||||
const parser_callback_t cb,
|
||||
const bool allow_exceptions)
|
||||
{
|
||||
@@ -1944,11 +1944,11 @@ json json::parse(raw_istream& i,
|
||||
|
||||
bool json::accept(std::string_view s)
|
||||
{
|
||||
raw_mem_istream is(span<const char>(s.data(), s.size()));
|
||||
raw_mem_istream is(std::span<const char>(s.data(), s.size()));
|
||||
return parser(is).accept(true);
|
||||
}
|
||||
|
||||
bool json::accept(span<const uint8_t> arr)
|
||||
bool json::accept(std::span<const uint8_t> arr)
|
||||
{
|
||||
raw_mem_istream is(arr);
|
||||
return parser(is).accept(true);
|
||||
|
||||
@@ -43,7 +43,6 @@ SOFTWARE.
|
||||
#include <algorithm> // all_of, copy, find, for_each, generate_n, min, reverse, remove, fill, none_of, transform
|
||||
#include <array> // array
|
||||
#include <cassert> // assert
|
||||
#include <ciso646> // and, not, or
|
||||
#include <cstddef> // nullptr_t, ptrdiff_t, size_t
|
||||
#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
|
||||
#include <exception> // exception
|
||||
@@ -52,6 +51,7 @@ SOFTWARE.
|
||||
#include <iterator>
|
||||
#include <limits> // numeric_limits
|
||||
#include <memory> // allocator, shared_ptr, make_shared, addressof
|
||||
#include <span>
|
||||
#include <stdexcept> // runtime_error
|
||||
#include <string> // string, char_traits, stoi, to_string
|
||||
#include <string_view>
|
||||
@@ -61,7 +61,6 @@ SOFTWARE.
|
||||
#include <vector> // vector
|
||||
|
||||
#include "wpi/StringMap.h"
|
||||
#include "wpi/span.h"
|
||||
|
||||
namespace wpi
|
||||
{
|
||||
@@ -1126,7 +1125,7 @@ struct external_constructor<value_t::array>
|
||||
}
|
||||
|
||||
template<typename BasicJsonType, typename T>
|
||||
static void construct(BasicJsonType& j, span<T> arr)
|
||||
static void construct(BasicJsonType& j, std::span<T> arr)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
@@ -7015,7 +7014,7 @@ class json
|
||||
const parser_callback_t cb = nullptr,
|
||||
const bool allow_exceptions = true);
|
||||
|
||||
static json parse(span<const uint8_t> arr,
|
||||
static json parse(std::span<const uint8_t> arr,
|
||||
const parser_callback_t cb = nullptr,
|
||||
const bool allow_exceptions = true);
|
||||
|
||||
@@ -7028,7 +7027,7 @@ class json
|
||||
|
||||
static bool accept(std::string_view s);
|
||||
|
||||
static bool accept(span<const uint8_t> arr);
|
||||
static bool accept(std::span<const uint8_t> arr);
|
||||
|
||||
static bool accept(raw_istream& i);
|
||||
|
||||
@@ -7206,8 +7205,8 @@ class json
|
||||
@since version 2.0.9
|
||||
*/
|
||||
static std::vector<uint8_t> to_cbor(const json& j);
|
||||
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 std::span<uint8_t> to_cbor(const json& j, std::vector<uint8_t>& buf);
|
||||
static std::span<uint8_t> to_cbor(const json& j, SmallVectorImpl<uint8_t>& buf);
|
||||
static void to_cbor(raw_ostream& os, const json& j);
|
||||
|
||||
/*!
|
||||
@@ -7291,8 +7290,8 @@ class json
|
||||
@since version 2.0.9
|
||||
*/
|
||||
static std::vector<uint8_t> to_msgpack(const json& j);
|
||||
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 std::span<uint8_t> to_msgpack(const json& j, std::vector<uint8_t>& buf);
|
||||
static std::span<uint8_t> to_msgpack(const json& j, SmallVectorImpl<uint8_t>& buf);
|
||||
static void to_msgpack(raw_ostream& os, const json& j);
|
||||
|
||||
/*!
|
||||
@@ -7378,9 +7377,9 @@ class json
|
||||
static std::vector<uint8_t> to_ubjson(const json& j,
|
||||
const bool use_size = false,
|
||||
const bool use_type = false);
|
||||
static span<uint8_t> to_ubjson(const json& j, std::vector<uint8_t>& buf,
|
||||
static std::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,
|
||||
static std::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);
|
||||
@@ -7484,7 +7483,7 @@ class json
|
||||
/*!
|
||||
@copydoc from_cbor(raw_istream&, const bool)
|
||||
*/
|
||||
static json from_cbor(span<const uint8_t> arr, const bool strict = true);
|
||||
static json from_cbor(std::span<const uint8_t> arr, const bool strict = true);
|
||||
|
||||
/*!
|
||||
@brief create a JSON value from an input in MessagePack format
|
||||
@@ -7565,7 +7564,7 @@ class json
|
||||
/*!
|
||||
@copydoc from_msgpack(raw_istream&, const bool)
|
||||
*/
|
||||
static json from_msgpack(span<const uint8_t> arr, const bool strict = true);
|
||||
static json from_msgpack(std::span<const uint8_t> arr, const bool strict = true);
|
||||
|
||||
/*!
|
||||
@brief create a JSON value from an input in UBJSON format
|
||||
@@ -7623,7 +7622,7 @@ class json
|
||||
static json from_ubjson(raw_istream& is,
|
||||
const bool strict = true);
|
||||
|
||||
static json from_ubjson(span<const uint8_t> arr, const bool strict = true);
|
||||
static json from_ubjson(std::span<const uint8_t> arr, const bool strict = true);
|
||||
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "wpi/span.h"
|
||||
#include <span>
|
||||
#include "wpi/ConvertUTF.h"
|
||||
#include "wpi/SmallVector.h"
|
||||
#include "wpi/ErrorHandling.h"
|
||||
@@ -21,7 +21,7 @@ bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source,
|
||||
char *&ResultPtr, const UTF8 *&ErrorPtr) {
|
||||
assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4);
|
||||
ConversionResult result = conversionOK;
|
||||
// Copy the character span over.
|
||||
// Copy the character std::span over.
|
||||
if (WideCharWidth == 1) {
|
||||
const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.data());
|
||||
if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.data() + Source.size()))) {
|
||||
@@ -78,13 +78,13 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasUTF16ByteOrderMark(span<const char> S) {
|
||||
bool hasUTF16ByteOrderMark(std::span<const char> S) {
|
||||
return (S.size() >= 2 &&
|
||||
((S[0] == '\xff' && S[1] == '\xfe') ||
|
||||
(S[0] == '\xfe' && S[1] == '\xff')));
|
||||
}
|
||||
|
||||
bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &Out) {
|
||||
bool convertUTF16ToUTF8String(std::span<const char> SrcBytes, SmallVectorImpl<char> &Out) {
|
||||
assert(Out.empty());
|
||||
|
||||
// Error out on an uneven byte count.
|
||||
@@ -95,8 +95,8 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &
|
||||
if (SrcBytes.empty())
|
||||
return true;
|
||||
|
||||
const UTF16 *Src = reinterpret_cast<const UTF16 *>(SrcBytes.begin());
|
||||
const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(SrcBytes.end());
|
||||
const UTF16 *Src = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin());
|
||||
const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin() + SrcBytes.size());
|
||||
|
||||
assert((uintptr_t)Src % sizeof(UTF16) == 0);
|
||||
|
||||
@@ -135,10 +135,10 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &
|
||||
return true;
|
||||
}
|
||||
|
||||
bool convertUTF16ToUTF8String(span<const UTF16> Src, SmallVectorImpl<char> &Out)
|
||||
bool convertUTF16ToUTF8String(std::span<const UTF16> Src, SmallVectorImpl<char> &Out)
|
||||
{
|
||||
return convertUTF16ToUTF8String(
|
||||
span<const char>(reinterpret_cast<const char *>(Src.data()),
|
||||
std::span<const char>(reinterpret_cast<const char *>(Src.data()),
|
||||
Src.size() * sizeof(UTF16)), Out);
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl<char> &Result
|
||||
return true;
|
||||
} else if (sizeof(wchar_t) == 2) {
|
||||
return convertUTF16ToUTF8String(
|
||||
span<const UTF16>(reinterpret_cast<const UTF16 *>(Source.data()),
|
||||
std::span<const UTF16>(reinterpret_cast<const UTF16 *>(Source.data()),
|
||||
Source.size()),
|
||||
Result);
|
||||
} else if (sizeof(wchar_t) == 4) {
|
||||
|
||||
@@ -104,8 +104,8 @@ namespace {
|
||||
template <typename MB>
|
||||
class MemoryBufferMem : public MB {
|
||||
public:
|
||||
explicit MemoryBufferMem(span<const uint8_t> inputData) {
|
||||
MemoryBuffer::Init(inputData.begin(), inputData.end());
|
||||
explicit MemoryBufferMem(std::span<const uint8_t> inputData) {
|
||||
MemoryBuffer::Init(&*inputData.begin(), &*inputData.end());
|
||||
}
|
||||
|
||||
/// Disable sized deallocation for MemoryBufferMem, because it has
|
||||
@@ -129,7 +129,7 @@ static std::unique_ptr<MB> GetFileAux(std::string_view filename,
|
||||
uint64_t mapSize, uint64_t offset);
|
||||
|
||||
std::unique_ptr<MemoryBuffer> MemoryBuffer::GetMemBuffer(
|
||||
span<const uint8_t> inputData, std::string_view bufferName) {
|
||||
std::span<const uint8_t> inputData, std::string_view bufferName) {
|
||||
auto* ret = new (NamedBufferAlloc(bufferName))
|
||||
MemoryBufferMem<MemoryBuffer>(inputData);
|
||||
return std::unique_ptr<MemoryBuffer>(ret);
|
||||
@@ -141,7 +141,7 @@ std::unique_ptr<MemoryBuffer> MemoryBuffer::GetMemBuffer(MemoryBufferRef ref) {
|
||||
}
|
||||
|
||||
static std::unique_ptr<WritableMemoryBuffer> GetMemBufferCopyImpl(
|
||||
span<const uint8_t> inputData, std::string_view bufferName,
|
||||
std::span<const uint8_t> inputData, std::string_view bufferName,
|
||||
std::error_code& ec) {
|
||||
auto buf =
|
||||
WritableMemoryBuffer::GetNewUninitMemBuffer(inputData.size(), bufferName);
|
||||
@@ -154,7 +154,7 @@ static std::unique_ptr<WritableMemoryBuffer> GetMemBufferCopyImpl(
|
||||
}
|
||||
|
||||
std::unique_ptr<MemoryBuffer> MemoryBuffer::GetMemBufferCopy(
|
||||
span<const uint8_t> inputData, std::string_view bufferName) {
|
||||
std::span<const uint8_t> inputData, std::string_view bufferName) {
|
||||
std::error_code ec;
|
||||
return GetMemBufferCopyImpl(inputData, bufferName, ec);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
#ifndef WPIUTIL_WPI_CONVERTUTF_H
|
||||
#define WPIUTIL_WPI_CONVERTUTF_H
|
||||
|
||||
#include "wpi/span.h"
|
||||
#include <span>
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
@@ -259,7 +259,7 @@ 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(span<const char> SrcBytes);
|
||||
bool hasUTF16ByteOrderMark(std::span<const char> SrcBytes);
|
||||
|
||||
/**
|
||||
* Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
|
||||
@@ -268,7 +268,7 @@ bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &Out);
|
||||
bool convertUTF16ToUTF8String(std::span<const char> SrcBytes, SmallVectorImpl<char> &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF16 string into a UTF8 std::string.
|
||||
@@ -277,7 +277,7 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF16ToUTF8String(span<const UTF16> Src, SmallVectorImpl<char> &Out);
|
||||
bool convertUTF16ToUTF8String(std::span<const UTF16> Src, SmallVectorImpl<char> &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string into a UTF-16 string with native endianness.
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
|
||||
#include "wpi/span.h"
|
||||
|
||||
// Duplicated from fs.h to avoid a dependency
|
||||
namespace fs {
|
||||
#if defined(_WIN32)
|
||||
@@ -61,7 +60,7 @@ class MemoryBuffer {
|
||||
const uint8_t* end() const { return m_bufferEnd; }
|
||||
size_t size() const { return m_bufferEnd - m_bufferStart; }
|
||||
|
||||
span<const uint8_t> GetBuffer() const { return {begin(), end()}; }
|
||||
std::span<const uint8_t> GetBuffer() const { return {begin(), end()}; }
|
||||
|
||||
/// Return an identifier for this buffer, typically the filename it was read
|
||||
/// from.
|
||||
@@ -98,14 +97,14 @@ class MemoryBuffer {
|
||||
|
||||
/// Open the specified memory range as a MemoryBuffer.
|
||||
static std::unique_ptr<MemoryBuffer> GetMemBuffer(
|
||||
span<const uint8_t> inputData, std::string_view bufferName = "");
|
||||
std::span<const uint8_t> inputData, std::string_view bufferName = "");
|
||||
|
||||
static std::unique_ptr<MemoryBuffer> GetMemBuffer(MemoryBufferRef ref);
|
||||
|
||||
/// Open the specified memory range as a MemoryBuffer, copying the contents
|
||||
/// and taking ownership of it.
|
||||
static std::unique_ptr<MemoryBuffer> GetMemBufferCopy(
|
||||
span<const uint8_t> inputData, std::string_view bufferName = "");
|
||||
std::span<const uint8_t> inputData, std::string_view bufferName = "");
|
||||
|
||||
/// Map a subrange of the specified file as a MemoryBuffer.
|
||||
static std::unique_ptr<MemoryBuffer> GetFileSlice(std::string_view filename,
|
||||
@@ -145,7 +144,7 @@ class WritableMemoryBuffer : public MemoryBuffer {
|
||||
// guaranteed to have been initialized with a mutable buffer.
|
||||
uint8_t* begin() { return const_cast<uint8_t*>(MemoryBuffer::begin()); }
|
||||
uint8_t* end() { return const_cast<uint8_t*>(MemoryBuffer::end()); }
|
||||
span<uint8_t> GetBuffer() { return {begin(), end()}; }
|
||||
std::span<uint8_t> GetBuffer() { return {begin(), end()}; }
|
||||
|
||||
static std::unique_ptr<WritableMemoryBuffer> GetFile(
|
||||
std::string_view filename, std::error_code& ec, int64_t fileSize = -1);
|
||||
@@ -196,7 +195,7 @@ class WriteThroughMemoryBuffer : public MemoryBuffer {
|
||||
// guaranteed to have been initialized with a mutable buffer.
|
||||
uint8_t* begin() { return const_cast<uint8_t*>(MemoryBuffer::begin()); }
|
||||
uint8_t* end() { return const_cast<uint8_t*>(MemoryBuffer::end()); }
|
||||
span<uint8_t> GetBuffer() { return {begin(), end()}; }
|
||||
std::span<uint8_t> GetBuffer() { return {begin(), end()}; }
|
||||
|
||||
static std::unique_ptr<WriteThroughMemoryBuffer> GetFile(
|
||||
std::string_view filename, std::error_code& ec, int64_t fileSize = -1);
|
||||
@@ -218,22 +217,22 @@ class WriteThroughMemoryBuffer : public MemoryBuffer {
|
||||
};
|
||||
|
||||
class MemoryBufferRef {
|
||||
span<const uint8_t> m_buffer;
|
||||
std::span<const uint8_t> m_buffer;
|
||||
std::string_view m_id;
|
||||
|
||||
public:
|
||||
MemoryBufferRef() = default;
|
||||
MemoryBufferRef(MemoryBuffer& buffer) // NOLINT
|
||||
: m_buffer(buffer.GetBuffer()), m_id(buffer.GetBufferIdentifier()) {}
|
||||
MemoryBufferRef(span<const uint8_t> buffer, std::string_view id)
|
||||
MemoryBufferRef(std::span<const uint8_t> buffer, std::string_view id)
|
||||
: m_buffer(buffer), m_id(id) {}
|
||||
|
||||
span<const uint8_t> GetBuffer() const { return m_buffer; }
|
||||
std::span<const uint8_t> GetBuffer() const { return m_buffer; }
|
||||
|
||||
std::string_view GetBufferIdentifier() const { return m_id; }
|
||||
|
||||
const uint8_t* begin() const { return m_buffer.begin(); }
|
||||
const uint8_t* end() const { return m_buffer.end(); }
|
||||
const uint8_t* begin() const { return &*m_buffer.begin(); }
|
||||
const uint8_t* end() const { return &*m_buffer.end(); }
|
||||
size_t size() const { return m_buffer.size(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define WPIUTIL_WPI_RAW_OSTREAM_H
|
||||
|
||||
#include "wpi/SmallVector.h"
|
||||
#include "wpi/span.h"
|
||||
#include <span>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
raw_ostream &operator<<(span<const uint8_t> Arr) {
|
||||
raw_ostream &operator<<(std::span<const uint8_t> Arr) {
|
||||
// Inline fast path, particularly for arrays with a known length.
|
||||
size_t Size = Arr.size();
|
||||
|
||||
@@ -675,9 +675,9 @@ public:
|
||||
|
||||
void flush() = delete;
|
||||
|
||||
/// 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()}; }
|
||||
/// Return an std::span for the vector contents.
|
||||
std::span<uint8_t> array() { return {OS.data(), OS.size()}; }
|
||||
std::span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
|
||||
};
|
||||
|
||||
/// A raw_ostream that writes to a vector. This is a
|
||||
@@ -709,9 +709,9 @@ public:
|
||||
|
||||
void flush() = delete;
|
||||
|
||||
/// 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()}; }
|
||||
/// Return a std::span for the vector contents.
|
||||
std::span<uint8_t> array() { return {OS.data(), OS.size()}; }
|
||||
std::span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,415 +0,0 @@
|
||||
|
||||
/*
|
||||
This is an implementation of C++20's std::span
|
||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
|
||||
*/
|
||||
|
||||
// Copyright Tristan Brindle 2018.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file ../../LICENSE_1_0.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef WPIUTIL_WPI_SPAN_HPP_INCLUDED
|
||||
#define WPIUTIL_WPI_SPAN_HPP_INCLUDED
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#if __cplusplus >= 202002L && __has_include(<span>)
|
||||
#include <span>
|
||||
#endif
|
||||
|
||||
namespace wpi {
|
||||
|
||||
inline constexpr std::size_t dynamic_extent = SIZE_MAX;
|
||||
|
||||
template <typename ElementType, std::size_t Extent = dynamic_extent>
|
||||
class span;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename E, std::size_t S>
|
||||
struct span_storage {
|
||||
constexpr span_storage() noexcept = default;
|
||||
|
||||
constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept
|
||||
: ptr(p_ptr)
|
||||
{}
|
||||
|
||||
E* ptr = nullptr;
|
||||
static constexpr std::size_t size = S;
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
struct span_storage<E, dynamic_extent> {
|
||||
constexpr span_storage() noexcept = default;
|
||||
|
||||
constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept
|
||||
: ptr(p_ptr), size(p_size)
|
||||
{}
|
||||
|
||||
E* ptr = nullptr;
|
||||
std::size_t size = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using uncvref_t =
|
||||
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
|
||||
template <typename>
|
||||
struct is_span : std::false_type {};
|
||||
|
||||
template <typename T, std::size_t S>
|
||||
struct is_span<span<T, S>> : std::true_type {};
|
||||
|
||||
template <typename>
|
||||
struct is_std_array : std::false_type {};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct is_std_array<std::array<T, N>> : std::true_type {};
|
||||
|
||||
template <typename, typename = void>
|
||||
struct has_size_and_data : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_size_and_data<T, std::void_t<decltype(std::size(std::declval<T>())),
|
||||
decltype(std::data(std::declval<T>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename C, typename U = uncvref_t<C>>
|
||||
struct is_container {
|
||||
static constexpr bool value =
|
||||
!is_span<U>::value && !is_std_array<U>::value &&
|
||||
!std::is_array<U>::value && has_size_and_data<C>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using remove_pointer_t = typename std::remove_pointer<T>::type;
|
||||
|
||||
template <typename, typename, typename = void>
|
||||
struct is_container_element_type_compatible : std::false_type {};
|
||||
|
||||
template <typename T, typename E>
|
||||
struct is_container_element_type_compatible<
|
||||
T, E,
|
||||
typename std::enable_if<
|
||||
!std::is_same<typename std::remove_cv<decltype(
|
||||
std::data(std::declval<T>()))>::type,
|
||||
void>::value>::type>
|
||||
: std::is_convertible<
|
||||
remove_pointer_t<decltype(std::data(std::declval<T>()))> (*)[],
|
||||
E (*)[]> {};
|
||||
|
||||
template <typename, typename = size_t>
|
||||
struct is_complete : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename ElementType, std::size_t Extent>
|
||||
class span {
|
||||
static_assert(std::is_object<ElementType>::value,
|
||||
"A span's ElementType must be an object type (not a "
|
||||
"reference type or void)");
|
||||
static_assert(detail::is_complete<ElementType>::value,
|
||||
"A span's ElementType must be a complete type (not a forward "
|
||||
"declaration)");
|
||||
static_assert(!std::is_abstract<ElementType>::value,
|
||||
"A span's ElementType cannot be an abstract class type");
|
||||
|
||||
using storage_type = detail::span_storage<ElementType, Extent>;
|
||||
|
||||
public:
|
||||
// constants and types
|
||||
using element_type = ElementType;
|
||||
using value_type = typename std::remove_cv<ElementType>::type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = element_type*;
|
||||
using const_pointer = const element_type*;
|
||||
using reference = element_type&;
|
||||
using const_reference = const element_type&;
|
||||
using iterator = pointer;
|
||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||
|
||||
static constexpr size_type extent = Extent;
|
||||
|
||||
// [span.cons], span constructors, copy, assignment, and destructor
|
||||
template <
|
||||
std::size_t E = Extent,
|
||||
typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
|
||||
constexpr span() noexcept
|
||||
{}
|
||||
|
||||
constexpr span(pointer ptr, size_type count)
|
||||
: storage_(ptr, count)
|
||||
{
|
||||
assert(extent == dynamic_extent || count == extent);
|
||||
}
|
||||
|
||||
constexpr span(pointer first_elem, pointer last_elem)
|
||||
: storage_(first_elem, last_elem - first_elem)
|
||||
{
|
||||
assert(extent == dynamic_extent ||
|
||||
last_elem - first_elem ==
|
||||
static_cast<std::ptrdiff_t>(extent));
|
||||
}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
element_type (&)[N], ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N)
|
||||
{}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
std::array<value_type, N>&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(std::array<value_type, N>& arr) noexcept
|
||||
: storage_(arr.data(), N)
|
||||
{}
|
||||
|
||||
template <std::size_t N, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
(E == dynamic_extent || N == E) &&
|
||||
detail::is_container_element_type_compatible<
|
||||
const std::array<value_type, N>&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(const std::array<value_type, N>& arr) noexcept
|
||||
: storage_(arr.data(), N)
|
||||
{}
|
||||
|
||||
template <
|
||||
typename Container, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
E == dynamic_extent && detail::is_container<Container>::value &&
|
||||
detail::is_container_element_type_compatible<
|
||||
Container&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(Container& cont)
|
||||
: storage_(std::data(cont), std::size(cont))
|
||||
{}
|
||||
|
||||
template <
|
||||
typename Container, std::size_t E = Extent,
|
||||
typename std::enable_if<
|
||||
E == dynamic_extent && detail::is_container<Container>::value &&
|
||||
detail::is_container_element_type_compatible<
|
||||
const Container&, ElementType>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(const Container& cont)
|
||||
: storage_(std::data(cont), std::size(cont))
|
||||
{}
|
||||
|
||||
constexpr span(const span& other) noexcept = default;
|
||||
|
||||
template <typename OtherElementType, std::size_t OtherExtent,
|
||||
typename std::enable_if<
|
||||
(Extent == OtherExtent || Extent == dynamic_extent) &&
|
||||
std::is_convertible<OtherElementType (*)[],
|
||||
ElementType (*)[]>::value,
|
||||
int>::type = 0>
|
||||
constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept
|
||||
: storage_(other.data(), other.size())
|
||||
{}
|
||||
|
||||
#ifdef __cpp_lib_span
|
||||
constexpr span(std::span<ElementType> other) noexcept
|
||||
: storage_(other.data(), other.size())
|
||||
{}
|
||||
#endif
|
||||
|
||||
~span() noexcept = default;
|
||||
|
||||
constexpr span&
|
||||
operator=(const span& other) noexcept = default;
|
||||
|
||||
// [span.sub], span subviews
|
||||
template <std::size_t Count>
|
||||
constexpr span<element_type, Count> first() const
|
||||
{
|
||||
assert(Count <= size());
|
||||
return {data(), Count};
|
||||
}
|
||||
|
||||
template <std::size_t Count>
|
||||
constexpr span<element_type, Count> last() const
|
||||
{
|
||||
assert(Count <= size());
|
||||
return {data() + (size() - Count), Count};
|
||||
}
|
||||
|
||||
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||
using subspan_return_t =
|
||||
span<ElementType, Count != dynamic_extent
|
||||
? Count
|
||||
: (Extent != dynamic_extent ? Extent - Offset
|
||||
: dynamic_extent)>;
|
||||
|
||||
template <std::size_t Offset, std::size_t Count = dynamic_extent>
|
||||
constexpr subspan_return_t<Offset, Count> subspan() const
|
||||
{
|
||||
assert(Offset <= size() &&
|
||||
(Count == dynamic_extent || Offset + Count <= size()));
|
||||
return {data() + Offset,
|
||||
Count != dynamic_extent ? Count : size() - Offset};
|
||||
}
|
||||
|
||||
constexpr span<element_type, dynamic_extent>
|
||||
first(size_type count) const
|
||||
{
|
||||
assert(count <= size());
|
||||
return {data(), count};
|
||||
}
|
||||
|
||||
constexpr span<element_type, dynamic_extent>
|
||||
last(size_type count) const
|
||||
{
|
||||
assert(count <= size());
|
||||
return {data() + (size() - count), count};
|
||||
}
|
||||
|
||||
constexpr span<element_type, dynamic_extent>
|
||||
subspan(size_type offset, size_type count = dynamic_extent) const
|
||||
{
|
||||
assert(offset <= size() &&
|
||||
(count == dynamic_extent || offset + count <= size()));
|
||||
return {data() + offset,
|
||||
count == dynamic_extent ? size() - offset : count};
|
||||
}
|
||||
|
||||
// [span.obs], span observers
|
||||
constexpr size_type size() const noexcept { return storage_.size; }
|
||||
|
||||
constexpr size_type size_bytes() const noexcept
|
||||
{
|
||||
return size() * sizeof(element_type);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
// [span.elem], span element access
|
||||
constexpr reference operator[](size_type idx) const
|
||||
{
|
||||
assert(idx < size());
|
||||
return *(data() + idx);
|
||||
}
|
||||
|
||||
constexpr reference front() const
|
||||
{
|
||||
assert(!empty());
|
||||
return *data();
|
||||
}
|
||||
|
||||
constexpr reference back() const
|
||||
{
|
||||
assert(!empty());
|
||||
return *(data() + (size() - 1));
|
||||
}
|
||||
|
||||
constexpr pointer data() const noexcept { return storage_.ptr; }
|
||||
|
||||
// [span.iterators], span iterator support
|
||||
constexpr iterator begin() const noexcept { return data(); }
|
||||
|
||||
constexpr iterator end() const noexcept { return data() + size(); }
|
||||
|
||||
constexpr reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
constexpr reverse_iterator rend() const noexcept
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_span
|
||||
constexpr operator auto() const {
|
||||
return std::span < ElementType,
|
||||
(Extent == dynamic_extent)
|
||||
? std::dynamic_extent
|
||||
: Extent > (storage_.ptr, storage_.size);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
storage_type storage_{};
|
||||
};
|
||||
|
||||
/* Deduction Guides */
|
||||
template <class T, size_t N>
|
||||
span(T (&)[N])->span<T, N>;
|
||||
|
||||
template <class T, size_t N>
|
||||
span(std::array<T, N>&)->span<T, N>;
|
||||
|
||||
template <class T, size_t N>
|
||||
span(const std::array<T, N>&)->span<const T, N>;
|
||||
|
||||
template <class Container>
|
||||
span(Container&)->span<typename Container::value_type>;
|
||||
|
||||
template <class Container>
|
||||
span(const Container&)->span<const typename Container::value_type>;
|
||||
|
||||
template <typename ElementType, std::size_t Extent>
|
||||
span<const std::byte, ((Extent == dynamic_extent) ? dynamic_extent
|
||||
: sizeof(ElementType) * Extent)>
|
||||
as_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <
|
||||
class ElementType, size_t Extent,
|
||||
typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
|
||||
span<std::byte, ((Extent == dynamic_extent) ? dynamic_extent
|
||||
: sizeof(ElementType) * Extent)>
|
||||
as_writable_bytes(span<ElementType, Extent> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template <std::size_t N, typename E, std::size_t S>
|
||||
constexpr auto get(span<E, S> s) -> decltype(s[N])
|
||||
{
|
||||
return s[N];
|
||||
}
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
namespace std {
|
||||
|
||||
template <typename ElementType, size_t Extent>
|
||||
class tuple_size<wpi::span<ElementType, Extent>>
|
||||
: public integral_constant<size_t, Extent> {};
|
||||
|
||||
template <typename ElementType>
|
||||
class tuple_size<wpi::span<
|
||||
ElementType, wpi::dynamic_extent>>; // not defined
|
||||
|
||||
template <size_t I, typename ElementType, size_t Extent>
|
||||
class tuple_element<I, wpi::span<ElementType, Extent>> {
|
||||
public:
|
||||
static_assert(Extent != wpi::dynamic_extent &&
|
||||
I < Extent,
|
||||
"");
|
||||
using type = ElementType;
|
||||
};
|
||||
|
||||
} // end namespace std
|
||||
|
||||
#endif // WPIUTIL_WPI_SPAN_HPP_INCLUDED
|
||||
Reference in New Issue
Block a user