bitis 0.10.5

Bitwise serialization of messages defined in a data description language with interfaces for rust, python and c++.
Documentation
#pragma once

#include "{{bitis_header_lib_file_name}}"
#include <optional>

//#define EXPECTED_BITIS_VERSION "{{bitis_version}}"
//#if EXPECTED_BITIS_VERSION != BITIS_CPP_LIB_VERSION
//#error "Unexpected bitis library version"
//#endif

{%+ for objo_name in object_order %}

// ****** {{ objo_name }} *****
{# ***************************************************************** -#}
{#- Enums ***************************************************************** -#}
{%+ for ce in d.enums ~%}{% if *objo_name == ce.name %}
{%- if let Some(comment_impl) = ce.comment -%}
///{{comment_impl}}
{%- endif -%}
namespace {{ ce.name }}Enum {
{%- for cv in ce.values +%}
    ENUM_INSTANCE({{ cv|pascal_case }});
{%- endfor %}
}
{% set def_enum="!!DEFAULT_UNDEFINED!!" %}
typedef BitisEnum<bitis_helper::Collector<{%- for cv in ce.values %}
    {{ ce.name }}Enum::{{ cv|pascal_case }}{% if !loop.last %}, {% endif %}{%- endfor %}
>, {{ ce.name }}Enum::{{ ce.default|pascal_case }}, {{ce.bit_size}}> {{ ce.name }};
{%- endif -%}{%- endfor -%}

{#- *****************************************************************#}
{#- Enums for oneof *****************************************************************#}
{%+ for (_, coo) in d.oos -%}{% if *objo_name == coo.name %}
struct {{ coo.name }}  {
    {%- for ca in coo.attributes %}
    struct OO_{{ca.base.name|pascal_case}} {
        static constexpr auto name = "{{ca.base.name|pascal_case}}"; typedef {{ ca.rust_type_str|safe}} OOType; };
    {%- endfor %}

    typedef BitisEnum<bitis_helper::Collector<{%- for ca in coo.attributes %}
        OO_{{ca.base.name|pascal_case}}{% if !loop.last %}, {% endif %}{%- endfor %}
    >, OO_{{coo.default_attrib_name|pascal_case}}, {{coo.dyn_bits}}> T_OOEnum;
    T_OOEnum oo_selector;

    typedef oneof_helper::UnionT<  // UnionDynSizeT
        {% for ca in coo.attributes -%}OO_{{ca.base.name|pascal_case}}::OOType{% if !loop.last %}, {% endif %}{%- endfor %}
    > T_OOValue;
    T_OOValue oo_value;
    //uint8_t *oo_value_ptr;

    {{ coo.name }}() : oo_selector() /*, oo_value_ptr(nullptr)*/ {}
    //~{{ coo.name }}() { delete [] oo_value_ptr; }

    template<typename OOT>
    {{ coo.name }} set_oo(typename OOT::OOType v) {
        static_assert(oneof_helper::ContainsType<OOT, T_OOEnum::EnumCollector>::value);
        oo_selector.set_enum<OOT>();
        oo_value.set(v);
        return *this;

        //delete [] oo_value_ptr;
        //oo_value_ptr = new uint8_t[sizeof(typename OOT::OOType)];
        //memcpy(oo_value_ptr, &v, sizeof(v));
        //return *this;
    }
    template<typename OOT>
    typename OOT::OOType *get_oo() const {
        static_assert(oneof_helper::ContainsType<OOT, T_OOEnum::EnumCollector>::value);
        if(oo_selector.is_enum<OOT>())
            return oo_value.get<typename OOT::OOType>();
            //return (typename OOT::OOType*) oo_value_ptr;
        return nullptr;
    }
    template<typename OOT>
    bool is_oo_value() const {
        static_assert(oneof_helper::ContainsType<OOT, T_OOEnum::EnumCollector>::value);
        if(oo_selector.is_enum<OOT>())
            return true;
        return false;
    }

    std::size_t serialize(BitisSerializer &ser) {
        return oneof_helper::oneof_serialize(this, ser);
    }
    static bitis_helper::BitiaDeserializerHelper<{{ coo.name }}> deserialize(BitisDeserializer &des) {
        return oneof_helper::oneof_deserialize<{{ coo.name }}>(des);
    }

    void print(const int16_t indent=0) {
        printf("Oneof = ");
        oneof_helper::oneof_print(this, (indent>=0) ? indent + 2 : indent);
    }

    bool is_equal(const {{ coo.name }} &other) const {
        if (oo_selector != other.oo_selector) return false;
        return oneof_helper::oneof_is_equal(this, &other);
    }
    bool operator==(const {{ coo.name }} &other) const { return is_equal(other); }
    bool operator!=(const {{ coo.name }} &other) const { return !is_equal(other); }
};
{%- endif %}{%- endfor -%}

{#- *****************************************************************#}
{#- Messages *****************************************************************#}
{% for cm in d.msgs ~%}{%- if *objo_name == cm.name -%}
{%- if let Some(comment_impl) = cm.comment -%}
///{{comment_impl}}
{%- endif -%}
struct {{cm.name}} {
{%- for ca in cm.attributes %}
    typedef {% include "data_object_attr_type.cpp.jinja" %} {{ca.base.name|pascal_case}}_T;
{%- endfor %}

    typedef message_helper::MessageT<
        {% for ca in cm.attributes +%}{{ca.base.name|pascal_case}}_T{% if !loop.last %}, {% endif %} {%- endfor %}
    > MsgT;
{%+ for ca in cm.attributes %}
{% include "data_object_attr.cpp.jinja" -%}
{%- endfor %}

    {%- for ca in cm.attributes %}
    const char * str_{{ca.base.name}} = "{{ca.base.name}}";{%- endfor %}
    const char *msg_attr[{{cm.attributes.len()}}] = { {%- for ca in cm.attributes -%}str_{{ca.base.name}}{% if !loop.last %}, {% endif %}{%- endfor -%}};

    //static const char *msg_attr[];

    std::size_t serialize(BitisSerializer &ser) {
        return message_helper::msg_serialize(this, ser);
    }
    static bitis_helper::BitiaDeserializerHelper<{{cm.name}}> deserialize(BitisDeserializer &des) {
        return message_helper::msg_deserialize<{{cm.name}}>(des);
    }

    void print(int16_t indent=0) {
        printf("{{cm.name}}{ ");
        if (indent>=0) printf("\n");
        message_helper::msg_print(this, (indent>=0) ? (2 + indent) : indent, msg_attr);
        print_indent(indent); printf("}");
        // if (indent>=0) printf("\n");
    }

    bool is_equal(const {{cm.name}} &other) const {
        {%- if cm.attributes.len() == 0 %}
        return true;
        {%- else %}
        return {% for ca in cm.attributes +%}{{ca.base.name}}==other.{{ca.base.name}}{% if !loop.last %} && {% endif %} {%- endfor %};
        {%- endif -%}
   }
    bool operator==(const {{cm.name}} &other) const { return is_equal(other); }
    bool operator!=(const {{cm.name}} &other) const { return !is_equal(other); }
};
//const char *{{cm.name}}::msg_attr[] = { {%- for ca in cm.attributes -%}"{{ca.base.name}}"{% if !loop.last %}, {% endif %}{%- endfor -%}};

{%- endif -%}{%- endfor -%}

{%- endfor -%}