mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-12 22:20:35 +05:00
archive for pointer to abstract base classes
This commit is contained in:
parent
2ec3bb0df1
commit
e845a203e9
@ -5,6 +5,17 @@ namespace ngcore
|
||||
{
|
||||
class Archive;
|
||||
|
||||
// create new pointer of type T if it is default constructible, else throw
|
||||
template<typename T>
|
||||
T* constructIfPossible_impl(...)
|
||||
{ throw std::runtime_error(std::string(typeid(T).name()) + " is not default constructible!"); }
|
||||
|
||||
template<typename T, typename= typename std::enable_if<std::is_constructible<T>::value>::type>
|
||||
T* constructIfPossible_impl(int) { return new T; }
|
||||
|
||||
template<typename T>
|
||||
T* constructIfPossible() { return constructIfPossible_impl<T>(int{}); }
|
||||
|
||||
// Type trait to check if a class implements a 'void DoArchive(Archive&)' function
|
||||
template<typename T>
|
||||
struct has_DoArchive
|
||||
@ -255,7 +266,7 @@ namespace ngcore
|
||||
+ typeid(*p).name()
|
||||
+ " not registered for archive");
|
||||
else
|
||||
reg_ptr = GetArchiveRegister()[typeid(*p).name()].downcaster(typeid(T), p);
|
||||
reg_ptr = GetArchiveRegister()[typeid(*p).name()].downcaster(typeid(T), (void*) p);
|
||||
}
|
||||
auto pos = ptr2nr.find(reg_ptr);
|
||||
// if the pointer is not found in the map create a new entry
|
||||
@ -300,29 +311,23 @@ namespace ngcore
|
||||
p = nullptr;
|
||||
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
||||
{
|
||||
if (std::is_constructible<T>::value)
|
||||
{
|
||||
p = new T;
|
||||
nr2ptr.push_back(p);
|
||||
(*this) & *p;
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("Class isn't registered properly");
|
||||
|
||||
p = constructIfPossible<T>();
|
||||
nr2ptr.push_back(p);
|
||||
(*this) & *p;
|
||||
}
|
||||
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
|
||||
{
|
||||
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
||||
std::string name;
|
||||
(*this) & name;
|
||||
auto info = GetArchiveRegister()[name];
|
||||
// the creator creates a new object of type name, and returns a void* pointing
|
||||
// to T (which may have an offset)
|
||||
p = (T*) info.creator(typeid(T));
|
||||
// we store the downcasted pointer (to be able to find it again from
|
||||
// another class in a multiple inheritance tree)
|
||||
nr2ptr.push_back(info.downcaster(typeid(T),p));
|
||||
(*this) & *p;
|
||||
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
||||
std::string name;
|
||||
(*this) & name;
|
||||
auto info = GetArchiveRegister()[name];
|
||||
// the creator creates a new object of type name, and returns a void* pointing
|
||||
// to T (which may have an offset)
|
||||
p = (T*) info.creator(typeid(T));
|
||||
// we store the downcasted pointer (to be able to find it again from
|
||||
// another class in a multiple inheritance tree)
|
||||
nr2ptr.push_back(info.downcaster(typeid(T),p));
|
||||
(*this) & *p;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -360,10 +365,10 @@ namespace ngcore
|
||||
public:
|
||||
RegisterClassForArchive()
|
||||
{
|
||||
static_assert(std::is_constructible<T>::value, "Class registered for archive must be default constructible");
|
||||
ClassArchiveInfo info;
|
||||
info.creator = [this,&info](const std::type_info& ti) -> void*
|
||||
{ return typeid(T) == ti ? new T : Caster<T, Bases...>::tryUpcast(ti, new T); };
|
||||
{ return typeid(T) == ti ? constructIfPossible<T>()
|
||||
: Caster<T, Bases...>::tryUpcast(ti, constructIfPossible<T>()); };
|
||||
info.upcaster = [this](const std::type_info& ti, void* p) -> void*
|
||||
{ return typeid(T) == ti ? p : Caster<T, Bases...>::tryUpcast(ti, (T*) p); };
|
||||
info.downcaster = [this](const std::type_info& ti, void* p) -> void*
|
||||
|
@ -326,9 +326,9 @@ namespace netgen
|
||||
|
||||
void CSGeometry :: DoArchive(Archive& archive)
|
||||
{
|
||||
archive & surfaces & surf2prim & solids & toplevelobjects & userpoints & userpoints_ref_factor
|
||||
archive & surfaces & solids & toplevelobjects & userpoints & userpoints_ref_factor
|
||||
& identpoints & boundingbox & identicsurfaces & isidenticto & ideps
|
||||
& filename & spline_surfaces; // TODO: & splinecurves2d & splinecurves3d
|
||||
& filename & spline_surfaces; // TODO: & splinecurves2d & splinecurves3d & surf2prim
|
||||
}
|
||||
|
||||
void CSGeometry :: SaveSurfaces (ostream & out) const
|
||||
|
@ -40,6 +40,11 @@ namespace netgen
|
||||
TopLevelObject (Solid * asolid,
|
||||
Surface * asurface = NULL);
|
||||
|
||||
void DoArchive(Archive& archive)
|
||||
{
|
||||
archive & solid & surface & red & blue & green & visible & transp & maxh
|
||||
& material & layer & bc & bcname;
|
||||
}
|
||||
const Solid * GetSolid() const { return solid; }
|
||||
Solid * GetSolid() { return solid; }
|
||||
|
||||
|
@ -57,6 +57,18 @@ namespace netgen
|
||||
Solid (optyp aop, Solid * as1, Solid * as2 = NULL);
|
||||
~Solid ();
|
||||
|
||||
void DoArchive(Archive& archive)
|
||||
{
|
||||
archive & name & prim & s1 & s2 & visited & maxh & num_surfs;
|
||||
if(archive.Output())
|
||||
archive << int(op);
|
||||
else
|
||||
{
|
||||
int iop;
|
||||
archive & iop;
|
||||
op = optyp(iop);
|
||||
}
|
||||
}
|
||||
const char * Name () const { return name; }
|
||||
void SetName (const char * aname);
|
||||
|
||||
|
@ -13,6 +13,7 @@ public:
|
||||
virtual void DoArchive(Archive& archive) { archive & a; }
|
||||
};
|
||||
|
||||
// pure abstract base class
|
||||
class SharedPtrHolder : virtual public CommonBase
|
||||
{
|
||||
public:
|
||||
@ -20,6 +21,7 @@ public:
|
||||
virtual ~SharedPtrHolder()
|
||||
{ }
|
||||
|
||||
virtual void abstract() = 0;
|
||||
virtual void DoArchive(Archive& archive)
|
||||
{
|
||||
CommonBase::DoArchive(archive);
|
||||
@ -49,6 +51,7 @@ public:
|
||||
SharedPtrHolder::DoArchive(archive);
|
||||
PtrHolder::DoArchive(archive);
|
||||
}
|
||||
virtual void abstract() {}
|
||||
};
|
||||
|
||||
// Classes without virt. or multiple inheritance do not need to be registered
|
||||
@ -91,12 +94,12 @@ void testSharedPointer(Archive& in, Archive& out)
|
||||
SECTION("Same shared ptr")
|
||||
{
|
||||
static_assert(has_DoArchive<SharedPtrHolder>::value, "");
|
||||
SharedPtrHolder holder, holder2;
|
||||
SharedPtrAndPtrHolder holder, holder2;
|
||||
holder.names.push_back(make_shared<string>("name"));
|
||||
holder2.names = holder.names; // same shared ptr
|
||||
out & holder & holder2;
|
||||
out.FlushBuffer();
|
||||
SharedPtrHolder inholder, inholder2;
|
||||
SharedPtrAndPtrHolder inholder, inholder2;
|
||||
in & inholder & inholder2;
|
||||
CHECK(inholder.names.size() == 1);
|
||||
CHECK(inholder.names[0] == inholder2.names[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user