Add Value::clear()

This commit is contained in:
Michael Davidsaver
2022-11-17 12:27:48 -08:00
parent bdcbf130d2
commit 53f83b6429
3 changed files with 79 additions and 1 deletions
+35
View File
@@ -175,6 +175,41 @@ Value Value::allocMember()
return Value::Helper::build(fld, *this); 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 bool Value::isMarked(bool parents, bool children) const
{ {
if(!desc) if(!desc)
+9
View File
@@ -550,6 +550,15 @@ public:
//! Use to allocate members for an array of Struct and array of Union //! Use to allocate members for an array of Struct and array of Union
Value allocMember(); 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 //! Does this Value actually reference some underlying storage
inline bool valid() const { return desc; } inline bool valid() const { return desc; }
inline explicit operator bool() const { return desc; } inline explicit operator bool() const { return desc; }
+35 -1
View File
@@ -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 } // namespace
MAIN(testdata) MAIN(testdata)
{ {
testPlan(116); testPlan(127);
testSetup(); testSetup();
testTraverse(); testTraverse();
testAssign(); testAssign();
@@ -390,6 +423,7 @@ MAIN(testdata)
testAssignSimilar(); testAssignSimilar();
testExtract(); testExtract();
testClear();
cleanup_for_valgrind(); cleanup_for_valgrind();
return testDone(); return testDone();
} }