Skip to content

Xetra fast Set #158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,14 @@ jobs:
run: curl -L https://archives.boost.io/release/1.72.0/source/boost_1_72_0.tar.gz | tar zx
shell: bash
- name: configure
run: cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DXETRA_FAST_SPECIFICATION=ON
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
- name: configure xetra
run: cmake -B ${{github.workspace}}/build-xetra -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DXETRA_FAST_SPECIFICATION=ON
- name: build
run: cmake --build build --parallel 2
run: cmake --build ${{github.workspace}}/build --parallel 2
- name: build xetra
run: cmake --build ${{github.workspace}}/build-xetra --parallel 2
- name: test
run: cd build && ctest -VV
run: cd ${{github.workspace}}/build && ctest -VV
- name: test xetra
run: cd ${{github.workspace}}/build-xetra && ctest -VV
6 changes: 6 additions & 0 deletions examples/message_printer/message_printer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <mfast.h>
#include <iostream>
#include <boost/io/ios_state.hpp>
#include <bitset>

using namespace mfast;

Expand Down Expand Up @@ -130,5 +131,10 @@ class message_printer
}
--indent_;
}

void visit(const set_cref& ref)
{
os_ << "0b" << std::bitset<16>{ref.value()};
}
};

4 changes: 4 additions & 0 deletions src/fast_type_gen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ else()
add_executable (fast_type_gen)
target_sources(fast_type_gen PRIVATE ${headers} ${sources})

if(XETRA_FAST_SPECIFICATION)
target_compile_definitions(fast_type_gen PRIVATE XETRA_FAST_SPECIFICATION)
endif(XETRA_FAST_SPECIFICATION)

target_link_libraries (fast_type_gen PRIVATE
mfast_xml_parser_static
mfast_static
Expand Down
14 changes: 14 additions & 0 deletions src/fast_type_gen/codegen_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,20 @@ class type_name_finder : public field_instruction_visitor {
dependency_->insert(inst->cpp_ns());
}
}

virtual void visit(const set_field_instruction *inst,
void *pIndex) override {
if (inst->ref_instruction()) {
inst->ref_instruction()->accept(*this, pIndex);
} else if (inst->cpp_ns() == nullptr || inst->cpp_ns()[0] == 0 ||
strcmp(caller_cpp_ns_, inst->cpp_ns()) == 0) {
name_ = inst->name();
} else {
name_ = std::string(inst->cpp_ns()) + "::" + inst->name();
if (dependency_)
dependency_->insert(inst->cpp_ns());
}
}
};

std::string codegen_base::cpp_type_of(const mfast::field_instruction *inst,
Expand Down
65 changes: 65 additions & 0 deletions src/fast_type_gen/cpp_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,71 @@ void cpp_gen::visit(const mfast::enum_field_instruction *inst, void *pIndex) {
}
}

void cpp_gen::visit(const mfast::set_field_instruction *inst, void *pIndex)
{
std::string name(cpp_name(inst));
std::string qualified_name = name;
std::string instruction_variable_name;
std::stringstream elements_variable_name;
std::stringstream num_elements_name;
std::stringstream instruction_type;
if (inst->ref_instruction())
qualified_name = cpp_type_of(inst);
if (pIndex == nullptr)
{
out_ << "const " << qualified_name << "::instruction_type*\n" << name
<< "::instruction()\n"
<< "{\n";
instruction_variable_name = " the_instruction";
instruction_type << qualified_name << "::instruction_type";
}
else
{
add_to_instruction_list(name);
instruction_variable_name = prefix_string() + name + "_instruction";
instruction_type << cref_scope() << name << "_cref::instruction_type";
}
if (inst->ref_instruction())
{
elements_variable_name << qualified_name << "::instruction()->elements()";
num_elements_name << qualified_name << "::instruction()->num_elements()";
instruction_type.str(qualified_name + "::instruction_type");
}
else
{
elements_variable_name << "elements";
num_elements_name << inst->num_elements();
out_ << "static const char* elements[] = {\n";
for (auto i = 0ul; i < inst->num_elements(); ++i)
{
if (i != 0)
out_ << ",\n";
out_ << " \"" << inst->elements()[i] << "\"";
}
out_ << "};\n";
}
std::string context = gen_op_context(inst->name(), inst->op_context());
out_ << "const static " << instruction_type.str() << "\n"
<< instruction_variable_name << "(\n"
<< " " << get_operator_name(inst) << ",\n"
<< " " << get_presence(inst) << ",\n"
<< " " << inst->id() << ", // id\n"
<< " \"" << inst->name() << "\", // name\n"
<< " \"" << inst->ns() << "\", // ns\n"
<< " " << context << ", // opContext\n"
<< " int_value_storage<uint64_t>("
<< inst->initial_value().get<uint64_t>() << "), // initial_value\n"
<< " " << elements_variable_name.str() << ", // element names\n"
<< " " << num_elements_name.str() << ",// num elements\n"
<< " nullptr, // ref_instruction\n"
<< " nullptr, // cpp_ns\n"
<< " " << inst->tag() << "); // tag\n\n";
if (pIndex == nullptr) {
out_ << " return &the_instruction;\n"
<< "}\n\n";
}
}

