mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-25 05:20:34 +05:00
Archive with nondefault constructor
This commit is contained in:
parent
22b45dde67
commit
90729810d4
@ -255,7 +255,6 @@ target_include_directories(nglib PRIVATE ${ZLIB_INCLUDE_DIRS})
|
|||||||
if(USE_GUI)
|
if(USE_GUI)
|
||||||
target_include_directories(nggui PRIVATE ${ZLIB_INCLUDE_DIRS})
|
target_include_directories(nggui PRIVATE ${ZLIB_INCLUDE_DIRS})
|
||||||
endif(USE_GUI)
|
endif(USE_GUI)
|
||||||
target_link_libraries(nglib PRIVATE ${ZLIB_LIBRARIES})
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -18,7 +18,8 @@ string(REPLACE "|" ";" ng_compile_flags_replace_sep "${NG_COMPILE_FLAGS}")
|
|||||||
target_compile_options(ngcore PUBLIC ${ng_compile_flags_replace_sep})
|
target_compile_options(ngcore PUBLIC ${ng_compile_flags_replace_sep})
|
||||||
|
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
target_link_options(nglib PUBLIC -sALLOW_MEMORY_GROWTH -sENVIRONMENT=web)
|
target_link_options(ngcore PUBLIC -sALLOW_MEMORY_GROWTH -sENVIRONMENT=web)
|
||||||
|
target_compile_options(ngcore PUBLIC -sNO_DISABLE_EXCEPTION_CATCHING)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
|
||||||
|
@ -41,16 +41,35 @@ namespace ngcore
|
|||||||
class NGCORE_API Archive;
|
class NGCORE_API Archive;
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
template <class T, class Tuple, size_t... Is>
|
||||||
|
T* construct_from_tuple(Tuple&& tuple, std::index_sequence<Is...> ) {
|
||||||
|
return new T{std::get<Is>(std::forward<Tuple>(tuple))...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Tuple>
|
||||||
|
T* construct_from_tuple(Tuple&& tuple) {
|
||||||
|
return construct_from_tuple<T>(std::forward<Tuple>(tuple),
|
||||||
|
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 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, typename ...Rest>
|
template<typename T, typename... TArgs>
|
||||||
T* constructIfPossible_impl(Rest... /*unused*/)
|
T* constructIfPossible(std::tuple<TArgs...> args)
|
||||||
{ throw Exception(std::string(Demangle(typeid(T).name())) + " is not default constructible!"); }
|
{
|
||||||
|
if constexpr(std::is_constructible_v<T, TArgs...>)
|
||||||
|
return construct_from_tuple<T>(args);
|
||||||
|
throw Exception(std::string(Demangle(typeid(T).name())) +
|
||||||
|
" is not constructible!");
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T, typename= std::enable_if_t<std::is_constructible<T>::value>>
|
template <typename T> T *constructIfPossible()
|
||||||
T* constructIfPossible_impl(int /*unused*/) { return new T; } // NOLINT
|
{
|
||||||
|
if constexpr(std::is_constructible_v<T>)
|
||||||
template<typename T>
|
return new T();
|
||||||
T* constructIfPossible() { return constructIfPossible_impl<T>(int{}); }
|
throw Exception(std::string(Demangle(typeid(T).name())) +
|
||||||
|
" is not default constructible!");
|
||||||
|
}
|
||||||
|
|
||||||
//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>
|
||||||
@ -87,7 +106,7 @@ namespace ngcore
|
|||||||
// create new object of this type and return a void* pointer that is points to the location
|
// create new object of this type and return a void* pointer that is points to the location
|
||||||
// of the (base)class given by type_info
|
// of the (base)class given by type_info
|
||||||
// std::function<void*(const std::type_info&)> creator;
|
// std::function<void*(const std::type_info&)> creator;
|
||||||
void* (*creator)(const std::type_info&);
|
void* (*creator)(const std::type_info&, Archive&);
|
||||||
// This caster takes a void* pointer to the type stored in this info and casts it to a
|
// This caster takes a void* pointer to the type stored in this info and casts it to a
|
||||||
// void* pointer pointing to the (base)class type_info
|
// void* pointer pointing to the (base)class type_info
|
||||||
// std::function<void*(const std::type_info&, void*)> upcaster;
|
// std::function<void*(const std::type_info&, void*)> upcaster;
|
||||||
@ -97,6 +116,9 @@ namespace ngcore
|
|||||||
// std::function<void*(const std::type_info&, void*)> downcaster;
|
// std::function<void*(const std::type_info&, void*)> downcaster;
|
||||||
void* (*downcaster)(const std::type_info&, void*);
|
void* (*downcaster)(const std::type_info&, void*);
|
||||||
|
|
||||||
|
// Archive constructor arguments
|
||||||
|
std::function<void(Archive&, void*)> cargs_archiver;
|
||||||
|
|
||||||
#ifdef NETGEN_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
// std::function<pybind11::object(const std::any&)> anyToPyCaster;
|
// std::function<pybind11::object(const std::any&)> anyToPyCaster;
|
||||||
pybind11::object (*anyToPyCaster)(const std::any&);
|
pybind11::object (*anyToPyCaster)(const std::any&);
|
||||||
@ -528,8 +550,18 @@ namespace ngcore
|
|||||||
if (std::is_constructible<T>::value)
|
if (std::is_constructible<T>::value)
|
||||||
return (*this) << -1 & (*p);
|
return (*this) << -1 & (*p);
|
||||||
else
|
else
|
||||||
throw Exception(std::string("Archive error: Class ") +
|
{
|
||||||
Demangle(typeid(*p).name()) + " does not provide a default constructor!");
|
if (IsRegistered(Demangle(typeid(*p).name())))
|
||||||
|
{
|
||||||
|
(*this) << -3 << Demangle(typeid(*p).name());
|
||||||
|
GetArchiveRegister(Demangle(typeid(*p).name())).
|
||||||
|
cargs_archiver(*this, p);
|
||||||
|
return (*this) & (*p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw Exception(std::string("Archive error: Class ") +
|
||||||
|
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
|
||||||
@ -540,7 +572,10 @@ namespace ngcore
|
|||||||
throw Exception(std::string("Archive error: Polymorphic type ")
|
throw Exception(std::string("Archive error: Polymorphic type ")
|
||||||
+ Demangle(typeid(*p).name())
|
+ Demangle(typeid(*p).name())
|
||||||
+ " not registered for archive");
|
+ " not registered for archive");
|
||||||
return (*this) << -3 << Demangle(typeid(*p).name()) & (*p);
|
(*this) << -3 << Demangle(typeid(*p).name());
|
||||||
|
GetArchiveRegister(Demangle(typeid(*p).name())).
|
||||||
|
cargs_archiver(*this, p);
|
||||||
|
return (*this) & (*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -571,7 +606,7 @@ namespace ngcore
|
|||||||
auto info = GetArchiveRegister(name);
|
auto info = GetArchiveRegister(name);
|
||||||
// the creator creates a new object of type name, and returns a void* pointing
|
// the creator creates a new object of type name, and returns a void* pointing
|
||||||
// to T (which may have an offset)
|
// to T (which may have an offset)
|
||||||
p = static_cast<T*>(info.creator(typeid(T)));
|
p = static_cast<T*>(info.creator(typeid(T), *this));
|
||||||
// we store the downcasted pointer (to be able to find it again from
|
// we store the downcasted pointer (to be able to find it again from
|
||||||
// another class in a multiple inheritance tree)
|
// another class in a multiple inheritance tree)
|
||||||
nr2ptr.push_back(info.downcaster(typeid(T),p));
|
nr2ptr.push_back(info.downcaster(typeid(T),p));
|
||||||
@ -595,6 +630,16 @@ namespace ngcore
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Archive& operator&(std::tuple<>&) { return *this; }
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
Archive& operator&(std::tuple<T...> &t)
|
||||||
|
{
|
||||||
|
// call operator& for each element of the tuple
|
||||||
|
std::apply([this](auto&... arg) { std::make_tuple(((*this) & arg).IsParallel()...);}, t);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// const ptr
|
// const ptr
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Archive& operator &(const T*& t)
|
Archive& operator &(const T*& t)
|
||||||
@ -618,7 +663,7 @@ namespace ngcore
|
|||||||
void SetParallel (bool _parallel) { parallel = _parallel; }
|
void SetParallel (bool _parallel) { parallel = _parallel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T, typename ... Bases>
|
template<typename T, typename Bases, typename CArgs>
|
||||||
friend class RegisterClassForArchive;
|
friend class RegisterClassForArchive;
|
||||||
|
|
||||||
#ifdef NETGEN_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
@ -637,7 +682,7 @@ namespace ngcore
|
|||||||
struct Caster{};
|
struct Caster{};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Caster<T>
|
struct Caster<T, std::tuple<>>
|
||||||
{
|
{
|
||||||
static void* tryUpcast (const std::type_info& /*unused*/, T* /*unused*/)
|
static void* tryUpcast (const std::type_info& /*unused*/, T* /*unused*/)
|
||||||
{
|
{
|
||||||
@ -649,8 +694,37 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, typename B1>
|
||||||
|
struct Caster<T,B1>
|
||||||
|
{
|
||||||
|
static void* tryUpcast(const std::type_info& ti, T* p)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return GetArchiveRegister(Demangle(typeid(B1).name()))
|
||||||
|
.upcaster(ti, static_cast<void *>(dynamic_cast<B1 *>(p)));
|
||||||
|
} catch (const Exception &) {
|
||||||
|
throw Exception("Upcast not successful, some classes are not "
|
||||||
|
"registered properly for archiving!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* tryDowncast(const std::type_info& ti, void* p)
|
||||||
|
{
|
||||||
|
if(typeid(B1) == ti)
|
||||||
|
return dynamic_cast<T*>(static_cast<B1*>(p));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return dynamic_cast<T*>(static_cast<B1*>(GetArchiveRegister(Demangle(typeid(B1).name())).
|
||||||
|
downcaster(ti, p)));
|
||||||
|
} catch (const Exception &) {
|
||||||
|
throw Exception("Downcast not successful, some classes are not "
|
||||||
|
"registered properly for archiving!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T, typename B1, typename ... Brest>
|
template<typename T, typename B1, typename ... Brest>
|
||||||
struct Caster<T,B1,Brest...>
|
struct Caster<T,std::tuple<B1, Brest...>>
|
||||||
{
|
{
|
||||||
static void* tryUpcast(const std::type_info& ti, T* p)
|
static void* tryUpcast(const std::type_info& ti, T* p)
|
||||||
{
|
{
|
||||||
@ -658,7 +732,7 @@ namespace ngcore
|
|||||||
{ return GetArchiveRegister(Demangle(typeid(B1).name())).
|
{ return GetArchiveRegister(Demangle(typeid(B1).name())).
|
||||||
upcaster(ti, static_cast<void*>(dynamic_cast<B1*>(p))); }
|
upcaster(ti, static_cast<void*>(dynamic_cast<B1*>(p))); }
|
||||||
catch(const Exception&)
|
catch(const Exception&)
|
||||||
{ return Caster<T, Brest...>::tryUpcast(ti, p); }
|
{ return Caster<T, std::tuple<Brest...>>::tryUpcast(ti, p); }
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* tryDowncast(const std::type_info& ti, void* p)
|
static void* tryDowncast(const std::type_info& ti, void* p)
|
||||||
@ -672,7 +746,7 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
catch(const Exception&)
|
catch(const Exception&)
|
||||||
{
|
{
|
||||||
return Caster<T, Brest...>::tryDowncast(ti, p);
|
return Caster<T, std::tuple<Brest...>>::tryDowncast(ti, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -156,30 +156,6 @@ namespace ngcore
|
|||||||
{ return std::string("sp_")+GetPyName<T>(); }
|
{ return std::string("sp_")+GetPyName<T>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// *************** Archiving functionality **************
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Archive& Archive :: Shallow(T& val)
|
|
||||||
{
|
|
||||||
static_assert(detail::is_any_pointer<T>, "ShallowArchive must be given pointer type!");
|
|
||||||
#ifdef NETGEN_PYTHON
|
|
||||||
if(shallow_to_python)
|
|
||||||
{
|
|
||||||
if(is_output)
|
|
||||||
ShallowOutPython(pybind11::cast(val));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pybind11::object obj;
|
|
||||||
ShallowInPython(obj);
|
|
||||||
val = pybind11::cast<T>(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // NETGEN_PYTHON
|
|
||||||
*this & val;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ARCHIVE>
|
template<typename ARCHIVE>
|
||||||
class NGCORE_API_EXPORT PyArchive : public ARCHIVE
|
class NGCORE_API_EXPORT PyArchive : public ARCHIVE
|
||||||
{
|
{
|
||||||
|
@ -5,35 +5,72 @@
|
|||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <pybind11/cast.h>
|
#include <pybind11/cast.h>
|
||||||
#endif // NETGEN_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#include "archive.hpp"
|
#include "archive.hpp"
|
||||||
|
|
||||||
namespace ngcore {
|
namespace ngcore {
|
||||||
|
// *************** Archiving functionality **************
|
||||||
|
|
||||||
template<typename T, typename ... Bases>
|
#ifdef NETGEN_PYTHON
|
||||||
|
template<typename T>
|
||||||
|
Archive& Archive :: Shallow(T& val)
|
||||||
|
{
|
||||||
|
static_assert(detail::is_any_pointer<T>, "ShallowArchive must be given pointer type!");
|
||||||
|
if(shallow_to_python)
|
||||||
|
{
|
||||||
|
if(is_output)
|
||||||
|
ShallowOutPython(pybind11::cast(val));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pybind11::object obj;
|
||||||
|
ShallowInPython(obj);
|
||||||
|
val = pybind11::cast<T>(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*this & val;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif // NETGEN_PYTHON
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename Bases=std::tuple<>, typename CArgs=std::tuple<>>
|
||||||
class RegisterClassForArchive
|
class RegisterClassForArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RegisterClassForArchive()
|
std::function<CArgs(T&)> get_cargs;
|
||||||
|
RegisterClassForArchive(std::function<CArgs(T&)> _get_cargs =
|
||||||
|
[](T&) -> std::tuple<> { return std::tuple<>{}; }) :
|
||||||
|
get_cargs(_get_cargs)
|
||||||
{
|
{
|
||||||
static_assert(detail::all_of_tmpl<std::is_base_of<Bases,T>::value...>,
|
static_assert(std::is_base_of<Bases, T>::value ||
|
||||||
"Variadic template arguments must be base classes of T");
|
detail::is_base_of_tuple<T, Bases>,
|
||||||
|
"Second argument must be base class or tuple of base classes of T");
|
||||||
detail::ClassArchiveInfo info {};
|
detail::ClassArchiveInfo info {};
|
||||||
info.creator = [](const std::type_info& ti) -> void*
|
info.creator = [](const std::type_info& ti, Archive& ar) -> void*
|
||||||
{ return typeid(T) == ti ? detail::constructIfPossible<T>()
|
|
||||||
: Archive::Caster<T, Bases...>::tryUpcast(ti, detail::constructIfPossible<T>()); };
|
|
||||||
info.upcaster = [/*this*/](const std::type_info& ti, void* p) -> void*
|
|
||||||
{ return typeid(T) == ti ? p : Archive::Caster<T, Bases...>::tryUpcast(ti, static_cast<T*>(p)); };
|
|
||||||
info.downcaster = [/*this*/](const std::type_info& ti, void* p) -> void*
|
|
||||||
{ return typeid(T) == ti ? p : Archive::Caster<T, Bases...>::tryDowncast(ti, p); };
|
|
||||||
#ifdef NETGEN_PYTHON
|
|
||||||
info.anyToPyCaster = [](const std::any& a)
|
|
||||||
{
|
{
|
||||||
const T* val = std::any_cast<T>(&a);
|
CArgs args;
|
||||||
return pybind11::cast(val); };
|
ar &args;
|
||||||
|
auto nT = detail::constructIfPossible<T>(args);
|
||||||
|
return typeid(T) == ti ? nT
|
||||||
|
: Archive::Caster<T, Bases>::tryUpcast(ti, nT);
|
||||||
|
};
|
||||||
|
info.upcaster = [/*this*/](const std::type_info& ti, void* p) -> void*
|
||||||
|
{ return typeid(T) == ti ? p : Archive::Caster<T, Bases>::tryUpcast(ti, static_cast<T*>(p)); };
|
||||||
|
info.downcaster = [/*this*/](const std::type_info& ti, void* p) -> void*
|
||||||
|
{ return typeid(T) == ti ? p : Archive::Caster<T, Bases>::tryDowncast(ti, p); };
|
||||||
|
info.cargs_archiver = [this](Archive &ar, void* p) {
|
||||||
|
ar << get_cargs(*static_cast<T*>(p));
|
||||||
|
};
|
||||||
|
#ifdef NETGEN_PYTHON
|
||||||
|
info.anyToPyCaster = [](const std::any &a) {
|
||||||
|
const T* val = std::any_cast<T>(&a);
|
||||||
|
return pybind11::cast(val);
|
||||||
|
};
|
||||||
#endif // NETGEN_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
Archive::SetArchiveRegister(std::string(Demangle(typeid(T).name())),info);
|
Archive::SetArchiveRegister(std::string(Demangle(typeid(T).name())),info);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ngcore
|
} // namespace ngcore
|
||||||
#endif // NETGEN_REGISTER_ARCHIVE_HPP
|
#endif // NETGEN_REGISTER_ARCHIVE_HPP
|
||||||
|
@ -16,6 +16,15 @@ namespace ngcore
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_any_pointer_impl : std::false_type {};
|
struct is_any_pointer_impl : std::false_type {};
|
||||||
|
|
||||||
|
// check if second template argument is tuple of base classes to first
|
||||||
|
// template argument, return constexpr bool
|
||||||
|
template<typename T, typename Tuple>
|
||||||
|
constexpr bool is_base_of_tuple = false;
|
||||||
|
|
||||||
|
template<typename T, typename... Ts>
|
||||||
|
constexpr bool is_base_of_tuple<T, std::tuple<Ts...>> =
|
||||||
|
all_of_tmpl<std::is_base_of<Ts, T>::value...>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_any_pointer_impl<T*> : std::true_type {};
|
struct is_any_pointer_impl<T*> : std::true_type {};
|
||||||
|
|
||||||
|
@ -43,6 +43,14 @@ namespace ngcore
|
|||||||
{
|
{
|
||||||
for(const auto & [r, sub] : demangle_regexes)
|
for(const auto & [r, sub] : demangle_regexes)
|
||||||
s = std::regex_replace (s,r,sub);
|
s = std::regex_replace (s,r,sub);
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
// for some reason regex_replace is not working at all
|
||||||
|
std::string temp = s;
|
||||||
|
s = "";
|
||||||
|
for(auto c : temp)
|
||||||
|
if(c!=' ')
|
||||||
|
s+=c;
|
||||||
|
#endif // EMSCRIPTEN
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -580,5 +580,5 @@ void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp)
|
|||||||
|
|
||||||
RegisterClassForArchive<Surface> regsurf;
|
RegisterClassForArchive<Surface> regsurf;
|
||||||
RegisterClassForArchive<Primitive> regprim;
|
RegisterClassForArchive<Primitive> regprim;
|
||||||
RegisterClassForArchive<OneSurfacePrimitive, Surface, Primitive> regosf;
|
RegisterClassForArchive<OneSurfacePrimitive, tuple<Surface, Primitive>> regosf;
|
||||||
}
|
}
|
||||||
|
@ -1105,6 +1105,6 @@ namespace netgen
|
|||||||
};
|
};
|
||||||
|
|
||||||
SplineGeoInit sginit;
|
SplineGeoInit sginit;
|
||||||
static RegisterClassForArchive<SplineGeometry2d, SplineGeometry<2>, NetgenGeometry> regspg2;
|
static RegisterClassForArchive<SplineGeometry2d, tuple<SplineGeometry<2>, NetgenGeometry>> regspg2;
|
||||||
static RegisterClassForArchive<SplineSegExt, SplineSeg<2>> regssext;
|
static RegisterClassForArchive<SplineSegExt, SplineSeg<2>> regssext;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ target_sources(nglib PRIVATE
|
|||||||
boundarylayer2d.cpp
|
boundarylayer2d.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries( nglib PRIVATE netgen_metis "$<BUILD_INTERFACE:netgen_python>" ${ZLIB_LIBRARIES} )
|
target_link_libraries( nglib PRIVATE netgen_metis "$<BUILD_INTERFACE:netgen_python>" )
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
adfront2.hpp adfront3.hpp basegeom.hpp bcfunctions.hpp bisect.hpp
|
adfront2.hpp adfront3.hpp basegeom.hpp bcfunctions.hpp bisect.hpp
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
#include "meshing.hpp"
|
#include "meshing.hpp"
|
||||||
#include "../general/gzstream.h"
|
#include "../general/gzstream.h"
|
||||||
|
|
||||||
#ifdef NG_PYTHON
|
#include <core/register_archive.hpp>
|
||||||
// must be included to instantiate Archive::Shallow(NetgenGeometry&)
|
|
||||||
#include <core/python_ngcore.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
@ -4493,7 +4490,11 @@ namespace netgen
|
|||||||
double local_sum = 0.0;
|
double local_sum = 0.0;
|
||||||
double teterrpow = mp.opterrpow;
|
double teterrpow = mp.opterrpow;
|
||||||
|
|
||||||
std::array<int,n_classes> classes_local{};
|
// std::array<int,n_classes> classes_local{};
|
||||||
|
size_t n_classes = tets_in_qualclass.Size();
|
||||||
|
Array<int> classes_local(n_classes);
|
||||||
|
for (int i = 0; i < n_classes; i++)
|
||||||
|
classes_local[i] = 0;
|
||||||
|
|
||||||
for (auto i : myrange)
|
for (auto i : myrange)
|
||||||
{
|
{
|
||||||
|
@ -3756,5 +3756,5 @@ void STLGeometry :: WriteChartToFile( ChartId chartnumber, filesystem::path file
|
|||||||
|
|
||||||
STLInit stlinit;
|
STLInit stlinit;
|
||||||
|
|
||||||
static RegisterClassForArchive<STLGeometry, NetgenGeometry, STLTopology> stlgeo;
|
static RegisterClassForArchive<STLGeometry, std::tuple<NetgenGeometry, STLTopology>> stlgeo;
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,32 @@ public:
|
|||||||
const int* getPtr() { return ptr; }
|
const int* getPtr() { return ptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class OneMoreDerivedClass : public SharedPtrAndPtrHolder {};
|
class ClassWithoutDefaultConstructor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int a;
|
||||||
|
double b;
|
||||||
|
double c;
|
||||||
|
ClassWithoutDefaultConstructor(int aa, double c) : a(aa), c(c) {}
|
||||||
|
|
||||||
|
void DoArchive(Archive& ar)
|
||||||
|
{
|
||||||
|
ar & b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static RegisterClassForArchive<ClassWithoutDefaultConstructor,
|
||||||
|
tuple<>, tuple<int, double>>
|
||||||
|
regwdc([](ClassWithoutDefaultConstructor& self)
|
||||||
|
{ return make_tuple(self.a, self.c); });
|
||||||
|
|
||||||
|
class OneMoreDerivedClass : public SharedPtrAndPtrHolder {
|
||||||
|
};
|
||||||
|
|
||||||
static RegisterClassForArchive<CommonBase> regb;
|
static RegisterClassForArchive<CommonBase> regb;
|
||||||
static RegisterClassForArchive<SharedPtrHolder, CommonBase> regsp;
|
static RegisterClassForArchive<SharedPtrHolder, CommonBase> regsp;
|
||||||
static RegisterClassForArchive<PtrHolder, CommonBase> regp;
|
static RegisterClassForArchive<PtrHolder, CommonBase> regp;
|
||||||
static RegisterClassForArchive<SharedPtrAndPtrHolder, SharedPtrHolder, PtrHolder> regspp;
|
static RegisterClassForArchive<SharedPtrAndPtrHolder, tuple<SharedPtrHolder, PtrHolder>> regspp;
|
||||||
static RegisterClassForArchive<OneMoreDerivedClass, SharedPtrAndPtrHolder> regom;
|
static RegisterClassForArchive<OneMoreDerivedClass, SharedPtrAndPtrHolder> regom;
|
||||||
|
|
||||||
void testNullPtr(Archive& in, Archive& out)
|
void testNullPtr(Archive& in, Archive& out)
|
||||||
@ -334,6 +354,19 @@ void testArchive(Archive& in, Archive& out)
|
|||||||
SharedPtrAndPtrHolder* p = new NotRegisteredForArchive;
|
SharedPtrAndPtrHolder* p = new NotRegisteredForArchive;
|
||||||
REQUIRE_THROWS(out & p, Catch::Contains("not registered for archive"));
|
REQUIRE_THROWS(out & p, Catch::Contains("not registered for archive"));
|
||||||
}
|
}
|
||||||
|
SECTION("Non-default constructor")
|
||||||
|
{
|
||||||
|
ClassWithoutDefaultConstructor c(5, 2.2);
|
||||||
|
c.b = 3.2;
|
||||||
|
auto p = &c;
|
||||||
|
out & p;
|
||||||
|
out.FlushBuffer();
|
||||||
|
ClassWithoutDefaultConstructor* cin;
|
||||||
|
in & cin;
|
||||||
|
CHECK(cin->a == 5);
|
||||||
|
CHECK(cin->b == 3.2);
|
||||||
|
CHECK(cin->c == 2.2);
|
||||||
|
}
|
||||||
SECTION("nullptr")
|
SECTION("nullptr")
|
||||||
{
|
{
|
||||||
testNullPtr(in, out);
|
testNullPtr(in, out);
|
||||||
|
Loading…
Reference in New Issue
Block a user