diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 12:18:14 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-12-04 12:18:14 +0100 |
commit | a14896f9ed209dd3f9597722e5a5697bd7dbf531 (patch) | |
tree | 089ca5cbbd206d1921f8f6b53292f5bc1902ca5c /modules/codec/data.h | |
parent | 84ecdcbca9e55b1f57fbb832e12ff4fdbb86e7c9 (diff) |
meta: Renamed folder containing source
Diffstat (limited to 'modules/codec/data.h')
-rw-r--r-- | modules/codec/data.h | 370 |
1 files changed, 370 insertions, 0 deletions
diff --git a/modules/codec/data.h b/modules/codec/data.h new file mode 100644 index 0000000..237ef5a --- /dev/null +++ b/modules/codec/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_;} +}; + + +} |