2021-11-29 15:08:18 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "schema.h"
|
|
|
|
|
|
|
|
namespace gin {
|
2021-12-05 16:17:23 +01:00
|
|
|
template <class T> class MessageContainer;
|
2021-11-29 15:08:18 +01:00
|
|
|
|
|
|
|
template <class T, class Container> class Message;
|
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <size_t N, class... T> struct MessageParameterPackType;
|
2021-11-29 15:08:18 +01:00
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <class TN, class... T> struct MessageParameterPackType<0, TN, T...> {
|
2021-11-29 15:08:18 +01:00
|
|
|
using Type = T;
|
|
|
|
};
|
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <size_t N, class TN, class... T>
|
|
|
|
struct MessageParameterPackType<N, TN, T...> {
|
|
|
|
using Type = typename MessageParameterPackType<N - 1, T...>::Type;
|
2021-11-29 15:08:18 +01:00
|
|
|
};
|
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <class T, class... TL> struct MessageParameterPackIndex;
|
2021-11-29 15:08:18 +01:00
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <class T, class... TL> struct MessageParameterPackIndex<T, T, TL...> {
|
2021-11-29 15:08:18 +01:00
|
|
|
static constexpr size_t Value = 0u;
|
|
|
|
};
|
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <class T, class TL0, class... TL>
|
|
|
|
struct MessageParameterPackIndex<T, TL0, TL...> {
|
|
|
|
static constexpr size_t Value =
|
|
|
|
1u + MessageParameterPackIndex<T, TL...>::Value;
|
2021-11-29 15:08:18 +01:00
|
|
|
};
|
|
|
|
|
2021-12-12 02:04:32 +01:00
|
|
|
template <class... V, StringLiteral... Keys>
|
|
|
|
class MessageContainer<schema::Struct<schema::NamedMember<V, Keys>...>> {
|
2021-11-29 15:08:18 +01:00
|
|
|
private:
|
|
|
|
using ValueType = std::tuple<Message<V, MessageContainer<V>>...>;
|
|
|
|
ValueType values;
|
2021-12-05 16:17:23 +01:00
|
|
|
|
2021-11-29 15:08:18 +01:00
|
|
|
public:
|
2021-12-12 02:04:32 +01:00
|
|
|
using SchemaType = schema::Struct<schema::NamedMember<V, Keys>...>;
|
2021-11-29 15:08:18 +01:00
|
|
|
|
2021-12-05 16:17:23 +01:00
|
|
|
template <size_t i>
|
2021-12-12 02:04:32 +01:00
|
|
|
using ElementType =
|
|
|
|
MessageParameterPackType<i, Message<V, MessageContainer<V>>...>::Type;
|
2021-11-29 15:08:18 +01:00
|
|
|
|
2021-12-12 02:04:32 +01:00
|
|
|
template <size_t i> ElementType<i> &get() { return std::get<i>(values); }
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Union storage
|
|
|
|
*/
|
|
|
|
template<class... V, StringLiteral... Keys>
|
|
|
|
class MessageContainer<schema::Union<schema::NamedMember<V,Keys>...>> {
|
|
|
|
private:
|
|
|
|
using ValueType = std::variant<Message<V,MessageContainer<V>>...>;
|
|
|
|
ValueType value;
|
|
|
|
public:
|
2021-12-12 19:14:52 +01:00
|
|
|
using SchemaType = schema::Union<schema::NamedMember<V, Keys>...>;
|
|
|
|
|
|
|
|
template <size_t i>
|
|
|
|
using ElementType =
|
|
|
|
MessageParameterPackType<i, Message<V, MessageContainer<V>>...>::Type;
|
|
|
|
|
|
|
|
|
|
|
|
template<size_t i> ElementType<i> &get() {return std::get<i>(value);}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Array storage
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
template<class T>
|
|
|
|
class MessageContainer<schema::Array> {
|
|
|
|
private:
|
|
|
|
using ValueType = std::vector<Message<T,MessageContainer<T>>>;
|
|
|
|
ValueType values;
|
|
|
|
public:
|
|
|
|
using SchemaType = schema::Array<T>;
|
|
|
|
|
|
|
|
template<size_t i> Message<T,MessageContainer<T>>& get(){
|
|
|
|
return values.at(i);
|
|
|
|
}
|
2021-11-29 15:08:18 +01:00
|
|
|
};
|
2021-12-12 19:14:52 +01:00
|
|
|
*/
|
2021-12-05 18:31:55 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Helper for the basic message container, so the class doesn't have to be
|
|
|
|
* specialized 10 times.
|
|
|
|
*/
|
|
|
|
template <class T> struct PrimitiveTypeHelper;
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::SignedIntegral, 1>> {
|
|
|
|
using Type = int8_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::SignedIntegral, 2>> {
|
|
|
|
using Type = int16_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::SignedIntegral, 4>> {
|
|
|
|
using Type = int32_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::SignedIntegral, 8>> {
|
|
|
|
using Type = int64_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::UnsignedIntegral, 1>> {
|
|
|
|
using Type = uint8_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::UnsignedIntegral, 2>> {
|
|
|
|
using Type = uint16_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::UnsignedIntegral, 4>> {
|
|
|
|
using Type = uint32_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::UnsignedIntegral, 8>> {
|
|
|
|
using Type = uint64_t;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::FloatingPoint, 4>> {
|
|
|
|
using Type = float;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PrimitiveTypeHelper<schema::Primitive<schema::FloatingPoint, 8>> {
|
|
|
|
using Type = double;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class T, class N> class MessageContainer<schema::Primitive<T, N>> {
|
|
|
|
public:
|
|
|
|
using ValueType = PrimitiveTypeHelper<schema::Primitive<T, N>>::Type;
|
|
|
|
|
|
|
|
private:
|
|
|
|
ValueType value;
|
|
|
|
|
|
|
|
public:
|
|
|
|
MessageContainer() : value{0} {}
|
|
|
|
|
|
|
|
void set(const ValueType &v) { value = v; }
|
|
|
|
|
2021-12-05 19:48:20 +01:00
|
|
|
const ValueType &get() const { return value; }
|
|
|
|
};
|
|
|
|
|
|
|
|
template <> class MessageContainer<schema::String> {
|
|
|
|
public:
|
|
|
|
private:
|
|
|
|
using ValueType = std::string;
|
|
|
|
ValueType value;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void set(const ValueType &v) { value = v; }
|
|
|
|
|
|
|
|
const ValueType &get() const { return value; }
|
2021-12-05 18:31:55 +01:00
|
|
|
};
|
2021-12-05 16:17:23 +01:00
|
|
|
} // namespace gin
|