[wpiutil] Change Struct to allow non-constexpr implementation (#5992)

This required changing the constant values (e.g. kSize) into functions
(e.g. GetSize()).

Fixed implementations of ForEachNested to be inline (as these are actually
templates).

Also added a ntcore Struct test.
This commit is contained in:
Peter Johnson
2023-12-02 23:36:44 -08:00
committed by GitHub
parent ca272de400
commit a583ca01e1
62 changed files with 812 additions and 450 deletions

View File

@@ -7,9 +7,9 @@
#include <stdint.h>
#include <atomic>
#include <memory>
#include <ranges>
#include <span>
#include <string_view>
#include <utility>
#include <vector>
@@ -121,16 +121,17 @@ class StructArraySubscriber : public Subscriber {
#endif
TimestampedValueType GetAtomic(U&& defaultValue) const {
wpi::SmallVector<uint8_t, 128> buf;
size_t size = S::GetSize();
TimestampedRawView view = ::nt::GetAtomicRaw(m_subHandle, buf, {});
if (view.value.size() == 0 || (view.value.size() % S::kSize) != 0) {
if (view.value.size() == 0 || (view.value.size() % size) != 0) {
return {0, 0, std::forward<U>(defaultValue)};
}
TimestampedValueType rv{view.time, view.serverTime, {}};
rv.value.reserve(view.value.size() / S::kSize);
rv.value.reserve(view.value.size() / size);
for (auto in = view.value.begin(), end = view.value.end(); in != end;
in += S::kSize) {
in += size) {
rv.value.emplace_back(
S::Unpack(std::span<const uint8_t, S::kSize>{in, in + S::kSize}));
S::Unpack(std::span<const uint8_t>{std::to_address(in), size}));
}
return rv;
}
@@ -145,16 +146,17 @@ class StructArraySubscriber : public Subscriber {
*/
TimestampedValueType GetAtomic(std::span<const T> defaultValue) const {
wpi::SmallVector<uint8_t, 128> buf;
size_t size = S::GetSize();
TimestampedRawView view = ::nt::GetAtomicRaw(m_subHandle, buf, {});
if (view.value.size() == 0 || (view.value.size() % S::kSize) != 0) {
if (view.value.size() == 0 || (view.value.size() % size) != 0) {
return {0, 0, {defaultValue.begin(), defaultValue.end()}};
}
TimestampedValueType rv{view.time, view.serverTime, {}};
rv.value.reserve(view.value.size() / S::kSize);
rv.value.reserve(view.value.size() / size);
for (auto in = view.value.begin(), end = view.value.end(); in != end;
in += S::kSize) {
in += size) {
rv.value.emplace_back(
S::Unpack(std::span<const uint8_t, S::kSize>{in, in + S::kSize}));
S::Unpack(std::span<const uint8_t>{std::to_address(in), size}));
}
return rv;
}
@@ -174,16 +176,17 @@ class StructArraySubscriber : public Subscriber {
auto raw = ::nt::ReadQueueRaw(m_subHandle);
std::vector<TimestampedValueType> rv;
rv.reserve(raw.size());
size_t size = S::GetSize();
for (auto&& r : raw) {
if (r.value.size() == 0 || (r.value.size() % S::kSize) != 0) {
if (r.value.size() == 0 || (r.value.size() % size) != 0) {
continue;
}
std::vector<T> values;
values.reserve(r.value.size() / S::kSize);
values.reserve(r.value.size() / size);
for (auto in = r.value.begin(), end = r.value.end(); in != end;
in += S::kSize) {
in += size) {
values.emplace_back(
S::Unpack(std::span<const uint8_t, S::kSize>{in, in + S::kSize}));
S::Unpack(std::span<const uint8_t>{std::to_address(in), size}));
}
rv.emplace_back(r.time, r.serverTime, std::move(values));
}

View File

@@ -32,6 +32,13 @@ class StructTopic;
template <wpi::StructSerializable T>
class StructSubscriber : public Subscriber {
using S = wpi::Struct<T>;
static constexpr size_t kBufSize = []() -> size_t {
if constexpr (wpi::is_constexpr([] { S::GetSize(); })) {
return S::GetSize();
} else {
return 128;
}
}();
public:
using TopicType = StructTopic<T>;
@@ -81,12 +88,12 @@ class StructSubscriber : public Subscriber {
* @return true if successful
*/
bool GetInto(T* out) {
wpi::SmallVector<uint8_t, S::kSize> buf;
wpi::SmallVector<uint8_t, kBufSize> buf;
TimestampedRawView view = ::nt::GetAtomicRaw(m_subHandle, buf, {});
if (view.value.size() < S::kSize) {
if (view.value.size() < S::GetSize()) {
return false;
} else {
wpi::UnpackStructInto(out, view.value.subspan<0, S::kSize>());
wpi::UnpackStructInto(out, view.value);
return true;
}
}
@@ -109,13 +116,12 @@ class StructSubscriber : public Subscriber {
* @return timestamped value
*/
TimestampedValueType GetAtomic(const T& defaultValue) const {
wpi::SmallVector<uint8_t, S::kSize> buf;
wpi::SmallVector<uint8_t, kBufSize> buf;
TimestampedRawView view = ::nt::GetAtomicRaw(m_subHandle, buf, {});
if (view.value.size() < S::kSize) {
if (view.value.size() < S::GetSize()) {
return {0, 0, defaultValue};
} else {
return {view.time, view.serverTime,
S::Unpack(view.value.subspan<0, S::kSize>())};
return {view.time, view.serverTime, S::Unpack(view.value)};
}
}
@@ -135,13 +141,11 @@ class StructSubscriber : public Subscriber {
std::vector<TimestampedValueType> rv;
rv.reserve(raw.size());
for (auto&& r : raw) {
if (r.value.size() < S::kSize) {
if (r.value.size() < S::GetSize()) {
continue;
} else {
rv.emplace_back(
r.time, r.serverTime,
S::Unpack(
std::span<const uint8_t>(r.value).subspan<0, S::kSize>()));
rv.emplace_back(r.time, r.serverTime,
S::Unpack(std::span<const uint8_t>(r.value)));
}
}
return rv;
@@ -208,9 +212,16 @@ class StructPublisher : public Publisher {
if (!m_schemaPublished.exchange(true, std::memory_order_relaxed)) {
GetTopic().GetInstance().template AddStructSchema<T>();
}
uint8_t buf[S::kSize];
S::Pack(buf, value);
::nt::SetRaw(m_pubHandle, buf, time);
if constexpr (wpi::is_constexpr([] { S::GetSize(); })) {
uint8_t buf[S::GetSize()];
S::Pack(buf, value);
::nt::SetRaw(m_pubHandle, buf, time);
} else {
wpi::SmallVector<uint8_t, 128> buf;
buf.resize_for_overwrite(S::GetSize());
S::Pack(buf, value);
::nt::SetRaw(m_pubHandle, buf, time);
}
}
/**
@@ -224,9 +235,16 @@ class StructPublisher : public Publisher {
if (!m_schemaPublished.exchange(true, std::memory_order_relaxed)) {
GetTopic().GetInstance().template AddStructSchema<T>();
}
uint8_t buf[S::kSize];
S::Pack(buf, value);
::nt::SetDefaultRaw(m_pubHandle, buf);
if constexpr (wpi::is_constexpr([] { S::GetSize(); })) {
uint8_t buf[S::GetSize()];
S::Pack(buf, value);
::nt::SetDefaultRaw(m_pubHandle, buf);
} else {
wpi::SmallVector<uint8_t, 128> buf;
buf.resize_for_overwrite(S::GetSize());
S::Pack(buf, value);
::nt::SetDefaultRaw(m_pubHandle, buf);
}
}
/**