Add Value::clear()
This commit is contained in:
@@ -175,6 +175,41 @@ Value Value::allocMember()
|
||||
return Value::Helper::build(fld, *this);
|
||||
}
|
||||
|
||||
void Value::clear()
|
||||
{
|
||||
if(!desc)
|
||||
return;
|
||||
|
||||
for(auto i : range(size_t(0u), desc->size())) {
|
||||
auto& s = store.get()[i];
|
||||
s.valid = false;
|
||||
|
||||
switch(s.code) {
|
||||
case StoreType::Array:
|
||||
s.as<shared_array<const void>>().clear();
|
||||
break;
|
||||
case StoreType::Compound:
|
||||
{
|
||||
auto& v = s.as<Value>();
|
||||
v.desc = nullptr;
|
||||
v.store.reset();
|
||||
}
|
||||
break;
|
||||
case StoreType::String:
|
||||
s.as<std::string>().clear();
|
||||
break;
|
||||
case StoreType::Null:
|
||||
break; // nothing to do
|
||||
case StoreType::Bool:
|
||||
case StoreType::UInteger:
|
||||
case StoreType::Integer:
|
||||
case StoreType::Real:
|
||||
memset(&s.store, 0, sizeof(s.store)); // just zero
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Value::isMarked(bool parents, bool children) const
|
||||
{
|
||||
if(!desc)
|
||||
|
||||
@@ -550,6 +550,15 @@ public:
|
||||
//! Use to allocate members for an array of Struct and array of Union
|
||||
Value allocMember();
|
||||
|
||||
/** Restore to newly allocated state.
|
||||
*
|
||||
* Free any allocation for array or string values, zero numeric values.
|
||||
* unmark() all fields.
|
||||
*
|
||||
* @since UNRELEASED
|
||||
*/
|
||||
void clear();
|
||||
|
||||
//! Does this Value actually reference some underlying storage
|
||||
inline bool valid() const { return desc; }
|
||||
inline explicit operator bool() const { return desc; }
|
||||
|
||||
+35
-1
@@ -342,11 +342,44 @@ void testExtract()
|
||||
}
|
||||
}
|
||||
|
||||
void testClear()
|
||||
{
|
||||
testShow()<<__func__;
|
||||
|
||||
auto val = TypeDef(TypeCode::Struct, {
|
||||
members::UInt32("int"),
|
||||
members::String("string"),
|
||||
members::UInt32A("arr"),
|
||||
members::Any("any"),
|
||||
}).create();
|
||||
|
||||
val["int"] = 0x12345678;
|
||||
val["string"] = "testing";
|
||||
val["arr"] = shared_array<const uint32_t>({1,2,3});
|
||||
val["any"].assign(nt::NTScalar{TypeCode::UInt32}.create());
|
||||
val["any->value"] = 0x01020304;
|
||||
|
||||
testEq(val["int"].as<uint32_t>(), 0x12345678u);
|
||||
testEq(val["string"].as<std::string>(), std::string("testing"));
|
||||
testEq(val["arr"].as<shared_array<const void>>().size(), 3u);
|
||||
testTrue(!!val["any->"]);
|
||||
testEq(val["any->value"].as<uint32_t>(), 0x01020304u);
|
||||
testTrue(val.isMarked(true, true));
|
||||
|
||||
val.clear();
|
||||
|
||||
testEq(val["int"].as<uint32_t>(), 0u);
|
||||
testEq(val["string"].as<std::string>(), std::string(""));
|
||||
testEq(val["arr"].as<shared_array<const void>>().size(), 0u);
|
||||
testFalse(val["any->"]);
|
||||
testFalse(val.isMarked(true, true));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(116);
|
||||
testPlan(127);
|
||||
testSetup();
|
||||
testTraverse();
|
||||
testAssign();
|
||||
@@ -390,6 +423,7 @@ MAIN(testdata)
|
||||
|
||||
testAssignSimilar();
|
||||
testExtract();
|
||||
testClear();
|
||||
cleanup_for_valgrind();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user