diff --git a/bragi/cpp_generator.py b/bragi/cpp_generator.py index 0cb30cb..85b9004 100644 --- a/bragi/cpp_generator.py +++ b/bragi/cpp_generator.py @@ -8,6 +8,8 @@ def allocator_argument(self): return '' def allocator_parameter(self): return '' + def array(self): + return 'std::array' def vector(self): return 'std::vector' def string(self): @@ -15,7 +17,7 @@ def string(self): def assert_func(self): return 'assert' def includes(self): - return ['', '', '', '', '', ''] + return ['', '', '', '', '', '', ''] class FriggTraits: def needs_allocator(self): @@ -24,6 +26,8 @@ def allocator_argument(self): return 'Allocator allocator = Allocator()' def allocator_parameter(self): return 'allocator' + def array(self): + return 'std::array' def vector(self): return 'frg::vector' def string(self): @@ -31,7 +35,7 @@ def string(self): def assert_func(self): return 'FRG_ASSERT' def includes(self): - return ['', '', '', '', '', ''] + return ['', '', '', '', '', '', ''] flatten = lambda l: [item for sublist in l for item in sublist] @@ -186,6 +190,9 @@ def generate_using(self, using): return out def check_needs_allocator(self, t): + if t.identity is TypeIdentity.ARRAY and t.n_elements is not None: + return False + return (t.identity in [TypeIdentity.STRING, TypeIdentity.ARRAY, TypeIdentity.STRUCT] or t.dynamic) and self.stdlib_traits.needs_allocator() @@ -201,7 +208,10 @@ def generate_type(self, t): elif t.identity is TypeIdentity.STRING: return f'{self.stdlib_traits.string()}{"" if self.stdlib_traits.needs_allocator() else ""}' elif t.identity is TypeIdentity.ARRAY: - return f'{self.stdlib_traits.vector()}<{self.generate_type(t.subtype)}{", Allocator" if self.stdlib_traits.needs_allocator() else ""}>' + if t.n_elements is None: + return f'{self.stdlib_traits.vector()}<{self.generate_type(t.subtype)}{", Allocator" if self.stdlib_traits.needs_allocator() else ""}>' + else: + return f'{self.stdlib_traits.array()}<{self.generate_type(t.subtype)}, {t.n_elements}>' elif t.identity is TypeIdentity.STRUCT: return f'{t.name}{"" if self.stdlib_traits.needs_allocator() else ""}' else: @@ -562,11 +572,6 @@ def emit_decode_fixed_internal(self, expr, expr_type, array_depth): out = '' - if self.parent.check_needs_allocator(expr_type.subtype): - out = f'{self.parent.indent}{expr}.resize({expr_type.n_elements}, allocator);\n' - else: - out = f'{self.parent.indent}{expr}.resize({expr_type.n_elements});\n' - out += f'{self.parent.indent}for (size_t i{array_depth} = 0; i{array_depth} < {expr_type.n_elements}; i{array_depth}++) {{\n' self.parent.enter_indent() out += self.emit_decode_fixed_internal(f'{expr}[i{array_depth}]', expr_type.subtype, array_depth + 1) @@ -642,10 +647,11 @@ def emit_decode_dynamic_internal(self, expr, expr_type, array_depth): if expr_type.identity is TypeIdentity.ARRAY and expr_type.n_elements: target_size = expr_type.n_elements - if self.parent.check_needs_allocator(expr_type.subtype): - out += f'{self.parent.indent}{expr}.resize({target_size}, allocator);\n' - else: - out += f'{self.parent.indent}{expr}.resize({target_size});\n' + if not (expr_type.identity is TypeIdentity.ARRAY and expr_type.n_elements is not None): + if self.parent.check_needs_allocator(expr_type.subtype): + out += f'{self.parent.indent}{expr}.resize({target_size}, allocator);\n' + else: + out += f'{self.parent.indent}{expr}.resize({target_size});\n' out += f'{self.parent.indent}for (size_t i{array_depth} = 0; i{array_depth} < {target_size}; i{array_depth}++)\n' if target_size != 'size': self.parent.enter_indent() @@ -816,12 +822,13 @@ def emit_accessors(self, members): self.leave_indent() out += f'{self.indent}}}\n\n' - out += f'{self.indent}void add_{m.name}({self.generate_type(m.type.subtype)} v) {{\n' - self.enter_indent() - out += f'{self.indent}p_{m.name} = true;\n' - out += f'{self.indent}m_{m.name}.push_back(v);\n' - self.leave_indent() - out += f'{self.indent}}}\n\n' + if m.type.n_elements is None: + out += f'{self.indent}void add_{m.name}({self.generate_type(m.type.subtype)} v) {{\n' + self.enter_indent() + out += f'{self.indent}p_{m.name} = true;\n' + out += f'{self.indent}m_{m.name}.push_back(v);\n' + self.leave_indent() + out += f'{self.indent}}}\n\n' return out diff --git a/tests/arrays/arrays.cpp b/tests/arrays/arrays.cpp index 84f08cf..bccca42 100644 --- a/tests/arrays/arrays.cpp +++ b/tests/arrays/arrays.cpp @@ -1,3 +1,4 @@ +#include #include #include "../test-util.hpp" @@ -30,7 +31,8 @@ void test1() { void test2() { auto t1 = test::make_msg(); - t1.set_arr(test::make_vector(0xDE, 0xAD, 0xBE, 0xEF)); + auto arr = std::array{0xDE, 0xAD, 0xBE, 0xEF}; + t1.set_arr(arr); assert(bragi::message_id == 2); assert(bragi::head_size == 128); @@ -42,7 +44,6 @@ void test2() { auto t2 = test::parse_with(head_buf); assert(t2); - auto arr = test::make_vector(0xDE, 0xAD, 0xBE, 0xEF, 0); assert(t2->arr() == arr); } @@ -77,17 +78,17 @@ void test3() { void test4() { auto t1 = test::make_msg(); - t1.set_arr1(test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5) + t1.set_arr1(test::make_vector>( + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5} )); - t1.set_arr2(test::make_vector>( + t1.set_arr2(std::array, 5>{ test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), test::make_vector(0xB1, 0x6B, 0x00, 0xB5) - )); + }); assert(bragi::message_id == 4); assert(bragi::head_size == 128); @@ -99,19 +100,19 @@ void test4() { auto t2 = test::parse_with(head_buf); assert(t2); - auto arr1 = test::make_vector>( + auto arr1 = test::make_vector>( + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5}, + std::array{}, + std::array{} + ); + + auto arr2 = std::array, 5>{ test::make_vector(0xDE, 0xAD, 0xBE, 0xEF, 0), test::make_vector(0xCA, 0xFE, 0xBA, 0xBE, 0), test::make_vector(0xB1, 0x6B, 0x00, 0xB5, 0) - ); - - auto arr2 = test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5), - test::make_vector(), - test::make_vector() - ); + }; assert(t2->arr1() == arr1); assert(t2->arr2() == arr2); @@ -120,11 +121,11 @@ void test4() { void test5_1() { auto t1 = test::make_msg(); - t1.set_arr(test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5) - )); + t1.set_arr(std::array, 4>{ + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5} + }); assert(bragi::message_id == 5); assert(bragi::head_size == 128); @@ -136,12 +137,12 @@ void test5_1() { auto t2 = test::parse_with(head_buf); assert(t2); - auto arr = test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5), - test::make_vector(0, 0, 0, 0) - ); + auto arr = std::array, 4>{ + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5}, + std::array{0, 0, 0, 0}, + }; assert(t2->arr() == arr); } @@ -149,12 +150,12 @@ void test5_1() { void test5_2() { auto t1 = test::make_msg(); - t1.set_arr(test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5), - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF) - )); + t1.set_arr(std::array, 4>{ + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5}, + std::array{0xDE, 0xAD, 0xBE, 0xEF} + }); assert(bragi::message_id == 5); assert(bragi::head_size == 128); @@ -166,12 +167,12 @@ void test5_2() { auto t2 = test::parse_with(head_buf); assert(t2); - auto arr = test::make_vector>( - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF), - test::make_vector(0xCA, 0xFE, 0xBA, 0xBE), - test::make_vector(0xB1, 0x6B, 0x00, 0xB5), - test::make_vector(0xDE, 0xAD, 0xBE, 0xEF) - ); + auto arr = std::array, 4>{ + std::array{0xDE, 0xAD, 0xBE, 0xEF}, + std::array{0xCA, 0xFE, 0xBA, 0xBE}, + std::array{0xB1, 0x6B, 0x00, 0xB5}, + std::array{0xDE, 0xAD, 0xBE, 0xEF} + }; assert(t2->arr() == arr); } diff --git a/tests/enums/enums.cpp b/tests/enums/enums.cpp index 70b46c0..7db337a 100644 --- a/tests/enums/enums.cpp +++ b/tests/enums/enums.cpp @@ -16,7 +16,7 @@ int main() { t1.set_bar(Bar::E); t1.set_foos(test::make_vector(Foo::D, Foo::A, Foo::F, Foo::B)); - t1.set_bars(test::make_vector(Bar::E, Bar::B, Bar::A, Bar::C)); + t1.set_bars(std::array{Bar::E, Bar::B, Bar::A, Bar::C}); assert(bragi::message_id == 1); assert(bragi::head_size == 128); @@ -48,6 +48,6 @@ int main() { auto foos = test::make_vector(Foo::D, Foo::A, Foo::F, Foo::B); assert(t2->foos() == foos); - auto bars = test::make_vector(Bar::E, Bar::B, Bar::A, Bar::C); + auto bars = std::array{Bar::E, Bar::B, Bar::A, Bar::C}; assert(t2->bars() == bars); }