[consider merging] proper cleanup of properties repo - this enables using user classes for names or values. Without this pre-finalization cleanup, the user class 'destroy' method may end up calling a method of an already destroyed class object.

This commit is contained in:
Matthias Koefferlein 2026-02-21 20:44:02 +01:00
parent bc49082955
commit c14d8cc877
2 changed files with 27 additions and 2 deletions

View File

@ -27,6 +27,7 @@
#include "tlString.h"
#include "tlAssert.h"
#include "tlHash.h"
#include "tlStaticObjects.h"
namespace db
{
@ -348,13 +349,21 @@ PropertiesSet::hash () const
// ----------------------------------------------------------------------------------
// PropertiesRepository implementation
static PropertiesRepository s_instance;
static PropertiesRepository *sp_global_instance = 0;
static PropertiesRepository *sp_temp_instance = 0;
PropertiesRepository &
PropertiesRepository::instance ()
{
return sp_temp_instance ? *sp_temp_instance : s_instance;
if (sp_temp_instance) {
return *sp_temp_instance;
} else {
if (! sp_global_instance) {
sp_global_instance = new PropertiesRepository ();
tl::StaticObjects::reg (&sp_global_instance);
}
return *sp_global_instance;
}
}
void

View File

@ -503,3 +503,19 @@ TEST(SameValueDifferentTypes)
EXPECT_EQ (db::property_name (rp.prop_name_id ((int) 5)).to_parsable_string (), "#5");
}
}
TEST(ComplexTypes)
{
// This is also a smoke test: we intentionally register globally as the finalization code
// is critical: without the right destruction order we destroy the class object before the
// variant and trigger an assertion (pure virtual function called)
db::PropertiesSet ps;
ps.insert (tl::Variant (17), db::DBox (0, 0, 1.5, 2.5));
db::properties_id_type pid = db::properties_id (ps);
auto const &ps_out = db::properties (pid);
EXPECT_EQ (ps_out.to_dict_var ().to_string (), "{17=>(0,0;1.5,2.5)}");
}