ReflectedSet.h
// ReflectedSet.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2022
@import "IObject.h"
@import "ReflectedType.h"
@import "ReflectedMap.h"
namespace ceda
{
template <typename K> class xset;
/*
set insert/delete is treated as an assignment to a boolean, mapped by the key.
*/
typedef AssignValue_params SetInsert_params;
typedef AssignValue_params SetDelete_params;
struct InsertIntoMSet_params : public FieldParams
{
// prefs to be inserted.
const prefbase* src;
ssize_t n;
};
struct DeleteFromMSet_params : public FieldParams
{
// prefs to be deleted.
const prefbase* src;
ssize_t n;
};
@api void OCB_SetInsert(SetInsert_params&);
@api void OCB_SetDelete(SetDelete_params&);
@api void OCB_InsertIntoMSet(InsertIntoMSet_params&);
@api void OCB_DeleteFromMSet(DeleteFromMSet_params&);
template <typename K>
inline bool genop_SetInsert(ptr<IObject> obj, const FieldPath& pathIncludingKey, xset<K>& field, const K& key)
{
if (field.Insert(key))
{
SetInsert_params params;
params.obj = obj;
params.fid.path = pathIncludingKey;
params.addr = &field;
params.visitPrefsFn = nullptr; // todo
OCB_SetInsert(params);
return true;
}
else
{
return false;
}
}
template <typename K>
inline bool genop_SetDelete(ptr<IObject> obj, const FieldPath& pathIncludingKey, xset<K>& field, const K& key)
{
if (field.Delete(key))
{
SetDelete_params params;
params.obj = obj;
params.fid.path = pathIncludingKey;
params.addr = &field;
params.visitPrefsFn = nullptr; // todo
OCB_SetDelete(params);
return true;
}
else
{
return false;
}
}
template <typename K>
inline void genop_InsertIntoMSet(ptr<IObject> obj, const FieldPath& path, xset<K>& field,
const K* src, ssize_t n)
{
InsertIntoMSet_params params;
params.obj = obj;
params.fid.path = path;
params.addr = &field;
params.src = src;
params.n = n;
OCB_InsertIntoMSet(params); // callback must be invoked before insertions are actually made
for (ssize_t i = 0 ; i < n ; ++i)
{
field.Insert(src[i]);
}
}
template <typename K>
inline void genop_DeleteFromMSet(ptr<IObject> obj, const FieldPath& path, xset<K>& field,
const K* src, ssize_t n)
{
for (ssize_t i = 0 ; i < n ; ++i)
{
field.Delete(src[i]);
}
DeleteFromMSet_params params;
params.obj = obj;
params.fid.path = path;
params.addr = &field;
params.src = src;
params.n = n;
OCB_DeleteFromMSet(params); // callback must be invoked after deletions are actually made???
}
template <typename K>
inline bool genop_InsertIntoMSet(ptr<IObject> obj, const FieldPath& path, xset<K>& field,
const K& src)
{
InsertIntoMSet_params params;
params.obj = obj;
params.fid.path = path;
params.addr = &field;
params.src = &src;
params.n = 1;
OCB_InsertIntoMSet(params); // callback must be invoked before insertions are actually made
return field.Insert(src);
}
template <typename K>
inline bool genop_DeleteFromMSet(ptr<IObject> obj, const FieldPath& path, xset<K>& field,
const K& src)
{
if (field.Delete(src))
{
DeleteFromMSet_params params;
params.obj = obj;
params.fid.path = path;
params.addr = &field;
params.src = &src;
params.n = 1;
OCB_DeleteFromMSet(params); // callback must be invoked after deletions are actually made???
return true;
}
else
{
return false;
}
}
$interface+ IXSet
{
// A bit weird to think this as a method!
void Construct();
// Reads the key from the archive, and inserts an element with that key into the set.
void Insert(InputArchive& ar);
// Reads the key from the archive, and deletes the element with that key (if any)
// from the set.
void Delete(InputArchive& ar);
// Reads the key from the archive, and sets found according to whether the key is
// present in the set.
void Find(InputArchive& ar, bool& found) const;
// Total number of elements in the set
ssize_t size() const;
// Serialise the entire set to the given archive
void Serialise(Archive& ar) const;
// Deserialise the entire set from the given archive
void Deserialise(InputArchive& ar);
ptr<IObject> GetRootNode();
// Retrieves an iterator that can be used to iterate through all key values of the set
// The returned iterator must be closed after it is no longer required.
ptr<IBiDirIterator> GetIterator() const;
/*static*/ void ScanOver(InputArchive& ar);
/*static*/ ptr<IKeyType> GetKeyType();
};
///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedSet
struct ReflectedSet
{
inline ptr<IXSet> make_ptr_IXSet(void* self) const
{
cxAssert(self);
cxAssert(IXSetFnTable);
return make_ptr<IXSet>(self,IXSetFnTable);
}
inline ptr<const IXSet> make_ptr_IXSet(const void* self) const
{
cxAssert(self);
cxAssert(IXSetFnTable);
return make_ptr<IXSet>(self,IXSetFnTable);
}
inline void Insert(void* data, InputArchive& ar) const
{
cxAssert(data);
cxAssert(IXSetFnTable);
cxAssert(IXSetFnTable->Insert);
(IXSetFnTable->Insert)(data, ar);
}
inline void Delete(void* data, InputArchive& ar) const
{
cxAssert(data);
cxAssert(IXSetFnTable);
cxAssert(IXSetFnTable->Delete);
(IXSetFnTable->Delete)(data, ar);
}
const TypeOps& ops;
ReflectedType element;
const IXSet::FnTable* IXSetFnTable = nullptr;
};
@api xostream& operator<<(xostream& os, const ReflectedSet& r);
template<typename T> struct is_set { constexpr static bool value = false; };
template<typename K> struct is_set<xset<K>> { constexpr static bool value = true; };
template<typename K>
inline const ReflectedSet& GetReflectedSet()
{
static ReflectedSet s =
{
GetTypeOpsX<xset<K>>(),
GetReflectedType<K>(),
&IXSet::Stubs<xset<K>>::GetTable()
};
return s;
}
template<typename K>
struct GetReflectedType_class<xset<K>>
{
static inline ReflectedType get()
{
ReflectedType r;
r.tag = EReflectedTypeTag::Set;
r.Set = &GetReflectedSet<K>();
return r;
}
};
} // namespace ceda