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
mr14.1
Donat Zenichev 7 months ago
parent 526e092915
commit 30b0dfc76e

@ -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<AmObject>, asAmObjectSharedVector, asSharedObject)
#undef VECTOR_GETTER
vector<ArgBlob> AmArg::asArgBlobVector() const {
@ -393,6 +398,8 @@ string AmArg::print(const AmArg &a) {
return "'" + string(a.asCStr()) + "'";
case AObject:
return "<Object>";
case AObjectShared:
return "<ObjectShared>";
case ADynInv:
return "<DynInv>";
case Blob:

@ -38,6 +38,9 @@ using std::vector;
#include <string>
using std::string;
#include <memory>
using std::shared_ptr;
#include <map>
#include <variant>
@ -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<std::monostate, long int, long long int, bool, double, std::string, AmObject*,
std::variant<std::monostate, long int, long long int, bool, double, std::string, AmObject*, shared_ptr<AmObject>,
AmDynInvoke*, ArgBlob, ValueArray, ValueStruct> value;
void invalidate();
@ -181,6 +187,11 @@ class AmArg
value(v)
{ }
AmArg(std::shared_ptr<AmObject> v)
: type(AObjectShared),
value(std::move(v))
{}
// convenience constructors
AmArg(vector<std::string>& v);
AmArg(const vector<int>& 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<bool>(value); }
double asDouble() const { return std::get<double>(value); }
const char* asCStr() const { return std::get<std::string>(value).c_str(); }
AmObject* asObject() const { return std::get<AmObject*>(value); }
AmDynInvoke* asDynInv() const { return std::get<AmDynInvoke*>(value); }
const ArgBlob& asBlob() const { return std::get<ArgBlob>(value); }
const ValueStruct& asStruct() const { return std::get<ValueStruct>(value); }
ValueStruct& asStruct() { return std::get<ValueStruct>(value); }
/* shared object compatible implementation */
AmObject* asObject() const {
if (type == AObjectShared)
return std::get<shared_ptr<AmObject>>(value).get();
if (type == AObject)
return std::get<AmObject*>(value);
return nullptr;
}
/* safe accessor for shared AmObject */
shared_ptr<AmObject> asSharedObject() const {
if (type == AObjectShared)
return std::get<shared_ptr<AmObject>>(value);
return nullptr; /* borrowed pointers cannot be promoted safely */
}
/* just a helper for all future objects moved to the shared pointer */
template<typename T>
shared_ptr<T> asShared() const {
if (type == AObjectShared) {
return std::dynamic_pointer_cast<T>(
std::get<shared_ptr<AmObject>>(value)
);
}
return nullptr;
}
vector<string> asStringVector() const;
vector<int> asIntVector() const;
vector<bool> asBoolVector() const;
vector<double> asDoubleVector() const;
vector<AmObject*> asAmObjectVector() const;
vector<shared_ptr<AmObject>> asAmObjectSharedVector() const;
vector<ArgBlob> asArgBlobVector() const;
// operations on arrays

Loading…
Cancel
Save