mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-27 13:20:34 +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;
|
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
|
// Type trait to check if a class implements a 'void DoArchive(Archive&)' function
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct has_DoArchive
|
struct has_DoArchive
|
||||||
@ -255,7 +266,7 @@ namespace ngcore
|
|||||||
+ typeid(*p).name()
|
+ typeid(*p).name()
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
else
|
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);
|
auto pos = ptr2nr.find(reg_ptr);
|
||||||
// if the pointer is not found in the map create a new entry
|
// if the pointer is not found in the map create a new entry
|
||||||
@ -300,16 +311,10 @@ namespace ngcore
|
|||||||
p = nullptr;
|
p = nullptr;
|
||||||
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
||||||
{
|
{
|
||||||
if (std::is_constructible<T>::value)
|
p = constructIfPossible<T>();
|
||||||
{
|
|
||||||
p = new T;
|
|
||||||
nr2ptr.push_back(p);
|
nr2ptr.push_back(p);
|
||||||
(*this) & *p;
|
(*this) & *p;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
throw std::runtime_error("Class isn't registered properly");
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
|
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
|
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
||||||
@ -360,10 +365,10 @@ namespace ngcore
|
|||||||
public:
|
public:
|
||||||
RegisterClassForArchive()
|
RegisterClassForArchive()
|
||||||
{
|
{
|
||||||
static_assert(std::is_constructible<T>::value, "Class registered for archive must be default constructible");
|
|
||||||
ClassArchiveInfo info;
|
ClassArchiveInfo info;
|
||||||
info.creator = [this,&info](const std::type_info& ti) -> void*
|
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*
|
info.upcaster = [this](const std::type_info& ti, void* p) -> void*
|
||||||
{ return typeid(T) == ti ? p : Caster<T, Bases...>::tryUpcast(ti, (T*) p); };
|
{ return typeid(T) == ti ? p : Caster<T, Bases...>::tryUpcast(ti, (T*) p); };
|
||||||
info.downcaster = [this](const std::type_info& ti, void* p) -> void*
|
info.downcaster = [this](const std::type_info& ti, void* p) -> void*
|
||||||
|
@ -326,9 +326,9 @@ namespace netgen
|
|||||||
|
|
||||||
void CSGeometry :: DoArchive(Archive& archive)
|
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
|
& identpoints & boundingbox & identicsurfaces & isidenticto & ideps
|
||||||
& filename & spline_surfaces; // TODO: & splinecurves2d & splinecurves3d
|
& filename & spline_surfaces; // TODO: & splinecurves2d & splinecurves3d & surf2prim
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSGeometry :: SaveSurfaces (ostream & out) const
|
void CSGeometry :: SaveSurfaces (ostream & out) const
|
||||||
|
@ -40,6 +40,11 @@ namespace netgen
|
|||||||
TopLevelObject (Solid * asolid,
|
TopLevelObject (Solid * asolid,
|
||||||
Surface * asurface = NULL);
|
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; }
|
const Solid * GetSolid() const { return solid; }
|
||||||
Solid * GetSolid() { return solid; }
|
Solid * GetSolid() { return solid; }
|
||||||
|
|
||||||
|
@ -57,6 +57,18 @@ namespace netgen
|
|||||||
Solid (optyp aop, Solid * as1, Solid * as2 = NULL);
|
Solid (optyp aop, Solid * as1, Solid * as2 = NULL);
|
||||||
~Solid ();
|
~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; }
|
const char * Name () const { return name; }
|
||||||
void SetName (const char * aname);
|
void SetName (const char * aname);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ public:
|
|||||||
virtual void DoArchive(Archive& archive) { archive & a; }
|
virtual void DoArchive(Archive& archive) { archive & a; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// pure abstract base class
|
||||||
class SharedPtrHolder : virtual public CommonBase
|
class SharedPtrHolder : virtual public CommonBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -20,6 +21,7 @@ public:
|
|||||||
virtual ~SharedPtrHolder()
|
virtual ~SharedPtrHolder()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
virtual void abstract() = 0;
|
||||||
virtual void DoArchive(Archive& archive)
|
virtual void DoArchive(Archive& archive)
|
||||||
{
|
{
|
||||||
CommonBase::DoArchive(archive);
|
CommonBase::DoArchive(archive);
|
||||||
@ -49,6 +51,7 @@ public:
|
|||||||
SharedPtrHolder::DoArchive(archive);
|
SharedPtrHolder::DoArchive(archive);
|
||||||
PtrHolder::DoArchive(archive);
|
PtrHolder::DoArchive(archive);
|
||||||
}
|
}
|
||||||
|
virtual void abstract() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Classes without virt. or multiple inheritance do not need to be registered
|
// 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")
|
SECTION("Same shared ptr")
|
||||||
{
|
{
|
||||||
static_assert(has_DoArchive<SharedPtrHolder>::value, "");
|
static_assert(has_DoArchive<SharedPtrHolder>::value, "");
|
||||||
SharedPtrHolder holder, holder2;
|
SharedPtrAndPtrHolder holder, holder2;
|
||||||
holder.names.push_back(make_shared<string>("name"));
|
holder.names.push_back(make_shared<string>("name"));
|
||||||
holder2.names = holder.names; // same shared ptr
|
holder2.names = holder.names; // same shared ptr
|
||||||
out & holder & holder2;
|
out & holder & holder2;
|
||||||
out.FlushBuffer();
|
out.FlushBuffer();
|
||||||
SharedPtrHolder inholder, inholder2;
|
SharedPtrAndPtrHolder inholder, inholder2;
|
||||||
in & inholder & inholder2;
|
in & inholder & inholder2;
|
||||||
CHECK(inholder.names.size() == 1);
|
CHECK(inholder.names.size() == 1);
|
||||||
CHECK(inholder.names[0] == inholder2.names[0]);
|
CHECK(inholder.names[0] == inholder2.names[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user