mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
CaptureKeys: Add support for std::map and std::unordered_map
This commit is contained in:
parent
4afa2ff190
commit
5572e294f7
264
test/integration/capture_keys.toml
Normal file
264
test/integration/capture_keys.toml
Normal file
@ -0,0 +1,264 @@
|
||||
# This file contains tests for core key-capture features at the top, followed
|
||||
# by basic tests for each container type which supports key capture.
|
||||
|
||||
includes = ["map"]
|
||||
definitions = '''
|
||||
struct MapHolder {
|
||||
std::map<int, int> captureMyKeys;
|
||||
std::map<int, int> dontCaptureKeysHere;
|
||||
};
|
||||
|
||||
enum class MyEnum {
|
||||
One = 1,
|
||||
Two = 2,
|
||||
Three = 3,
|
||||
};
|
||||
'''
|
||||
[cases]
|
||||
[cases.int]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const std::map<int, int>&"]
|
||||
setup = "return {{{1,2},{3,4}}};"
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
top_level = true
|
||||
'''
|
||||
expect_json_v2 = '''[{
|
||||
"name": "a0",
|
||||
"typePath": ["a0"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 1,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 3,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]'''
|
||||
|
||||
[cases.string]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const std::map<std::string, int>&"]
|
||||
setup = '''return
|
||||
{{
|
||||
{"abc", 1},
|
||||
{"hohoho", 2}
|
||||
}};'''
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
top_level = true
|
||||
'''
|
||||
expect_json_v2 = '''[{
|
||||
"name": "a0",
|
||||
"typePath": ["a0"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": "abc",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": "hohoho",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]'''
|
||||
|
||||
[cases.enum]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const std::map<MyEnum, int>&"]
|
||||
setup = "return {{{MyEnum::One,2},{MyEnum::Three,4}}};"
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
top_level = true
|
||||
'''
|
||||
expect_json_v2 = '''[{
|
||||
"name": "a0",
|
||||
"typePath": ["a0"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 1,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 3,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]'''
|
||||
|
||||
[cases.multi_level]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const std::map<int, std::map<std::string, std::vector<int>>>&"]
|
||||
setup = '''return
|
||||
{{
|
||||
{123, {
|
||||
{"haha", {1,2}}
|
||||
}},
|
||||
{456, {
|
||||
{"uh oh", {3}},
|
||||
{"spaghettio", {4,5,6}}
|
||||
}}
|
||||
}};'''
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
top_level = true
|
||||
'''
|
||||
expect_json_v2 = '''[{
|
||||
"name": "a0",
|
||||
"typePath": ["a0"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 123,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{
|
||||
"name": "value",
|
||||
"typePath": ["a0","[]","value"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]","value","[]"],
|
||||
"NOT":"data",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","value","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]"],
|
||||
"data": 456,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","key"]},
|
||||
{
|
||||
"name": "value",
|
||||
"typePath": ["a0","[]","value"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]","value","[]"],
|
||||
"NOT":"data",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","value","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value","[]","value"]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","[]","value","[]"],
|
||||
"NOT":"data",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","[]","value","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","[]","value","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]'''
|
||||
|
||||
[cases.config]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const MapHolder&"]
|
||||
setup = '''return {MapHolder{
|
||||
.captureMyKeys{ {1,2},{3,4} },
|
||||
.dontCaptureKeysHere{ {5,6} },
|
||||
}};'''
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
type = "MapHolder"
|
||||
members = ["captureMyKeys"]
|
||||
'''
|
||||
expect_json_v2 = '''[{
|
||||
"members": [
|
||||
{
|
||||
"name": "captureMyKeys",
|
||||
"typePath": ["a0","captureMyKeys"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","captureMyKeys","[]"],
|
||||
"data": 1,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","captureMyKeys","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","captureMyKeys","[]","value"]}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","captureMyKeys","[]"],
|
||||
"data": 3,
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","captureMyKeys","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","captureMyKeys","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dontCaptureKeysHere",
|
||||
"typePath": ["a0","dontCaptureKeysHere"],
|
||||
"members": [
|
||||
{
|
||||
"name": "[]",
|
||||
"typePath": ["a0","dontCaptureKeysHere","[]"],
|
||||
"NOT":"data",
|
||||
"members": [
|
||||
{"name": "key", "typePath": ["a0","dontCaptureKeysHere","[]","key"]},
|
||||
{"name": "value", "typePath": ["a0","dontCaptureKeysHere","[]","value"]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]'''
|
||||
|
||||
[cases.std_unordered_map]
|
||||
oid_skip = "Requires TreeBuilderV2"
|
||||
param_types = ["const std::unordered_map<int, int>&"]
|
||||
setup = "return {{{1,2}}};"
|
||||
config_suffix = '''
|
||||
[[codegen.capture_keys]]
|
||||
top_level = true
|
||||
'''
|
||||
expect_json_v2 = '[{"members": [{"data": 1}]}]'
|
@ -76,7 +76,8 @@ auto tail = returnArg
|
||||
|
||||
for (const auto &entry: container) {
|
||||
tail = tail.delegate([&key = entry.first, &value = entry.second](auto ret) {
|
||||
auto next = ret.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
|
||||
auto start = maybeCaptureKey<captureKeys, DB, T0>(key, ret);
|
||||
auto next = start.delegate([&key](typename TypeHandler<DB, T0>::type ret) {
|
||||
return OIInternal::getSizeType<DB>(key, ret);
|
||||
});
|
||||
return OIInternal::getSizeType<DB>(value, next);
|
||||
@ -92,9 +93,18 @@ func = "el.pointer = std::get<ParsedData::VarInt>(d.val).value;"
|
||||
|
||||
[[codegen.processor]]
|
||||
type = """
|
||||
types::st::List<DB, types::st::Pair<DB,
|
||||
std::conditional_t<captureKeys,
|
||||
types::st::List<DB,
|
||||
types::st::Pair<DB,
|
||||
typename CaptureKeyHandler<DB, T0>::type,
|
||||
types::st::Pair<DB,
|
||||
typename TypeHandler<DB, T0>::type,
|
||||
typename TypeHandler<DB, T1>::type>>>,
|
||||
types::st::List<DB,
|
||||
types::st::Pair<DB,
|
||||
typename TypeHandler<DB, T0>::type,
|
||||
typename TypeHandler<DB, T1>::type>>
|
||||
>
|
||||
"""
|
||||
func = """
|
||||
#ifdef __GLIBCXX__
|
||||
@ -147,13 +157,16 @@ static constexpr std::array<inst::Field, 2> element_fields{
|
||||
make_field<DB, T0>("key"),
|
||||
make_field<DB, T1>("value"),
|
||||
};
|
||||
|
||||
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, DB, T0>();
|
||||
|
||||
static constexpr inst::Field element{
|
||||
element_size,
|
||||
element_size - sizeof(T0) - sizeof(T1),
|
||||
"[]",
|
||||
std::array<std::string_view, 0>{},
|
||||
element_fields,
|
||||
std::array<inst::ProcessorInst, 0>{},
|
||||
processors,
|
||||
};
|
||||
|
||||
auto list = std::get<ParsedData::List>(d.val);
|
||||
|
@ -81,9 +81,13 @@ auto tail = returnArg
|
||||
.write(container.bucket_count())
|
||||
.write(container.size());
|
||||
|
||||
for (const auto &it : container) {
|
||||
tail = tail.delegate([&it](auto ret) {
|
||||
return OIInternal::getSizeType<DB>(it, ret);
|
||||
for (const auto& kv : container) {
|
||||
tail = tail.delegate([&kv](auto ret) {
|
||||
auto start = maybeCaptureKey<captureKeys, DB, T0>(kv.first, ret);
|
||||
auto next = start.delegate([&kv](typename TypeHandler<DB, T0>::type ret) {
|
||||
return OIInternal::getSizeType<DB>(kv.first, ret);
|
||||
});
|
||||
return OIInternal::getSizeType<DB>(kv.second, next);
|
||||
});
|
||||
}
|
||||
|
||||
@ -108,9 +112,17 @@ el.container_stats.emplace(result::Element::ContainerStats {
|
||||
|
||||
[[codegen.processor]]
|
||||
type = """
|
||||
std::conditional_t<captureKeys,
|
||||
types::st::List<DB,
|
||||
types::st::Pair<DB,
|
||||
typename CaptureKeyHandler<DB, T0>::type,
|
||||
types::st::Pair<DB,
|
||||
typename TypeHandler<DB, T0>::type,
|
||||
typename TypeHandler<DB, T1>::type>>>,
|
||||
types::st::List<DB, types::st::Pair<DB,
|
||||
typename TypeHandler<DB, T0>::type,
|
||||
typename TypeHandler<DB, T1>::type>>
|
||||
>
|
||||
"""
|
||||
func = """
|
||||
#ifdef __GLIBCXX__
|
||||
@ -150,13 +162,15 @@ static constexpr std::array<inst::Field, 2> element_fields{
|
||||
make_field<DB, T1>("value"),
|
||||
};
|
||||
|
||||
static constexpr auto processors = maybeCaptureKeysProcessor<captureKeys, DB, T0>();
|
||||
|
||||
static constexpr auto element = inst::Field{
|
||||
element_size,
|
||||
element_size - sizeof(T0) - sizeof(T1),
|
||||
"[]",
|
||||
std::array<std::string_view, 0>{},
|
||||
element_fields,
|
||||
std::array<inst::ProcessorInst, 0>{},
|
||||
processors,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < list.length; i++)
|
||||
|
Loading…
Reference in New Issue
Block a user