#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 -%}