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:
Tyler Veness
2022-10-15 16:33:14 -07:00
committed by GitHub
parent 396143004c
commit fbdc810887
355 changed files with 1659 additions and 2918 deletions

View File

@@ -138,8 +138,8 @@ size_t Base64Decode(std::string_view encoded, std::vector<uint8_t>* plain) {
return Base64Decode(os, encoded);
}
span<uint8_t> Base64Decode(std::string_view encoded, size_t* num_read,
SmallVectorImpl<uint8_t>& buf) {
std::span<uint8_t> Base64Decode(std::string_view encoded, size_t* num_read,
SmallVectorImpl<uint8_t>& buf) {
buf.clear();
raw_usvector_ostream os(buf);
*num_read = Base64Decode(os, encoded);
@@ -193,19 +193,19 @@ std::string_view Base64Encode(std::string_view plain,
return os.str();
}
void Base64Encode(raw_ostream& os, span<const uint8_t> plain) {
void Base64Encode(raw_ostream& os, std::span<const uint8_t> plain) {
Base64Encode(os, std::string_view{reinterpret_cast<const char*>(plain.data()),
plain.size()});
}
void Base64Encode(span<const uint8_t> plain, std::string* encoded) {
void Base64Encode(std::span<const uint8_t> plain, std::string* encoded) {
encoded->resize(0);
raw_string_ostream os(*encoded);
Base64Encode(os, plain);
os.flush();
}
std::string_view Base64Encode(span<const uint8_t> plain,
std::string_view Base64Encode(std::span<const uint8_t> plain,
SmallVectorImpl<char>& buf) {
buf.clear();
raw_svector_ostream os(buf);

View File

@@ -109,8 +109,8 @@ class DataLog::Buffer {
size_t GetRemaining() const { return m_maxLen - m_len; }
wpi::span<uint8_t> GetData() { return {m_buf, m_len}; }
wpi::span<const uint8_t> GetData() const { return {m_buf, m_len}; }
std::span<uint8_t> GetData() { return {m_buf, m_len}; }
std::span<const uint8_t> GetData() const { return {m_buf, m_len}; }
private:
uint8_t* m_buf;
@@ -142,12 +142,12 @@ DataLog::DataLog(wpi::Logger& msglog, std::string_view dir,
m_newFilename{filename},
m_thread{[this, dir = std::string{dir}] { WriterThreadMain(dir); }} {}
DataLog::DataLog(std::function<void(wpi::span<const uint8_t> data)> write,
DataLog::DataLog(std::function<void(std::span<const uint8_t> data)> write,
double period, std::string_view extraHeader)
: DataLog{defaultMessageLog, std::move(write), period, extraHeader} {}
DataLog::DataLog(wpi::Logger& msglog,
std::function<void(wpi::span<const uint8_t> data)> write,
std::function<void(std::span<const uint8_t> data)> write,
double period, std::string_view extraHeader)
: m_msglog{msglog},
m_period{period},
@@ -192,7 +192,7 @@ void DataLog::Resume() {
m_paused = false;
}
static void WriteToFile(fs::file_t f, wpi::span<const uint8_t> data,
static void WriteToFile(fs::file_t f, std::span<const uint8_t> data,
std::string_view filename, wpi::Logger& msglog) {
do {
#ifdef _WIN32
@@ -365,7 +365,7 @@ void DataLog::WriterThreadMain(std::string_view dir) {
}
void DataLog::WriterThreadMain(
std::function<void(wpi::span<const uint8_t> data)> write) {
std::function<void(std::span<const uint8_t> data)> write) {
std::chrono::duration<double> periodTime{m_period};
// write header (version 1.0)
@@ -509,7 +509,7 @@ uint8_t* DataLog::StartRecord(uint32_t entry, uint64_t timestamp,
return buf;
}
void DataLog::AppendImpl(wpi::span<const uint8_t> data) {
void DataLog::AppendImpl(std::span<const uint8_t> data) {
while (data.size() > kBlockSize) {
uint8_t* buf = Reserve(kBlockSize);
std::memcpy(buf, data.data(), kBlockSize);
@@ -525,7 +525,7 @@ void DataLog::AppendStringImpl(std::string_view str) {
AppendImpl({reinterpret_cast<const uint8_t*>(str.data()), str.size()});
}
void DataLog::AppendRaw(int entry, wpi::span<const uint8_t> data,
void DataLog::AppendRaw(int entry, std::span<const uint8_t> data,
int64_t timestamp) {
if (entry <= 0) {
return;
@@ -539,7 +539,7 @@ void DataLog::AppendRaw(int entry, wpi::span<const uint8_t> data,
}
void DataLog::AppendRaw2(int entry,
wpi::span<const wpi::span<const uint8_t>> data,
std::span<const std::span<const uint8_t>> data,
int64_t timestamp) {
if (entry <= 0) {
return;
@@ -623,7 +623,7 @@ void DataLog::AppendString(int entry, std::string_view value,
timestamp);
}
void DataLog::AppendBooleanArray(int entry, wpi::span<const bool> arr,
void DataLog::AppendBooleanArray(int entry, std::span<const bool> arr,
int64_t timestamp) {
if (entry <= 0) {
return;
@@ -647,7 +647,7 @@ void DataLog::AppendBooleanArray(int entry, wpi::span<const bool> arr,
}
}
void DataLog::AppendBooleanArray(int entry, wpi::span<const int> arr,
void DataLog::AppendBooleanArray(int entry, std::span<const int> arr,
int64_t timestamp) {
if (entry <= 0) {
return;
@@ -671,12 +671,12 @@ void DataLog::AppendBooleanArray(int entry, wpi::span<const int> arr,
}
}
void DataLog::AppendBooleanArray(int entry, wpi::span<const uint8_t> arr,
void DataLog::AppendBooleanArray(int entry, std::span<const uint8_t> arr,
int64_t timestamp) {
AppendRaw(entry, arr, timestamp);
}
void DataLog::AppendIntegerArray(int entry, wpi::span<const int64_t> arr,
void DataLog::AppendIntegerArray(int entry, std::span<const int64_t> arr,
int64_t timestamp) {
if constexpr (wpi::support::endian::system_endianness() ==
wpi::support::little) {
@@ -709,7 +709,7 @@ void DataLog::AppendIntegerArray(int entry, wpi::span<const int64_t> arr,
}
}
void DataLog::AppendFloatArray(int entry, wpi::span<const float> arr,
void DataLog::AppendFloatArray(int entry, std::span<const float> arr,
int64_t timestamp) {
if constexpr (wpi::support::endian::system_endianness() ==
wpi::support::little) {
@@ -742,7 +742,7 @@ void DataLog::AppendFloatArray(int entry, wpi::span<const float> arr,
}
}
void DataLog::AppendDoubleArray(int entry, wpi::span<const double> arr,
void DataLog::AppendDoubleArray(int entry, std::span<const double> arr,
int64_t timestamp) {
if constexpr (wpi::support::endian::system_endianness() ==
wpi::support::little) {
@@ -775,7 +775,7 @@ void DataLog::AppendDoubleArray(int entry, wpi::span<const double> arr,
}
}
void DataLog::AppendStringArray(int entry, wpi::span<const std::string> arr,
void DataLog::AppendStringArray(int entry, std::span<const std::string> arr,
int64_t timestamp) {
if (entry <= 0) {
return;
@@ -798,7 +798,7 @@ void DataLog::AppendStringArray(int entry, wpi::span<const std::string> arr,
}
void DataLog::AppendStringArray(int entry,
wpi::span<const std::string_view> arr,
std::span<const std::string_view> arr,
int64_t timestamp) {
if (entry <= 0) {
return;

View File

@@ -10,7 +10,7 @@
using namespace wpi::log;
static bool ReadString(wpi::span<const uint8_t>* buf, std::string_view* str) {
static bool ReadString(std::span<const uint8_t>* buf, std::string_view* str) {
if (buf->size() < 4) {
*str = {};
return false;
@@ -241,7 +241,7 @@ DataLogReader::iterator DataLogReader::begin() const {
return DataLogIterator{this, 12 + size};
}
static uint64_t ReadVarInt(wpi::span<const uint8_t> buf) {
static uint64_t ReadVarInt(std::span<const uint8_t> buf) {
uint64_t val = 0;
int shift = 0;
for (auto v : buf) {

View File

@@ -166,20 +166,20 @@ bool wpi::WaitForObject(WPI_Handle handle) {
bool wpi::WaitForObject(WPI_Handle handle, double timeout, bool* timedOut) {
WPI_Handle signaledValue;
auto signaled = WaitForObjects(
wpi::span(&handle, 1), wpi::span(&signaledValue, 1), timeout, timedOut);
std::span(&handle, 1), std::span(&signaledValue, 1), timeout, timedOut);
if (signaled.empty()) {
return false;
}
return (signaled[0] & 0x80000000ul) == 0;
}
wpi::span<WPI_Handle> wpi::WaitForObjects(wpi::span<const WPI_Handle> handles,
wpi::span<WPI_Handle> signaled) {
std::span<WPI_Handle> wpi::WaitForObjects(std::span<const WPI_Handle> handles,
std::span<WPI_Handle> signaled) {
return WaitForObjects(handles, signaled, -1, nullptr);
}
wpi::span<WPI_Handle> wpi::WaitForObjects(wpi::span<const WPI_Handle> handles,
wpi::span<WPI_Handle> signaled,
std::span<WPI_Handle> wpi::WaitForObjects(std::span<const WPI_Handle> handles,
std::span<WPI_Handle> signaled,
double timeout, bool* timedOut) {
auto& manager = GetManager();
if (gShutdown) {
@@ -368,8 +368,8 @@ int WPI_WaitForObjectTimeout(WPI_Handle handle, double timeout,
int WPI_WaitForObjects(const WPI_Handle* handles, int handles_count,
WPI_Handle* signaled) {
return wpi::WaitForObjects(wpi::span(handles, handles_count),
wpi::span(signaled, handles_count))
return wpi::WaitForObjects(std::span(handles, handles_count),
std::span(signaled, handles_count))
.size();
}
@@ -377,8 +377,8 @@ int WPI_WaitForObjectsTimeout(const WPI_Handle* handles, int handles_count,
WPI_Handle* signaled, double timeout,
int* timed_out) {
bool timedOutBool;
auto signaledResult = wpi::WaitForObjects(wpi::span(handles, handles_count),
wpi::span(signaled, handles_count),
auto signaledResult = wpi::WaitForObjects(std::span(handles, handles_count),
std::span(signaled, handles_count),
timeout, &timedOutBool);
*timed_out = timedOutBool ? 1 : 0;
return signaledResult.size();

View File

@@ -247,7 +247,7 @@ Java_edu_wpi_first_util_WPIUtilJNI_waitForObjects
JIntArrayRef handlesArr{env, handles};
wpi::SmallVector<WPI_Handle, 8> signaledBuf;
signaledBuf.resize(handlesArr.size());
wpi::span<const WPI_Handle> handlesArr2{
std::span<const WPI_Handle> handlesArr2{
reinterpret_cast<const WPI_Handle*>(handlesArr.array().data()),
handlesArr.size()};
@@ -271,7 +271,7 @@ Java_edu_wpi_first_util_WPIUtilJNI_waitForObjectsTimeout
JIntArrayRef handlesArr{env, handles};
wpi::SmallVector<WPI_Handle, 8> signaledBuf;
signaledBuf.resize(handlesArr.size());
wpi::span<const WPI_Handle> handlesArr2{
std::span<const WPI_Handle> handlesArr2{
reinterpret_cast<const WPI_Handle*>(handlesArr.array().data()),
handlesArr.size()};

View File

@@ -7,7 +7,6 @@
#include "wpi/SpanExtras.h"
#include "wpi/raw_istream.h"
#include "wpi/raw_ostream.h"
#include "wpi/span.h"
namespace wpi {
@@ -98,7 +97,7 @@ bool ReadUleb128(raw_istream& is, uint64_t* ret) {
return true;
}
std::optional<uint64_t> Uleb128Reader::ReadOne(span<const uint8_t>* in) {
std::optional<uint64_t> Uleb128Reader::ReadOne(std::span<const uint8_t>* in) {
while (!in->empty()) {
uint8_t byte = in->front();
*in = wpi::drop_front(*in);

View File

@@ -217,7 +217,7 @@ SHA1::SHA1() {
}
void SHA1::Update(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()));
Update(is);
}

View File

@@ -6,12 +6,11 @@
#define WPIUTIL_WPI_BASE64_H_
#include <cstddef>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include "wpi/span.h"
namespace wpi {
template <typename T>
class SmallVectorImpl;
@@ -26,8 +25,8 @@ std::string_view Base64Decode(std::string_view encoded, size_t* num_read,
size_t Base64Decode(std::string_view encoded, std::vector<uint8_t>* plain);
span<uint8_t> Base64Decode(std::string_view encoded, size_t* num_read,
SmallVectorImpl<uint8_t>& buf);
std::span<uint8_t> Base64Decode(std::string_view encoded, size_t* num_read,
SmallVectorImpl<uint8_t>& buf);
void Base64Encode(raw_ostream& os, std::string_view plain);
@@ -36,11 +35,11 @@ void Base64Encode(std::string_view plain, std::string* encoded);
std::string_view Base64Encode(std::string_view plain,
SmallVectorImpl<char>& buf);
void Base64Encode(raw_ostream& os, span<const uint8_t> plain);
void Base64Encode(raw_ostream& os, std::span<const uint8_t> plain);
void Base64Encode(span<const uint8_t> plain, std::string* encoded);
void Base64Encode(std::span<const uint8_t> plain, std::string* encoded);
std::string_view Base64Encode(span<const uint8_t> plain,
std::string_view Base64Encode(std::span<const uint8_t> plain,
SmallVectorImpl<char>& buf);
} // namespace wpi

View File

@@ -9,6 +9,7 @@
#include <functional>
#include <initializer_list>
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <thread>
@@ -18,7 +19,6 @@
#include "wpi/StringMap.h"
#include "wpi/condition_variable.h"
#include "wpi/mutex.h"
#include "wpi/span.h"
namespace wpi {
class Logger;
@@ -106,7 +106,7 @@ class DataLog final {
* this is a time/storage tradeoff
* @param extraHeader extra header data
*/
explicit DataLog(std::function<void(wpi::span<const uint8_t> data)> write,
explicit DataLog(std::function<void(std::span<const uint8_t> data)> write,
double period = 0.25, std::string_view extraHeader = "");
/**
@@ -122,7 +122,7 @@ class DataLog final {
* @param extraHeader extra header data
*/
explicit DataLog(wpi::Logger& msglog,
std::function<void(wpi::span<const uint8_t> data)> write,
std::function<void(std::span<const uint8_t> data)> write,
double period = 0.25, std::string_view extraHeader = "");
~DataLog();
@@ -196,7 +196,7 @@ class DataLog final {
* @param data Data to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void AppendRaw(int entry, wpi::span<const uint8_t> data, int64_t timestamp);
void AppendRaw(int entry, std::span<const uint8_t> data, int64_t timestamp);
/**
* Appends a record to the log.
@@ -205,7 +205,7 @@ class DataLog final {
* @param data Data to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void AppendRaw2(int entry, wpi::span<const wpi::span<const uint8_t>> data,
void AppendRaw2(int entry, std::span<const std::span<const uint8_t>> data,
int64_t timestamp);
void AppendBoolean(int entry, bool value, int64_t timestamp);
@@ -213,33 +213,33 @@ class DataLog final {
void AppendFloat(int entry, float value, int64_t timestamp);
void AppendDouble(int entry, double value, int64_t timestamp);
void AppendString(int entry, std::string_view value, int64_t timestamp);
void AppendBooleanArray(int entry, wpi::span<const bool> arr,
void AppendBooleanArray(int entry, std::span<const bool> arr,
int64_t timestamp);
void AppendBooleanArray(int entry, wpi::span<const int> arr,
void AppendBooleanArray(int entry, std::span<const int> arr,
int64_t timestamp);
void AppendBooleanArray(int entry, wpi::span<const uint8_t> arr,
void AppendBooleanArray(int entry, std::span<const uint8_t> arr,
int64_t timestamp);
void AppendIntegerArray(int entry, wpi::span<const int64_t> arr,
void AppendIntegerArray(int entry, std::span<const int64_t> arr,
int64_t timestamp);
void AppendFloatArray(int entry, wpi::span<const float> arr,
void AppendFloatArray(int entry, std::span<const float> arr,
int64_t timestamp);
void AppendDoubleArray(int entry, wpi::span<const double> arr,
void AppendDoubleArray(int entry, std::span<const double> arr,
int64_t timestamp);
void AppendStringArray(int entry, wpi::span<const std::string> arr,
void AppendStringArray(int entry, std::span<const std::string> arr,
int64_t timestamp);
void AppendStringArray(int entry, wpi::span<const std::string_view> arr,
void AppendStringArray(int entry, std::span<const std::string_view> arr,
int64_t timestamp);
private:
void WriterThreadMain(std::string_view dir);
void WriterThreadMain(
std::function<void(wpi::span<const uint8_t> data)> write);
std::function<void(std::span<const uint8_t> data)> write);
// must be called with m_mutex held
uint8_t* StartRecord(uint32_t entry, uint64_t timestamp, uint32_t payloadSize,
size_t reserveSize);
uint8_t* Reserve(size_t size);
void AppendImpl(wpi::span<const uint8_t> data);
void AppendImpl(std::span<const uint8_t> data);
void AppendStringImpl(std::string_view str);
wpi::Logger& m_msglog;
@@ -338,7 +338,7 @@ class RawLogEntry : public DataLogEntry {
* @param data Data to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const uint8_t> data, int64_t timestamp = 0) {
void Append(std::span<const uint8_t> data, int64_t timestamp = 0) {
m_log->AppendRaw(m_entry, data, timestamp);
}
};
@@ -493,7 +493,7 @@ class BooleanArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const bool> arr, int64_t timestamp = 0) {
void Append(std::span<const bool> arr, int64_t timestamp = 0) {
m_log->AppendBooleanArray(m_entry, arr, timestamp);
}
@@ -504,7 +504,7 @@ class BooleanArrayLogEntry : public DataLogEntry {
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(std::initializer_list<bool> arr, int64_t timestamp = 0) {
Append(wpi::span{arr.begin(), arr.end()}, timestamp);
Append(std::span{arr.begin(), arr.end()}, timestamp);
}
/**
@@ -513,7 +513,7 @@ class BooleanArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const int> arr, int64_t timestamp = 0) {
void Append(std::span<const int> arr, int64_t timestamp = 0) {
m_log->AppendBooleanArray(m_entry, arr, timestamp);
}
@@ -524,7 +524,7 @@ class BooleanArrayLogEntry : public DataLogEntry {
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(std::initializer_list<int> arr, int64_t timestamp = 0) {
Append(wpi::span{arr.begin(), arr.end()}, timestamp);
Append(std::span{arr.begin(), arr.end()}, timestamp);
}
/**
@@ -533,7 +533,7 @@ class BooleanArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const uint8_t> arr, int64_t timestamp = 0) {
void Append(std::span<const uint8_t> arr, int64_t timestamp = 0) {
m_log->AppendBooleanArray(m_entry, arr, timestamp);
}
};
@@ -559,7 +559,7 @@ class IntegerArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const int64_t> arr, int64_t timestamp = 0) {
void Append(std::span<const int64_t> arr, int64_t timestamp = 0) {
m_log->AppendIntegerArray(m_entry, arr, timestamp);
}
@@ -594,7 +594,7 @@ class FloatArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const float> arr, int64_t timestamp = 0) {
void Append(std::span<const float> arr, int64_t timestamp = 0) {
m_log->AppendFloatArray(m_entry, arr, timestamp);
}
@@ -630,7 +630,7 @@ class DoubleArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const double> arr, int64_t timestamp = 0) {
void Append(std::span<const double> arr, int64_t timestamp = 0) {
m_log->AppendDoubleArray(m_entry, arr, timestamp);
}
@@ -666,7 +666,7 @@ class StringArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const std::string> arr, int64_t timestamp = 0) {
void Append(std::span<const std::string> arr, int64_t timestamp = 0) {
m_log->AppendStringArray(m_entry, arr, timestamp);
}
@@ -676,7 +676,7 @@ class StringArrayLogEntry : public DataLogEntry {
* @param arr Values to record
* @param timestamp Time stamp (may be 0 to indicate now)
*/
void Append(wpi::span<const std::string_view> arr, int64_t timestamp = 0) {
void Append(std::span<const std::string_view> arr, int64_t timestamp = 0) {
m_log->AppendStringArray(m_entry, arr, timestamp);
}
@@ -688,7 +688,7 @@ class StringArrayLogEntry : public DataLogEntry {
*/
void Append(std::initializer_list<std::string_view> arr,
int64_t timestamp = 0) {
Append(wpi::span<const std::string_view>{arr.begin(), arr.end()},
Append(std::span<const std::string_view>{arr.begin(), arr.end()},
timestamp);
}
};

View File

@@ -8,11 +8,11 @@
#include <iterator>
#include <memory>
#include <span>
#include <utility>
#include <vector>
#include "wpi/MemoryBuffer.h"
#include "wpi/span.h"
namespace wpi::log {
@@ -54,7 +54,7 @@ struct MetadataRecordData {
class DataLogRecord {
public:
DataLogRecord() = default;
DataLogRecord(int entry, int64_t timestamp, wpi::span<const uint8_t> data)
DataLogRecord(int entry, int64_t timestamp, std::span<const uint8_t> data)
: m_timestamp{timestamp}, m_data{data}, m_entry{entry} {}
/**
@@ -82,7 +82,7 @@ class DataLogRecord {
* Gets the raw data. Use the GetX functions to decode based on the data type
* in the entry's start record.
*/
wpi::span<const uint8_t> GetRaw() const { return m_data; }
std::span<const uint8_t> GetRaw() const { return m_data; }
/**
* Returns true if the record is a control record.
@@ -241,7 +241,7 @@ class DataLogRecord {
private:
int64_t m_timestamp{0};
wpi::span<const uint8_t> m_data;
std::span<const uint8_t> m_data;
int m_entry{-1};
};

View File

@@ -6,11 +6,11 @@
#include <stdint.h>
#include <span>
#include <string>
#include <string_view>
#include "wpi/mpack.h"
#include "wpi/span.h"
namespace mpack {
@@ -19,13 +19,13 @@ inline void mpack_write_str(mpack_writer_t* writer, std::string_view str) {
}
inline void mpack_write_bytes(mpack_writer_t* writer,
wpi::span<const uint8_t> data) {
std::span<const uint8_t> data) {
mpack_write_bytes(writer, reinterpret_cast<const char*>(data.data()),
data.size());
}
inline void mpack_reader_init_data(mpack_reader_t* reader,
wpi::span<const uint8_t> data) {
std::span<const uint8_t> data) {
mpack_reader_init_data(reader, reinterpret_cast<const char*>(data.data()),
data.size());
}

View File

@@ -5,21 +5,22 @@
#pragma once
#include <cassert>
#include "wpi/span.h"
#include <span>
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) {
constexpr std::span<T> drop_front(std::span<T> in,
typename std::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) {
constexpr std::span<T> drop_back(std::span<T> in,
typename std::span<T>::size_type n = 1) {
assert(in.size() >= n && "Dropping more elements than exist");
return in.subspan(0, in.size() - n);
}

View File

@@ -8,8 +8,7 @@
#ifdef __cplusplus
#include <initializer_list>
#include "wpi/span.h"
#include <span>
#endif
/**
@@ -149,8 +148,8 @@ bool WaitForObject(WPI_Handle handle, double timeout, bool* timedOut);
* least the size of the handles input array
* @return array of signaled handles (points into signaled array)
*/
wpi::span<WPI_Handle> WaitForObjects(wpi::span<const WPI_Handle> handles,
wpi::span<WPI_Handle> signaled);
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
std::span<WPI_Handle> signaled);
/**
* Waits for one or more handles to be signaled.
@@ -163,9 +162,9 @@ wpi::span<WPI_Handle> WaitForObjects(wpi::span<const WPI_Handle> handles,
* least the size of the handles input array
* @return array of signaled handles (points into signaled array)
*/
inline wpi::span<WPI_Handle> WaitForObjects(
std::initializer_list<WPI_Handle> handles, wpi::span<WPI_Handle> signaled) {
return WaitForObjects(wpi::span{handles.begin(), handles.size()}, signaled);
inline std::span<WPI_Handle> WaitForObjects(
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled) {
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled);
}
/**
@@ -182,8 +181,8 @@ inline wpi::span<WPI_Handle> WaitForObjects(
* handle being signaled; set to false otherwise (output)
* @return array of signaled handles (points into signaled array)
*/
wpi::span<WPI_Handle> WaitForObjects(wpi::span<const WPI_Handle> handles,
wpi::span<WPI_Handle> signaled,
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
std::span<WPI_Handle> signaled,
double timeout, bool* timedOut);
/**
* Waits for one or more handles to be signaled, with timeout.
@@ -199,10 +198,10 @@ wpi::span<WPI_Handle> WaitForObjects(wpi::span<const WPI_Handle> handles,
* handle being signaled; set to false otherwise (output)
* @return array of signaled handles (points into signaled array)
*/
inline wpi::span<WPI_Handle> WaitForObjects(
std::initializer_list<WPI_Handle> handles, wpi::span<WPI_Handle> signaled,
inline std::span<WPI_Handle> WaitForObjects(
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled,
double timeout, bool* timedOut) {
return WaitForObjects(wpi::span{handles.begin(), handles.size()}, signaled,
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled,
timeout, timedOut);
}

View File

@@ -8,6 +8,7 @@
#include <jni.h>
#include <queue>
#include <span>
#include <string>
#include <string_view>
#include <type_traits>
@@ -21,7 +22,6 @@
#include "wpi/StringExtras.h"
#include "wpi/mutex.h"
#include "wpi/raw_ostream.h"
#include "wpi/span.h"
/** Java Native Interface (JNI) utility functions */
namespace wpi::java {
@@ -154,7 +154,7 @@ class JStringRef {
jsize size = env->GetStringLength(str);
const jchar* chars = env->GetStringCritical(str, nullptr);
if (chars) {
convertUTF16ToUTF8String(wpi::span<const jchar>(chars, size), m_str);
convertUTF16ToUTF8String(std::span<const jchar>(chars, size), m_str);
env->ReleaseStringCritical(str, chars);
}
} else {
@@ -181,7 +181,7 @@ namespace detail {
template <typename C, typename T>
class JArrayRefInner {
public:
operator span<const T>() const { // NOLINT
operator std::span<const T>() const { // NOLINT
return static_cast<const C*>(this)->array();
}
};
@@ -203,7 +203,7 @@ class JArrayRefInner<C, jbyte> {
return {reinterpret_cast<const char*>(arr.data()), arr.size()};
}
span<const uint8_t> uarray() const {
std::span<const uint8_t> uarray() const {
auto arr = static_cast<const C*>(this)->array();
if (arr.empty()) {
return {};
@@ -222,7 +222,7 @@ class JArrayRefInner<C, jlong> {
template <typename U,
typename = std::enable_if_t<sizeof(U) == sizeof(jlong) &&
std::is_integral_v<U>>>
operator span<const U>() const { // NOLINT
operator std::span<const U>() const { // NOLINT
auto arr = static_cast<const C*>(this)->array();
if (arr.empty()) {
return {};
@@ -239,7 +239,7 @@ class JArrayRefBase : public JArrayRefInner<JArrayRefBase<T>, T> {
public:
explicit operator bool() const { return this->m_elements != nullptr; }
span<const T> array() const {
std::span<const T> array() const {
if (!this->m_elements) {
return {};
}
@@ -406,7 +406,7 @@ namespace detail {
template <typename T,
bool = (std::is_integral<T>::value && sizeof(jint) == sizeof(T))>
struct ConvertIntArray {
static jintArray ToJava(JNIEnv* env, span<const T> arr) {
static jintArray ToJava(JNIEnv* env, std::span<const T> arr) {
jintArray jarr = env->NewIntArray(arr.size());
if (!jarr) {
return nullptr;
@@ -429,7 +429,7 @@ struct ConvertIntArray {
*/
template <typename T>
struct ConvertIntArray<T, true> {
static jintArray ToJava(JNIEnv* env, span<const T> arr) {
static jintArray ToJava(JNIEnv* env, std::span<const T> arr) {
jintArray jarr = env->NewIntArray(arr.size());
if (!jarr) {
return nullptr;
@@ -449,7 +449,7 @@ struct ConvertIntArray<T, true> {
* @param arr Span to convert.
*/
template <typename T>
inline jintArray MakeJIntArray(JNIEnv* env, span<const T> arr) {
inline jintArray MakeJIntArray(JNIEnv* env, std::span<const T> arr) {
return detail::ConvertIntArray<T>::ToJava(env, arr);
}
@@ -460,7 +460,7 @@ inline jintArray MakeJIntArray(JNIEnv* env, span<const T> arr) {
* @param arr Span to convert.
*/
template <typename T>
inline jintArray MakeJIntArray(JNIEnv* env, span<T> arr) {
inline jintArray MakeJIntArray(JNIEnv* env, std::span<T> arr) {
return detail::ConvertIntArray<T>::ToJava(env, arr);
}
@@ -498,7 +498,7 @@ inline jintArray MakeJIntArray(JNIEnv* env, const std::vector<T>& arr) {
* @param env JRE environment.
* @param str span to convert.
*/
inline jbyteArray MakeJByteArray(JNIEnv* env, span<const uint8_t> str) {
inline jbyteArray MakeJByteArray(JNIEnv* env, std::span<const uint8_t> str) {
jbyteArray jarr = env->NewByteArray(str.size());
if (!jarr) {
return nullptr;
@@ -514,7 +514,7 @@ inline jbyteArray MakeJByteArray(JNIEnv* env, span<const uint8_t> str) {
* @param env JRE environment.
* @param arr Array to convert.
*/
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const int> arr) {
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, std::span<const int> arr) {
jbooleanArray jarr = env->NewBooleanArray(arr.size());
if (!jarr) {
return nullptr;
@@ -537,7 +537,7 @@ inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const int> arr) {
* @param env JRE environment.
* @param arr Array to convert.
*/
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const bool> arr) {
inline jbooleanArray MakeJBooleanArray(JNIEnv* env, std::span<const bool> arr) {
jbooleanArray jarr = env->NewBooleanArray(arr.size());
if (!jarr) {
return nullptr;
@@ -556,14 +556,14 @@ inline jbooleanArray MakeJBooleanArray(JNIEnv* env, span<const bool> arr) {
// Other MakeJ*Array conversions.
#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; \
#define WPI_JNI_MAKEJARRAY(T, F) \
inline T##Array MakeJ##F##Array(JNIEnv* env, std::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)
@@ -593,7 +593,8 @@ inline jlongArray MakeJLongArray(JNIEnv* env, const T& arr) {
* @param env JRE environment.
* @param arr Array to convert.
*/
inline jobjectArray MakeJStringArray(JNIEnv* env, span<const std::string> arr) {
inline jobjectArray MakeJStringArray(JNIEnv* env,
std::span<const std::string> arr) {
static JClass stringCls{env, "java/lang/String"};
if (!stringCls) {
return nullptr;
@@ -615,7 +616,8 @@ inline jobjectArray MakeJStringArray(JNIEnv* env, span<const std::string> arr) {
* @param env JRE environment.
* @param arr Array to convert.
*/
inline jobjectArray MakeJStringArray(JNIEnv* env, span<std::string_view> arr) {
inline jobjectArray MakeJStringArray(JNIEnv* env,
std::span<std::string_view> arr) {
static JClass stringCls{env, "java/lang/String"};
if (!stringCls) {
return nullptr;

View File

@@ -8,8 +8,7 @@
#include <stdint.h>
#include <optional>
#include "wpi/span.h"
#include <span>
namespace wpi {
@@ -100,7 +99,7 @@ class Uleb128Reader {
* is left when function returns).
* @return value (in std::optional)
*/
std::optional<uint64_t> ReadOne(span<const uint8_t>* in);
std::optional<uint64_t> ReadOne(std::span<const uint8_t>* in);
private:
uint64_t m_result = 0;

View File

@@ -1,20 +0,0 @@
// 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 "wpi/numbers"
// clang-format off
#ifdef _MSC_VER
#pragma message("warning: Use <wpi/numbers> and wpi::numbers instead to reflect C++20 <numbers> and std::numbers")
#else
#warning "Use <wpi/numbers> and wpi::numbers instead to reflect C++20 <numbers> and std::numbers"
#endif
// clang-format on
namespace wpi::math {
using namespace wpi::numbers;
} // namespace wpi::math

View File

@@ -1,64 +0,0 @@
// 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 <type_traits>
namespace wpi::numbers {
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T e_v = 2.718281828459045235360287471352662498L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T log2e_v = 1.442695040888963407359924681001892137L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T log10e_v = 0.434294481903251827651128918916605082L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T pi_v = 3.141592653589793238462643383279502884L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T inv_pi_v = 0.318309886183790671537767526745028724L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T inv_sqrtpi_v = 0.564189583547756286948079451560772586L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T ln2_v = 0.693147180559945309417232121458176568L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T ln10_v = 2.302585092994045684017991454684364208L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T sqrt2_v = 1.414213562373095048801688724209698078L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T sqrt3_v = 1.732050807568877293527446341505872366L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T inv_sqrt3_v = 0.577350269189625764509148780501957456L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T egamma_v = 0.577215664901532860606512090082402431L;
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T phi_v = 1.618033988749894848204586834365638117L;
inline constexpr double e = e_v<double>;
inline constexpr double log2e = log2e_v<double>;
inline constexpr double log10e = log10e_v<double>;
inline constexpr double pi = pi_v<double>;
inline constexpr double inv_pi = inv_pi_v<double>;
inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
inline constexpr double ln2 = ln2_v<double>;
inline constexpr double ln10 = ln10_v<double>;
inline constexpr double sqrt2 = sqrt2_v<double>;
inline constexpr double sqrt3 = sqrt3_v<double>;
inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
inline constexpr double egamma = egamma_v<double>;
inline constexpr double phi = phi_v<double>;
} // namespace wpi::numbers

View File

@@ -9,13 +9,13 @@
#include <algorithm>
#include <cstddef>
#include <span>
#include <string>
#include <string_view>
#include <system_error>
#include <vector>
#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(span<const char> mem)
explicit raw_mem_istream(std::span<const char> mem)
: raw_mem_istream(mem.data(), mem.size()) {}
explicit raw_mem_istream(span<const uint8_t> mem)
explicit raw_mem_istream(std::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

@@ -6,12 +6,12 @@
#include <functional>
#include <memory>
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include "wpi/SmallVector.h"
#include "wpi/span.h"
namespace wpi {
@@ -112,7 +112,7 @@ class SendableBuilder {
*/
virtual void AddBooleanArrayProperty(
std::string_view key, std::function<std::vector<int>()> getter,
std::function<void(wpi::span<const int>)> setter) = 0;
std::function<void(std::span<const int>)> setter) = 0;
/**
* Add an integer array property.
@@ -123,7 +123,7 @@ class SendableBuilder {
*/
virtual void AddIntegerArrayProperty(
std::string_view key, std::function<std::vector<int64_t>()> getter,
std::function<void(wpi::span<const int64_t>)> setter) = 0;
std::function<void(std::span<const int64_t>)> setter) = 0;
/**
* Add a float array property.
@@ -134,7 +134,7 @@ class SendableBuilder {
*/
virtual void AddFloatArrayProperty(
std::string_view key, std::function<std::vector<float>()> getter,
std::function<void(wpi::span<const float>)> setter) = 0;
std::function<void(std::span<const float>)> setter) = 0;
/**
* Add a double array property.
@@ -145,7 +145,7 @@ class SendableBuilder {
*/
virtual void AddDoubleArrayProperty(
std::string_view key, std::function<std::vector<double>()> getter,
std::function<void(wpi::span<const double>)> setter) = 0;
std::function<void(std::span<const double>)> setter) = 0;
/**
* Add a string array property.
@@ -156,7 +156,7 @@ class SendableBuilder {
*/
virtual void AddStringArrayProperty(
std::string_view key, std::function<std::vector<std::string>()> getter,
std::function<void(wpi::span<const std::string>)> setter) = 0;
std::function<void(std::span<const std::string>)> setter) = 0;
/**
* Add a raw property.
@@ -169,7 +169,7 @@ class SendableBuilder {
virtual void AddRawProperty(
std::string_view key, std::string_view typeString,
std::function<std::vector<uint8_t>()> getter,
std::function<void(wpi::span<const uint8_t>)> setter) = 0;
std::function<void(std::span<const uint8_t>)> setter) = 0;
/**
* Add a string property (SmallString form).
@@ -192,9 +192,9 @@ class SendableBuilder {
*/
virtual void AddSmallBooleanArrayProperty(
std::string_view key,
std::function<wpi::span<const int>(wpi::SmallVectorImpl<int>& buf)>
std::function<std::span<const int>(wpi::SmallVectorImpl<int>& buf)>
getter,
std::function<void(wpi::span<const int>)> setter) = 0;
std::function<void(std::span<const int>)> setter) = 0;
/**
* Add an integer array property (SmallVector form).
@@ -206,9 +206,9 @@ class SendableBuilder {
virtual void AddSmallIntegerArrayProperty(
std::string_view key,
std::function<
wpi::span<const int64_t>(wpi::SmallVectorImpl<int64_t>& buf)>
std::span<const int64_t>(wpi::SmallVectorImpl<int64_t>& buf)>
getter,
std::function<void(wpi::span<const int64_t>)> setter) = 0;
std::function<void(std::span<const int64_t>)> setter) = 0;
/**
* Add a float array property (SmallVector form).
@@ -219,9 +219,9 @@ class SendableBuilder {
*/
virtual void AddSmallFloatArrayProperty(
std::string_view key,
std::function<wpi::span<const float>(wpi::SmallVectorImpl<float>& buf)>
std::function<std::span<const float>(wpi::SmallVectorImpl<float>& buf)>
getter,
std::function<void(wpi::span<const float>)> setter) = 0;
std::function<void(std::span<const float>)> setter) = 0;
/**
* Add a double array property (SmallVector form).
@@ -232,9 +232,9 @@ class SendableBuilder {
*/
virtual void AddSmallDoubleArrayProperty(
std::string_view key,
std::function<wpi::span<const double>(wpi::SmallVectorImpl<double>& buf)>
std::function<std::span<const double>(wpi::SmallVectorImpl<double>& buf)>
getter,
std::function<void(wpi::span<const double>)> setter) = 0;
std::function<void(std::span<const double>)> setter) = 0;
/**
* Add a string array property (SmallVector form).
@@ -246,9 +246,9 @@ class SendableBuilder {
virtual void AddSmallStringArrayProperty(
std::string_view key,
std::function<
wpi::span<const std::string>(wpi::SmallVectorImpl<std::string>& buf)>
std::span<const std::string>(wpi::SmallVectorImpl<std::string>& buf)>
getter,
std::function<void(wpi::span<const std::string>)> setter) = 0;
std::function<void(std::span<const std::string>)> setter) = 0;
/**
* Add a raw property (SmallVector form).
@@ -260,9 +260,9 @@ class SendableBuilder {
*/
virtual void AddSmallRawProperty(
std::string_view key, std::string_view typeString,
std::function<wpi::span<uint8_t>(wpi::SmallVectorImpl<uint8_t>& buf)>
std::function<std::span<uint8_t>(wpi::SmallVectorImpl<uint8_t>& buf)>
getter,
std::function<void(wpi::span<const uint8_t>)> setter) = 0;
std::function<void(std::span<const uint8_t>)> setter) = 0;
/**
* Gets the kind of backend being used.

View File

@@ -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...} {
}

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);
/// @}

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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.

View File

@@ -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(); }
};

View File

@@ -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()}; }
};

View File

@@ -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