mirror of
https://github.com/NGSolve/netgen.git
synced 2025-04-08 22:37:28 +05:00
store demangled type names for cross platform archive
This commit is contained in:
parent
e845a203e9
commit
a1847ec05f
@ -1,8 +1,19 @@
|
|||||||
|
|
||||||
#include "ngcore.hpp"
|
#include "ngcore.hpp"
|
||||||
|
|
||||||
|
#ifndef WIN
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ngcore
|
namespace ngcore
|
||||||
{
|
{
|
||||||
|
#ifdef WIN
|
||||||
|
// windows does demangling in typeid(T).name()
|
||||||
|
std::string demangle(const char* typeinfo) { return typeinfo; }
|
||||||
|
#else
|
||||||
|
std::string demangle(const char* typeinfo) { int status; return abi::__cxa_demangle(typeinfo, 0, 0, &status); }
|
||||||
|
#endif
|
||||||
|
|
||||||
std::map<std::string, ClassArchiveInfo>& GetArchiveRegister()
|
std::map<std::string, ClassArchiveInfo>& GetArchiveRegister()
|
||||||
{
|
{
|
||||||
static std::map<std::string, ClassArchiveInfo> type_register;
|
static std::map<std::string, ClassArchiveInfo> type_register;
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
namespace ngcore
|
namespace ngcore
|
||||||
{
|
{
|
||||||
class Archive;
|
class Archive;
|
||||||
|
std::string demangle(const char* typeinfo);
|
||||||
|
|
||||||
// create new pointer of type T if it is default constructible, else throw
|
// create new pointer of type T if it is default constructible, else throw
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* constructIfPossible_impl(...)
|
T* constructIfPossible_impl(...)
|
||||||
{ throw std::runtime_error(std::string(typeid(T).name()) + " is not default constructible!"); }
|
{ throw std::runtime_error(std::string(demangle(typeid(T).name())) + " is not default constructible!"); }
|
||||||
|
|
||||||
template<typename T, typename= typename std::enable_if<std::is_constructible<T>::value>::type>
|
template<typename T, typename= typename std::enable_if<std::is_constructible<T>::value>::type>
|
||||||
T* constructIfPossible_impl(int) { return new T; }
|
T* constructIfPossible_impl(int) { return new T; }
|
||||||
@ -164,11 +165,11 @@ namespace ngcore
|
|||||||
// Downcasting is only possible for our registered classes
|
// Downcasting is only possible for our registered classes
|
||||||
if(typeid(T) != typeid(*ptr))
|
if(typeid(T) != typeid(*ptr))
|
||||||
{
|
{
|
||||||
if(GetArchiveRegister().count(std::string(typeid(*ptr).name())) == 0)
|
if(GetArchiveRegister().count(demangle(typeid(*ptr).name())) == 0)
|
||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ typeid(*ptr).name()
|
+ demangle(typeid(*ptr).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
reg_ptr = GetArchiveRegister()[typeid(*ptr).name()].downcaster(typeid(T), ptr.get());
|
reg_ptr = GetArchiveRegister()[demangle(typeid(*ptr).name())].downcaster(typeid(T), ptr.get());
|
||||||
// if there was a true downcast we have to store more information
|
// if there was a true downcast we have to store more information
|
||||||
if(reg_ptr != (void*) ptr.get())
|
if(reg_ptr != (void*) ptr.get())
|
||||||
neededDowncast = true;
|
neededDowncast = true;
|
||||||
@ -182,14 +183,14 @@ namespace ngcore
|
|||||||
(*this) & neededDowncast & p;
|
(*this) & neededDowncast & p;
|
||||||
// if we did downcast we store the true type as well
|
// if we did downcast we store the true type as well
|
||||||
if(neededDowncast)
|
if(neededDowncast)
|
||||||
(*this) << std::string(typeid(*ptr).name());
|
(*this) << demangle(typeid(*ptr).name());
|
||||||
shared_ptr2nr[reg_ptr] = shared_ptr_count++;
|
shared_ptr2nr[reg_ptr] = shared_ptr_count++;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// if found store the position and if it has to be downcasted and how
|
// if found store the position and if it has to be downcasted and how
|
||||||
(*this) << pos->second << neededDowncast;
|
(*this) << pos->second << neededDowncast;
|
||||||
if(neededDowncast)
|
if(neededDowncast)
|
||||||
(*this) << std::string(typeid(*ptr).name());
|
(*this) << demangle(typeid(*ptr).name());
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
else // Input
|
else // Input
|
||||||
@ -261,12 +262,12 @@ namespace ngcore
|
|||||||
void* reg_ptr = (void*)p;
|
void* reg_ptr = (void*)p;
|
||||||
if(typeid(T) != typeid(*p))
|
if(typeid(T) != typeid(*p))
|
||||||
{
|
{
|
||||||
if(GetArchiveRegister().count(std::string(typeid(*p).name())) == 0)
|
if(GetArchiveRegister().count(demangle(typeid(*p).name())) == 0)
|
||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ typeid(*p).name()
|
+ demangle(typeid(*p).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
else
|
else
|
||||||
reg_ptr = GetArchiveRegister()[typeid(*p).name()].downcaster(typeid(T), (void*) p);
|
reg_ptr = GetArchiveRegister()[demangle(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
|
||||||
@ -280,19 +281,19 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw std::runtime_error(std::string("Archive error: Class ") +
|
throw std::runtime_error(std::string("Archive error: Class ") +
|
||||||
typeid(*p).name() + " does not provide a default constructor!");
|
demangle(typeid(*p).name()) + " does not provide a default constructor!");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if a pointer to a base class is archived, the class hierarchy must be registered
|
// if a pointer to a base class is archived, the class hierarchy must be registered
|
||||||
// to avoid compile time issues we allow this behaviour only for "our" classes that
|
// to avoid compile time issues we allow this behaviour only for "our" classes that
|
||||||
// implement a void DoArchive(Archive&) member function
|
// implement a void DoArchive(Archive&) member function
|
||||||
// To recreate the object we need to store the true type of it
|
// To recreate the object we need to store the true type of it
|
||||||
if(GetArchiveRegister().count(std::string(typeid(*p).name())) == 0)
|
if(GetArchiveRegister().count(demangle(typeid(*p).name())) == 0)
|
||||||
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
throw std::runtime_error(std::string("Archive error: Polymorphic type ")
|
||||||
+ typeid(*p).name()
|
+ demangle(typeid(*p).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
else
|
else
|
||||||
return (*this) << -3 << std::string(typeid(*p).name()) & (*p);
|
return (*this) << -3 << demangle(typeid(*p).name()) & (*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -300,7 +301,7 @@ namespace ngcore
|
|||||||
(*this) & pos->second;
|
(*this) & pos->second;
|
||||||
bool downcasted = !(reg_ptr == (void*) p);
|
bool downcasted = !(reg_ptr == (void*) p);
|
||||||
// store if the class has been downcasted and the name
|
// store if the class has been downcasted and the name
|
||||||
(*this) << downcasted << std::string(typeid(*p).name());
|
(*this) << downcasted << demangle(typeid(*p).name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -373,7 +374,7 @@ namespace ngcore
|
|||||||
{ 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*
|
||||||
{ return typeid(T) == ti ? p : Caster<T, Bases...>::tryDowncast(ti, p); };
|
{ return typeid(T) == ti ? p : Caster<T, Bases...>::tryDowncast(ti, p); };
|
||||||
GetArchiveRegister()[std::string(typeid(T).name())] = info;
|
GetArchiveRegister()[std::string(demangle(typeid(T).name()))] = info;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -396,7 +397,7 @@ namespace ngcore
|
|||||||
static void* tryUpcast(const std::type_info& ti, T* p)
|
static void* tryUpcast(const std::type_info& ti, T* p)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{ return GetArchiveRegister()[typeid(B1).name()].upcaster(ti, (void*) (dynamic_cast<B1*>(p))); }
|
{ return GetArchiveRegister()[demangle(typeid(B1).name())].upcaster(ti, (void*) (dynamic_cast<B1*>(p))); }
|
||||||
catch(std::exception)
|
catch(std::exception)
|
||||||
{ return Caster<T, Brest...>::tryUpcast(ti, p); }
|
{ return Caster<T, Brest...>::tryUpcast(ti, p); }
|
||||||
}
|
}
|
||||||
@ -406,7 +407,7 @@ namespace ngcore
|
|||||||
if(typeid(B1) == ti)
|
if(typeid(B1) == ti)
|
||||||
return dynamic_cast<T*>((B1*) p);
|
return dynamic_cast<T*>((B1*) p);
|
||||||
try
|
try
|
||||||
{ return GetArchiveRegister()[typeid(B1).name()].downcaster(ti, (void*) ((B1*)p)); }
|
{ return GetArchiveRegister()[demangle(typeid(B1).name())].downcaster(ti, (void*) ((B1*)p)); }
|
||||||
catch(std::exception)
|
catch(std::exception)
|
||||||
{ return Caster<T, Brest...>::tryDowncast(ti, p); }
|
{ return Caster<T, Brest...>::tryDowncast(ti, p); }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user