mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-25 05:20:34 +05:00
Add std::any to py::object caster for archive registered types
This commit is contained in:
parent
8760559690
commit
bd29763b16
@ -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
|
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
|
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
|
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)
|
DESTINATION ${NG_INSTALL_DIR_INCLUDE}/core COMPONENT netgen_devel)
|
||||||
|
|
||||||
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
if(ENABLE_CPP_CORE_GUIDELINES_CHECK)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "archive.hpp"
|
#include "archive.hpp"
|
||||||
|
#include "register_archive.hpp"
|
||||||
#include "version.hpp"
|
#include "version.hpp"
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@ -28,4 +29,13 @@ namespace ngcore
|
|||||||
std::make_unique<std::map<std::string, detail::ClassArchiveInfo>>();
|
std::make_unique<std::map<std::string, detail::ClassArchiveInfo>>();
|
||||||
return type_register->count(classname) != 0;
|
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
|
} // namespace ngcore
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef NETGEN_CORE_ARCHIVE_HPP
|
#ifndef NETGEN_CORE_ARCHIVE_HPP
|
||||||
#define NETGEN_CORE_ARCHIVE_HPP
|
#define NETGEN_CORE_ARCHIVE_HPP
|
||||||
|
|
||||||
|
#include <any>
|
||||||
#include <array> // for array
|
#include <array> // for array
|
||||||
#include <complex> // for complex
|
#include <complex> // for complex
|
||||||
#include <cstring> // for size_t, strlen
|
#include <cstring> // for size_t, strlen
|
||||||
@ -32,8 +33,11 @@ namespace pybind11
|
|||||||
namespace ngcore
|
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
|
namespace detail
|
||||||
{
|
{
|
||||||
// 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
|
||||||
@ -88,6 +92,10 @@ namespace ngcore
|
|||||||
// This caster takes a void* pointer to the (base)class type_info and returns void* pointing
|
// This caster takes a void* pointer to the (base)class type_info and returns void* pointing
|
||||||
// to the type stored in this info
|
// to the type stored in this info
|
||||||
std::function<void*(const std::type_info&, void*)> downcaster;
|
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
|
} // namespace detail
|
||||||
|
|
||||||
@ -641,6 +649,10 @@ namespace ngcore
|
|||||||
template<typename T, typename ... Bases>
|
template<typename T, typename ... Bases>
|
||||||
friend class RegisterClassForArchive;
|
friend class RegisterClassForArchive;
|
||||||
|
|
||||||
|
#ifdef NETGEN_PYTHON
|
||||||
|
friend pybind11::object CastAnyToPy(const std::any&);
|
||||||
|
#endif // NETGEN_PYTHON
|
||||||
|
|
||||||
// Returns ClassArchiveInfo of Demangled typeid
|
// Returns ClassArchiveInfo of Demangled typeid
|
||||||
static const detail::ClassArchiveInfo& GetArchiveRegister(const std::string& classname);
|
static const detail::ClassArchiveInfo& GetArchiveRegister(const std::string& classname);
|
||||||
// Set ClassArchiveInfo for Demangled typeid, this is done by creating an instance of
|
// 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 ======================================================================
|
// BinaryOutArchive ======================================================================
|
||||||
class NGCORE_API BinaryOutArchive : public Archive
|
class NGCORE_API BinaryOutArchive : public Archive
|
||||||
{
|
{
|
||||||
|
@ -167,6 +167,7 @@ namespace ngcore
|
|||||||
int GetNStringListFlags () const { return strlistflags.Size(); }
|
int GetNStringListFlags () const { return strlistflags.Size(); }
|
||||||
/// number of num-list flags
|
/// number of num-list flags
|
||||||
int GetNNumListFlags () const { return numlistflags.Size(); }
|
int GetNNumListFlags () const { return numlistflags.Size(); }
|
||||||
|
int GetNAnyFlags() const { return anyflags.Size(); }
|
||||||
|
|
||||||
///
|
///
|
||||||
const std::string & GetStringFlag (int i, std::string & name) const
|
const std::string & GetStringFlag (int i, std::string & name) const
|
||||||
@ -181,6 +182,8 @@ namespace ngcore
|
|||||||
{ name = strlistflags.GetName(i); return strlistflags[i]; }
|
{ name = strlistflags.GetName(i); return strlistflags[i]; }
|
||||||
const Flags & GetFlagsFlag (int i, std::string & name) const
|
const Flags & GetFlagsFlag (int i, std::string & name) const
|
||||||
{ name = flaglistflags.GetName(i); return flaglistflags[i]; }
|
{ 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
|
/// Print flags
|
||||||
|
@ -157,6 +157,11 @@ namespace ngcore
|
|||||||
auto val = flags.GetDefineFlag(i, key);
|
auto val = flags.GetDefineFlag(i, key);
|
||||||
d[key.c_str()] = val;
|
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;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
libsrc/core/register_archive.hpp
Normal file
42
libsrc/core/register_archive.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
std::cout << "call anytopycast on " << Demangle(a.type().name()) << std::endl;
|
||||||
|
const T* val = std::any_cast<T>(&a);
|
||||||
|
if(!val)
|
||||||
|
throw Exception("Incorrect type in any object!");
|
||||||
|
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 <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
#include <myadt.hpp>
|
#include <myadt.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <myadt.hpp>
|
#include <myadt.hpp>
|
||||||
#include <csg.hpp>
|
#include <csg.hpp>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <meshing.hpp>
|
#include <meshing.hpp>
|
||||||
#include <geometry2d.hpp>
|
#include <geometry2d.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,8 @@ Spline curve for Mesh generator
|
|||||||
#include <gprim.hpp>
|
#include <gprim.hpp>
|
||||||
#include "spline.hpp"
|
#include "spline.hpp"
|
||||||
|
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
#include <gprim.hpp>
|
#include <gprim.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
#include "splinegeometry.hpp"
|
#include "splinegeometry.hpp"
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
#include "meshing.hpp"
|
#include "meshing.hpp"
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
#include <occgeom.hpp>
|
#include <occgeom.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "ShapeAnalysis_ShapeTolerance.hxx"
|
#include "ShapeAnalysis_ShapeTolerance.hxx"
|
||||||
#include "ShapeAnalysis_ShapeContents.hxx"
|
#include "ShapeAnalysis_ShapeContents.hxx"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <meshing.hpp>
|
#include <meshing.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include "stlgeom.hpp"
|
#include "stlgeom.hpp"
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <mystdlib.h>
|
#include <mystdlib.h>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
|
|
||||||
#include <myadt.hpp>
|
#include <myadt.hpp>
|
||||||
#include <linalg.hpp>
|
#include <linalg.hpp>
|
||||||
|
@ -3,7 +3,7 @@ if(ENABLE_UNIT_TESTS)
|
|||||||
add_custom_target(unit_tests)
|
add_custom_target(unit_tests)
|
||||||
|
|
||||||
# Build catch_main test object
|
# Build catch_main test object
|
||||||
include_directories(${CATCH_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../libsrc/include ${SPDLOG_INCLUDE_DIR})
|
include_directories(${CATCH_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../../libsrc/include ${SPDLOG_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS})
|
||||||
add_library(catch_main STATIC main.cpp)
|
add_library(catch_main STATIC main.cpp)
|
||||||
set_target_properties(catch_main PROPERTIES CXX_STANDARD 17)
|
set_target_properties(catch_main PROPERTIES CXX_STANDARD 17)
|
||||||
add_dependencies(unit_tests catch_main)
|
add_dependencies(unit_tests catch_main)
|
||||||
@ -14,7 +14,7 @@ add_test(NAME unit_tests_built COMMAND ${CMAKE_COMMAND} --build . --target unit_
|
|||||||
|
|
||||||
macro(add_unit_test name sources)
|
macro(add_unit_test name sources)
|
||||||
add_executable(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_dependencies(unit_tests test_${name})
|
||||||
add_test(NAME unit_${name} COMMAND test_${name})
|
add_test(NAME unit_${name} COMMAND test_${name})
|
||||||
@ -26,6 +26,10 @@ macro(add_unit_test name sources)
|
|||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
add_unit_test(archive archive.cpp)
|
add_unit_test(archive archive.cpp)
|
||||||
|
if(USE_PYTHON)
|
||||||
|
# RegisterForArchive needs Python.h if built with Python
|
||||||
|
target_link_libraries(test_archive ${PYTHON_LIBRARIES})
|
||||||
|
endif(USE_PYTHON)
|
||||||
add_unit_test(array array.cpp)
|
add_unit_test(array array.cpp)
|
||||||
add_unit_test(ranges ranges.cpp)
|
add_unit_test(ranges ranges.cpp)
|
||||||
add_unit_test(symboltable symboltable.cpp)
|
add_unit_test(symboltable symboltable.cpp)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
#include <../core/ngcore.hpp>
|
#include <../core/ngcore.hpp>
|
||||||
|
#include <core/register_archive.hpp>
|
||||||
using namespace ngcore;
|
using namespace ngcore;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user