Skip to content

Commit

Permalink
cpp_generator: use std:array for fixed-size arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
no92 committed May 26, 2024
1 parent 5cd3b08 commit d4a8e63
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 61 deletions.
43 changes: 25 additions & 18 deletions bragi/cpp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ 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):
return 'std::string'
def assert_func(self):
return 'assert'
def includes(self):
return ['<stdint.h>', '<stddef.h>', '<vector>', '<cassert>', '<optional>', '<string>']
return ['<stdint.h>', '<stddef.h>', '<array>', '<vector>', '<cassert>', '<optional>', '<string>']

class FriggTraits:
def needs_allocator(self):
Expand All @@ -24,14 +26,16 @@ 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):
return 'frg::string'
def assert_func(self):
return 'FRG_ASSERT'
def includes(self):
return ['<stdint.h>', '<stddef.h>', '<frg/vector.hpp>', '<frg/macros.hpp>', '<frg/optional.hpp>', '<frg/string.hpp>']
return ['<stdint.h>', '<stddef.h>', '<array>', '<frg/vector.hpp>', '<frg/macros.hpp>', '<frg/optional.hpp>', '<frg/string.hpp>']

flatten = lambda l: [item for sublist in l for item in sublist]

Expand Down Expand Up @@ -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()

Expand All @@ -201,7 +208,10 @@ def generate_type(self, t):
elif t.identity is TypeIdentity.STRING:
return f'{self.stdlib_traits.string()}{"<Allocator>" 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}{"<Allocator>" if self.stdlib_traits.needs_allocator() else ""}'
else:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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

Expand Down
83 changes: 42 additions & 41 deletions tests/arrays/arrays.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <array>
#include <iostream>

#include "../test-util.hpp"
Expand Down Expand Up @@ -30,7 +31,8 @@ void test1() {

void test2() {
auto t1 = test::make_msg<Test2>();
t1.set_arr(test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF));
auto arr = std::array<uint8_t, 5>{0xDE, 0xAD, 0xBE, 0xEF};
t1.set_arr(arr);

assert(bragi::message_id<Test2> == 2);
assert(bragi::head_size<Test2> == 128);
Expand All @@ -42,7 +44,6 @@ void test2() {
auto t2 = test::parse_with<Test2>(head_buf);
assert(t2);

auto arr = test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF, 0);
assert(t2->arr() == arr);
}

Expand Down Expand Up @@ -77,17 +78,17 @@ void test3() {
void test4() {
auto t1 = test::make_msg<Test4>();

t1.set_arr1(test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5)
t1.set_arr1(test::make_vector<std::array<uint8_t, 5>>(
std::array<uint8_t, 5>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 5>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 5>{0xB1, 0x6B, 0x00, 0xB5}
));

t1.set_arr2(test::make_vector<test::vec_of<uint8_t>>(
t1.set_arr2(std::array<test::vec_of<uint8_t>, 5>{
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5)
));
});

assert(bragi::message_id<Test4> == 4);
assert(bragi::head_size<Test4> == 128);
Expand All @@ -99,19 +100,19 @@ void test4() {
auto t2 = test::parse_with<Test4>(head_buf);
assert(t2);

auto arr1 = test::make_vector<test::vec_of<uint8_t>>(
auto arr1 = test::make_vector<std::array<uint8_t, 5>>(
std::array<uint8_t, 5>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 5>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 5>{0xB1, 0x6B, 0x00, 0xB5},
std::array<uint8_t, 5>{},
std::array<uint8_t, 5>{}
);

auto arr2 = std::array<test::vec_of<uint8_t>, 5>{
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF, 0),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE, 0),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5, 0)
);

auto arr2 = test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5),
test::make_vector<uint8_t>(),
test::make_vector<uint8_t>()
);
};

assert(t2->arr1() == arr1);
assert(t2->arr2() == arr2);
Expand All @@ -120,11 +121,11 @@ void test4() {
void test5_1() {
auto t1 = test::make_msg<Test5>();

t1.set_arr(test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5)
));
t1.set_arr(std::array<std::array<uint8_t, 4>, 4>{
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 4>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 4>{0xB1, 0x6B, 0x00, 0xB5}
});

assert(bragi::message_id<Test5> == 5);
assert(bragi::head_size<Test5> == 128);
Expand All @@ -136,25 +137,25 @@ void test5_1() {
auto t2 = test::parse_with<Test5>(head_buf);
assert(t2);

auto arr = test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5),
test::make_vector<uint8_t>(0, 0, 0, 0)
);
auto arr = std::array<std::array<uint8_t, 4>, 4>{
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 4>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 4>{0xB1, 0x6B, 0x00, 0xB5},
std::array<uint8_t, 4>{0, 0, 0, 0},
};

assert(t2->arr() == arr);
}

void test5_2() {
auto t1 = test::make_msg<Test5>();

t1.set_arr(test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5),
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF)
));
t1.set_arr(std::array<std::array<uint8_t, 4>, 4>{
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 4>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 4>{0xB1, 0x6B, 0x00, 0xB5},
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF}
});

assert(bragi::message_id<Test5> == 5);
assert(bragi::head_size<Test5> == 128);
Expand All @@ -166,12 +167,12 @@ void test5_2() {
auto t2 = test::parse_with<Test5>(head_buf);
assert(t2);

auto arr = test::make_vector<test::vec_of<uint8_t>>(
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF),
test::make_vector<uint8_t>(0xCA, 0xFE, 0xBA, 0xBE),
test::make_vector<uint8_t>(0xB1, 0x6B, 0x00, 0xB5),
test::make_vector<uint8_t>(0xDE, 0xAD, 0xBE, 0xEF)
);
auto arr = std::array<std::array<uint8_t, 4>, 4>{
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF},
std::array<uint8_t, 4>{0xCA, 0xFE, 0xBA, 0xBE},
std::array<uint8_t, 4>{0xB1, 0x6B, 0x00, 0xB5},
std::array<uint8_t, 4>{0xDE, 0xAD, 0xBE, 0xEF}
};

assert(t2->arr() == arr);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/enums/enums.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int main() {
t1.set_bar(Bar::E);

t1.set_foos(test::make_vector<Foo>(Foo::D, Foo::A, Foo::F, Foo::B));
t1.set_bars(test::make_vector<uint8_t>(Bar::E, Bar::B, Bar::A, Bar::C));
t1.set_bars(std::array<uint8_t, 4>{Bar::E, Bar::B, Bar::A, Bar::C});

assert(bragi::message_id<Test> == 1);
assert(bragi::head_size<Test> == 128);
Expand Down Expand Up @@ -48,6 +48,6 @@ int main() {
auto foos = test::make_vector<Foo>(Foo::D, Foo::A, Foo::F, Foo::B);
assert(t2->foos() == foos);

auto bars = test::make_vector<uint8_t>(Bar::E, Bar::B, Bar::A, Bar::C);
auto bars = std::array<uint8_t, 4>{Bar::E, Bar::B, Bar::A, Bar::C};
assert(t2->bars() == bars);
}

0 comments on commit d4a8e63

Please sign in to comment.