mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +00:00
[wpiutil] Struct: Change from GetTypeString() to GetTypeName() (#6872)
This makes it easier to define schemas when the type name is non-trivial (e.g., templated structs). This is breaking for a) custom struct implementations and b) anything calling `wpi::Struct<T>::GetTypeString(info...)` in C++ directly. In both cases, it's a simple translation: For A, rename `GetTypeString()` to `GetTypeName()` and remove the struct: at the beginning, and for B, use `wpi::GetStructTypeString<T>(info...)` instead.
This commit is contained in:
@@ -49,15 +49,15 @@ struct Struct {};
|
||||
* Implementations must define a template specialization for wpi::Struct with
|
||||
* T being the type that is being serialized/deserialized, with the following
|
||||
* static members (as enforced by this concept):
|
||||
* - std::string_view GetTypeString(): function that returns the type string
|
||||
* - std::string_view GetTypeName(): function that returns the type name
|
||||
* - size_t GetSize(): function that returns the structure size in bytes
|
||||
* - std::string_view GetSchema(): function that returns the struct schema
|
||||
* - T Unpack(std::span<const uint8_t>): function for deserialization
|
||||
* - void Pack(std::span<uint8_t>, T&& value): function for
|
||||
* serialization
|
||||
*
|
||||
* If possible, the GetTypeString(), GetSize(), and GetSchema() functions should
|
||||
* be marked constexpr. GetTypeString() and GetSchema() may return types other
|
||||
* If possible, the GetTypeName(), GetSize(), and GetSchema() functions should
|
||||
* be marked constexpr. GetTypeName() and GetSchema() may return types other
|
||||
* than std::string_view, as long as the return value is convertible to
|
||||
* std::string_view.
|
||||
*
|
||||
@@ -72,7 +72,7 @@ concept StructSerializable = requires(std::span<const uint8_t> in,
|
||||
typename std::remove_cvref_t<I>...>;
|
||||
{
|
||||
Struct<typename std::remove_cvref_t<T>,
|
||||
typename std::remove_cvref_t<I>...>::GetTypeString(info...)
|
||||
typename std::remove_cvref_t<I>...>::GetTypeName(info...)
|
||||
} -> std::convertible_to<std::string_view>;
|
||||
{
|
||||
Struct<typename std::remove_cvref_t<T>,
|
||||
@@ -229,18 +229,41 @@ inline void UnpackStructInto(T* out, std::span<const uint8_t> data,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type name for a raw struct serializable type
|
||||
*
|
||||
* @tparam T serializable type
|
||||
* @param info optional struct type info
|
||||
* @return type name
|
||||
*/
|
||||
template <typename T, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
constexpr auto GetStructTypeName(const I&... info) {
|
||||
using S = Struct<T, typename std::remove_cvref_t<I>...>;
|
||||
return S::GetTypeName(info...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type string for a raw struct serializable type
|
||||
*
|
||||
* @tparam T serializable type
|
||||
* @param info optional struct type info
|
||||
* @return type string
|
||||
* @return type string (struct: followed by type name)
|
||||
*/
|
||||
template <typename T, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
constexpr auto GetStructTypeString(const I&... info) {
|
||||
using S = Struct<T, typename std::remove_cvref_t<I>...>;
|
||||
return S::GetTypeString(info...);
|
||||
if constexpr (sizeof...(I) == 0 &&
|
||||
is_constexpr([&] { S::GetTypeName(info...); })) {
|
||||
constexpr auto typeName = S::GetTypeName(info...);
|
||||
using namespace literals;
|
||||
return Concat(
|
||||
"struct:"_ct_string,
|
||||
ct_string<char, std::char_traits<char>, typeName.size()>{typeName});
|
||||
} else {
|
||||
return fmt::format("struct:{}", S::GetTypeName(info...));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,32 +282,43 @@ constexpr size_t GetStructSize(const I&... info) {
|
||||
|
||||
template <typename T, size_t N, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
constexpr auto MakeStructArrayTypeString(const I&... info) {
|
||||
constexpr auto MakeStructArrayTypeName(const I&... info) {
|
||||
using S = Struct<T, typename std::remove_cvref_t<I>...>;
|
||||
if constexpr (sizeof...(I) == 0 &&
|
||||
is_constexpr([&] { S::GetTypeString(info...); })) {
|
||||
constexpr auto typeString = S::GetTypeString(info...);
|
||||
is_constexpr([&] { S::GetTypeName(info...); })) {
|
||||
constexpr auto typeName = S::GetTypeName(info...);
|
||||
using namespace literals;
|
||||
if constexpr (N == std::dynamic_extent) {
|
||||
return Concat(
|
||||
ct_string<char, std::char_traits<char>, typeString.size()>{
|
||||
typeString},
|
||||
ct_string<char, std::char_traits<char>, typeName.size()>{typeName},
|
||||
"[]"_ct_string);
|
||||
} else {
|
||||
return Concat(
|
||||
ct_string<char, std::char_traits<char>, typeString.size()>{
|
||||
typeString},
|
||||
ct_string<char, std::char_traits<char>, typeName.size()>{typeName},
|
||||
"["_ct_string, NumToCtString<N>(), "]"_ct_string);
|
||||
}
|
||||
} else {
|
||||
if constexpr (N == std::dynamic_extent) {
|
||||
return fmt::format("{}[]", S::GetTypeString(info...));
|
||||
return fmt::format("{}[]", S::GetTypeName(info...));
|
||||
} else {
|
||||
return fmt::format("{}[{}]", S::GetTypeString(info...), N);
|
||||
return fmt::format("{}[{}]", S::GetTypeName(info...), N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, size_t N, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
constexpr auto MakeStructArrayTypeString(const I&... info) {
|
||||
using S = Struct<T, typename std::remove_cvref_t<I>...>;
|
||||
if constexpr (sizeof...(I) == 0 &&
|
||||
is_constexpr([&] { S::GetTypeName(info...); })) {
|
||||
using namespace literals;
|
||||
return Concat("struct:"_ct_string, MakeStructArrayTypeName<T, N>(info...));
|
||||
} else {
|
||||
return fmt::format("struct:{}", MakeStructArrayTypeName<T, N>(info...));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, size_t N, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
constexpr auto MakeStructArraySchema(const I&... info) {
|
||||
@@ -336,7 +370,7 @@ void ForEachStructSchema(
|
||||
if constexpr (HasNestedStruct<T, I...>) {
|
||||
S::ForEachNested(fn, info...);
|
||||
}
|
||||
fn(S::GetTypeString(info...), S::GetSchema(info...));
|
||||
fn(GetStructTypeString<T>(info...), S::GetSchema(info...));
|
||||
}
|
||||
|
||||
template <typename T, typename... I>
|
||||
@@ -397,8 +431,8 @@ class StructArrayBuffer {
|
||||
template <typename T, size_t N, typename... I>
|
||||
requires StructSerializable<T, I...>
|
||||
struct Struct<std::array<T, N>, I...> {
|
||||
static constexpr auto GetTypeString(const I&... info) {
|
||||
return MakeStructArrayTypeString<T, N>(info...);
|
||||
static constexpr auto GetTypeName(const I&... info) {
|
||||
return MakeStructArrayTypeName<T, N>(info...);
|
||||
}
|
||||
static constexpr size_t GetSize(const I&... info) {
|
||||
return N * GetStructSize<T>(info...);
|
||||
@@ -447,7 +481,7 @@ struct Struct<std::array<T, N>, I...> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<bool> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:bool"; }
|
||||
static constexpr std::string_view GetTypeName() { return "bool"; }
|
||||
static constexpr size_t GetSize() { return 1; }
|
||||
static constexpr std::string_view GetSchema() { return "bool value"; }
|
||||
static bool Unpack(std::span<const uint8_t> data) { return data[0]; }
|
||||
@@ -462,7 +496,7 @@ struct Struct<bool> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<uint8_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:uint8"; }
|
||||
static constexpr std::string_view GetTypeName() { return "uint8"; }
|
||||
static constexpr size_t GetSize() { return 1; }
|
||||
static constexpr std::string_view GetSchema() { return "uint8 value"; }
|
||||
static uint8_t Unpack(std::span<const uint8_t> data) { return data[0]; }
|
||||
@@ -475,7 +509,7 @@ struct Struct<uint8_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<int8_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:int8"; }
|
||||
static constexpr std::string_view GetTypeName() { return "int8"; }
|
||||
static constexpr size_t GetSize() { return 1; }
|
||||
static constexpr std::string_view GetSchema() { return "int8 value"; }
|
||||
static int8_t Unpack(std::span<const uint8_t> data) { return data[0]; }
|
||||
@@ -488,7 +522,7 @@ struct Struct<int8_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<uint16_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:uint16"; }
|
||||
static constexpr std::string_view GetTypeName() { return "uint16"; }
|
||||
static constexpr size_t GetSize() { return 2; }
|
||||
static constexpr std::string_view GetSchema() { return "uint16 value"; }
|
||||
static uint16_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -505,7 +539,7 @@ struct Struct<uint16_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<int16_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:int16"; }
|
||||
static constexpr std::string_view GetTypeName() { return "int16"; }
|
||||
static constexpr size_t GetSize() { return 2; }
|
||||
static constexpr std::string_view GetSchema() { return "int16 value"; }
|
||||
static int16_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -522,7 +556,7 @@ struct Struct<int16_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<uint32_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:uint32"; }
|
||||
static constexpr std::string_view GetTypeName() { return "uint32"; }
|
||||
static constexpr size_t GetSize() { return 4; }
|
||||
static constexpr std::string_view GetSchema() { return "uint32 value"; }
|
||||
static uint32_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -539,7 +573,7 @@ struct Struct<uint32_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<int32_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:int32"; }
|
||||
static constexpr std::string_view GetTypeName() { return "int32"; }
|
||||
static constexpr size_t GetSize() { return 4; }
|
||||
static constexpr std::string_view GetSchema() { return "int32 value"; }
|
||||
static int32_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -556,7 +590,7 @@ struct Struct<int32_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<uint64_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:uint64"; }
|
||||
static constexpr std::string_view GetTypeName() { return "uint64"; }
|
||||
static constexpr size_t GetSize() { return 8; }
|
||||
static constexpr std::string_view GetSchema() { return "uint64 value"; }
|
||||
static uint64_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -573,7 +607,7 @@ struct Struct<uint64_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<int64_t> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:int64"; }
|
||||
static constexpr std::string_view GetTypeName() { return "int64"; }
|
||||
static constexpr size_t GetSize() { return 8; }
|
||||
static constexpr std::string_view GetSchema() { return "int64 value"; }
|
||||
static int64_t Unpack(std::span<const uint8_t> data) {
|
||||
@@ -590,7 +624,7 @@ struct Struct<int64_t> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<float> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:float"; }
|
||||
static constexpr std::string_view GetTypeName() { return "float"; }
|
||||
static constexpr size_t GetSize() { return 4; }
|
||||
static constexpr std::string_view GetSchema() { return "float value"; }
|
||||
static float Unpack(std::span<const uint8_t> data) {
|
||||
@@ -607,7 +641,7 @@ struct Struct<float> {
|
||||
*/
|
||||
template <>
|
||||
struct Struct<double> {
|
||||
static constexpr std::string_view GetTypeString() { return "struct:double"; }
|
||||
static constexpr std::string_view GetTypeName() { return "double"; }
|
||||
static constexpr size_t GetSize() { return 8; }
|
||||
static constexpr std::string_view GetSchema() { return "double value"; }
|
||||
static double Unpack(std::span<const uint8_t> data) {
|
||||
|
||||
Reference in New Issue
Block a user