From 30b0dfc76ef1d1b67ef22ab972b061b6ab4458b0 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Fri, 9 Jan 2026 11:29:00 +0100 Subject: [PATCH] MT#64120 AmArg: add a possibility to operate on shared ptr Instead of using borrowed raw pointers (which is a big risk when there are multiple users of the container) give a possibility to operate on the AmObject as a shared pointer, which at least ensures that the object won't be gone if there are still some users. In the next improvements the raw pointers usage for `AmDynInvoke*` and `AmObject*` will be deprecated and both of them will be replaced with shared pointers, accordingly callers refactoring is required. Change-Id: I576b0eca22f01b41473b0551b940452dc2515e19 --- core/AmArg.cpp | 7 +++++++ core/AmArg.h | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/core/AmArg.cpp b/core/AmArg.cpp index 1641b760..af9f15c7 100644 --- a/core/AmArg.cpp +++ b/core/AmArg.cpp @@ -29,6 +29,8 @@ #include "log.h" #include "AmUtils.h" +using std::shared_ptr; + const char* AmArg::t2str(int type) { switch (type) { case AmArg::Undef: return "Undef"; @@ -38,6 +40,7 @@ const char* AmArg::t2str(int type) { case AmArg::Double: return "Double"; case AmArg::CStr: return "CStr"; case AmArg::AObject: return "AObject"; + case AmArg::AObjectShared: return "AObjectShared"; case AmArg::ADynInv: return "ADynInv"; case AmArg::Blob: return "Blob"; case AmArg::Array: return "Array"; @@ -336,6 +339,7 @@ void AmArg::assertArrayFmt(const char* format) const { case 'f': assertArgDouble(get(i)); got+='f'; break; case 's': assertArgCStr(get(i)); got+='s'; break; case 'o': assertArgAObject(get(i)); got+='o'; break; + case 'h': assertArgAObjectShared(get(i)); got+='h'; break; case 'd': assertArgADynInv(get(i)); got+='d'; break; case 'a': assertArgArray(get(i)); got+='a'; break; case 'b': assertArgBlob(get(i)); got+='b'; break; @@ -363,6 +367,7 @@ VECTOR_GETTER(int, asIntVector, asInt) VECTOR_GETTER(bool, asBoolVector, asBool) VECTOR_GETTER(double, asDoubleVector, asDouble) VECTOR_GETTER(AmObject*, asAmObjectVector, asObject) +VECTOR_GETTER(shared_ptr, asAmObjectSharedVector, asSharedObject) #undef VECTOR_GETTER vector AmArg::asArgBlobVector() const { @@ -393,6 +398,8 @@ string AmArg::print(const AmArg &a) { return "'" + string(a.asCStr()) + "'"; case AObject: return ""; + case AObjectShared: + return ""; case ADynInv: return ""; case Blob: diff --git a/core/AmArg.h b/core/AmArg.h index f73acea3..968ccf67 100644 --- a/core/AmArg.h +++ b/core/AmArg.h @@ -38,6 +38,9 @@ using std::vector; #include using std::string; +#include +using std::shared_ptr; + #include #include @@ -84,6 +87,7 @@ class AmArg : public AmObject { public: + // type enum enum { Undef=0, @@ -97,6 +101,8 @@ class AmArg ADynInv, // pointer to a AmDynInvoke (useful for call backs) Blob, + AObjectShared, + Array, Struct }; @@ -117,7 +123,7 @@ class AmArg short type; // value - std::variant, AmDynInvoke*, ArgBlob, ValueArray, ValueStruct> value; void invalidate(); @@ -181,6 +187,11 @@ class AmArg value(v) { } + AmArg(std::shared_ptr v) + : type(AObjectShared), + value(std::move(v)) + {} + // convenience constructors AmArg(vector& v); AmArg(const vector& v ); @@ -210,6 +221,7 @@ class AmArg #define isArgBool(a) (AmArg::Bool == a.getType()) #define isArgCStr(a) (AmArg::CStr == a.getType()) #define isArgAObject(a) (AmArg::AObject == a.getType()) +#define isArgAObjectShared(a) (AmArg::AObjectShared == a.getType()) #define isArgADynInv(a) (AmArg::ADynInv == a.getType()) #define isArgBlob(a) (AmArg::Blob == a.getType()) @@ -240,6 +252,9 @@ class AmArg #define assertArgAObject(a) \ if (!isArgAObject(a)) \ _THROW_TYPE_MISMATCH(AObject,a); +#define assertArgAObjectShared(a) \ + if (!isArgAObjectShared(a)) \ + _THROW_TYPE_MISMATCH(AObjectShared,a); #define assertArgADynInv(a) \ if (!isArgADynInv(a)) \ _THROW_TYPE_MISMATCH(ADynInv,a); @@ -262,17 +277,45 @@ class AmArg bool asBool() const { return std::get(value); } double asDouble() const { return std::get(value); } const char* asCStr() const { return std::get(value).c_str(); } - AmObject* asObject() const { return std::get(value); } AmDynInvoke* asDynInv() const { return std::get(value); } const ArgBlob& asBlob() const { return std::get(value); } const ValueStruct& asStruct() const { return std::get(value); } ValueStruct& asStruct() { return std::get(value); } + /* shared object compatible implementation */ + AmObject* asObject() const { + if (type == AObjectShared) + return std::get>(value).get(); + if (type == AObject) + return std::get(value); + + return nullptr; + } + /* safe accessor for shared AmObject */ + shared_ptr asSharedObject() const { + if (type == AObjectShared) + return std::get>(value); + + return nullptr; /* borrowed pointers cannot be promoted safely */ + } + /* just a helper for all future objects moved to the shared pointer */ + template + shared_ptr asShared() const { + if (type == AObjectShared) { + return std::dynamic_pointer_cast( + std::get>(value) + ); + } + + return nullptr; + } + vector asStringVector() const; vector asIntVector() const; vector asBoolVector() const; vector asDoubleVector() const; vector asAmObjectVector() const; + vector> asAmObjectSharedVector() const; vector asArgBlobVector() const; // operations on arrays