allow Union deref w/o field name
This commit is contained in:
+12
-2
@@ -715,7 +715,7 @@ void Value::traverse(const std::string &expr, bool modify, bool dothrow)
|
||||
|
||||
maybedot = false;
|
||||
|
||||
if(expr.size()-pos >= 3 && expr[pos]=='-' && expr[pos+1]=='>') {
|
||||
if(expr.size()-pos >= 2 && expr[pos]=='-' && expr[pos+1]=='>') {
|
||||
pos += 2; // skip past "->"
|
||||
|
||||
if(desc->code.code==TypeCode::Any) {
|
||||
@@ -727,10 +727,10 @@ void Value::traverse(const std::string &expr, bool modify, bool dothrow)
|
||||
size_t sep = expr.find_first_of("<[-.", pos);
|
||||
|
||||
decltype (desc->mlookup)::const_iterator it;
|
||||
auto& fld = store->as<Value>();
|
||||
|
||||
if(sep>0 && (it=desc->mlookup.find(expr.substr(pos, sep-pos)))!=desc->mlookup.end()) {
|
||||
// found it.
|
||||
auto& fld = store->as<Value>();
|
||||
|
||||
if(modify || fld.desc==&desc->members[it->second]) {
|
||||
// will select, or already selected
|
||||
@@ -750,6 +750,16 @@ void Value::traverse(const std::string &expr, bool modify, bool dothrow)
|
||||
if(dothrow)
|
||||
throw LookupError(SB()<<"traversing const Value, can't select Union in '"<<expr<<"'");
|
||||
}
|
||||
|
||||
} else if(fld.desc) {
|
||||
// deref selected
|
||||
*this = fld;
|
||||
|
||||
} else {
|
||||
store.reset();
|
||||
desc = nullptr;
|
||||
if(dothrow)
|
||||
throw LookupError(SB()<<"can't deref. empty Union '"<<expr<<"'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
+25
-1
@@ -67,6 +67,29 @@ void testAssign()
|
||||
testOk1(!val["alarm"].isMarked(true, false));
|
||||
}
|
||||
|
||||
void testAssignUnion()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
|
||||
auto val = TypeDef(TypeCode::Union, {
|
||||
members::UInt16("u16"),
|
||||
members::String("s"),
|
||||
}).create();
|
||||
|
||||
val["->u16"] = 42;
|
||||
testEq(val.as<std::string>(), "42");
|
||||
val["->s"] = "test";
|
||||
testEq(val.as<std::string>(), "test");
|
||||
|
||||
testEq(val.nameOf(val["->"]), "s");
|
||||
|
||||
testThrows<std::invalid_argument>([&val](){
|
||||
val["->u16"] = "hello";
|
||||
});
|
||||
|
||||
//val = nullptr;
|
||||
}
|
||||
|
||||
void testName()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
@@ -314,10 +337,11 @@ void testAssignSimilar()
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(93);
|
||||
testPlan(97);
|
||||
testSetup();
|
||||
testTraverse();
|
||||
testAssign();
|
||||
testAssignUnion();
|
||||
testName();
|
||||
testIterStruct();
|
||||
testIterUnion();
|
||||
|
||||
Reference in New Issue
Block a user