diff --git a/dev.oid.toml b/dev.oid.toml index 709b6b8..7bc40d8 100644 --- a/dev.oid.toml +++ b/dev.oid.toml @@ -39,6 +39,7 @@ containers = [ "PWD/types/f14_vector_map.toml", "PWD/types/f14_fast_set.toml", "PWD/types/f14_node_set.toml", + "PWD/types/f14_value_set.toml", "PWD/types/f14_vector_set.toml", "PWD/types/sorted_vec_set_type.toml", "PWD/types/map_seq_type.toml", diff --git a/test/ci.oid.toml b/test/ci.oid.toml index a3eea01..978a17b 100644 --- a/test/ci.oid.toml +++ b/test/ci.oid.toml @@ -35,6 +35,7 @@ containers = [ "../types/f14_vector_map.toml", "../types/f14_fast_set.toml", "../types/f14_node_set.toml", + "../types/f14_value_set.toml", "../types/f14_vector_set.toml", "../types/sorted_vec_set_type.toml", "../types/map_seq_type.toml", diff --git a/test/integration/folly_f14_value_set.toml b/test/integration/folly_f14_value_set.toml new file mode 100644 index 0000000..93cda81 --- /dev/null +++ b/test/integration/folly_f14_value_set.toml @@ -0,0 +1,83 @@ +includes = ["folly/container/F14Set.h"] +definitions = ''' + struct Bar { + float a, b; + }; + + inline bool operator==(const Bar &lhs, const Bar &rhs) noexcept { + return lhs.a == rhs.a && lhs.b == rhs.b; + } + + struct BarHasher { + inline size_t operator()(const Bar &bar) const { + return folly::hash::hash_combine(bar.a, bar.b); + } + }; + + struct Foo { + folly::F14ValueSet m1; + folly::F14ValueSet m2; + folly::F14ValueSet m3; + folly::F14ValueSet m4; + }; +''' + +[cases] + [cases.a] + param_types = ["const Foo&"] + setup = ''' + Foo foo; + + foo.m1.reserve(3); + for (int i = 0; i < 3; i++) { + foo.m1.emplace(i); + } + + foo.m2.reserve(5); + for (int i = 0; i < 5; i++) { + foo.m2.emplace(Bar{(float)i, 0.0f}); + } + + foo.m3.reserve(7); + for (int i = 0; i < 7; i++) { + foo.m3.emplace(i); + } + + foo.m4.reserve(9); + for (int i = 0; i < 9; i++) { + foo.m4.emplace(i); + } + + return {foo}; + ''' + expect_json = '''[{ + "staticSize":96, + "dynamicSize":208, + "members":[ + {"name":"m1", "staticSize":24, "dynamicSize":32, "length":3, "capacity":3, "elementStaticSize":4}, + { + "name":"m2", + "staticSize":24, + "dynamicSize":64, + "length":5, + "capacity":5, + "elementStaticSize":8, + "members":[ + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]}, + {"staticSize":8, "members":[{"name":"a"}, {"name": "b"}]} + ]}, + {"name":"m3", "staticSize":24, "dynamicSize":48, "length":7, "capacity":7, "elementStaticSize":4}, + {"name":"m4", "staticSize":24, "dynamicSize":64, "length":9, "capacity":9, "elementStaticSize":4} + ]}]''' + expect_json_v2 = '''[{ + "staticSize":96, + "exclusiveSize": 0, + "members":[ + {"name":"m1", "staticSize":24, "exclusiveSize": 24, "length": 3, "capacity": 3}, + {"name":"m2", "staticSize":24, "exclusiveSize": 24, "length": 5, "capacity": 5}, + {"name":"m3", "staticSize":24, "exclusiveSize": 24, "length": 7, "capacity": 7}, + {"name":"m4", "staticSize":24, "exclusiveSize": 24, "length": 9, "capacity": 9} + ]}]''' diff --git a/types/f14_value_set.toml b/types/f14_value_set.toml new file mode 100644 index 0000000..f5c07e6 --- /dev/null +++ b/types/f14_value_set.toml @@ -0,0 +1,103 @@ +[info] +type_name = "folly::F14ValueSet" +stub_template_params = [1,2,3] +ctype = "F14_SET" +header = "folly/container/F14Set.h" + +# Old: +typeName = "folly::F14ValueSet<" +ns = ["folly::F14ValueSet"] +numTemplateParams = 1 +replaceTemplateParamIndex = [1, 2] +allocatorIndex = 3 + +[codegen] +decl = """ +template +void getSizeType(const %1% &container, size_t& returnArg); +""" + +func = """ +template +void getSizeType(const %1% &container, size_t& returnArg) +{ + size_t memorySize = container.getAllocatedMemorySize(); + SAVE_SIZE(sizeof(%1%) + memorySize); + + SAVE_DATA(memorySize); + SAVE_DATA(container.bucket_count()); + SAVE_DATA(container.size()); + + // The double ampersand is needed otherwise this loop doesn't work with vector + for (auto&& it: container) { + getSizeType(it, returnArg); + } +} +""" + +handler = """ +template +struct TypeHandler> { + using type = types::st::Pair, + types::st::Pair, + types::st::List::type>>>; + + static types::st::Unit getSizeType( + const %1%& container, + typename TypeHandler>::type returnArg) { + size_t memorySize = container.getAllocatedMemorySize(); + auto tail = returnArg + .write(memorySize) + .write(container.bucket_count()) + .write(container.size()); + + for (auto &&entry: container) { + tail = tail.delegate([&entry](auto ret) { + return OIInternal::getSizeType(entry, ret); + }); + } + + return tail.finish(); + } +}; +""" + +traversal_func = """ +// TODO: This implementation enables the traversal of the container, +// but doesn't report the memory footprint accurately. +// Revisit this implementation and fix memory footprint reporting. +auto tail = returnArg + .write((uintptr_t)&container) + .write(container.size()); + +for (auto &&entry: container) { + tail = tail.delegate([&entry](auto ret) { + return OIInternal::getSizeType(entry, ret); + }); +} + +return tail.finish(); +""" + +[[codegen.processor]] +type = "types::st::VarInt" +func = "el.pointer = std::get(d.val).value;" + +[[codegen.processor]] +type = """ +types::st::List::type> +""" +func = """ +auto list = std::get(d.val); +el.container_stats.emplace(result::Element::ContainerStats { + .capacity = list.length, + .length = list.length, +}); + +static constexpr auto childField = make_field("[]"); +for (size_t i = 0; i < list.length; i++) + ins.emplace(childField); +"""