#pragma once #include #include #include #include #include #include #include #include "schema.h" namespace saw { namespace encode { struct Native {}; } template class codec; /* * Helper for the basic message container, so the class doesn't have to be * specialized 10 times. */ template struct native_data_type; template <> struct native_data_type> { using type = int8_t; }; template <> struct native_data_type> { using type = int16_t; }; template <> struct native_data_type> { using type = int32_t; }; template <> struct native_data_type> { using type = int64_t; }; template <> struct native_data_type> { using type = uint8_t; }; template <> struct native_data_type> { using type = uint16_t; }; template <> struct native_data_type> { using type = uint32_t; }; template <> struct native_data_type> { using type = uint64_t; }; template <> struct native_data_type> { using type = float; }; template <> struct native_data_type> { using type = double; }; template class data { private: static_assert(always_false, "Type not supported"); }; template class data...>, encode::Native> { private: std::variant...> value_; public: data() = default; SAW_DEFAULT_COPY(data); SAW_DEFAULT_MOVE(data); template void set(data::value, T...>::type, encode::Native> val){ value_ = std::move(val); } template bool holds_alternative() const { return (parameter_key_pack_index::value == value_.index()); } template data::value, T...>::type, encode::Native>& get(){ return std::get::value>(value_); } template const data::value, T...>::type, encode::Native>& get() const{ return std::get::value>(value_); } }; template class data...>, encode::Native> { private: std::tuple...> value_; public: data() = default; SAW_DEFAULT_COPY(data); SAW_DEFAULT_MOVE(data); template data< typename parameter_pack_type< parameter_key_pack_index< literal, literals... >::value , T...>::type , encode::Native>& get(){ return std::get::value>(value_); } template const data< typename parameter_pack_type< parameter_key_pack_index< literal, literals... >::value , T...>::type , encode::Native>& get() const { return std::get::value>(value_); } constexpr size_t size() const { return sizeof...(T); } }; template class data, encode::Native> { private: std::tuple...> value_; public: data() = default; SAW_DEFAULT_COPY(data); SAW_DEFAULT_MOVE(data); template data::type, encode::Native>& get(){ return std::get(value_); } template const data::type, encode::Native>& get() const{ return std::get(value_); } constexpr size_t size() const { return sizeof...(T); } }; template class data, encode::Native> { private: std::array dims_; std::vector> 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& i): dims_{i}, value_{} { value_.resize(get_full_size()); } template data(Dims... size_): data{{size_...}} { static_assert(sizeof...(Dims)==Dim, "Argument size must be equal to the Dimension"); } data& at(const std::array& ind){ return value_.at(this->get_flat_index(ind)); } const data& at(const std::array& ind) const { return value_.at(this->get_flat_index(ind)); } template data& at(Dims... i){ return value_.at(this->get_flat_index({i...})); } template const data& 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& i) const { std::size_t s = 0; std::size_t stride = 1; for(std::size_t iter = 0; iter < Dim; ++iter){ s += i.at(iter) * stride; stride *= dims_.at(iter); } return s; } }; template<> class data { 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 class data, encode::Native> { private: typename native_data_type>::type value_; public: data():value_{{}}{}; SAW_DEFAULT_COPY(data); SAW_DEFAULT_MOVE(data); data(typename native_data_type>::type value__): value_{std::move(value__)}{} void set(typename native_data_type>::type val){ value_ = val; } typename native_data_type>::type get() const {return value_;} }; }