Skip to content

Commit 7b691c6

Browse files
Merge branch 'master' into sequence_lenght
2 parents 62629b2 + 2627c36 commit 7b691c6

9 files changed

Lines changed: 192 additions & 40 deletions

File tree

src/fast_type_gen/inl_gen.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ std::string get_properties_type(const Instruction *inst) {
2525
using namespace mfast;
2626
struct ext_cref_type_getter : mfast::field_instruction_visitor {
2727
std::stringstream out_;
28+
bool is_group_type_ = false;
2829

2930
public:
3031
ext_cref_type_getter() {}
3132

3233
std::string get() { return out_.str(); }
34+
bool group_type() { return is_group_type_; }
3335

3436
virtual void visit(const int32_field_instruction *inst, void *) override {
3537
out_ << "ext_cref<int32_cref, " << get_operator_tag(inst) << ", "
@@ -83,6 +85,7 @@ struct ext_cref_type_getter : mfast::field_instruction_visitor {
8385
virtual void visit(const group_field_instruction *inst, void *) override {
8486
out_ << "ext_cref< " << codegen_base::cpp_name(inst)
8587
<< "_cref, group_type_tag, " << get_properties_type(inst) << ">";
88+
is_group_type_ = true;
8689
}
8790

8891
virtual void visit(const sequence_field_instruction *inst, void *) override;
@@ -132,6 +135,12 @@ std::string get_ext_cref_type(const field_instruction *inst) {
132135
return getter.get();
133136
}
134137

138+
bool is_group_type(const field_instruction *inst) {
139+
ext_cref_type_getter getter;
140+
inst->accept(getter, nullptr);
141+
return getter.group_type();
142+
}
143+
135144
void ext_cref_type_getter::visit(const sequence_field_instruction *inst,
136145
void *) {
137146
const uint32_field_instruction *length_inst = inst->length_instruction();
@@ -473,9 +482,17 @@ void inl_gen::visit(const mfast::group_field_instruction *inst, void *pIndex) {
473482

474483
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
475484
const field_instruction *subinst = inst->subinstructions()[i];
476-
;
477-
out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)["
478-
<< i << "]) );\n";
485+
486+
if (is_group_type(subinst) && subinst->optional())
487+
{
488+
out_ << " {\n"
489+
<< " " << get_ext_cref_type(subinst) << " ext_cref_group((*this)[" << i << "]);\n"
490+
<< " ext_cref_group.set_group_present(this->field_storage(" << i << ")->is_present());\n"
491+
<< " visitor.visit(ext_cref_group);\n"
492+
<< " }\n";
493+
}
494+
else
495+
out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)[" << i << "]) );\n";
479496
}
480497

481498
out_ << "}\n\n";
@@ -508,6 +525,7 @@ void inl_gen::visit(const mfast::group_field_instruction *inst, void *pIndex) {
508525

509526
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
510527
const field_instruction *subinst = inst->subinstructions()[i];
528+
511529
out_ << " visitor.visit(" << get_ext_mref_type(subinst) << " ((*this)["
512530
<< i << "]) );\n";
513531
}
@@ -662,7 +680,7 @@ void inl_gen::visit(const mfast::sequence_field_instruction *inst,
662680

663681
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
664682
const field_instruction *subinst = inst->subinstructions()[i];
665-
;
683+
666684
out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)["
667685
<< i << "]) );\n";
668686
}
@@ -677,7 +695,7 @@ void inl_gen::visit(const mfast::sequence_field_instruction *inst,
677695

678696
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
679697
const field_instruction *subinst = inst->subinstructions()[i];
680-
;
698+
681699
out_ << " visitor.visit(" << get_ext_mref_type(subinst) << " ((*this)["
682700
<< i << "]) );\n";
683701
}
@@ -791,9 +809,17 @@ void inl_gen::visit(const mfast::template_instruction *inst, void *) {
791809

792810
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
793811
const field_instruction *subinst = inst->subinstructions()[i];
794-
;
795-
out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)["
796-
<< i << "]) );\n";
812+
813+
if (is_group_type(subinst) && subinst->optional())
814+
{
815+
out_ << " {\n"
816+
<< " " << get_ext_cref_type(subinst) << " ext_cref_group((*this)[" << i << "]);\n"
817+
<< " ext_cref_group.set_group_present(this->field_storage(" << i << ")->is_present());\n"
818+
<< " visitor.visit(ext_cref_group);\n"
819+
<< " }\n";
820+
}
821+
else
822+
out_ << " visitor.visit(" << get_ext_cref_type(subinst) << " ((*this)[" << i << "]) );\n";
797823
}
798824

799825
out_ << "}\n\n";
@@ -842,7 +868,7 @@ void inl_gen::visit(const mfast::template_instruction *inst, void *) {
842868

843869
for (std::size_t i = 0; i < inst->subinstructions().size(); ++i) {
844870
const field_instruction *subinst = inst->subinstructions()[i];
845-
;
871+
846872
out_ << " visitor.visit(" << get_ext_mref_type(subinst) << " ((*this)["
847873
<< i << "]) );\n";
848874
}

src/mfast/aggregate_ref.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ class aggregate_cref {
5757
this->instruction_ = other.instruction_;
5858
this->storage_array_ = other.storage_array_;
5959
}
60-
bool content() const { return storage_array_->of_group.content_ != nullptr; }
6160

6261
class iterator
6362
: public boost::iterator_facade<iterator, field_cref,

src/mfast/ext_ref.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@ class ext_cref<BaseCRef, group_type_tag, Properties>
203203
explicit ext_cref(const field_cref &base) : base_(base) {}
204204
explicit ext_cref(const aggregate_cref &base) : base_(base) {}
205205
cref_type get() const { return base_; }
206-
bool present() const { return !this->optional() || base_.content(); }
206+
bool present() const { return !this->optional() || group_present_; }
207+
208+
void set_group_present(bool present) { group_present_ = present; }
207209

208210
private:
209211
cref_type base_;
212+
bool group_present_ = true;
210213
};
211214

212215
template <typename Properties>
@@ -221,8 +224,11 @@ class ext_cref<nested_message_cref, group_type_tag, Properties>
221224
cref_type get() const { return cref_type(aggregate_cref(base_)[0]); }
222225
bool present() const { return !this->optional() || base_.present(); }
223226

227+
void set_group_present(bool present) { group_present_ = present; }
228+
224229
private:
225230
field_cref base_;
231+
bool group_present_ = true;
226232
};
227233

228234
///////////////////////////////////////////////////////////////

src/mfast/sequence_type.h

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,37 @@
77
#include <boost/move/core.hpp>
88
#include "sequence_ref.h"
99
namespace mfast {
10-
template <typename CRef> class squence_type_base {
10+
template <typename CRef> class sequence_type_base {
1111
#ifdef BOOST_NO_RVALUE_REFERENCES
12-
BOOST_MOVABLE_BUT_NOT_COPYABLE(squence_type_base)
12+
BOOST_MOVABLE_BUT_NOT_COPYABLE(sequence_type_base)
1313
#endif
1414
public:
1515
typedef typename CRef::instruction_cptr instruction_cptr;
1616
typedef CRef cref_type;
1717
typedef typename mref_of<cref_type>::type mref_type;
1818

19-
squence_type_base(mfast::allocator *alloc = nullptr,
19+
sequence_type_base(mfast::allocator *alloc = nullptr,
2020
instruction_cptr instruction = 0,
2121
value_storage *fields_storage = nullptr);
2222

2323
// a special constructor to facilitate puting a message_type instance in an
2424
// associative
2525
// container
2626
// using emplace()
27-
squence_type_base(std::pair<mfast::allocator *, instruction_cptr> p);
28-
~squence_type_base();
27+
sequence_type_base(std::pair<mfast::allocator *, instruction_cptr> p);
28+
~sequence_type_base();
2929

30-
squence_type_base(const cref_type &other, mfast::allocator *alloc);
30+
sequence_type_base(const cref_type &other, mfast::allocator *alloc);
3131

32-
squence_type_base(BOOST_RV_REF(squence_type_base) other)
32+
sequence_type_base(BOOST_RV_REF(sequence_type_base) other)
3333
: alloc_(other.alloc_), instruction_(other.instruction_) {
3434
// g++ 4.7.1 doesn't allow this member function to defined out of class
3535
// declaration
3636
my_storage_ = other.my_storage_;
3737
other.instruction_ = 0;
3838
}
3939

40-
squence_type_base &operator=(BOOST_RV_REF(squence_type_base) other) {
40+
sequence_type_base &operator=(BOOST_RV_REF(sequence_type_base) other) {
4141
// g++ 4.7.1 doesn't allow this member function to defined out of class
4242
// declaration
4343
if (this->instruction())
@@ -77,92 +77,92 @@ template <typename CRef> class squence_type_base {
7777
value_storage my_storage_;
7878
};
7979

80-
typedef squence_type_base<sequence_cref> sequence_type;
80+
typedef sequence_type_base<sequence_cref> sequence_type;
8181

8282
///////////////////////////////////////////////////////
8383

8484
template <typename CRef>
85-
inline squence_type_base<CRef>::squence_type_base(
85+
inline sequence_type_base<CRef>::sequence_type_base(
8686
mfast::allocator *alloc,
87-
typename squence_type_base<CRef>::instruction_cptr instruction,
87+
typename sequence_type_base<CRef>::instruction_cptr instruction,
8888
value_storage *fields_storage)
8989
: alloc_(alloc), instruction_(instruction) {
9090
if (instruction_)
9191
instruction_->construct_value(my_storage_, fields_storage, alloc_, false);
9292
}
9393

9494
template <typename CRef>
95-
inline squence_type_base<CRef>::squence_type_base(
95+
inline sequence_type_base<CRef>::sequence_type_base(
9696
std::pair<mfast::allocator *,
97-
typename squence_type_base<CRef>::instruction_cptr> p)
97+
typename sequence_type_base<CRef>::instruction_cptr> p)
9898
: alloc_(p.first), instruction_(p.second) {
9999
instruction_->construct_value(my_storage_, 0, alloc_, false);
100100
}
101101

102-
template <typename CRef> inline squence_type_base<CRef>::~squence_type_base() {
102+
template <typename CRef> inline sequence_type_base<CRef>::~sequence_type_base() {
103103
if (alloc_ && this->instruction())
104104
this->instruction()->destruct_value(my_storage_, alloc_);
105105
}
106106

107107
template <typename CRef>
108-
inline typename squence_type_base<CRef>::instruction_cptr
109-
squence_type_base<CRef>::instruction() const {
108+
inline typename sequence_type_base<CRef>::instruction_cptr
109+
sequence_type_base<CRef>::instruction() const {
110110
return instruction_;
111111
}
112112

113113
template <typename CRef>
114-
inline squence_type_base<CRef>::squence_type_base(const CRef &other,
114+
inline sequence_type_base<CRef>::sequence_type_base(const CRef &other,
115115
mfast::allocator *alloc)
116116
: alloc_(alloc), instruction_(other.instruction()) {
117117
this->instruction()->copy_construct_value(
118118
*field_cref_core_access::storage_of(other), my_storage_, alloc, nullptr);
119119
}
120120

121121
template <typename CRef>
122-
inline typename squence_type_base<CRef>::mref_type
123-
squence_type_base<CRef>::ref() {
122+
inline typename sequence_type_base<CRef>::mref_type
123+
sequence_type_base<CRef>::ref() {
124124
return mref_type(alloc_, &my_storage_, instruction_);
125125
}
126126

127127
template <typename CRef>
128-
inline typename squence_type_base<CRef>::mref_type
129-
squence_type_base<CRef>::mref() {
128+
inline typename sequence_type_base<CRef>::mref_type
129+
sequence_type_base<CRef>::mref() {
130130
return mref_type(alloc_, &my_storage_, instruction_);
131131
}
132132

133133
template <typename CRef>
134-
inline typename squence_type_base<CRef>::cref_type
135-
squence_type_base<CRef>::ref() const {
134+
inline typename sequence_type_base<CRef>::cref_type
135+
sequence_type_base<CRef>::ref() const {
136136
return cref_type(&my_storage_, instruction_);
137137
}
138138

139139
template <typename CRef>
140-
inline typename squence_type_base<CRef>::cref_type
141-
squence_type_base<CRef>::cref() const {
140+
inline typename sequence_type_base<CRef>::cref_type
141+
sequence_type_base<CRef>::cref() const {
142142
return cref_type(&my_storage_, instruction_);
143143
}
144144

145145
template <typename CRef>
146-
inline const char *squence_type_base<CRef>::name() const {
146+
inline const char *sequence_type_base<CRef>::name() const {
147147
return instruction_->name();
148148
}
149149

150150
template <typename CRef>
151-
inline mfast::allocator *squence_type_base<CRef>::allocator() const {
151+
inline mfast::allocator *sequence_type_base<CRef>::allocator() const {
152152
return this->alloc_;
153153
}
154154

155155
// template <typename CRef>
156156
// inline void
157-
// squence_type_base<CRef>::reset()
157+
// sequence_type_base<CRef>::reset()
158158
// {
159159
// my_storage_.of_array.content_ = 0;
160160
// my_storage_.of_array.capacity_in_bytes_ = 0;
161161
// }
162162
//
163163
// template <typename CRef>
164164
// inline void
165-
// squence_type_base<CRef>::ensure_valid()
165+
// sequence_type_base<CRef>::ensure_valid()
166166
// {
167167
// instruction_->ensure_valid_storage(my_storage_, alloc_);
168168
// }

src/mfast/value_storage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ union MFAST_EXPORT value_storage {
107107
void defined(bool v) { of_array.defined_bit_ = v; }
108108
bool is_empty() const { return of_array.len_ == 0; }
109109
void present(bool p) { of_array.len_ = p; }
110+
bool is_present() const { return of_group.present_ == 1; }
110111
uint32_t array_length() const {
111112
return of_array.len_ == 0 ? 0 : of_array.len_ - 1;
112113
};

tests/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ FASTTYPEGEN_TARGET(simple_types9 simple9.xml)
2121
FASTTYPEGEN_TARGET(simple_types10 simple10.xml)
2222
FASTTYPEGEN_TARGET(simple_types11 simple11.xml)
2323
FASTTYPEGEN_TARGET(simple_types12 simple12.xml)
24+
FASTTYPEGEN_TARGET(simple_types13 simple13.xml)
2425
FASTTYPEGEN_TARGET(simple_types14 simple14.xml)
2526

2627

@@ -42,6 +43,8 @@ add_executable (mfast_test
4243
encoder_decoder_test.cpp
4344
encoder_decoder_test_v2.cpp
4445
field_comparator_test.cpp
46+
group_encoder_decoder_v2.cpp
47+
group_encoder_decoder.cpp
4548
coder_test.cpp
4649
value_storage_test.cpp
4750
${FASTTYPEGEN_test_types1_OUTPUTS}
@@ -61,6 +64,7 @@ add_executable (mfast_test
6164
${FASTTYPEGEN_simple_types10_OUTPUTS}
6265
${FASTTYPEGEN_simple_types11_OUTPUTS}
6366
${FASTTYPEGEN_simple_types12_OUTPUTS}
67+
${FASTTYPEGEN_simple_types13_OUTPUTS}
6468
${FASTTYPEGEN_simple_types14_OUTPUTS}
6569
fast_type_gen_test.cpp
6670
dictionary_builder_test.cpp

tests/group_encoder_decoder.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "catch.hpp"
2+
#include <mfast.h>
3+
4+
#include "fast_test_coding_case.hpp"
5+
#include "byte_stream.h"
6+
7+
#include "simple13.h"
8+
9+
using namespace test::coding;
10+
11+
TEST_CASE("only field without group encoder/decoder","[field_without_group_encoder_decoder]")
12+
{
13+
fast_test_coding_case<simple13::templates_description> test_case;
14+
15+
simple13::Test_1 test_1;
16+
simple13::Test_1_mref test_1_mref = test_1.mref();
17+
18+
test_1_mref.set_field_1_1().as(30);
19+
test_1_mref.set_field_1_2().as(40);
20+
21+
REQUIRE(test_case.encoding(test_1.cref(),"\xC0\x81\x9F\xA8",true));
22+
REQUIRE(test_case.decoding("\xC0\x81\x9F\xA8",test_1.cref(),true));
23+
}
24+
25+
TEST_CASE("field with group encoder/decoder","[field_without_group_encoder_decoder]")
26+
{
27+
fast_test_coding_case<simple13::templates_description> test_case;
28+
29+
simple13::Test_1 test_1;
30+
simple13::Test_1_mref test_1_mref = test_1.mref();
31+
32+
test_1_mref.set_field_1_1().as(30);
33+
test_1_mref.set_field_1_2().as(40);
34+
35+
auto group_1 = test_1_mref.set_group_1();
36+
group_1.set_field_1_4().as(10);
37+
38+
REQUIRE(test_case.encoding(test_1.cref(),"\xE0\x81\x9F\xA8\x80\x8B",true));
39+
REQUIRE(test_case.decoding("\xE0\x81\x9F\xA8\x80\x8B",test_1.cref(),true));
40+
}
41+
42+

0 commit comments

Comments
 (0)