mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-11 16:49:16 +05:00
Archive classes with non default ctor
This commit is contained in:
parent
3ff2e46ddd
commit
7fa30dbfac
@ -14,6 +14,7 @@
|
||||
#include <string> // for string
|
||||
#include <type_traits> // for declval, enable_if_t, false_type, is_co...
|
||||
#include <cstddef> // for std::byte
|
||||
#include <set> // for set
|
||||
#include <typeinfo> // for type_info
|
||||
#include <utility> // for move, swap, pair
|
||||
#include <vector> // for vector
|
||||
@ -33,6 +34,13 @@ namespace pybind11
|
||||
|
||||
namespace ngcore
|
||||
{
|
||||
template <typename T>
|
||||
struct Shallow {
|
||||
T val;
|
||||
Shallow() = default;
|
||||
Shallow(T aval) : val(aval) { ; }
|
||||
operator T&() { return val; }
|
||||
};
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
pybind11::object CastAnyToPy(const std::any& a);
|
||||
@ -101,6 +109,31 @@ namespace ngcore
|
||||
NGCORE_API static constexpr bool value = type::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_GetCArgs
|
||||
{
|
||||
template <typename C> static std::true_type check( decltype( sizeof(&C::GetCArgs )) ) { return std::true_type(); }
|
||||
template <typename> static std::false_type check(...) { return std::false_type(); }
|
||||
typedef decltype( check<T>(sizeof(char)) ) type;
|
||||
static constexpr type value = type();
|
||||
};
|
||||
template<typename T>
|
||||
constexpr bool has_GetCArgs_v = has_GetCArgs<T>::value;
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<!has_GetCArgs_v<T>>::type* = nullptr>
|
||||
std::tuple<> GetCArgs(T&val) { return {}; }
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<has_GetCArgs_v<T>>::type* = nullptr>
|
||||
auto GetCArgs(T&val) {
|
||||
return val.GetCArgs();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
using TCargs = decltype(GetCArgs<T>(*static_cast<T*>(nullptr)));
|
||||
|
||||
|
||||
struct ClassArchiveInfo
|
||||
{
|
||||
// create new object of this type and return a void* pointer that is points to the location
|
||||
@ -336,6 +369,26 @@ namespace ngcore
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
template <typename T>
|
||||
Archive& operator&(std::set<T> &s)
|
||||
{
|
||||
auto size = s.size();
|
||||
(*this) & size;
|
||||
if(Output())
|
||||
for(const auto & val : s)
|
||||
(*this) << val;
|
||||
else
|
||||
{
|
||||
for(size_t i=0; i<size; i++)
|
||||
{
|
||||
T val;
|
||||
(*this) & val;
|
||||
s.insert(val);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Archive arrays =====================================================
|
||||
// this functions can be overloaded in Archive implementations for more efficiency
|
||||
template <typename T, typename = std::enable_if_t<is_archivable<T>>>
|
||||
@ -420,6 +473,12 @@ namespace ngcore
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
Archive& operator & (ngcore::Shallow<T>& shallow)
|
||||
{
|
||||
this->Shallow(shallow.val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Archive shared_ptrs =================================================
|
||||
@ -663,7 +722,7 @@ namespace ngcore
|
||||
void SetParallel (bool _parallel) { parallel = _parallel; }
|
||||
|
||||
private:
|
||||
template<typename T, typename Bases, typename CArgs>
|
||||
template<typename T, typename Bases>
|
||||
friend class RegisterClassForArchive;
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
|
@ -37,7 +37,7 @@ namespace ngcore {
|
||||
template <typename T>
|
||||
struct has_shared_from_this
|
||||
{
|
||||
template <typename C> static std::true_type check( decltype( sizeof(&C::shared_from_this() )) ) { return std::true_type(); }
|
||||
template <typename C> static std::true_type check( decltype( sizeof(&C::shared_from_this )) ) { return std::true_type(); }
|
||||
template <typename> static std::false_type check(...) { return std::false_type(); }
|
||||
typedef decltype( check<T>(sizeof(char)) ) type;
|
||||
static constexpr type value = type();
|
||||
@ -45,14 +45,11 @@ namespace ngcore {
|
||||
#endif // NETGEN_PYTHON
|
||||
|
||||
|
||||
template<typename T, typename Bases=std::tuple<>, typename CArgs=std::tuple<>>
|
||||
template<typename T, typename Bases=std::tuple<>>
|
||||
class RegisterClassForArchive
|
||||
{
|
||||
public:
|
||||
std::function<CArgs(T&)> get_cargs;
|
||||
RegisterClassForArchive(std::function<CArgs(T&)> _get_cargs =
|
||||
[](T&) -> std::tuple<> { return std::tuple<>{}; }) :
|
||||
get_cargs(_get_cargs)
|
||||
RegisterClassForArchive()
|
||||
{
|
||||
static_assert(std::is_base_of<Bases, T>::value ||
|
||||
detail::is_base_of_tuple<T, Bases>,
|
||||
@ -60,7 +57,7 @@ namespace ngcore {
|
||||
detail::ClassArchiveInfo info {};
|
||||
info.creator = [](const std::type_info& ti, Archive& ar) -> void*
|
||||
{
|
||||
CArgs args;
|
||||
detail::TCargs<T> args;
|
||||
ar &args;
|
||||
auto nT = detail::constructIfPossible<T>(args);
|
||||
return typeid(T) == ti ? nT
|
||||
@ -71,7 +68,8 @@ namespace ngcore {
|
||||
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));
|
||||
if constexpr(detail::has_GetCArgs_v<T>)
|
||||
ar << static_cast<T*>(p)->GetCArgs();
|
||||
};
|
||||
#ifdef NETGEN_PYTHON
|
||||
info.anyToPyCaster = [](const std::any &a) {
|
||||
|
@ -98,12 +98,14 @@ public:
|
||||
{
|
||||
ar & b;
|
||||
}
|
||||
|
||||
auto GetCArgs()
|
||||
{
|
||||
return make_tuple(a, c);
|
||||
}
|
||||
};
|
||||
|
||||
static RegisterClassForArchive<ClassWithoutDefaultConstructor,
|
||||
tuple<>, tuple<int, double>>
|
||||
regwdc([](ClassWithoutDefaultConstructor& self)
|
||||
{ return make_tuple(self.a, self.c); });
|
||||
static RegisterClassForArchive<ClassWithoutDefaultConstructor> regwdc;
|
||||
|
||||
class OneMoreDerivedClass : public SharedPtrAndPtrHolder {
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user