void cpp_gen::generate(const mfast::aggregate_view_info &info) {
std::string my_name = cpp_name(info.name_);

Expand Down
1 change: 1 addition & 0 deletions src/fast_type_gen/cpp_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class cpp_gen : public codegen_base {
virtual void visit(const mfast::uint64_vector_field_instruction *,
void *) override;
virtual void visit(const mfast::enum_field_instruction *, void *) override;
virtual void visit(const mfast::set_field_instruction *, void *) override;

private:
virtual void generate(const mfast::aggregate_view_info &info);
Expand Down
82 changes: 82 additions & 0 deletions src/fast_type_gen/hpp_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,88 @@ void hpp_gen::visit(const mfast::enum_field_instruction *inst, void *pIndex) {
}
}

void hpp_gen::visit(const mfast::set_field_instruction *inst, void *pIndex)
{
std::string name(cpp_name(inst));
if (inst->ref_instruction() == nullptr)
{
header_cref_ << indent << "struct " << export_symbol_uppercase_ << name
<< "\n" << indent << "{\n" << indent << " enum element {\n";
for (auto i = 0ul; i < inst->num_elements(); ++i)
{
header_cref_ << indent << " " << cpp_name(inst->elements()[i]);
if (i == 0)
header_cref_ << " = 1";
else
header_cref_ << " = 1 << " << i;
if (i + 1 < inst->num_elements())
header_cref_ << ",\n";
}
header_cref_ << "\n" << indent << " };\n" << indent
<< " using instruction_type = "
<< "mfast::set_field_instruction_ex<"
<< name << ">;\n" << indent
<< " static const instruction_type* instruction();\n"
<< indent << "};\n\n";
header_cref_ << indent << "class " << name << "_cref\n" << indent
<< " : public mfast::set_cref_ex<" << name << "_cref, "
<< name << ">\n" << indent << "{\n" << indent << " public:\n"
<< indent << " using base_type = mfast::set_cref_ex<"
<< name << "_cref, " << name << ">;\n" << indent
<< " using element_type = " << name << "::element;\n"
<< indent << " using instruction_type = " << name
<< "::instruction_type;\n" << indent << " "
<< name << "_cref(\n" << indent
<< " const mfast::value_storage* storage=nullptr,\n" << indent
<< " instruction_cptr instruction=nullptr);\n\n"
<< indent << " explicit " << name
<< "_cref(const field_cref& other);\n\n" << indent
<< " element_type value() const;\n\n";
for (auto i = 0ul; i < inst->num_elements_; ++i)
{
std::string element_name = cpp_name(inst->elements_[i]);
header_cref_ << indent << " bool has_" << element_name << "() const;\n";
}
header_cref_ << indent << "};\n\n";
header_mref_ << indent << "class " << name << "_mref\n" << indent
<< " : public mfast::set_mref_ex<" << name << "_mref, "
<< name << "_cref>\n" << indent << "{\n" << indent
<< " public:\n" << indent
<< " using base_type = mfast::set_mref_ex<" << name
<< "_mref, " << name << "_cref>;\n" << indent
<< " using element_type = " << name << "::element;\n"
<< indent << " " << name << "_mref(\n" << indent
<< " mfast::allocator* alloc=nullptr,\n" << indent
<< " mfast::value_storage* storage=nullptr,\n" << indent
<< " instruction_cptr instruction=nullptr);\n"
<< indent << " explicit " << name
<< "_mref(const mfast::field_mref_base& other);\n\n";
for (auto i = 0ul; i < inst->num_elements_; ++i)
{
std::string element_name = cpp_name(inst->elements_[i]);
header_mref_ << indent << " void set_" << element_name << "() const;\n";
header_mref_ << indent << " void unset_" << element_name << "() const;\n";
}
header_mref_ << indent << "};\n\n";
}
if (pIndex) {
std::string ret_type = cpp_type_of(inst, &dependency_);
header_cref_ << indent << ret_type << "_cref get_" << name << "() const;\n";
header_cref_ << indent << ret_type << "_cref try_get_" << name << "() const;\n";
if (inst->field_operator() != mfast::operator_constant)
header_mref_ << indent << ret_type << "_mref set_" << name << "() const;\n";
if (inst->optional()) {
header_mref_ << indent << "void omit_" << name << "() const;\n";
}
} else {
content_ << header_cref_.str() << header_mref_.str();
header_cref_.clear();
header_cref_.str("");
header_mref_.clear();
header_mref_.str("");
}
}

void hpp_gen::generate(const mfast::aggregate_view_info &info) {
std::string ns_prefix;
std::string my_name = cpp_name(info.name_);
Expand Down
1 change: 1 addition & 0 deletions src/fast_type_gen/hpp_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class hpp_gen : public codegen_base {
virtual void visit(const mfast::template_instruction *, void *) override;
virtual void visit(const mfast::templateref_instruction *, void *) override;
virtual void visit(const mfast::enum_field_instruction *, void *) override;
virtual void visit(const mfast::set_field_instruction *, void *) override;

private:
void gen_primitive(const char *cpp_type,
Expand Down
80 changes: 80 additions & 0 deletions src/fast_type_gen/inl_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ struct ext_cref_type_getter : mfast::field_instruction_visitor {
out_ << "ext_cref<enum_cref, " << get_operator_tag(inst) << ", "
<< get_properties_type(inst) << ">";
}

virtual void visit(const set_field_instruction *inst, void *) override {
out_ << "ext_cref<set_cref, " << get_operator_tag(inst) << ", "
<< get_properties_type(inst) << ">";
}
};

std::string get_ext_cref_type(const field_instruction *inst) {
Expand Down Expand Up @@ -260,6 +265,11 @@ struct ext_mref_type_getter : mfast::field_instruction_visitor {
out_ << "ext_mref<enum_mref, " << get_operator_tag(inst) << ", "
<< get_properties_type(inst) << ">";
}

virtual void visit(const set_field_instruction *inst, void *) override {
out_ << "ext_mref<set_mref, " << get_operator_tag(inst) << ", "
<< get_properties_type(inst) << ">";
}
};

std::string get_ext_mref_type(const field_instruction *inst) {
Expand Down Expand Up @@ -1045,6 +1055,76 @@ void inl_gen::visit(const mfast::enum_field_instruction *inst, void *pIndex) {
gen_accessors(inst, name, cref_type_name, mref_type_name, pIndex);
}

void inl_gen::visit(const mfast::set_field_instruction *inst, void *pIndex)
{
std::string name(cpp_name(inst));
std::string cref_type_name = cref_scope_.str() + name + "_cref";
std::string mref_type_name = mref_scope_.str() + name + "_mref";
if (inst->ref_instruction() == nullptr)
{
out_ << "inline\n" << cref_type_name << "::" << name << "_cref(\n"
<< " const mfast::value_storage* storage,\n"
<< " " << cref_type_name << "::instruction_cptr instruction)\n"
<< " : base_type(storage, instruction)\n"
<< "{\n"
<< "}\n\n"
<< "inline\n" << cref_type_name << "::" << name << "_cref(\n"
<< " const mfast::field_cref& other)\n"
<< " : base_type(other)\n"
<< "{\n"
<< "}\n\n"
<< "inline\n" << mref_type_name << "::" << name << "_mref(\n"
<< " mfast::allocator* alloc,\n"
<< " mfast::value_storage* storage,\n"
<< " " << mref_type_name << "::instruction_cptr instruction)\n"
<< " : base_type(alloc, storage, instruction)\n"
<< "{\n"
<< "}\n\n"
<< "inline\n" << mref_type_name << "::" << name << "_mref(\n"
<< " const mfast::field_mref_base& other)\n"
<< " : base_type(other)\n"
<< "{\n"
<< "}\n\n"
<< "inline\n" << cref_type_name << "::element_type\n" << cref_type_name
<< "::value() const\n"
<< "{\n"
<< " return static_cast<" << name
<< "::element>(base_type::value());\n"
<< "}\n\n";
for (auto i = 0ul; i < inst->num_elements_; ++i)
{
std::string element_name = cpp_name(inst->elements_[i]);
out_ << "inline\n"
<< "bool " << cref_type_name << "::has_" << element_name
<< "() const\n"
<< "{\n"
<< " return this->value() & " << name << "::" << element_name
<< ";\n"
<< "}\n\n"
<< "inline\n"
<< "void " << mref_type_name << "::set_" << element_name
<< "() const\n"
<< "{\n"
<< " auto tmp = this->value() | "
<< name << "::" << element_name << ";\n"
<< " return this->as(static_cast<element_type>(tmp));\n"
<< "}\n\n"
<< "inline\n"
<< "void " << mref_type_name << "::unset_" << element_name
<< "() const\n"
<< "{\n"
<< " auto tmp = this->value() & ~"
<< name << "::" << element_name << ";\n"
<< " return this->as(static_cast<element_type>(tmp));\n"
<< "}\n\n";
}
}
std::string ret_type = cpp_type_of(inst, nullptr);
auto ret_cref = ret_type + "_cref";
auto ret_mref = ret_type + "_mref";
gen_accessors(inst, name, ret_cref, ret_mref, pIndex);
}

void inl_gen::gen_accessors(const mfast::field_instruction *inst,
const std::string &name,
const std::string &cref_type_name,
Expand Down
1 change: 1 addition & 0 deletions src/fast_type_gen/inl_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class inl_gen : public codegen_base {
virtual void visit(const mfast::template_instruction *, void *) override;
virtual void visit(const mfast::templateref_instruction *, void *) override;
virtual void visit(const mfast::enum_field_instruction *, void *) override;
virtual void visit(const mfast::set_field_instruction *, void *) override;

private:
virtual void traverse(const mfast::group_field_instruction *inst,
Expand Down
9 changes: 9 additions & 0 deletions src/mfast/coder/common/dictionary_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,4 +385,13 @@ void dictionary_builder::visit(const enum_field_instruction *src_inst,
get_dictionary_storage(dest->name(), dest->ns(), dest->op_context_,
field_type_uint64, &dest->prev_storage_, dest);
}

void dictionary_builder::visit(const set_field_instruction *src_inst,
void *dest_inst) {
auto& dest = *static_cast<set_field_instruction**>(dest_inst);
dest = src_inst->clone(alloc_);
dest->prev_value_ =
get_dictionary_storage(dest->name(), dest->ns(), dest->op_context_,
field_type_uint64, &dest->prev_storage_, dest);
}
}
1 change: 1 addition & 0 deletions src/mfast/coder/common/dictionary_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class MFAST_CODER_EXPORT dictionary_builder
virtual void visit(const templateref_instruction *, void *) override;

virtual void visit(const enum_field_instruction *, void *) override;
virtual void visit(const set_field_instruction *, void *) override;

template_instruction *clone_instruction(const template_instruction *);

Expand Down
4 changes: 4 additions & 0 deletions src/mfast/coder/decoder/fast_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ struct fast_decoder_impl {
this->visit(reinterpret_cast<uint64_mref &>(mref));
}

void visit(set_mref &mref) {
this->visit(reinterpret_cast<uint64_mref &>(mref));
}

template <typename SimpleMRef> void visit(const SimpleMRef &mref);

template <typename IntType> void visit(const int_vector_mref<IntType> &mref);
Expand Down
Loading