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 <string> // for string
|
||||||
#include <type_traits> // for declval, enable_if_t, false_type, is_co...
|
#include <type_traits> // for declval, enable_if_t, false_type, is_co...
|
||||||
#include <cstddef> // for std::byte
|
#include <cstddef> // for std::byte
|
||||||
|
#include <set> // for set
|
||||||
#include <typeinfo> // for type_info
|
#include <typeinfo> // for type_info
|
||||||
#include <utility> // for move, swap, pair
|
#include <utility> // for move, swap, pair
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
@ -33,6 +34,13 @@ namespace pybind11
|
|||||||
|
|
||||||
namespace ngcore
|
namespace ngcore
|
||||||
{
|
{
|
||||||
|
template <typename T>
|
||||||
|
struct Shallow {
|
||||||
|
T val;
|
||||||
|
Shallow() = default;
|
||||||
|
Shallow(T aval) : val(aval) { ; }
|
||||||
|
operator T&() { return val; }
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef NETGEN_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
pybind11::object CastAnyToPy(const std::any& a);
|
pybind11::object CastAnyToPy(const std::any& a);
|
||||||
@ -101,6 +109,31 @@ namespace ngcore
|
|||||||
NGCORE_API static constexpr bool value = type::value;
|
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
|
struct ClassArchiveInfo
|
||||||
{
|
{
|
||||||
// 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
|
||||||
@ -336,6 +369,26 @@ namespace ngcore
|
|||||||
}
|
}
|
||||||
return (*this);
|
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 =====================================================
|
// Archive arrays =====================================================
|
||||||
// this functions can be overloaded in Archive implementations for more efficiency
|
// this functions can be overloaded in Archive implementations for more efficiency
|
||||||
template <typename T, typename = std::enable_if_t<is_archivable<T>>>
|
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 =================================================
|
// Archive shared_ptrs =================================================
|
||||||
@ -663,7 +722,7 @@ namespace ngcore
|
|||||||
void SetParallel (bool _parallel) { parallel = _parallel; }
|
void SetParallel (bool _parallel) { parallel = _parallel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T, typename Bases, typename CArgs>
|
template<typename T, typename Bases>
|
||||||
friend class RegisterClassForArchive;
|
friend class RegisterClassForArchive;
|
||||||
|
|
||||||
#ifdef NETGEN_PYTHON
|
#ifdef NETGEN_PYTHON
|
||||||
|
@ -37,7 +37,7 @@ namespace ngcore {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct has_shared_from_this
|
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(); }
|
template <typename> static std::false_type check(...) { return std::false_type(); }
|
||||||
typedef decltype( check<T>(sizeof(char)) ) type;
|
typedef decltype( check<T>(sizeof(char)) ) type;
|
||||||
static constexpr type value = type();
|
static constexpr type value = type();
|
||||||
@ -45,14 +45,11 @@ namespace ngcore {
|
|||||||
#endif // NETGEN_PYTHON
|
#endif // NETGEN_PYTHON
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename Bases=std::tuple<>, typename CArgs=std::tuple<>>
|
template<typename T, typename Bases=std::tuple<>>
|
||||||
class RegisterClassForArchive
|
class RegisterClassForArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::function<CArgs(T&)> get_cargs;
|
RegisterClassForArchive()
|
||||||
RegisterClassForArchive(std::function<CArgs(T&)> _get_cargs =
|
|
||||||
[](T&) -> std::tuple<> { return std::tuple<>{}; }) :
|
|
||||||
get_cargs(_get_cargs)
|
|
||||||
{
|
{
|
||||||
static_assert(std::is_base_of<Bases, T>::value ||
|
static_assert(std::is_base_of<Bases, T>::value ||
|
||||||
detail::is_base_of_tuple<T, Bases>,
|
detail::is_base_of_tuple<T, Bases>,
|
||||||
@ -60,7 +57,7 @@ namespace ngcore {
|
|||||||
detail::ClassArchiveInfo info {};
|
detail::ClassArchiveInfo info {};
|
||||||
info.creator = [](const std::type_info& ti, Archive& ar) -> void*
|
info.creator = [](const std::type_info& ti, Archive& ar) -> void*
|
||||||
{
|
{
|
||||||
CArgs args;
|
detail::TCargs<T> args;
|
||||||
ar &args;
|
ar &args;
|
||||||
auto nT = detail::constructIfPossible<T>(args);
|
auto nT = detail::constructIfPossible<T>(args);
|
||||||
return typeid(T) == ti ? nT
|
return typeid(T) == ti ? nT
|
||||||
@ -71,7 +68,8 @@ namespace ngcore {
|
|||||||
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 : Archive::Caster<T, Bases>::tryDowncast(ti, p); };
|
{ return typeid(T) == ti ? p : Archive::Caster<T, Bases>::tryDowncast(ti, p); };
|
||||||
info.cargs_archiver = [this](Archive &ar, void* 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
|
#ifdef NETGEN_PYTHON
|
||||||
info.anyToPyCaster = [](const std::any &a) {
|
info.anyToPyCaster = [](const std::any &a) {
|
||||||
|
@ -98,12 +98,14 @@ public:
|
|||||||
{
|
{
|
||||||
ar & b;
|
ar & b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto GetCArgs()
|
||||||
|
{
|
||||||
|
return make_tuple(a, c);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static RegisterClassForArchive<ClassWithoutDefaultConstructor,
|
static RegisterClassForArchive<ClassWithoutDefaultConstructor> regwdc;
|
||||||
tuple<>, tuple<int, double>>
|
|
||||||
regwdc([](ClassWithoutDefaultConstructor& self)
|
|
||||||
{ return make_tuple(self.a, self.c); });
|
|
||||||
|
|
||||||
class OneMoreDerivedClass : public SharedPtrAndPtrHolder {
|
class OneMoreDerivedClass : public SharedPtrAndPtrHolder {
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user