mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 05:50:32 +05:00
Merge branch 'std_any_to_py_object' into 'master'
Add std::any to py::object caster for archive registered types See merge request jschoeberl/netgen!426
This commit is contained in:
commit
50ef307622
@ -74,6 +74,7 @@ install(FILES ngcore.hpp archive.hpp type_traits.hpp version.hpp ngcore_api.hpp
|
||||
array.hpp taskmanager.hpp concurrentqueue.h localheap.hpp python_ngcore.hpp flags.hpp
|
||||
xbool.hpp signal.hpp bitarray.hpp table.hpp hashtable.hpp ranges.hpp ngstream.hpp
|
||||
simd.hpp simd_avx.hpp simd_avx512.hpp simd_generic.hpp simd_sse.hpp simd_arm64.hpp
|
||||
register_archive.hpp
|
||||
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
||||
|
||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include "archive.hpp"
|
||||
#include "register_archive.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#ifndef WIN32
|
||||
@ -28,4 +29,13 @@ namespace ngcore
|
||||
std::make_unique<std::map<std::string, detail::ClassArchiveInfo>>();
|
||||
return type_register->count(classname) != 0;
|
||||
}
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
pybind11::object CastAnyToPy(const std::any& a)
|
||||
{
|
||||
auto info = Archive::GetArchiveRegister(Demangle(a.type().name()));
|
||||
return info.anyToPyCaster(a);
|
||||
}
|
||||
#endif // NETGEN_PYTHON
|
||||
|
||||
} // namespace ngcore
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef NETGEN_CORE_ARCHIVE_HPP
|
||||
#define NETGEN_CORE_ARCHIVE_HPP
|
||||
|
||||
#include <any>
|
||||
#include <array> // for array
|
||||
#include <complex> // for complex
|
||||
#include <cstring> // for size_t, strlen
|
||||
@ -32,8 +33,11 @@ namespace pybind11
|
||||
namespace ngcore
|
||||
{
|
||||
|
||||
class NGCORE_API Archive;
|
||||
#ifdef NETGEN_PYTHON
|
||||
pybind11::object CastAnyToPy(const std::any& a);
|
||||
#endif // NETGEN_PYTHON
|
||||
|
||||
class NGCORE_API Archive;
|
||||
namespace detail
|
||||
{
|
||||
// create new pointer of type T if it is default constructible, else throw
|
||||
@ -88,6 +92,10 @@ namespace ngcore
|
||||
// This caster takes a void* pointer to the (base)class type_info and returns void* pointing
|
||||
// to the type stored in this info
|
||||
std::function<void*(const std::type_info&, void*)> downcaster;
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
std::function<pybind11::object(const std::any&)> anyToPyCaster;
|
||||
#endif // NETGEN_PYTHON
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
@ -641,6 +649,10 @@ namespace ngcore
|
||||
template<typename T, typename ... Bases>
|
||||
friend class RegisterClassForArchive;
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
friend pybind11::object CastAnyToPy(const std::any&);
|
||||
#endif // NETGEN_PYTHON
|
||||
|
||||
// Returns ClassArchiveInfo of Demangled typeid
|
||||
static const detail::ClassArchiveInfo& GetArchiveRegister(const std::string& classname);
|
||||
// Set ClassArchiveInfo for Demangled typeid, this is done by creating an instance of
|
||||
@ -694,26 +706,6 @@ namespace ngcore
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T, typename ... Bases>
|
||||
class RegisterClassForArchive
|
||||
{
|
||||
public:
|
||||
RegisterClassForArchive()
|
||||
{
|
||||
static_assert(detail::all_of_tmpl<std::is_base_of<Bases,T>::value...>,
|
||||
"Variadic template arguments must be base classes of T");
|
||||
detail::ClassArchiveInfo info {};
|
||||
info.creator = [](const std::type_info& ti) -> 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); };
|
||||
Archive::SetArchiveRegister(std::string(Demangle(typeid(T).name())),info);
|
||||
}
|
||||
};
|
||||
|
||||
// BinaryOutArchive ======================================================================
|
||||
class NGCORE_API BinaryOutArchive : public Archive
|
||||
{
|
||||
|
@ -167,6 +167,7 @@ namespace ngcore
|
||||
int GetNStringListFlags () const { return strlistflags.Size(); }
|
||||
/// number of num-list flags
|
||||
int GetNNumListFlags () const { return numlistflags.Size(); }
|
||||
int GetNAnyFlags() const { return anyflags.Size(); }
|
||||
|
||||
///
|
||||
const std::string & GetStringFlag (int i, std::string & name) const
|
||||
@ -181,6 +182,8 @@ namespace ngcore
|
||||
{ name = strlistflags.GetName(i); return strlistflags[i]; }
|
||||
const Flags & GetFlagsFlag (int i, std::string & name) const
|
||||
{ name = flaglistflags.GetName(i); return flaglistflags[i]; }
|
||||
const std::any& GetAnyFlag(int i, std::string& name) const
|
||||
{ name = anyflags.GetName(i); return anyflags[i]; }
|
||||
};
|
||||
|
||||
/// Print flags
|
||||
|
@ -157,6 +157,11 @@ namespace ngcore
|
||||
auto val = flags.GetDefineFlag(i, key);
|
||||
d[key.c_str()] = val;
|
||||
}
|
||||
for(auto i : Range(flags.GetNAnyFlags()))
|
||||
{
|
||||
auto& a = flags.GetAnyFlag(i, key);
|
||||
d[key.c_str()] = CastAnyToPy(a);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
39
libsrc/core/register_archive.hpp
Normal file
39
libsrc/core/register_archive.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef NETGEN_REGISTER_ARCHIVE_HPP
|
||||
#define NETGEN_REGISTER_ARCHIVE_HPP
|
||||
|
||||
#ifdef NETGEN_PYTHON
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/cast.h>
|
||||
#endif // NETGEN_PYTHON
|
||||
|
||||
#include "archive.hpp"
|
||||
|
||||
namespace ngcore {
|
||||
|
||||
template<typename T, typename ... Bases>
|
||||
class RegisterClassForArchive
|
||||
{
|
||||
public:
|
||||
RegisterClassForArchive()
|
||||
{
|
||||
static_assert(detail::all_of_tmpl<std::is_base_of<Bases,T>::value...>,
|
||||
"Variadic template arguments must be base classes of T");
|
||||
detail::ClassArchiveInfo info {};
|
||||
info.creator = [](const std::type_info& ti) -> 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);
|
||||
return pybind11::cast(val); };
|
||||
#endif // NETGEN_PYTHON
|
||||
Archive::SetArchiveRegister(std::string(Demangle(typeid(T).name())),info);
|
||||
}
|
||||
};
|
||||
} // namespace ngcore
|
||||
#endif // NETGEN_REGISTER_ARCHIVE_HPP
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
|
||||
#include <linalg.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <linalg.hpp>
|
||||
#include <csg.hpp>
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <mystdlib.h>
|
||||
#include <myadt.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <linalg.hpp>
|
||||
#include <csg.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <linalg.hpp>
|
||||
#include <csg.hpp>
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <linalg.hpp>
|
||||
#include <csg.hpp>
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include <csg.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
namespace netgen
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <myadt.hpp>
|
||||
#include <csg.hpp>
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <meshing.hpp>
|
||||
#include <geometry2d.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
namespace netgen
|
||||
{
|
||||
|
@ -9,6 +9,8 @@ Spline curve for Mesh generator
|
||||
#include <gprim.hpp>
|
||||
#include "spline.hpp"
|
||||
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
namespace netgen
|
||||
{
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <mystdlib.h>
|
||||
#include <linalg.hpp>
|
||||
#include <gprim.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
#include "splinegeometry.hpp"
|
||||
|
||||
namespace netgen
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <mystdlib.h>
|
||||
#include "meshing.hpp"
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
namespace netgen
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <mystdlib.h>
|
||||
#include <occgeom.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
#include <cstdio>
|
||||
#include "ShapeAnalysis_ShapeTolerance.hxx"
|
||||
#include "ShapeAnalysis_ShapeContents.hxx"
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <meshing.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include "stlgeom.hpp"
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <mystdlib.h>
|
||||
#include <core/register_archive.hpp>
|
||||
|
||||
#include <myadt.hpp>
|
||||
#include <linalg.hpp>
|
||||
|
@ -14,7 +14,7 @@ add_test(NAME unit_tests_built COMMAND ${CMAKE_COMMAND} --build . --target unit_
|
||||
|
||||
macro(add_unit_test name sources)
|
||||
add_executable(test_${name} ${sources} )
|
||||
target_link_libraries(test_${name} ngcore catch_main nglib ${PYTHON_LIBRARIES})
|
||||
target_link_libraries(test_${name} ngcore catch_main nglib)
|
||||
|
||||
add_dependencies(unit_tests test_${name})
|
||||
add_test(NAME unit_${name} COMMAND test_${name})
|
||||
@ -26,6 +26,8 @@ macro(add_unit_test name sources)
|
||||
endmacro()
|
||||
|
||||
add_unit_test(archive archive.cpp)
|
||||
# RegisterForArchive needs Python.h if built with Python
|
||||
target_link_libraries(test_archive netgen_python)
|
||||
add_unit_test(array array.cpp)
|
||||
add_unit_test(ranges ranges.cpp)
|
||||
add_unit_test(symboltable symboltable.cpp)
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
#include <../core/ngcore.hpp>
|
||||
#include <core/register_archive.hpp>
|
||||
using namespace ngcore;
|
||||
using namespace std;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user