netgen-mesher 6.2.2506.post35.dev0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netgen/NgOCC.py +7 -0
- netgen/__init__.py +114 -0
- netgen/__init__.pyi +22 -0
- netgen/__main__.py +53 -0
- netgen/cmake/NetgenConfig.cmake +79 -0
- netgen/cmake/netgen-targets-release.cmake +69 -0
- netgen/cmake/netgen-targets.cmake +146 -0
- netgen/config/__init__.py +1 -0
- netgen/config/__init__.pyi +52 -0
- netgen/config/__main__.py +4 -0
- netgen/config/config.py +68 -0
- netgen/config/config.pyi +54 -0
- netgen/csg.py +25 -0
- netgen/geom2d.py +178 -0
- netgen/gui.py +82 -0
- netgen/include/core/archive.hpp +1256 -0
- netgen/include/core/array.hpp +1760 -0
- netgen/include/core/autodiff.hpp +1131 -0
- netgen/include/core/autodiffdiff.hpp +733 -0
- netgen/include/core/bitarray.hpp +240 -0
- netgen/include/core/concurrentqueue.h +3619 -0
- netgen/include/core/exception.hpp +145 -0
- netgen/include/core/flags.hpp +199 -0
- netgen/include/core/hashtable.hpp +1281 -0
- netgen/include/core/localheap.hpp +318 -0
- netgen/include/core/logging.hpp +117 -0
- netgen/include/core/memtracer.hpp +221 -0
- netgen/include/core/mpi4py_pycapi.h +245 -0
- netgen/include/core/mpi_wrapper.hpp +643 -0
- netgen/include/core/ng_mpi.hpp +94 -0
- netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
- netgen/include/core/ng_mpi_native.hpp +25 -0
- netgen/include/core/ngcore.hpp +32 -0
- netgen/include/core/ngcore_api.hpp +152 -0
- netgen/include/core/ngstream.hpp +115 -0
- netgen/include/core/paje_trace.hpp +279 -0
- netgen/include/core/profiler.hpp +382 -0
- netgen/include/core/python_ngcore.hpp +457 -0
- netgen/include/core/ranges.hpp +109 -0
- netgen/include/core/register_archive.hpp +100 -0
- netgen/include/core/signal.hpp +82 -0
- netgen/include/core/simd.hpp +160 -0
- netgen/include/core/simd_arm64.hpp +407 -0
- netgen/include/core/simd_avx.hpp +394 -0
- netgen/include/core/simd_avx512.hpp +285 -0
- netgen/include/core/simd_generic.hpp +1053 -0
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +289 -0
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/symboltable.hpp +153 -0
- netgen/include/core/table.hpp +810 -0
- netgen/include/core/taskmanager.hpp +1161 -0
- netgen/include/core/type_traits.hpp +65 -0
- netgen/include/core/utils.hpp +385 -0
- netgen/include/core/version.hpp +102 -0
- netgen/include/core/xbool.hpp +47 -0
- netgen/include/csg/algprim.hpp +563 -0
- netgen/include/csg/brick.hpp +150 -0
- netgen/include/csg/csg.hpp +43 -0
- netgen/include/csg/csgeom.hpp +389 -0
- netgen/include/csg/csgparser.hpp +101 -0
- netgen/include/csg/curve2d.hpp +67 -0
- netgen/include/csg/edgeflw.hpp +112 -0
- netgen/include/csg/explicitcurve2d.hpp +113 -0
- netgen/include/csg/extrusion.hpp +185 -0
- netgen/include/csg/gencyl.hpp +70 -0
- netgen/include/csg/geoml.hpp +16 -0
- netgen/include/csg/identify.hpp +213 -0
- netgen/include/csg/manifold.hpp +29 -0
- netgen/include/csg/meshsurf.hpp +46 -0
- netgen/include/csg/polyhedra.hpp +121 -0
- netgen/include/csg/revolution.hpp +180 -0
- netgen/include/csg/singularref.hpp +84 -0
- netgen/include/csg/solid.hpp +295 -0
- netgen/include/csg/specpoin.hpp +194 -0
- netgen/include/csg/spline3d.hpp +99 -0
- netgen/include/csg/splinesurface.hpp +85 -0
- netgen/include/csg/surface.hpp +394 -0
- netgen/include/csg/triapprox.hpp +63 -0
- netgen/include/csg/vscsg.hpp +34 -0
- netgen/include/general/autodiff.hpp +356 -0
- netgen/include/general/autoptr.hpp +39 -0
- netgen/include/general/gzstream.h +121 -0
- netgen/include/general/hashtabl.hpp +1692 -0
- netgen/include/general/myadt.hpp +48 -0
- netgen/include/general/mystring.hpp +226 -0
- netgen/include/general/netgenout.hpp +205 -0
- netgen/include/general/ngarray.hpp +797 -0
- netgen/include/general/ngbitarray.hpp +149 -0
- netgen/include/general/ngpython.hpp +74 -0
- netgen/include/general/optmem.hpp +44 -0
- netgen/include/general/parthreads.hpp +138 -0
- netgen/include/general/seti.hpp +50 -0
- netgen/include/general/sort.hpp +47 -0
- netgen/include/general/spbita2d.hpp +59 -0
- netgen/include/general/stack.hpp +114 -0
- netgen/include/general/table.hpp +280 -0
- netgen/include/general/template.hpp +509 -0
- netgen/include/geom2d/csg2d.hpp +750 -0
- netgen/include/geom2d/geometry2d.hpp +280 -0
- netgen/include/geom2d/spline2d.hpp +234 -0
- netgen/include/geom2d/vsgeom2d.hpp +28 -0
- netgen/include/gprim/adtree.hpp +1392 -0
- netgen/include/gprim/geom2d.hpp +858 -0
- netgen/include/gprim/geom3d.hpp +749 -0
- netgen/include/gprim/geomfuncs.hpp +212 -0
- netgen/include/gprim/geomobjects.hpp +544 -0
- netgen/include/gprim/geomops.hpp +404 -0
- netgen/include/gprim/geomtest3d.hpp +101 -0
- netgen/include/gprim/gprim.hpp +33 -0
- netgen/include/gprim/spline.hpp +778 -0
- netgen/include/gprim/splinegeometry.hpp +73 -0
- netgen/include/gprim/transform3d.hpp +216 -0
- netgen/include/include/acisgeom.hpp +3 -0
- netgen/include/include/csg.hpp +1 -0
- netgen/include/include/geometry2d.hpp +1 -0
- netgen/include/include/gprim.hpp +1 -0
- netgen/include/include/incopengl.hpp +62 -0
- netgen/include/include/inctcl.hpp +13 -0
- netgen/include/include/incvis.hpp +6 -0
- netgen/include/include/linalg.hpp +1 -0
- netgen/include/include/meshing.hpp +1 -0
- netgen/include/include/myadt.hpp +1 -0
- netgen/include/include/mydefs.hpp +70 -0
- netgen/include/include/mystdlib.h +59 -0
- netgen/include/include/netgen_config.hpp +27 -0
- netgen/include/include/netgen_version.hpp +9 -0
- netgen/include/include/nginterface_v2_impl.hpp +395 -0
- netgen/include/include/ngsimd.hpp +1 -0
- netgen/include/include/occgeom.hpp +1 -0
- netgen/include/include/opti.hpp +1 -0
- netgen/include/include/parallel.hpp +1 -0
- netgen/include/include/stlgeom.hpp +1 -0
- netgen/include/include/visual.hpp +1 -0
- netgen/include/interface/rw_medit.hpp +11 -0
- netgen/include/interface/writeuser.hpp +80 -0
- netgen/include/linalg/densemat.hpp +414 -0
- netgen/include/linalg/linalg.hpp +29 -0
- netgen/include/linalg/opti.hpp +142 -0
- netgen/include/linalg/polynomial.hpp +47 -0
- netgen/include/linalg/vector.hpp +217 -0
- netgen/include/meshing/adfront2.hpp +274 -0
- netgen/include/meshing/adfront3.hpp +332 -0
- netgen/include/meshing/basegeom.hpp +370 -0
- netgen/include/meshing/bcfunctions.hpp +53 -0
- netgen/include/meshing/bisect.hpp +72 -0
- netgen/include/meshing/boundarylayer.hpp +113 -0
- netgen/include/meshing/classifyhpel.hpp +1984 -0
- netgen/include/meshing/clusters.hpp +46 -0
- netgen/include/meshing/curvedelems.hpp +274 -0
- netgen/include/meshing/delaunay2d.hpp +73 -0
- netgen/include/meshing/fieldlines.hpp +103 -0
- netgen/include/meshing/findip.hpp +198 -0
- netgen/include/meshing/findip2.hpp +103 -0
- netgen/include/meshing/geomsearch.hpp +69 -0
- netgen/include/meshing/global.hpp +54 -0
- netgen/include/meshing/hpref_hex.hpp +330 -0
- netgen/include/meshing/hpref_prism.hpp +3405 -0
- netgen/include/meshing/hpref_pyramid.hpp +154 -0
- netgen/include/meshing/hpref_quad.hpp +2082 -0
- netgen/include/meshing/hpref_segm.hpp +122 -0
- netgen/include/meshing/hpref_tet.hpp +4230 -0
- netgen/include/meshing/hpref_trig.hpp +848 -0
- netgen/include/meshing/hprefinement.hpp +366 -0
- netgen/include/meshing/improve2.hpp +178 -0
- netgen/include/meshing/improve3.hpp +151 -0
- netgen/include/meshing/localh.hpp +223 -0
- netgen/include/meshing/meshclass.hpp +1076 -0
- netgen/include/meshing/meshfunc.hpp +47 -0
- netgen/include/meshing/meshing.hpp +63 -0
- netgen/include/meshing/meshing2.hpp +163 -0
- netgen/include/meshing/meshing3.hpp +123 -0
- netgen/include/meshing/meshtool.hpp +90 -0
- netgen/include/meshing/meshtype.hpp +1930 -0
- netgen/include/meshing/msghandler.hpp +62 -0
- netgen/include/meshing/paralleltop.hpp +172 -0
- netgen/include/meshing/python_mesh.hpp +206 -0
- netgen/include/meshing/ruler2.hpp +172 -0
- netgen/include/meshing/ruler3.hpp +211 -0
- netgen/include/meshing/soldata.hpp +141 -0
- netgen/include/meshing/specials.hpp +17 -0
- netgen/include/meshing/surfacegeom.hpp +73 -0
- netgen/include/meshing/topology.hpp +1003 -0
- netgen/include/meshing/validate.hpp +21 -0
- netgen/include/meshing/visual_interface.hpp +71 -0
- netgen/include/mydefs.hpp +70 -0
- netgen/include/nginterface.h +474 -0
- netgen/include/nginterface_v2.hpp +406 -0
- netgen/include/nglib.h +697 -0
- netgen/include/nglib_occ.h +50 -0
- netgen/include/occ/occ_edge.hpp +47 -0
- netgen/include/occ/occ_face.hpp +52 -0
- netgen/include/occ/occ_solid.hpp +23 -0
- netgen/include/occ/occ_utils.hpp +376 -0
- netgen/include/occ/occ_vertex.hpp +30 -0
- netgen/include/occ/occgeom.hpp +659 -0
- netgen/include/occ/occmeshsurf.hpp +168 -0
- netgen/include/occ/vsocc.hpp +33 -0
- netgen/include/pybind11/LICENSE +29 -0
- netgen/include/pybind11/attr.h +722 -0
- netgen/include/pybind11/buffer_info.h +208 -0
- netgen/include/pybind11/cast.h +2361 -0
- netgen/include/pybind11/chrono.h +228 -0
- netgen/include/pybind11/common.h +2 -0
- netgen/include/pybind11/complex.h +74 -0
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +823 -0
- netgen/include/pybind11/detail/common.h +1348 -0
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +226 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +538 -0
- netgen/include/pybind11/detail/internals.h +799 -0
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +1591 -0
- netgen/include/pybind11/detail/typeid.h +65 -0
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/common.h +9 -0
- netgen/include/pybind11/eigen/matrix.h +723 -0
- netgen/include/pybind11/eigen/tensor.h +521 -0
- netgen/include/pybind11/eigen.h +12 -0
- netgen/include/pybind11/embed.h +320 -0
- netgen/include/pybind11/eval.h +161 -0
- netgen/include/pybind11/functional.h +147 -0
- netgen/include/pybind11/gil.h +199 -0
- netgen/include/pybind11/gil_safe_call_once.h +102 -0
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/iostream.h +265 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +2312 -0
- netgen/include/pybind11/operators.h +202 -0
- netgen/include/pybind11/options.h +92 -0
- netgen/include/pybind11/pybind11.h +3645 -0
- netgen/include/pybind11/pytypes.h +2680 -0
- netgen/include/pybind11/stl/filesystem.h +114 -0
- netgen/include/pybind11/stl.h +666 -0
- netgen/include/pybind11/stl_bind.h +858 -0
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
- netgen/include/pybind11/typing.h +298 -0
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/stlgeom/meshstlsurface.hpp +67 -0
- netgen/include/stlgeom/stlgeom.hpp +491 -0
- netgen/include/stlgeom/stlline.hpp +193 -0
- netgen/include/stlgeom/stltool.hpp +331 -0
- netgen/include/stlgeom/stltopology.hpp +419 -0
- netgen/include/stlgeom/vsstl.hpp +58 -0
- netgen/include/visualization/meshdoc.hpp +42 -0
- netgen/include/visualization/mvdraw.hpp +325 -0
- netgen/include/visualization/vispar.hpp +128 -0
- netgen/include/visualization/visual.hpp +28 -0
- netgen/include/visualization/visual_api.hpp +10 -0
- netgen/include/visualization/vssolution.hpp +399 -0
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/lib/togl.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.lib +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +1545 -0
- netgen/libngpy/__init__.pyi +7 -0
- netgen/libngpy/_csg.pyi +259 -0
- netgen/libngpy/_geom2d.pyi +323 -0
- netgen/libngpy/_meshing.pyi +1111 -0
- netgen/libngpy/_stl.pyi +131 -0
- netgen/libngpy.lib +0 -0
- netgen/libngpy.pyd +0 -0
- netgen/meshing.py +65 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/occ.py +52 -0
- netgen/read_gmsh.py +259 -0
- netgen/read_meshio.py +22 -0
- netgen/stl.py +2 -0
- netgen/togl.dll +0 -0
- netgen/version.py +2 -0
- netgen/webgui.py +529 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
- netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
- netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
- pyngcore/__init__.py +1 -0
- pyngcore/pyngcore.cp314-win_amd64.pyd +0 -0
|
@@ -0,0 +1,1256 @@
|
|
|
1
|
+
#ifndef NETGEN_CORE_ARCHIVE_HPP
|
|
2
|
+
#define NETGEN_CORE_ARCHIVE_HPP
|
|
3
|
+
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include <any>
|
|
6
|
+
#include <array> // for array
|
|
7
|
+
#include <complex> // for complex
|
|
8
|
+
#include <cstring> // for size_t, strlen
|
|
9
|
+
#include <filesystem> // for path
|
|
10
|
+
#include <fstream> // for ifstream, ofstream
|
|
11
|
+
#include <functional> // for function
|
|
12
|
+
#include <map> // for map
|
|
13
|
+
#include <memory> // for shared_ptr
|
|
14
|
+
#include <optional> // for optional
|
|
15
|
+
#include <string> // for string
|
|
16
|
+
#include <type_traits> // for declval, enable_if_t, false_type, is_co...
|
|
17
|
+
#include <cstddef> // for std::byte
|
|
18
|
+
#include <set> // for set
|
|
19
|
+
#include <typeinfo> // for type_info
|
|
20
|
+
#include <utility> // for move, swap, pair
|
|
21
|
+
#include <vector> // for vector
|
|
22
|
+
|
|
23
|
+
#include "exception.hpp" // for UnreachableCodeException, Exception
|
|
24
|
+
#include "ngcore_api.hpp" // for NGCORE_API
|
|
25
|
+
#include "type_traits.hpp" // for all_of_tmpl
|
|
26
|
+
#include "utils.hpp" // for Demangle, unlikely
|
|
27
|
+
#include "version.hpp" // for VersionInfo
|
|
28
|
+
|
|
29
|
+
#ifdef NETGEN_PYTHON
|
|
30
|
+
namespace pybind11
|
|
31
|
+
{
|
|
32
|
+
class object;
|
|
33
|
+
}
|
|
34
|
+
#endif // NETGEN_PYTHON
|
|
35
|
+
|
|
36
|
+
namespace ngcore
|
|
37
|
+
{
|
|
38
|
+
template <typename T>
|
|
39
|
+
struct Shallow {
|
|
40
|
+
T val;
|
|
41
|
+
Shallow() = default;
|
|
42
|
+
Shallow(T aval) : val(aval) { ; }
|
|
43
|
+
operator T&() { return val; }
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Helper to detect shared_from_this
|
|
47
|
+
template <typename T>
|
|
48
|
+
class has_shared_from_this2
|
|
49
|
+
{
|
|
50
|
+
private:
|
|
51
|
+
// typedef T* T_ptr;
|
|
52
|
+
template <typename C> static std::true_type test(decltype(((C*)nullptr)->shared_from_this()));
|
|
53
|
+
template <typename C> static std::false_type test(...);
|
|
54
|
+
|
|
55
|
+
public:
|
|
56
|
+
// If the test returns true_type, then T has shared_from_this
|
|
57
|
+
static constexpr bool value = decltype(test<T>(0))::value;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
template <typename T, typename = void>
|
|
64
|
+
class has_shallow_archive : public std::false_type {};
|
|
65
|
+
|
|
66
|
+
template <typename T>
|
|
67
|
+
class has_shallow_archive<T, std::void_t<decltype(T::shallow_archive)>>
|
|
68
|
+
: public std::is_same<decltype(T::shallow_archive), std::true_type> {};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#ifdef NETGEN_PYTHON
|
|
73
|
+
NGCORE_API pybind11::object CastAnyToPy(const std::any& a);
|
|
74
|
+
NGCORE_API std::any CastPyToAny(pybind11::object& h);
|
|
75
|
+
#endif // NETGEN_PYTHON
|
|
76
|
+
|
|
77
|
+
class NGCORE_API Archive;
|
|
78
|
+
namespace detail
|
|
79
|
+
{
|
|
80
|
+
template <class T, class Tuple, size_t... Is>
|
|
81
|
+
T* construct_from_tuple(Tuple&& tuple, std::index_sequence<Is...> ) {
|
|
82
|
+
// return new T{std::get<Is>(std::forward<Tuple>(tuple))...};
|
|
83
|
+
return new T{std::get<Is>(std::move(tuple))...};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
template <class T, class Tuple>
|
|
87
|
+
T* construct_from_tuple(Tuple&& tuple) {
|
|
88
|
+
return construct_from_tuple<T>(std::forward<Tuple>(tuple),
|
|
89
|
+
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// create new pointer of type T if it is default constructible, else throw
|
|
94
|
+
template<typename T, typename... TArgs>
|
|
95
|
+
T* constructIfPossible(std::tuple<TArgs...> args)
|
|
96
|
+
{
|
|
97
|
+
if constexpr(std::is_constructible_v<T, TArgs...>)
|
|
98
|
+
return construct_from_tuple<T>(args);
|
|
99
|
+
throw Exception(std::string(Demangle(typeid(T).name())) +
|
|
100
|
+
" is not constructible!");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
template <typename T> T *constructIfPossible()
|
|
104
|
+
{
|
|
105
|
+
if constexpr(std::is_constructible_v<T>)
|
|
106
|
+
return new T();
|
|
107
|
+
throw Exception(std::string(Demangle(typeid(T).name())) +
|
|
108
|
+
" is not default constructible!");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//Type trait to check if a class implements a 'void DoArchive(Archive&)' function
|
|
112
|
+
template<typename T>
|
|
113
|
+
struct has_DoArchive
|
|
114
|
+
{
|
|
115
|
+
private:
|
|
116
|
+
template<typename T2>
|
|
117
|
+
static constexpr auto check(T2*) ->
|
|
118
|
+
typename std::is_same<decltype(std::declval<T2>().DoArchive(std::declval<Archive&>())),void>::type;
|
|
119
|
+
template<typename>
|
|
120
|
+
static constexpr std::false_type check(...);
|
|
121
|
+
using type = decltype(check<T>(nullptr)); // NOLINT
|
|
122
|
+
public:
|
|
123
|
+
NGCORE_API static constexpr bool value = type::value;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Check if class is archivable
|
|
127
|
+
template<typename T>
|
|
128
|
+
struct is_Archivable_struct
|
|
129
|
+
{
|
|
130
|
+
private:
|
|
131
|
+
template<typename T2>
|
|
132
|
+
static constexpr auto check(T2*) ->
|
|
133
|
+
typename std::is_same<decltype(std::declval<Archive>() & std::declval<T2&>()),Archive&>::type;
|
|
134
|
+
template<typename>
|
|
135
|
+
static constexpr std::false_type check(...);
|
|
136
|
+
using type = decltype(check<T>(nullptr)); // NOLINT
|
|
137
|
+
public:
|
|
138
|
+
NGCORE_API static constexpr bool value = type::value;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
template <typename T>
|
|
142
|
+
struct has_GetCArgs
|
|
143
|
+
{
|
|
144
|
+
template <typename C> static std::true_type check( decltype( sizeof(&C::GetCArgs )) ) { return std::true_type(); }
|
|
145
|
+
template <typename> static std::false_type check(...) { return std::false_type(); }
|
|
146
|
+
typedef decltype( check<T>(sizeof(char)) ) type;
|
|
147
|
+
static constexpr type value = type();
|
|
148
|
+
};
|
|
149
|
+
template<typename T>
|
|
150
|
+
constexpr bool has_GetCArgs_v = has_GetCArgs<T>::value;
|
|
151
|
+
|
|
152
|
+
template<typename T,
|
|
153
|
+
typename std::enable_if<!has_GetCArgs_v<T>>::type* = nullptr>
|
|
154
|
+
std::tuple<> GetCArgs(T&val) { return {}; }
|
|
155
|
+
|
|
156
|
+
template<typename T,
|
|
157
|
+
typename std::enable_if<has_GetCArgs_v<T>>::type* = nullptr>
|
|
158
|
+
auto GetCArgs(T&val) {
|
|
159
|
+
return val.GetCArgs();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
template<typename T>
|
|
163
|
+
using TCargs = decltype(GetCArgs<T>(*static_cast<T*>(nullptr)));
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
struct ClassArchiveInfo
|
|
167
|
+
{
|
|
168
|
+
// create new object of this type and return a void* pointer that is points to the location
|
|
169
|
+
// of the (base)class given by type_info
|
|
170
|
+
// std::function<void*(const std::type_info&)> creator;
|
|
171
|
+
void* (*creator)(const std::type_info&, Archive&);
|
|
172
|
+
// This caster takes a void* pointer to the type stored in this info and casts it to a
|
|
173
|
+
// void* pointer pointing to the (base)class type_info
|
|
174
|
+
// std::function<void*(const std::type_info&, void*)> upcaster;
|
|
175
|
+
void* (*upcaster) (const std::type_info&, void*);
|
|
176
|
+
// This caster takes a void* pointer to the (base)class type_info and returns void* pointing
|
|
177
|
+
// to the type stored in this info
|
|
178
|
+
// std::function<void*(const std::type_info&, void*)> downcaster;
|
|
179
|
+
void* (*downcaster)(const std::type_info&, void*);
|
|
180
|
+
|
|
181
|
+
// Archive constructor arguments
|
|
182
|
+
// std::function<void(Archive&, void*)> cargs_archiver;
|
|
183
|
+
void (*cargs_archiver)(Archive&, void*);
|
|
184
|
+
|
|
185
|
+
#ifdef NETGEN_PYTHON
|
|
186
|
+
// std::function<pybind11::object(const std::any&)> anyToPyCaster;
|
|
187
|
+
pybind11::object (*anyToPyCaster)(const std::any&);
|
|
188
|
+
std::any (*pyToAnyCaster)(pybind11::object&);
|
|
189
|
+
#endif // NETGEN_PYTHON
|
|
190
|
+
};
|
|
191
|
+
} // namespace detail
|
|
192
|
+
|
|
193
|
+
template<typename T>
|
|
194
|
+
constexpr bool is_archivable = detail::is_Archivable_struct<T>::value;
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
template <typename T, typename ... Trest>
|
|
198
|
+
constexpr size_t TotSize ()
|
|
199
|
+
{
|
|
200
|
+
if constexpr (sizeof...(Trest) == 0)
|
|
201
|
+
return sizeof(T);
|
|
202
|
+
else
|
|
203
|
+
return sizeof(T) + TotSize<Trest...> ();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
// Base Archive class
|
|
208
|
+
class NGCORE_API Archive
|
|
209
|
+
{
|
|
210
|
+
const bool is_output;
|
|
211
|
+
// how many different shared_ptr/pointer have been (un)archived
|
|
212
|
+
int shared_ptr_count{0}, ptr_count{0};
|
|
213
|
+
// maps for archived shared pointers and pointers
|
|
214
|
+
std::map<void*, int> shared_ptr2nr{}, ptr2nr{};
|
|
215
|
+
// vectors for storing the unarchived (shared) pointers
|
|
216
|
+
std::vector<std::shared_ptr<void>> nr2shared_ptr{};
|
|
217
|
+
std::vector<void*> nr2ptr{};
|
|
218
|
+
protected:
|
|
219
|
+
bool shallow_to_python = false;
|
|
220
|
+
std::map<std::string, VersionInfo> version_map = GetLibraryVersions();
|
|
221
|
+
public:
|
|
222
|
+
template<typename T>
|
|
223
|
+
static constexpr bool is_archivable = detail::is_Archivable_struct<T>::value;
|
|
224
|
+
|
|
225
|
+
Archive() = delete;
|
|
226
|
+
Archive(const Archive&) = delete;
|
|
227
|
+
Archive(Archive&&) = delete;
|
|
228
|
+
Archive (bool ais_output) : is_output(ais_output) { ; }
|
|
229
|
+
|
|
230
|
+
virtual ~Archive() { ; }
|
|
231
|
+
|
|
232
|
+
// If the object is pickled, all shallow archived objects will be pickled as a list,
|
|
233
|
+
// instead of written as a binary archive. This allows pickle to serialize every object only
|
|
234
|
+
// once and put them together correctly afterwards. Therefore all objects that may live in
|
|
235
|
+
// Python should be archived using this Shallow function. If Shallow is called from C++ code
|
|
236
|
+
// it archives the object normally.
|
|
237
|
+
#ifdef NETGEN_PYTHON
|
|
238
|
+
template<typename T>
|
|
239
|
+
Archive& Shallow(T& val); // implemented in register_archive.hpp
|
|
240
|
+
#ifndef __CUDACC__
|
|
241
|
+
Archive& Shallow(std::any& val); // implemented in python_ngcore.cpp
|
|
242
|
+
#endif // __CUDACC__
|
|
243
|
+
#else // NETGEN_PYTHON
|
|
244
|
+
template<typename T>
|
|
245
|
+
Archive& Shallow(T& val)
|
|
246
|
+
{
|
|
247
|
+
static_assert(detail::is_any_pointer<T>, "ShallowArchive must be given pointer type!");
|
|
248
|
+
*this & val;
|
|
249
|
+
return *this;
|
|
250
|
+
}
|
|
251
|
+
#endif // NETGEN_PYTHON
|
|
252
|
+
|
|
253
|
+
#ifdef NETGEN_PYTHON
|
|
254
|
+
virtual void ShallowOutPython(const pybind11::object& /*unused*/)
|
|
255
|
+
{ throw UnreachableCodeException{}; }
|
|
256
|
+
virtual void ShallowInPython(pybind11::object &)
|
|
257
|
+
{ throw UnreachableCodeException{}; }
|
|
258
|
+
#endif // NETGEN_PYTHON
|
|
259
|
+
|
|
260
|
+
Archive& operator=(const Archive&) = delete;
|
|
261
|
+
Archive& operator=(Archive&&) = delete;
|
|
262
|
+
|
|
263
|
+
bool Output () const { return is_output; }
|
|
264
|
+
bool Input () const { return !is_output; }
|
|
265
|
+
const VersionInfo& GetVersion(const std::string& library)
|
|
266
|
+
{ return version_map[library]; }
|
|
267
|
+
|
|
268
|
+
// only used for PyArchive
|
|
269
|
+
virtual void NeedsVersion(const std::string& /*unused*/, const std::string& /*unused*/) {}
|
|
270
|
+
|
|
271
|
+
// Pure virtual functions that have to be implemented by In-/OutArchive
|
|
272
|
+
virtual Archive & operator & (std::byte & d) = 0;
|
|
273
|
+
virtual Archive & operator & (float & d) = 0;
|
|
274
|
+
virtual Archive & operator & (double & d) = 0;
|
|
275
|
+
virtual Archive & operator & (int & i) = 0;
|
|
276
|
+
virtual Archive & operator & (long & i) = 0;
|
|
277
|
+
virtual Archive & operator & (size_t & i) = 0;
|
|
278
|
+
virtual Archive & operator & (short & i) = 0;
|
|
279
|
+
virtual Archive & operator & (unsigned char & i) = 0;
|
|
280
|
+
virtual Archive & operator & (bool & b) = 0;
|
|
281
|
+
virtual Archive & operator & (std::string & str) = 0;
|
|
282
|
+
virtual Archive & operator & (char *& str) = 0;
|
|
283
|
+
|
|
284
|
+
Archive & operator &(std::any& a)
|
|
285
|
+
{
|
|
286
|
+
Shallow(a);
|
|
287
|
+
return *this;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
Archive & operator & (VersionInfo & version)
|
|
291
|
+
{
|
|
292
|
+
if(Output())
|
|
293
|
+
(*this) << version.to_string();
|
|
294
|
+
else
|
|
295
|
+
{
|
|
296
|
+
std::string s;
|
|
297
|
+
(*this) & s;
|
|
298
|
+
version = VersionInfo(s);
|
|
299
|
+
}
|
|
300
|
+
return *this;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Archive std classes ================================================
|
|
304
|
+
template<typename T>
|
|
305
|
+
Archive& operator & (std::complex<T>& c)
|
|
306
|
+
{
|
|
307
|
+
if(Output())
|
|
308
|
+
(*this) << c.real() << c.imag();
|
|
309
|
+
else
|
|
310
|
+
{
|
|
311
|
+
T tmp;
|
|
312
|
+
(*this) & tmp;
|
|
313
|
+
c.real(tmp);
|
|
314
|
+
(*this) & tmp;
|
|
315
|
+
c.imag(tmp);
|
|
316
|
+
}
|
|
317
|
+
return (*this);
|
|
318
|
+
}
|
|
319
|
+
template<typename T>
|
|
320
|
+
Archive& operator & (std::vector<T>& v)
|
|
321
|
+
{
|
|
322
|
+
size_t size;
|
|
323
|
+
if(Output())
|
|
324
|
+
size = v.size();
|
|
325
|
+
(*this) & size;
|
|
326
|
+
if(Input())
|
|
327
|
+
v.resize(size);
|
|
328
|
+
Do(&v[0], size);
|
|
329
|
+
return (*this);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// archive implementation for enums
|
|
333
|
+
template<typename T>
|
|
334
|
+
auto operator & (T& val) -> std::enable_if_t<std::is_enum<T>::value, Archive&>
|
|
335
|
+
{
|
|
336
|
+
int enumval;
|
|
337
|
+
if(Output())
|
|
338
|
+
enumval = int(val);
|
|
339
|
+
*this & enumval;
|
|
340
|
+
if(Input())
|
|
341
|
+
val = T(enumval);
|
|
342
|
+
return *this;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// vector<bool> has special implementation (like a bitarray) therefore
|
|
346
|
+
// it needs a special overload (this could probably be more efficient, but we
|
|
347
|
+
// don't use it that often anyway)
|
|
348
|
+
Archive& operator& (std::vector<bool>& v)
|
|
349
|
+
{
|
|
350
|
+
size_t size;
|
|
351
|
+
if(Output())
|
|
352
|
+
size = v.size();
|
|
353
|
+
(*this) & size;
|
|
354
|
+
if(Input())
|
|
355
|
+
{
|
|
356
|
+
v.resize(size);
|
|
357
|
+
bool b;
|
|
358
|
+
for(size_t i=0; i<size; i++)
|
|
359
|
+
{
|
|
360
|
+
(*this) & b;
|
|
361
|
+
v[i] = b;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else
|
|
365
|
+
{
|
|
366
|
+
for(bool b : v)
|
|
367
|
+
(*this) & b;
|
|
368
|
+
}
|
|
369
|
+
return *this;
|
|
370
|
+
}
|
|
371
|
+
template<typename T1, typename T2>
|
|
372
|
+
Archive& operator& (std::map<T1, T2>& map)
|
|
373
|
+
{
|
|
374
|
+
if(Output())
|
|
375
|
+
{
|
|
376
|
+
(*this) << size_t(map.size());
|
|
377
|
+
for(auto& pair : map)
|
|
378
|
+
(*this) << pair.first << pair.second;
|
|
379
|
+
}
|
|
380
|
+
else
|
|
381
|
+
{
|
|
382
|
+
size_t size = 0;
|
|
383
|
+
(*this) & size;
|
|
384
|
+
T1 key; T2 val;
|
|
385
|
+
for(size_t i = 0; i < size; i++)
|
|
386
|
+
{
|
|
387
|
+
T1 key; T2 val;
|
|
388
|
+
(*this) & key & val;
|
|
389
|
+
map[key] = val;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return (*this);
|
|
393
|
+
}
|
|
394
|
+
template<typename T>
|
|
395
|
+
Archive& operator& (std::optional<T>& opt)
|
|
396
|
+
{
|
|
397
|
+
bool has_value = opt.has_value();
|
|
398
|
+
(*this) & has_value;
|
|
399
|
+
if(has_value)
|
|
400
|
+
{
|
|
401
|
+
if(Output())
|
|
402
|
+
(*this) << *opt;
|
|
403
|
+
else
|
|
404
|
+
{
|
|
405
|
+
T value;
|
|
406
|
+
(*this) & value;
|
|
407
|
+
opt = value;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return (*this);
|
|
411
|
+
}
|
|
412
|
+
template <typename T>
|
|
413
|
+
Archive& operator&(std::set<T> &s)
|
|
414
|
+
{
|
|
415
|
+
auto size = s.size();
|
|
416
|
+
(*this) & size;
|
|
417
|
+
if(Output())
|
|
418
|
+
for(const auto & val : s)
|
|
419
|
+
(*this) << val;
|
|
420
|
+
else
|
|
421
|
+
{
|
|
422
|
+
for(size_t i=0; i<size; i++)
|
|
423
|
+
{
|
|
424
|
+
T val;
|
|
425
|
+
(*this) & val;
|
|
426
|
+
s.insert(val);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return *this;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Archive arrays =====================================================
|
|
433
|
+
// this functions can be overloaded in Archive implementations for more efficiency
|
|
434
|
+
template <typename T, typename = std::enable_if_t<is_archivable<T>>>
|
|
435
|
+
Archive & Do (T * data, size_t n)
|
|
436
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & data[j]; }; return *this; }; // NOLINT
|
|
437
|
+
|
|
438
|
+
virtual Archive & Do (std::byte * d, size_t n)
|
|
439
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & d[j]; }; return *this; }; // NOLINT
|
|
440
|
+
|
|
441
|
+
virtual Archive & Do (double * d, size_t n)
|
|
442
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & d[j]; }; return *this; }; // NOLINT
|
|
443
|
+
|
|
444
|
+
virtual Archive & Do (int * i, size_t n)
|
|
445
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & i[j]; }; return *this; }; // NOLINT
|
|
446
|
+
|
|
447
|
+
virtual Archive & Do (long * i, size_t n)
|
|
448
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & i[j]; }; return *this; }; // NOLINT
|
|
449
|
+
|
|
450
|
+
virtual Archive & Do (size_t * i, size_t n)
|
|
451
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & i[j]; }; return *this; }; // NOLINT
|
|
452
|
+
|
|
453
|
+
virtual Archive & Do (short * i, size_t n)
|
|
454
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & i[j]; }; return *this; }; // NOLINT
|
|
455
|
+
|
|
456
|
+
virtual Archive & Do (unsigned char * i, size_t n)
|
|
457
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & i[j]; }; return *this; }; // NOLINT
|
|
458
|
+
|
|
459
|
+
virtual Archive & Do (bool * b, size_t n)
|
|
460
|
+
{ for (size_t j = 0; j < n; j++) { (*this) & b[j]; }; return *this; }; // NOLINT
|
|
461
|
+
|
|
462
|
+
// Archive a class implementing a (void DoArchive(Archive&)) method =======
|
|
463
|
+
template<typename T, typename=std::enable_if_t<detail::has_DoArchive<T>::value>>
|
|
464
|
+
Archive& operator & (T& val)
|
|
465
|
+
{
|
|
466
|
+
val.DoArchive(*this); return *this;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
// pack elements to binary
|
|
473
|
+
template <typename ... Types>
|
|
474
|
+
Archive & DoPacked (Types & ... args)
|
|
475
|
+
{
|
|
476
|
+
if (true) // (isbinary)
|
|
477
|
+
{
|
|
478
|
+
constexpr size_t totsize = TotSize<Types...>(); // (args...);
|
|
479
|
+
std::byte mem[totsize];
|
|
480
|
+
if (is_output)
|
|
481
|
+
{
|
|
482
|
+
CopyToBin (&mem[0], args...);
|
|
483
|
+
Do(&mem[0], totsize);
|
|
484
|
+
}
|
|
485
|
+
else
|
|
486
|
+
{
|
|
487
|
+
Do(&mem[0], totsize);
|
|
488
|
+
CopyFromBin (&mem[0], args...);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// else
|
|
492
|
+
// cout << "DoPacked of non-binary called --> individual pickling" << endl;
|
|
493
|
+
return *this;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
template <typename T, typename ... Trest>
|
|
498
|
+
constexpr void CopyToBin (std::byte * ptr, T & first, Trest & ...rest) const
|
|
499
|
+
{
|
|
500
|
+
memcpy (ptr, &first, sizeof(first));
|
|
501
|
+
CopyToBin(ptr+sizeof(first), rest...);
|
|
502
|
+
}
|
|
503
|
+
constexpr void CopyToBin (std::byte * ptr) const { }
|
|
504
|
+
|
|
505
|
+
template <typename T, typename ... Trest>
|
|
506
|
+
constexpr void CopyFromBin (std::byte * ptr, T & first, Trest & ...rest) const
|
|
507
|
+
{
|
|
508
|
+
memcpy (&first, ptr, sizeof(first));
|
|
509
|
+
CopyFromBin(ptr+sizeof(first), rest...);
|
|
510
|
+
}
|
|
511
|
+
constexpr void CopyFromBin (std::byte * ptr) const { }
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
template <typename T>
|
|
517
|
+
Archive& operator & (ngcore::Shallow<T>& shallow)
|
|
518
|
+
{
|
|
519
|
+
if(shallow_to_python)
|
|
520
|
+
Shallow(shallow.val);
|
|
521
|
+
return *this;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
// Archive shared_ptrs =================================================
|
|
526
|
+
template <typename T>
|
|
527
|
+
Archive& operator & (std::shared_ptr<T>& ptr)
|
|
528
|
+
{
|
|
529
|
+
if constexpr(has_shallow_archive<T>::value)
|
|
530
|
+
if (shallow_to_python)
|
|
531
|
+
{
|
|
532
|
+
Shallow (ptr);
|
|
533
|
+
return *this;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if(Output())
|
|
537
|
+
{
|
|
538
|
+
// save -2 for nullptr
|
|
539
|
+
if(!ptr)
|
|
540
|
+
return (*this) << -2;
|
|
541
|
+
|
|
542
|
+
void* reg_ptr = ptr.get();
|
|
543
|
+
bool neededDowncast = false;
|
|
544
|
+
// Downcasting is only possible for our registered classes
|
|
545
|
+
if(typeid(T) != typeid(*ptr))
|
|
546
|
+
{
|
|
547
|
+
if(!IsRegistered(Demangle(typeid(*ptr).name())))
|
|
548
|
+
throw Exception(std::string("Archive error: Polymorphic type ")
|
|
549
|
+
+ Demangle(typeid(*ptr).name())
|
|
550
|
+
+ " not registered for archive");
|
|
551
|
+
reg_ptr = GetArchiveRegister(Demangle(typeid(*ptr).name())).downcaster(typeid(T), ptr.get());
|
|
552
|
+
// if there was a true downcast we have to store more information
|
|
553
|
+
if(reg_ptr != static_cast<void*>(ptr.get()))
|
|
554
|
+
neededDowncast = true;
|
|
555
|
+
}
|
|
556
|
+
auto pos = shared_ptr2nr.find(reg_ptr);
|
|
557
|
+
// if not found store -1 and the pointer
|
|
558
|
+
if(pos == shared_ptr2nr.end())
|
|
559
|
+
{
|
|
560
|
+
auto p = ptr.get();
|
|
561
|
+
(*this) << -1;
|
|
562
|
+
(*this) & neededDowncast & p;
|
|
563
|
+
// if we did downcast we store the true type as well
|
|
564
|
+
if(neededDowncast)
|
|
565
|
+
(*this) << Demangle(typeid(*ptr).name());
|
|
566
|
+
shared_ptr2nr[reg_ptr] = shared_ptr_count++;
|
|
567
|
+
return *this;
|
|
568
|
+
}
|
|
569
|
+
// if found store the position and if it has to be downcasted and how
|
|
570
|
+
(*this) << pos->second << neededDowncast;
|
|
571
|
+
if(neededDowncast)
|
|
572
|
+
(*this) << Demangle(typeid(*ptr).name());
|
|
573
|
+
}
|
|
574
|
+
else // Input
|
|
575
|
+
{
|
|
576
|
+
int nr;
|
|
577
|
+
(*this) & nr;
|
|
578
|
+
// -2 restores a nullptr
|
|
579
|
+
if(nr == -2)
|
|
580
|
+
{
|
|
581
|
+
ptr = nullptr;
|
|
582
|
+
return *this;
|
|
583
|
+
}
|
|
584
|
+
// -1 restores a new shared ptr by restoring the inner pointer and creating a shared_ptr to it
|
|
585
|
+
if (nr == -1)
|
|
586
|
+
{
|
|
587
|
+
T* p = nullptr;
|
|
588
|
+
bool neededDowncast;
|
|
589
|
+
(*this) & neededDowncast & p;
|
|
590
|
+
ptr = std::shared_ptr<T>(p);
|
|
591
|
+
// if we did downcast we need to store a shared_ptr<void> to the true object
|
|
592
|
+
if(neededDowncast)
|
|
593
|
+
{
|
|
594
|
+
std::string name;
|
|
595
|
+
(*this) & name;
|
|
596
|
+
auto info = GetArchiveRegister(name);
|
|
597
|
+
// for this we use an aliasing constructor to create a shared pointer sharing lifetime
|
|
598
|
+
// with our shared ptr, but pointing to the true object
|
|
599
|
+
nr2shared_ptr.push_back(std::shared_ptr<void>(std::static_pointer_cast<void>(ptr),
|
|
600
|
+
info.downcaster(typeid(T),
|
|
601
|
+
ptr.get())));
|
|
602
|
+
}
|
|
603
|
+
else
|
|
604
|
+
nr2shared_ptr.push_back(ptr);
|
|
605
|
+
}
|
|
606
|
+
else
|
|
607
|
+
{
|
|
608
|
+
auto other = nr2shared_ptr[nr];
|
|
609
|
+
bool neededDowncast;
|
|
610
|
+
(*this) & neededDowncast;
|
|
611
|
+
if(neededDowncast)
|
|
612
|
+
{
|
|
613
|
+
// if there was a downcast we can expect the class to be registered (since archiving
|
|
614
|
+
// wouldn't have worked else)
|
|
615
|
+
std::string name;
|
|
616
|
+
(*this) & name;
|
|
617
|
+
auto info = GetArchiveRegister(name);
|
|
618
|
+
// same trick as above, create a shared ptr sharing lifetime with
|
|
619
|
+
// the shared_ptr<void> in the register, but pointing to our object
|
|
620
|
+
ptr = std::static_pointer_cast<T>(std::shared_ptr<void>(other,
|
|
621
|
+
info.upcaster(typeid(T),
|
|
622
|
+
other.get())));
|
|
623
|
+
}
|
|
624
|
+
else
|
|
625
|
+
{
|
|
626
|
+
ptr = std::static_pointer_cast<T>(other);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return *this;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Archive pointers =======================================================
|
|
634
|
+
template <typename T>
|
|
635
|
+
Archive & operator& (T *& p)
|
|
636
|
+
{
|
|
637
|
+
if (Output())
|
|
638
|
+
{
|
|
639
|
+
// if the pointer is null store -2
|
|
640
|
+
if (!p)
|
|
641
|
+
return (*this) << -2;
|
|
642
|
+
auto reg_ptr = static_cast<void*>(p);
|
|
643
|
+
if(typeid(T) != typeid(*p))
|
|
644
|
+
{
|
|
645
|
+
if(!IsRegistered(Demangle(typeid(*p).name())))
|
|
646
|
+
throw Exception(std::string("Archive error: Polymorphic type ")
|
|
647
|
+
+ Demangle(typeid(*p).name())
|
|
648
|
+
+ " not registered for archive");
|
|
649
|
+
reg_ptr = GetArchiveRegister(Demangle(typeid(*p).name())).downcaster(typeid(T), static_cast<void*>(p));
|
|
650
|
+
}
|
|
651
|
+
auto pos = ptr2nr.find(reg_ptr);
|
|
652
|
+
// if the pointer is not found in the map create a new entry
|
|
653
|
+
if (pos == ptr2nr.end())
|
|
654
|
+
{
|
|
655
|
+
ptr2nr[reg_ptr] = ptr_count++;
|
|
656
|
+
if(typeid(*p) == typeid(T))
|
|
657
|
+
if (std::is_constructible<T>::value)
|
|
658
|
+
return (*this) << -1 & (*p);
|
|
659
|
+
else
|
|
660
|
+
{
|
|
661
|
+
if (IsRegistered(Demangle(typeid(*p).name())))
|
|
662
|
+
{
|
|
663
|
+
(*this) << -3 << Demangle(typeid(*p).name());
|
|
664
|
+
GetArchiveRegister(Demangle(typeid(*p).name())).
|
|
665
|
+
cargs_archiver(*this, p);
|
|
666
|
+
return (*this) & (*p);
|
|
667
|
+
}
|
|
668
|
+
else
|
|
669
|
+
throw Exception(std::string("Archive error: Class ") +
|
|
670
|
+
Demangle(typeid(*p).name()) + " does not provide a default constructor!");
|
|
671
|
+
}
|
|
672
|
+
else
|
|
673
|
+
{
|
|
674
|
+
// if a pointer to a base class is archived, the class hierarchy must be registered
|
|
675
|
+
// to avoid compile time issues we allow this behaviour only for "our" classes that
|
|
676
|
+
// implement a void DoArchive(Archive&) member function
|
|
677
|
+
// To recreate the object we need to store the true type of it
|
|
678
|
+
if(!IsRegistered(Demangle(typeid(*p).name())))
|
|
679
|
+
throw Exception(std::string("Archive error: Polymorphic type ")
|
|
680
|
+
+ Demangle(typeid(*p).name())
|
|
681
|
+
+ " not registered for archive");
|
|
682
|
+
(*this) << -3 << Demangle(typeid(*p).name());
|
|
683
|
+
GetArchiveRegister(Demangle(typeid(*p).name())).
|
|
684
|
+
cargs_archiver(*this, p);
|
|
685
|
+
return (*this) & (*p);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
else
|
|
689
|
+
{
|
|
690
|
+
(*this) & pos->second;
|
|
691
|
+
bool downcasted = !(reg_ptr == static_cast<void*>(p) );
|
|
692
|
+
// store if the class has been downcasted and the name
|
|
693
|
+
(*this) << downcasted << Demangle(typeid(*p).name());
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
else
|
|
697
|
+
{
|
|
698
|
+
int nr;
|
|
699
|
+
(*this) & nr;
|
|
700
|
+
if (nr == -2) // restore a nullptr
|
|
701
|
+
p = nullptr;
|
|
702
|
+
else if (nr == -1) // create a new pointer of standard type (no virtual or multiple inheritance,...)
|
|
703
|
+
{
|
|
704
|
+
p = detail::constructIfPossible<T>();
|
|
705
|
+
nr2ptr.push_back(p);
|
|
706
|
+
(*this) & *p;
|
|
707
|
+
}
|
|
708
|
+
else if(nr == -3) // restore one of our registered classes that can have multiple inheritance,...
|
|
709
|
+
{
|
|
710
|
+
// As stated above, we want this special behaviour only for our classes that implement DoArchive
|
|
711
|
+
std::string name;
|
|
712
|
+
(*this) & name;
|
|
713
|
+
auto info = GetArchiveRegister(name);
|
|
714
|
+
// the creator creates a new object of type name, and returns a void* pointing
|
|
715
|
+
// to T (which may have an offset)
|
|
716
|
+
p = static_cast<T*>(info.creator(typeid(T), *this));
|
|
717
|
+
// we store the downcasted pointer (to be able to find it again from
|
|
718
|
+
// another class in a multiple inheritance tree)
|
|
719
|
+
nr2ptr.push_back(info.downcaster(typeid(T),p));
|
|
720
|
+
(*this) & *p;
|
|
721
|
+
}
|
|
722
|
+
else
|
|
723
|
+
{
|
|
724
|
+
bool downcasted;
|
|
725
|
+
std::string name;
|
|
726
|
+
(*this) & downcasted & name;
|
|
727
|
+
if(downcasted)
|
|
728
|
+
{
|
|
729
|
+
// if the class has been downcasted we can assume it is in the register
|
|
730
|
+
auto info = GetArchiveRegister(name);
|
|
731
|
+
p = static_cast<T*>(info.upcaster(typeid(T), nr2ptr[nr]));
|
|
732
|
+
}
|
|
733
|
+
else
|
|
734
|
+
p = static_cast<T*>(nr2ptr[nr]);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return *this;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
Archive& operator&(std::tuple<>&) { return *this; }
|
|
741
|
+
|
|
742
|
+
template <typename... T>
|
|
743
|
+
Archive& operator&(std::tuple<T...> &t)
|
|
744
|
+
{
|
|
745
|
+
// call operator& for each element of the tuple
|
|
746
|
+
std::apply([this](auto&... arg) { std::make_tuple(((*this) & arg).IsParallel()...);}, t);
|
|
747
|
+
return *this;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// const ptr
|
|
751
|
+
template<typename T>
|
|
752
|
+
Archive& operator &(const T*& t)
|
|
753
|
+
{
|
|
754
|
+
return (*this) & const_cast<T*&>(t); // NOLINT
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// Write a read only variable
|
|
758
|
+
template <typename T>
|
|
759
|
+
Archive & operator << (const T & t)
|
|
760
|
+
{
|
|
761
|
+
T ht(t);
|
|
762
|
+
(*this) & ht;
|
|
763
|
+
return *this;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
virtual void FlushBuffer() {}
|
|
767
|
+
|
|
768
|
+
bool parallel = false;
|
|
769
|
+
bool IsParallel() const { return parallel; }
|
|
770
|
+
void SetParallel (bool _parallel) { parallel = _parallel; }
|
|
771
|
+
|
|
772
|
+
private:
|
|
773
|
+
template<typename T, typename Bases>
|
|
774
|
+
friend class RegisterClassForArchive;
|
|
775
|
+
|
|
776
|
+
#ifdef NETGEN_PYTHON
|
|
777
|
+
friend pybind11::object CastAnyToPy(const std::any&);
|
|
778
|
+
friend std::any CastPyToAny(pybind11::object&);
|
|
779
|
+
#endif // NETGEN_PYTHON
|
|
780
|
+
|
|
781
|
+
// Returns ClassArchiveInfo of Demangled typeid
|
|
782
|
+
static const detail::ClassArchiveInfo& GetArchiveRegister(const std::string& classname);
|
|
783
|
+
// Set ClassArchiveInfo for Demangled typeid, this is done by creating an instance of
|
|
784
|
+
// RegisterClassForArchive<type, bases...>
|
|
785
|
+
static void SetArchiveRegister(const std::string& classname, const detail::ClassArchiveInfo& info);
|
|
786
|
+
static bool IsRegistered(const std::string& classname);
|
|
787
|
+
|
|
788
|
+
// Helper class for up-/downcasting
|
|
789
|
+
template<typename T, typename ... Bases>
|
|
790
|
+
struct Caster{};
|
|
791
|
+
|
|
792
|
+
template<typename T>
|
|
793
|
+
struct Caster<T, std::tuple<>>
|
|
794
|
+
{
|
|
795
|
+
static void* tryUpcast (const std::type_info& /*unused*/, T* /*unused*/)
|
|
796
|
+
{
|
|
797
|
+
throw Exception("Upcast not successful, some classes are not registered properly for archiving!");
|
|
798
|
+
}
|
|
799
|
+
static void* tryDowncast (const std::type_info& /*unused*/, void* /*unused*/)
|
|
800
|
+
{
|
|
801
|
+
throw Exception("Downcast not successful, some classes are not registered properly for archiving!");
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
template<typename T, typename B1>
|
|
806
|
+
struct Caster<T,B1>
|
|
807
|
+
{
|
|
808
|
+
static void* tryUpcast(const std::type_info& ti, T* p)
|
|
809
|
+
{
|
|
810
|
+
try {
|
|
811
|
+
return GetArchiveRegister(Demangle(typeid(B1).name()))
|
|
812
|
+
.upcaster(ti, static_cast<void *>(dynamic_cast<B1 *>(p)));
|
|
813
|
+
} catch (const Exception &) {
|
|
814
|
+
throw Exception("Upcast not successful, some classes are not "
|
|
815
|
+
"registered properly for archiving!");
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
static void* tryDowncast(const std::type_info& ti, void* p)
|
|
820
|
+
{
|
|
821
|
+
if(typeid(B1) == ti)
|
|
822
|
+
return dynamic_cast<T*>(static_cast<B1*>(p));
|
|
823
|
+
try
|
|
824
|
+
{
|
|
825
|
+
return dynamic_cast<T*>(static_cast<B1*>(GetArchiveRegister(Demangle(typeid(B1).name())).
|
|
826
|
+
downcaster(ti, p)));
|
|
827
|
+
} catch (const Exception &) {
|
|
828
|
+
throw Exception("Downcast not successful, some classes are not "
|
|
829
|
+
"registered properly for archiving!");
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
template<typename T, typename B1, typename ... Brest>
|
|
835
|
+
struct Caster<T,std::tuple<B1, Brest...>>
|
|
836
|
+
{
|
|
837
|
+
static void* tryUpcast(const std::type_info& ti, T* p)
|
|
838
|
+
{
|
|
839
|
+
try
|
|
840
|
+
{ return GetArchiveRegister(Demangle(typeid(B1).name())).
|
|
841
|
+
upcaster(ti, static_cast<void*>(dynamic_cast<B1*>(p))); }
|
|
842
|
+
catch(const Exception&)
|
|
843
|
+
{ return Caster<T, std::tuple<Brest...>>::tryUpcast(ti, p); }
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
static void* tryDowncast(const std::type_info& ti, void* p)
|
|
847
|
+
{
|
|
848
|
+
if(typeid(B1) == ti)
|
|
849
|
+
return dynamic_cast<T*>(static_cast<B1*>(p));
|
|
850
|
+
try
|
|
851
|
+
{
|
|
852
|
+
return dynamic_cast<T*>(static_cast<B1*>(GetArchiveRegister(Demangle(typeid(B1).name())).
|
|
853
|
+
downcaster(ti, p)));
|
|
854
|
+
}
|
|
855
|
+
catch(const Exception&)
|
|
856
|
+
{
|
|
857
|
+
return Caster<T, std::tuple<Brest...>>::tryDowncast(ti, p);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
};
|
|
862
|
+
|
|
863
|
+
// BinaryOutArchive ======================================================================
|
|
864
|
+
class NGCORE_API BinaryOutArchive : public Archive
|
|
865
|
+
{
|
|
866
|
+
static constexpr size_t BUFFERSIZE = 1024;
|
|
867
|
+
std::array<char,BUFFERSIZE> buffer{};
|
|
868
|
+
size_t ptr = 0;
|
|
869
|
+
protected:
|
|
870
|
+
std::shared_ptr<std::ostream> stream;
|
|
871
|
+
public:
|
|
872
|
+
BinaryOutArchive() = delete;
|
|
873
|
+
BinaryOutArchive(const BinaryOutArchive&) = delete;
|
|
874
|
+
BinaryOutArchive(BinaryOutArchive&&) = delete;
|
|
875
|
+
BinaryOutArchive(std::shared_ptr<std::ostream>&& astream)
|
|
876
|
+
: Archive(true), stream(std::move(astream))
|
|
877
|
+
{ }
|
|
878
|
+
BinaryOutArchive(const std::filesystem::path& filename)
|
|
879
|
+
: BinaryOutArchive(std::make_shared<std::ofstream>(filename)) {}
|
|
880
|
+
~BinaryOutArchive () override { FlushBuffer(); }
|
|
881
|
+
|
|
882
|
+
BinaryOutArchive& operator=(const BinaryOutArchive&) = delete;
|
|
883
|
+
BinaryOutArchive& operator=(BinaryOutArchive&&) = delete;
|
|
884
|
+
|
|
885
|
+
using Archive::operator&;
|
|
886
|
+
Archive & operator & (std::byte & d) override
|
|
887
|
+
{ return Write(d); }
|
|
888
|
+
Archive & operator & (float & f) override
|
|
889
|
+
{ return Write(f); }
|
|
890
|
+
Archive & operator & (double & d) override
|
|
891
|
+
{ return Write(d); }
|
|
892
|
+
Archive & operator & (int & i) override
|
|
893
|
+
{ return Write(i); }
|
|
894
|
+
Archive & operator & (short & i) override
|
|
895
|
+
{ return Write(i); }
|
|
896
|
+
Archive & operator & (long & i) override
|
|
897
|
+
{
|
|
898
|
+
// for platform independence
|
|
899
|
+
if constexpr (sizeof(long) == 8)
|
|
900
|
+
return Write(i);
|
|
901
|
+
else
|
|
902
|
+
return Write(static_cast<int64_t>(i));
|
|
903
|
+
}
|
|
904
|
+
Archive & operator & (size_t & i) override
|
|
905
|
+
{
|
|
906
|
+
// for platform independence
|
|
907
|
+
if constexpr (sizeof(size_t) == 8)
|
|
908
|
+
return Write(i);
|
|
909
|
+
else
|
|
910
|
+
return Write(static_cast<uint64_t>(i));
|
|
911
|
+
}
|
|
912
|
+
Archive & operator & (unsigned char & i) override
|
|
913
|
+
{ return Write(i); }
|
|
914
|
+
Archive & operator & (bool & b) override
|
|
915
|
+
{ return Write(b); }
|
|
916
|
+
|
|
917
|
+
Archive & operator & (std::string & str) override
|
|
918
|
+
{
|
|
919
|
+
int len = str.length();
|
|
920
|
+
(*this) & len;
|
|
921
|
+
FlushBuffer();
|
|
922
|
+
if(len)
|
|
923
|
+
stream->write (&str[0], len);
|
|
924
|
+
return *this;
|
|
925
|
+
}
|
|
926
|
+
Archive & operator & (char *& str) override
|
|
927
|
+
{
|
|
928
|
+
long len = str ? static_cast<long>(strlen (str)) : -1;
|
|
929
|
+
(*this) & len;
|
|
930
|
+
FlushBuffer();
|
|
931
|
+
if(len > 0)
|
|
932
|
+
stream->write (&str[0], len); // NOLINT
|
|
933
|
+
return *this;
|
|
934
|
+
}
|
|
935
|
+
void FlushBuffer() override
|
|
936
|
+
{
|
|
937
|
+
if (ptr > 0)
|
|
938
|
+
{
|
|
939
|
+
stream->write(&buffer[0], ptr);
|
|
940
|
+
ptr = 0;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
Archive & Do (std::byte * d, size_t n) override
|
|
944
|
+
{
|
|
945
|
+
FlushBuffer();
|
|
946
|
+
stream->write(reinterpret_cast<char*>(d), n*sizeof(std::byte)); return *this;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
private:
|
|
950
|
+
template <typename T>
|
|
951
|
+
Archive & Write (T x)
|
|
952
|
+
{
|
|
953
|
+
static_assert(sizeof(T) < BUFFERSIZE, "Cannot write large types with this function!");
|
|
954
|
+
if (unlikely(ptr > BUFFERSIZE-sizeof(T)))
|
|
955
|
+
{
|
|
956
|
+
stream->write(&buffer[0], ptr);
|
|
957
|
+
ptr = 0;
|
|
958
|
+
}
|
|
959
|
+
memcpy(&buffer[ptr], &x, sizeof(T));
|
|
960
|
+
ptr += sizeof(T);
|
|
961
|
+
return *this;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
// BinaryInArchive ======================================================================
|
|
966
|
+
class NGCORE_API BinaryInArchive : public Archive
|
|
967
|
+
{
|
|
968
|
+
protected:
|
|
969
|
+
std::shared_ptr<std::istream> stream;
|
|
970
|
+
public:
|
|
971
|
+
BinaryInArchive (std::shared_ptr<std::istream>&& astream)
|
|
972
|
+
: Archive(false), stream(std::move(astream))
|
|
973
|
+
{ }
|
|
974
|
+
BinaryInArchive (const std::filesystem::path& filename)
|
|
975
|
+
: BinaryInArchive(std::make_shared<std::ifstream>(filename)) { ; }
|
|
976
|
+
|
|
977
|
+
using Archive::operator&;
|
|
978
|
+
Archive & operator & (std::byte & d) override
|
|
979
|
+
{ Read(d); return *this; }
|
|
980
|
+
Archive & operator & (float & f) override
|
|
981
|
+
{ Read(f); return *this; }
|
|
982
|
+
Archive & operator & (double & d) override
|
|
983
|
+
{ Read(d); return *this; }
|
|
984
|
+
Archive & operator & (int & i) override
|
|
985
|
+
{ Read(i); return *this; }
|
|
986
|
+
Archive & operator & (short & i) override
|
|
987
|
+
{ Read(i); return *this; }
|
|
988
|
+
Archive & operator & (long & i) override
|
|
989
|
+
{
|
|
990
|
+
// for platform independence
|
|
991
|
+
if constexpr (sizeof(long) == 8)
|
|
992
|
+
Read(i);
|
|
993
|
+
else
|
|
994
|
+
{
|
|
995
|
+
int64_t tmp = 0;
|
|
996
|
+
Read(tmp);
|
|
997
|
+
i = tmp;
|
|
998
|
+
}
|
|
999
|
+
return *this;
|
|
1000
|
+
}
|
|
1001
|
+
Archive & operator & (size_t & i) override
|
|
1002
|
+
{
|
|
1003
|
+
// for platform independence
|
|
1004
|
+
if constexpr (sizeof(long) == 8)
|
|
1005
|
+
Read(i);
|
|
1006
|
+
else
|
|
1007
|
+
{
|
|
1008
|
+
uint64_t tmp = 0;
|
|
1009
|
+
Read(tmp);
|
|
1010
|
+
i = tmp;
|
|
1011
|
+
}
|
|
1012
|
+
return *this;
|
|
1013
|
+
}
|
|
1014
|
+
Archive & operator & (unsigned char & i) override
|
|
1015
|
+
{ Read(i); return *this; }
|
|
1016
|
+
Archive & operator & (bool & b) override
|
|
1017
|
+
{ Read(b); return *this; }
|
|
1018
|
+
Archive & operator & (std::string & str) override
|
|
1019
|
+
{
|
|
1020
|
+
int len;
|
|
1021
|
+
(*this) & len;
|
|
1022
|
+
str.resize(len);
|
|
1023
|
+
if(len)
|
|
1024
|
+
stream->read(&str[0], len); // NOLINT
|
|
1025
|
+
return *this;
|
|
1026
|
+
}
|
|
1027
|
+
Archive & operator & (char *& str) override
|
|
1028
|
+
{
|
|
1029
|
+
long len;
|
|
1030
|
+
(*this) & len;
|
|
1031
|
+
if(len == -1)
|
|
1032
|
+
str = nullptr;
|
|
1033
|
+
else
|
|
1034
|
+
{
|
|
1035
|
+
str = new char[len+1]; // NOLINT
|
|
1036
|
+
stream->read(&str[0], len); // NOLINT
|
|
1037
|
+
str[len] = '\0'; // NOLINT
|
|
1038
|
+
}
|
|
1039
|
+
return *this;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
Archive & Do (std::byte * d, size_t n) override
|
|
1043
|
+
{ stream->read(reinterpret_cast<char*>(d), n*sizeof(std::byte)); return *this; } // NOLINT
|
|
1044
|
+
Archive & Do (double * d, size_t n) override
|
|
1045
|
+
{ stream->read(reinterpret_cast<char*>(d), n*sizeof(double)); return *this; } // NOLINT
|
|
1046
|
+
Archive & Do (int * i, size_t n) override
|
|
1047
|
+
{ stream->read(reinterpret_cast<char*>(i), n*sizeof(int)); return *this; } // NOLINT
|
|
1048
|
+
Archive & Do (size_t * i, size_t n) override
|
|
1049
|
+
{
|
|
1050
|
+
// for platform independence
|
|
1051
|
+
if constexpr (sizeof(long) == 8)
|
|
1052
|
+
stream->read(reinterpret_cast<char*>(i), n*sizeof(size_t)); // NOLINT
|
|
1053
|
+
else
|
|
1054
|
+
for(size_t j = 0; j < n; j++)
|
|
1055
|
+
(*this) & i[j];
|
|
1056
|
+
return *this;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
private:
|
|
1060
|
+
template<typename T>
|
|
1061
|
+
inline void Read(T& val)
|
|
1062
|
+
{ stream->read(reinterpret_cast<char*>(&val), sizeof(T)); } // NOLINT
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
// TextOutArchive ======================================================================
|
|
1066
|
+
class NGCORE_API TextOutArchive : public Archive
|
|
1067
|
+
{
|
|
1068
|
+
protected:
|
|
1069
|
+
std::shared_ptr<std::ostream> stream;
|
|
1070
|
+
public:
|
|
1071
|
+
TextOutArchive (std::shared_ptr<std::ostream>&& astream)
|
|
1072
|
+
: Archive(true), stream(std::move(astream))
|
|
1073
|
+
{ }
|
|
1074
|
+
TextOutArchive (const std::filesystem::path& filename) :
|
|
1075
|
+
TextOutArchive(std::make_shared<std::ofstream>(filename)) { }
|
|
1076
|
+
|
|
1077
|
+
using Archive::operator&;
|
|
1078
|
+
Archive & operator & (std::byte & d) override
|
|
1079
|
+
{ *stream << int(d) << ' '; return *this; }
|
|
1080
|
+
Archive & operator & (float & f) override
|
|
1081
|
+
{ *stream << f << '\n'; return *this; }
|
|
1082
|
+
Archive & operator & (double & d) override
|
|
1083
|
+
{ *stream << d << '\n'; return *this; }
|
|
1084
|
+
Archive & operator & (int & i) override
|
|
1085
|
+
{ *stream << i << '\n'; return *this; }
|
|
1086
|
+
Archive & operator & (short & i) override
|
|
1087
|
+
{ *stream << i << '\n'; return *this; }
|
|
1088
|
+
Archive & operator & (long & i) override
|
|
1089
|
+
{ *stream << i << '\n'; return *this; }
|
|
1090
|
+
Archive & operator & (size_t & i) override
|
|
1091
|
+
{ *stream << i << '\n'; return *this; }
|
|
1092
|
+
Archive & operator & (unsigned char & i) override
|
|
1093
|
+
{ *stream << int(i) << '\n'; return *this; }
|
|
1094
|
+
Archive & operator & (bool & b) override
|
|
1095
|
+
{ *stream << (b ? 't' : 'f') << '\n'; return *this; }
|
|
1096
|
+
Archive & operator & (std::string & str) override
|
|
1097
|
+
{
|
|
1098
|
+
int len = str.length();
|
|
1099
|
+
*stream << len << '\n';
|
|
1100
|
+
if(len)
|
|
1101
|
+
{
|
|
1102
|
+
stream->write(&str[0], len); // NOLINT
|
|
1103
|
+
*stream << '\n';
|
|
1104
|
+
}
|
|
1105
|
+
return *this;
|
|
1106
|
+
}
|
|
1107
|
+
Archive & operator & (char *& str) override
|
|
1108
|
+
{
|
|
1109
|
+
long len = str ? static_cast<long>(strlen (str)) : -1;
|
|
1110
|
+
*this & len;
|
|
1111
|
+
if(len > 0)
|
|
1112
|
+
{
|
|
1113
|
+
stream->write (&str[0], len); // NOLINT
|
|
1114
|
+
*stream << '\n';
|
|
1115
|
+
}
|
|
1116
|
+
return *this;
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
// TextInArchive ======================================================================
|
|
1121
|
+
class NGCORE_API TextInArchive : public Archive
|
|
1122
|
+
{
|
|
1123
|
+
protected:
|
|
1124
|
+
std::shared_ptr<std::istream> stream;
|
|
1125
|
+
public:
|
|
1126
|
+
TextInArchive (std::shared_ptr<std::istream>&& astream) :
|
|
1127
|
+
Archive(false), stream(std::move(astream))
|
|
1128
|
+
{ }
|
|
1129
|
+
TextInArchive (const std::filesystem::path& filename)
|
|
1130
|
+
: TextInArchive(std::make_shared<std::ifstream>(filename)) {}
|
|
1131
|
+
|
|
1132
|
+
using Archive::operator&;
|
|
1133
|
+
Archive & operator & (std::byte & d) override
|
|
1134
|
+
{ int tmp; *stream >> tmp; d = std::byte(tmp); return *this; }
|
|
1135
|
+
Archive & operator & (float & f) override
|
|
1136
|
+
{ *stream >> f; return *this; }
|
|
1137
|
+
Archive & operator & (double & d) override
|
|
1138
|
+
{ *stream >> d; return *this; }
|
|
1139
|
+
Archive & operator & (int & i) override
|
|
1140
|
+
{ *stream >> i; return *this; }
|
|
1141
|
+
Archive & operator & (short & i) override
|
|
1142
|
+
{ *stream >> i; return *this; }
|
|
1143
|
+
Archive & operator & (long & i) override
|
|
1144
|
+
{ *stream >> i; return *this; }
|
|
1145
|
+
Archive & operator & (size_t & i) override
|
|
1146
|
+
{ *stream >> i; return *this; }
|
|
1147
|
+
Archive & operator & (unsigned char & i) override
|
|
1148
|
+
{ int _i; *stream >> _i; i = _i; return *this; }
|
|
1149
|
+
Archive & operator & (bool & b) override
|
|
1150
|
+
{ char c; *stream >> c; b = (c=='t'); return *this; }
|
|
1151
|
+
Archive & operator & (std::string & str) override
|
|
1152
|
+
{
|
|
1153
|
+
// Ignore \r (carriage return) characters when reading strings
|
|
1154
|
+
// this is necessary for instance when a file was written on Windows and is read on Unix
|
|
1155
|
+
|
|
1156
|
+
int len;
|
|
1157
|
+
*stream >> len;
|
|
1158
|
+
char ch;
|
|
1159
|
+
stream->get(ch); // read newline character
|
|
1160
|
+
if(ch == '\r') // windows line endings -> read \n as well
|
|
1161
|
+
stream->get(ch);
|
|
1162
|
+
str.resize(len);
|
|
1163
|
+
if(len)
|
|
1164
|
+
stream->get(&str[0], len+1, '\0');
|
|
1165
|
+
|
|
1166
|
+
// remove all \r characters from the string, check if size changed
|
|
1167
|
+
// if so, read the remaining characters
|
|
1168
|
+
str.erase(std::remove(str.begin(), str.end(), '\r'), str.cend());
|
|
1169
|
+
size_t chars_to_read = len-str.size();
|
|
1170
|
+
while (chars_to_read>0)
|
|
1171
|
+
{
|
|
1172
|
+
auto old_size = str.size();
|
|
1173
|
+
str.resize(len);
|
|
1174
|
+
|
|
1175
|
+
stream->get(&str[old_size], chars_to_read+1, '\0');
|
|
1176
|
+
str.erase(std::remove(str.begin()+old_size, str.end(), '\r'), str.cend());
|
|
1177
|
+
chars_to_read = len - str.size();
|
|
1178
|
+
}
|
|
1179
|
+
return *this;
|
|
1180
|
+
}
|
|
1181
|
+
Archive & operator & (char *& str) override
|
|
1182
|
+
{
|
|
1183
|
+
long len;
|
|
1184
|
+
(*this) & len;
|
|
1185
|
+
char ch;
|
|
1186
|
+
if(len == -1)
|
|
1187
|
+
{
|
|
1188
|
+
str = nullptr;
|
|
1189
|
+
return (*this);
|
|
1190
|
+
}
|
|
1191
|
+
str = new char[len+1]; // NOLINT
|
|
1192
|
+
if(len)
|
|
1193
|
+
{
|
|
1194
|
+
stream->get(ch); // \n
|
|
1195
|
+
if(ch == '\r') // windows line endings, read \n as well
|
|
1196
|
+
stream->get(ch);
|
|
1197
|
+
stream->get(&str[0], len+1, '\0'); // NOLINT
|
|
1198
|
+
}
|
|
1199
|
+
str[len] = '\0'; // NOLINT
|
|
1200
|
+
return *this;
|
|
1201
|
+
}
|
|
1202
|
+
};
|
|
1203
|
+
|
|
1204
|
+
// HashArchive =================================================================
|
|
1205
|
+
// This class enables to easily create hashes for archivable objects by xoring
|
|
1206
|
+
// threw its data
|
|
1207
|
+
|
|
1208
|
+
class NGCORE_API HashArchive : public Archive
|
|
1209
|
+
{
|
|
1210
|
+
size_t hash_value = 0;
|
|
1211
|
+
char* h;
|
|
1212
|
+
int offset = 0;
|
|
1213
|
+
public:
|
|
1214
|
+
HashArchive() : Archive(true)
|
|
1215
|
+
{ h = (char*)&hash_value; }
|
|
1216
|
+
|
|
1217
|
+
using Archive::operator&;
|
|
1218
|
+
Archive & operator & (std::byte & d) override { return ApplyHash(d); }
|
|
1219
|
+
Archive & operator & (float & f) override { return ApplyHash(f); }
|
|
1220
|
+
Archive & operator & (double & d) override { return ApplyHash(d); }
|
|
1221
|
+
Archive & operator & (int & i) override { return ApplyHash(i); }
|
|
1222
|
+
Archive & operator & (short & i) override { return ApplyHash(i); }
|
|
1223
|
+
Archive & operator & (long & i) override { return ApplyHash(i); }
|
|
1224
|
+
Archive & operator & (size_t & i) override { return ApplyHash(i); }
|
|
1225
|
+
Archive & operator & (unsigned char & i) override { return ApplyHash(i); }
|
|
1226
|
+
Archive & operator & (bool & b) override { return ApplyHash(b); }
|
|
1227
|
+
Archive & operator & (std::string & str) override
|
|
1228
|
+
{ for(auto c : str) ApplyHash(c); return *this; }
|
|
1229
|
+
Archive & operator & (char *& str) override
|
|
1230
|
+
{ char* s = str; while(*s != '\0') ApplyHash(*(s++)); return *this; }
|
|
1231
|
+
|
|
1232
|
+
// HashArchive can be used in const context
|
|
1233
|
+
template<typename T>
|
|
1234
|
+
Archive & operator& (const T& val) const
|
|
1235
|
+
{ return (*this) & const_cast<T&>(val); }
|
|
1236
|
+
|
|
1237
|
+
size_t GetHash() const { return hash_value; }
|
|
1238
|
+
|
|
1239
|
+
private:
|
|
1240
|
+
template<typename T>
|
|
1241
|
+
Archive& ApplyHash(T val)
|
|
1242
|
+
{
|
|
1243
|
+
size_t n = sizeof(T);
|
|
1244
|
+
char* pval = (char*)&val;
|
|
1245
|
+
for(size_t i = 0; i < n; i++)
|
|
1246
|
+
{
|
|
1247
|
+
h[offset++] ^= pval[i];
|
|
1248
|
+
offset %= 8;
|
|
1249
|
+
}
|
|
1250
|
+
return *this;
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
|
|
1254
|
+
} // namespace ngcore
|
|
1255
|
+
|
|
1256
|
+
#endif // NETGEN_CORE_ARCHIVE_HPP
|