summaryrefslogtreecommitdiff
path: root/modules/codec/c++/data.h
diff options
context:
space:
mode:
Diffstat (limited to 'modules/codec/c++/data.h')
-rw-r--r--modules/codec/c++/data.h370
1 files changed, 370 insertions, 0 deletions
diff --git a/modules/codec/c++/data.h b/modules/codec/c++/data.h
new file mode 100644
index 0000000..237ef5a
--- /dev/null
+++ b/modules/codec/c++/data.h
@@ -0,0 +1,370 @@
+#pragma once
+
+#include <forstio/core/common.h>
+#include <forstio/core/templates.h>
+
+#include <cassert>
+
+#include <array>
+#include <concepts>
+#include <variant>
+#include <vector>
+
+#include "schema.h"
+
+namespace saw {
+namespace encode {
+struct Native {};
+}
+template<typename Schema, typename Encode>
+class codec;
+/*
+ * Helper for the basic message container, so the class doesn't have to be
+ * specialized 10 times.
+ */
+template <class T> struct native_data_type;
+
+template <>
+struct native_data_type<schema::Primitive<schema::SignedInteger, 1>> {
+ using type = int8_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::SignedInteger, 2>> {
+ using type = int16_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::SignedInteger, 4>> {
+ using type = int32_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::SignedInteger, 8>> {
+ using type = int64_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::UnsignedInteger, 1>> {
+ using type = uint8_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::UnsignedInteger, 2>> {
+ using type = uint16_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::UnsignedInteger, 4>> {
+ using type = uint32_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::UnsignedInteger, 8>> {
+ using type = uint64_t;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::FloatingPoint, 4>> {
+ using type = float;
+};
+
+template <>
+struct native_data_type<schema::Primitive<schema::FloatingPoint, 8>> {
+ using type = double;
+};
+
+template<typename T, typename Encoding = encode::Native>
+class data {
+private:
+ static_assert(always_false<T>, "Type not supported");
+};
+
+template<typename... T, string_literal... literals>
+class data<schema::Union<schema::Member<T, literals>...>, encode::Native> {
+private:
+ std::variant<data<T,encode::Native>...> value_;
+public:
+ data() = default;
+
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ template<string_literal lit>
+ void set(data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native> val){
+ value_ = std::move(val);
+ }
+
+ template<string_literal lit>
+ data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& init(){
+ value_ = data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>{};
+ return get<lit>();
+ }
+
+ template<string_literal lit>
+ bool holds_alternative() const {
+ return (parameter_key_pack_index<lit, literals...>::value == value_.index());
+ }
+
+ template<string_literal lit>
+ data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get(){
+ return std::get<parameter_key_pack_index<lit, literals...>::value>(value_);
+ }
+
+ template<string_literal lit>
+ const data<typename parameter_pack_type<parameter_key_pack_index<lit, literals...>::value, T...>::type, encode::Native>& get() const{
+ return std::get<parameter_key_pack_index<lit, literals...>::value>(value_);
+ }
+};
+
+template<typename... T, string_literal... literals>
+class data<schema::Struct<schema::Member<T, literals>...>, encode::Native> {
+private:
+ std::tuple<data<T,encode::Native>...> value_;
+public:
+ data() = default;
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ template<string_literal literal>
+ data<
+ typename parameter_pack_type<
+ parameter_key_pack_index<
+ literal, literals...
+ >::value
+ , T...>::type
+ , encode::Native>& get(){
+ return std::get<parameter_key_pack_index<literal, literals...>::value>(value_);
+ }
+
+ template<string_literal literal>
+ const data<
+ typename parameter_pack_type<
+ parameter_key_pack_index<
+ literal, literals...
+ >::value
+ , T...>::type
+ , encode::Native>& get() const {
+ return std::get<parameter_key_pack_index<literal, literals...>::value>(value_);
+ }
+
+ constexpr size_t size() const {
+ return sizeof...(T);
+ }
+};
+
+template<typename... T>
+class data<schema::Tuple<T...>, encode::Native> {
+private:
+ std::tuple<data<T,encode::Native>...> value_;
+public:
+ data() = default;
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ template<size_t i>
+ data<typename parameter_pack_type<i,T...>::type, encode::Native>& get(){
+ return std::get<i>(value_);
+ }
+
+ template<size_t i>
+ const data<typename parameter_pack_type<i,T...>::type, encode::Native>& get() const{
+ return std::get<i>(value_);
+ }
+
+ constexpr size_t size() const {
+ return sizeof...(T);
+ }
+};
+
+template<typename T, size_t Dim>
+class data<schema::Array<T,Dim>, encode::Native> {
+ private:
+ std::array<std::size_t, Dim> dims_;
+ std::vector<data<T, encode::Native>> value_;
+
+ std::size_t get_full_size() const {
+ std::size_t s = 1;
+
+ for(std::size_t iter = 0; iter < Dim; ++iter){
+ assert(dims_.at(iter) > 0);
+ s *= dims_.at(iter);
+ }
+
+ return s;
+ }
+ public:
+ data() = default;
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ data(const std::array<std::size_t, Dim>& i):
+ dims_{i},
+ value_{}
+ {
+ value_.resize(get_full_size());
+ }
+
+ template<std::integral... Dims>
+ data(Dims... size_):
+ data{{size_...}}
+ {
+ static_assert(sizeof...(Dims)==Dim, "Argument size must be equal to the Dimension");
+ }
+
+ data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind){
+ return value_.at(this->get_flat_index(ind));
+ }
+
+ const data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind) const {
+ return value_.at(this->get_flat_index(ind));
+ }
+
+ template<std::integral... Dims>
+ data<T, encode::Native>& at(Dims... i){
+ return value_.at(this->get_flat_index({i...}));
+ }
+
+ template<std::integral... Dims>
+ const data<T, encode::Native>& at(Dims... i) const {
+ return value_.at(this->get_flat_index({i...}));
+ }
+
+ std::size_t get_dim_size(std::size_t i) const {
+ return dims_.at(i);
+ }
+
+ size_t size() const { return value_.size();}
+
+private:
+ std::size_t get_flat_index(const std::array<std::size_t, Dim>& i) const {
+ std::size_t s = 0;
+
+ std::size_t stride = 1;
+
+ for(std::size_t iter = 0; iter < Dim; ++iter){
+ assert(i.at(iter) < dims_.at(iter));
+ s += i.at(iter) * stride;
+ stride *= dims_.at(iter);
+ }
+
+ return s;
+ }
+};
+
+template<typename T, std::size_t... D>
+class data<schema::FixedArray<T,D...>, encode::Native> {
+private:
+ //using inner_type = std::array<data<T, encode::Native>, multiply_helper<Dims...>::value>;
+ //std::unique_ptr<inner_type> value_;
+ std::vector<data<T, encode::Native>> value_;
+
+public:
+ data(){
+ value_.resize(ct_multiply<std::size_t, D...>::value);
+ }
+
+ data<T, encode::Native>& at(const std::array<std::size_t, sizeof...(D)>& ind){
+ return value_.at(this->get_flat_index(ind));
+ }
+
+ const data<T, encode::Native>& at(const std::array<std::size_t, sizeof...(D)>& ind) const {
+ return value_.at(this->get_flat_index(ind));
+ }
+
+ template<std::integral... Dims>
+ data<T, encode::Native>& at(Dims... i) {
+ return value_.at(this->get_flat_index({i...}));
+ }
+
+ template<std::integral... Dims>
+ const data<T, encode::Native>& at(Dims... i) const {
+ return value_.at(this->get_flat_index({i...}));
+ }
+
+ template<std::size_t i>
+ std::size_t get_dim_size() const {
+ return parameter_pack_value<i, std::size_t, D...>::value;
+ }
+private:
+ std::size_t get_flat_index(const std::array<std::size_t, sizeof...(D)>& i) const {
+ std::size_t s = 0;
+
+ std::size_t stride = 1;
+
+ constexpr static std::array<std::size_t, sizeof...(D)> dims_{D...};
+
+ for(std::size_t iter = 0; iter < sizeof...(D); ++iter){
+ assert(i.at(iter) < dims_.at(iter));
+ s += i.at(iter) * stride;
+ stride *= dims_.at(iter);
+ }
+
+ return s;
+ }
+};
+
+template<>
+class data<schema::String, encode::Native> {
+private:
+ std::string value_;
+public:
+ data() = default;
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ data(std::string value__):value_{std::move(value__)}{}
+ data(std::size_t size_){
+ value_.resize(size_);
+ }
+
+ std::size_t size() const {
+ return value_.size();
+ }
+
+ void set(std::string str){
+ value_ = std::move(str);
+ }
+
+ char& at(size_t i) {
+ return value_.at(i);
+ }
+
+ const char& at(size_t i) const {
+ return value_.at(i);
+ }
+
+ char get_at(size_t i) const{
+ return value_.at(i);
+ }
+
+ void set_at(size_t i, char val){
+ value_.at(i) = val;
+ }
+
+ bool operator==(const std::string_view& val)const{
+ return value_ == val;
+ }
+};
+
+template<typename T, size_t N>
+class data<schema::Primitive<T,N>, encode::Native> {
+private:
+ typename native_data_type<schema::Primitive<T,N>>::type value_;
+public:
+ data():value_{{}}{};
+ SAW_DEFAULT_COPY(data);
+ SAW_DEFAULT_MOVE(data);
+
+ data(typename native_data_type<schema::Primitive<T,N>>::type value__):
+ value_{std::move(value__)}{}
+
+ void set(typename native_data_type<schema::Primitive<T,N>>::type val){
+ value_ = val;
+ }
+
+ typename native_data_type<schema::Primitive<T,N>>::type get() const {return value_;}
+};
+
+
+}