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.
Files changed (340) hide show
  1. netgen/NgOCC.py +7 -0
  2. netgen/__init__.py +114 -0
  3. netgen/__init__.pyi +22 -0
  4. netgen/__main__.py +53 -0
  5. netgen/cmake/NetgenConfig.cmake +79 -0
  6. netgen/cmake/netgen-targets-release.cmake +69 -0
  7. netgen/cmake/netgen-targets.cmake +146 -0
  8. netgen/config/__init__.py +1 -0
  9. netgen/config/__init__.pyi +52 -0
  10. netgen/config/__main__.py +4 -0
  11. netgen/config/config.py +68 -0
  12. netgen/config/config.pyi +54 -0
  13. netgen/csg.py +25 -0
  14. netgen/geom2d.py +178 -0
  15. netgen/gui.py +82 -0
  16. netgen/include/core/archive.hpp +1256 -0
  17. netgen/include/core/array.hpp +1760 -0
  18. netgen/include/core/autodiff.hpp +1131 -0
  19. netgen/include/core/autodiffdiff.hpp +733 -0
  20. netgen/include/core/bitarray.hpp +240 -0
  21. netgen/include/core/concurrentqueue.h +3619 -0
  22. netgen/include/core/exception.hpp +145 -0
  23. netgen/include/core/flags.hpp +199 -0
  24. netgen/include/core/hashtable.hpp +1281 -0
  25. netgen/include/core/localheap.hpp +318 -0
  26. netgen/include/core/logging.hpp +117 -0
  27. netgen/include/core/memtracer.hpp +221 -0
  28. netgen/include/core/mpi4py_pycapi.h +245 -0
  29. netgen/include/core/mpi_wrapper.hpp +643 -0
  30. netgen/include/core/ng_mpi.hpp +94 -0
  31. netgen/include/core/ng_mpi_generated_declarations.hpp +155 -0
  32. netgen/include/core/ng_mpi_native.hpp +25 -0
  33. netgen/include/core/ngcore.hpp +32 -0
  34. netgen/include/core/ngcore_api.hpp +152 -0
  35. netgen/include/core/ngstream.hpp +115 -0
  36. netgen/include/core/paje_trace.hpp +279 -0
  37. netgen/include/core/profiler.hpp +382 -0
  38. netgen/include/core/python_ngcore.hpp +457 -0
  39. netgen/include/core/ranges.hpp +109 -0
  40. netgen/include/core/register_archive.hpp +100 -0
  41. netgen/include/core/signal.hpp +82 -0
  42. netgen/include/core/simd.hpp +160 -0
  43. netgen/include/core/simd_arm64.hpp +407 -0
  44. netgen/include/core/simd_avx.hpp +394 -0
  45. netgen/include/core/simd_avx512.hpp +285 -0
  46. netgen/include/core/simd_generic.hpp +1053 -0
  47. netgen/include/core/simd_math.hpp +178 -0
  48. netgen/include/core/simd_sse.hpp +289 -0
  49. netgen/include/core/statushandler.hpp +37 -0
  50. netgen/include/core/symboltable.hpp +153 -0
  51. netgen/include/core/table.hpp +810 -0
  52. netgen/include/core/taskmanager.hpp +1161 -0
  53. netgen/include/core/type_traits.hpp +65 -0
  54. netgen/include/core/utils.hpp +385 -0
  55. netgen/include/core/version.hpp +102 -0
  56. netgen/include/core/xbool.hpp +47 -0
  57. netgen/include/csg/algprim.hpp +563 -0
  58. netgen/include/csg/brick.hpp +150 -0
  59. netgen/include/csg/csg.hpp +43 -0
  60. netgen/include/csg/csgeom.hpp +389 -0
  61. netgen/include/csg/csgparser.hpp +101 -0
  62. netgen/include/csg/curve2d.hpp +67 -0
  63. netgen/include/csg/edgeflw.hpp +112 -0
  64. netgen/include/csg/explicitcurve2d.hpp +113 -0
  65. netgen/include/csg/extrusion.hpp +185 -0
  66. netgen/include/csg/gencyl.hpp +70 -0
  67. netgen/include/csg/geoml.hpp +16 -0
  68. netgen/include/csg/identify.hpp +213 -0
  69. netgen/include/csg/manifold.hpp +29 -0
  70. netgen/include/csg/meshsurf.hpp +46 -0
  71. netgen/include/csg/polyhedra.hpp +121 -0
  72. netgen/include/csg/revolution.hpp +180 -0
  73. netgen/include/csg/singularref.hpp +84 -0
  74. netgen/include/csg/solid.hpp +295 -0
  75. netgen/include/csg/specpoin.hpp +194 -0
  76. netgen/include/csg/spline3d.hpp +99 -0
  77. netgen/include/csg/splinesurface.hpp +85 -0
  78. netgen/include/csg/surface.hpp +394 -0
  79. netgen/include/csg/triapprox.hpp +63 -0
  80. netgen/include/csg/vscsg.hpp +34 -0
  81. netgen/include/general/autodiff.hpp +356 -0
  82. netgen/include/general/autoptr.hpp +39 -0
  83. netgen/include/general/gzstream.h +121 -0
  84. netgen/include/general/hashtabl.hpp +1692 -0
  85. netgen/include/general/myadt.hpp +48 -0
  86. netgen/include/general/mystring.hpp +226 -0
  87. netgen/include/general/netgenout.hpp +205 -0
  88. netgen/include/general/ngarray.hpp +797 -0
  89. netgen/include/general/ngbitarray.hpp +149 -0
  90. netgen/include/general/ngpython.hpp +74 -0
  91. netgen/include/general/optmem.hpp +44 -0
  92. netgen/include/general/parthreads.hpp +138 -0
  93. netgen/include/general/seti.hpp +50 -0
  94. netgen/include/general/sort.hpp +47 -0
  95. netgen/include/general/spbita2d.hpp +59 -0
  96. netgen/include/general/stack.hpp +114 -0
  97. netgen/include/general/table.hpp +280 -0
  98. netgen/include/general/template.hpp +509 -0
  99. netgen/include/geom2d/csg2d.hpp +750 -0
  100. netgen/include/geom2d/geometry2d.hpp +280 -0
  101. netgen/include/geom2d/spline2d.hpp +234 -0
  102. netgen/include/geom2d/vsgeom2d.hpp +28 -0
  103. netgen/include/gprim/adtree.hpp +1392 -0
  104. netgen/include/gprim/geom2d.hpp +858 -0
  105. netgen/include/gprim/geom3d.hpp +749 -0
  106. netgen/include/gprim/geomfuncs.hpp +212 -0
  107. netgen/include/gprim/geomobjects.hpp +544 -0
  108. netgen/include/gprim/geomops.hpp +404 -0
  109. netgen/include/gprim/geomtest3d.hpp +101 -0
  110. netgen/include/gprim/gprim.hpp +33 -0
  111. netgen/include/gprim/spline.hpp +778 -0
  112. netgen/include/gprim/splinegeometry.hpp +73 -0
  113. netgen/include/gprim/transform3d.hpp +216 -0
  114. netgen/include/include/acisgeom.hpp +3 -0
  115. netgen/include/include/csg.hpp +1 -0
  116. netgen/include/include/geometry2d.hpp +1 -0
  117. netgen/include/include/gprim.hpp +1 -0
  118. netgen/include/include/incopengl.hpp +62 -0
  119. netgen/include/include/inctcl.hpp +13 -0
  120. netgen/include/include/incvis.hpp +6 -0
  121. netgen/include/include/linalg.hpp +1 -0
  122. netgen/include/include/meshing.hpp +1 -0
  123. netgen/include/include/myadt.hpp +1 -0
  124. netgen/include/include/mydefs.hpp +70 -0
  125. netgen/include/include/mystdlib.h +59 -0
  126. netgen/include/include/netgen_config.hpp +27 -0
  127. netgen/include/include/netgen_version.hpp +9 -0
  128. netgen/include/include/nginterface_v2_impl.hpp +395 -0
  129. netgen/include/include/ngsimd.hpp +1 -0
  130. netgen/include/include/occgeom.hpp +1 -0
  131. netgen/include/include/opti.hpp +1 -0
  132. netgen/include/include/parallel.hpp +1 -0
  133. netgen/include/include/stlgeom.hpp +1 -0
  134. netgen/include/include/visual.hpp +1 -0
  135. netgen/include/interface/rw_medit.hpp +11 -0
  136. netgen/include/interface/writeuser.hpp +80 -0
  137. netgen/include/linalg/densemat.hpp +414 -0
  138. netgen/include/linalg/linalg.hpp +29 -0
  139. netgen/include/linalg/opti.hpp +142 -0
  140. netgen/include/linalg/polynomial.hpp +47 -0
  141. netgen/include/linalg/vector.hpp +217 -0
  142. netgen/include/meshing/adfront2.hpp +274 -0
  143. netgen/include/meshing/adfront3.hpp +332 -0
  144. netgen/include/meshing/basegeom.hpp +370 -0
  145. netgen/include/meshing/bcfunctions.hpp +53 -0
  146. netgen/include/meshing/bisect.hpp +72 -0
  147. netgen/include/meshing/boundarylayer.hpp +113 -0
  148. netgen/include/meshing/classifyhpel.hpp +1984 -0
  149. netgen/include/meshing/clusters.hpp +46 -0
  150. netgen/include/meshing/curvedelems.hpp +274 -0
  151. netgen/include/meshing/delaunay2d.hpp +73 -0
  152. netgen/include/meshing/fieldlines.hpp +103 -0
  153. netgen/include/meshing/findip.hpp +198 -0
  154. netgen/include/meshing/findip2.hpp +103 -0
  155. netgen/include/meshing/geomsearch.hpp +69 -0
  156. netgen/include/meshing/global.hpp +54 -0
  157. netgen/include/meshing/hpref_hex.hpp +330 -0
  158. netgen/include/meshing/hpref_prism.hpp +3405 -0
  159. netgen/include/meshing/hpref_pyramid.hpp +154 -0
  160. netgen/include/meshing/hpref_quad.hpp +2082 -0
  161. netgen/include/meshing/hpref_segm.hpp +122 -0
  162. netgen/include/meshing/hpref_tet.hpp +4230 -0
  163. netgen/include/meshing/hpref_trig.hpp +848 -0
  164. netgen/include/meshing/hprefinement.hpp +366 -0
  165. netgen/include/meshing/improve2.hpp +178 -0
  166. netgen/include/meshing/improve3.hpp +151 -0
  167. netgen/include/meshing/localh.hpp +223 -0
  168. netgen/include/meshing/meshclass.hpp +1076 -0
  169. netgen/include/meshing/meshfunc.hpp +47 -0
  170. netgen/include/meshing/meshing.hpp +63 -0
  171. netgen/include/meshing/meshing2.hpp +163 -0
  172. netgen/include/meshing/meshing3.hpp +123 -0
  173. netgen/include/meshing/meshtool.hpp +90 -0
  174. netgen/include/meshing/meshtype.hpp +1930 -0
  175. netgen/include/meshing/msghandler.hpp +62 -0
  176. netgen/include/meshing/paralleltop.hpp +172 -0
  177. netgen/include/meshing/python_mesh.hpp +206 -0
  178. netgen/include/meshing/ruler2.hpp +172 -0
  179. netgen/include/meshing/ruler3.hpp +211 -0
  180. netgen/include/meshing/soldata.hpp +141 -0
  181. netgen/include/meshing/specials.hpp +17 -0
  182. netgen/include/meshing/surfacegeom.hpp +73 -0
  183. netgen/include/meshing/topology.hpp +1003 -0
  184. netgen/include/meshing/validate.hpp +21 -0
  185. netgen/include/meshing/visual_interface.hpp +71 -0
  186. netgen/include/mydefs.hpp +70 -0
  187. netgen/include/nginterface.h +474 -0
  188. netgen/include/nginterface_v2.hpp +406 -0
  189. netgen/include/nglib.h +697 -0
  190. netgen/include/nglib_occ.h +50 -0
  191. netgen/include/occ/occ_edge.hpp +47 -0
  192. netgen/include/occ/occ_face.hpp +52 -0
  193. netgen/include/occ/occ_solid.hpp +23 -0
  194. netgen/include/occ/occ_utils.hpp +376 -0
  195. netgen/include/occ/occ_vertex.hpp +30 -0
  196. netgen/include/occ/occgeom.hpp +659 -0
  197. netgen/include/occ/occmeshsurf.hpp +168 -0
  198. netgen/include/occ/vsocc.hpp +33 -0
  199. netgen/include/pybind11/LICENSE +29 -0
  200. netgen/include/pybind11/attr.h +722 -0
  201. netgen/include/pybind11/buffer_info.h +208 -0
  202. netgen/include/pybind11/cast.h +2361 -0
  203. netgen/include/pybind11/chrono.h +228 -0
  204. netgen/include/pybind11/common.h +2 -0
  205. netgen/include/pybind11/complex.h +74 -0
  206. netgen/include/pybind11/conduit/README.txt +15 -0
  207. netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
  208. netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
  209. netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
  210. netgen/include/pybind11/critical_section.h +56 -0
  211. netgen/include/pybind11/detail/class.h +823 -0
  212. netgen/include/pybind11/detail/common.h +1348 -0
  213. netgen/include/pybind11/detail/cpp_conduit.h +75 -0
  214. netgen/include/pybind11/detail/descr.h +226 -0
  215. netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
  216. netgen/include/pybind11/detail/exception_translation.h +71 -0
  217. netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
  218. netgen/include/pybind11/detail/init.h +538 -0
  219. netgen/include/pybind11/detail/internals.h +799 -0
  220. netgen/include/pybind11/detail/native_enum_data.h +209 -0
  221. netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
  222. netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
  223. netgen/include/pybind11/detail/type_caster_base.h +1591 -0
  224. netgen/include/pybind11/detail/typeid.h +65 -0
  225. netgen/include/pybind11/detail/using_smart_holder.h +22 -0
  226. netgen/include/pybind11/detail/value_and_holder.h +90 -0
  227. netgen/include/pybind11/eigen/common.h +9 -0
  228. netgen/include/pybind11/eigen/matrix.h +723 -0
  229. netgen/include/pybind11/eigen/tensor.h +521 -0
  230. netgen/include/pybind11/eigen.h +12 -0
  231. netgen/include/pybind11/embed.h +320 -0
  232. netgen/include/pybind11/eval.h +161 -0
  233. netgen/include/pybind11/functional.h +147 -0
  234. netgen/include/pybind11/gil.h +199 -0
  235. netgen/include/pybind11/gil_safe_call_once.h +102 -0
  236. netgen/include/pybind11/gil_simple.h +37 -0
  237. netgen/include/pybind11/iostream.h +265 -0
  238. netgen/include/pybind11/native_enum.h +67 -0
  239. netgen/include/pybind11/numpy.h +2312 -0
  240. netgen/include/pybind11/operators.h +202 -0
  241. netgen/include/pybind11/options.h +92 -0
  242. netgen/include/pybind11/pybind11.h +3645 -0
  243. netgen/include/pybind11/pytypes.h +2680 -0
  244. netgen/include/pybind11/stl/filesystem.h +114 -0
  245. netgen/include/pybind11/stl.h +666 -0
  246. netgen/include/pybind11/stl_bind.h +858 -0
  247. netgen/include/pybind11/subinterpreter.h +299 -0
  248. netgen/include/pybind11/trampoline_self_life_support.h +65 -0
  249. netgen/include/pybind11/type_caster_pyobject_ptr.h +61 -0
  250. netgen/include/pybind11/typing.h +298 -0
  251. netgen/include/pybind11/warnings.h +75 -0
  252. netgen/include/stlgeom/meshstlsurface.hpp +67 -0
  253. netgen/include/stlgeom/stlgeom.hpp +491 -0
  254. netgen/include/stlgeom/stlline.hpp +193 -0
  255. netgen/include/stlgeom/stltool.hpp +331 -0
  256. netgen/include/stlgeom/stltopology.hpp +419 -0
  257. netgen/include/stlgeom/vsstl.hpp +58 -0
  258. netgen/include/visualization/meshdoc.hpp +42 -0
  259. netgen/include/visualization/mvdraw.hpp +325 -0
  260. netgen/include/visualization/vispar.hpp +128 -0
  261. netgen/include/visualization/visual.hpp +28 -0
  262. netgen/include/visualization/visual_api.hpp +10 -0
  263. netgen/include/visualization/vssolution.hpp +399 -0
  264. netgen/lib/libnggui.lib +0 -0
  265. netgen/lib/ngcore.lib +0 -0
  266. netgen/lib/nglib.lib +0 -0
  267. netgen/lib/togl.lib +0 -0
  268. netgen/libnggui.dll +0 -0
  269. netgen/libngguipy.lib +0 -0
  270. netgen/libngguipy.pyd +0 -0
  271. netgen/libngpy/_NgOCC.pyi +1545 -0
  272. netgen/libngpy/__init__.pyi +7 -0
  273. netgen/libngpy/_csg.pyi +259 -0
  274. netgen/libngpy/_geom2d.pyi +323 -0
  275. netgen/libngpy/_meshing.pyi +1111 -0
  276. netgen/libngpy/_stl.pyi +131 -0
  277. netgen/libngpy.lib +0 -0
  278. netgen/libngpy.pyd +0 -0
  279. netgen/meshing.py +65 -0
  280. netgen/ngcore.dll +0 -0
  281. netgen/nglib.dll +0 -0
  282. netgen/occ.py +52 -0
  283. netgen/read_gmsh.py +259 -0
  284. netgen/read_meshio.py +22 -0
  285. netgen/stl.py +2 -0
  286. netgen/togl.dll +0 -0
  287. netgen/version.py +2 -0
  288. netgen/webgui.py +529 -0
  289. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boundarycondition.geo +16 -0
  290. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/boxcyl.geo +32 -0
  291. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/circle_on_cube.geo +27 -0
  292. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cone.geo +13 -0
  293. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cube.geo +16 -0
  294. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandring.geo +55 -0
  295. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubeandspheres.geo +21 -0
  296. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemcyl.geo +18 -0
  297. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cubemsphere.geo +19 -0
  298. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylinder.geo +12 -0
  299. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/cylsphere.geo +12 -0
  300. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/doc/ng4.pdf +0 -0
  301. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipsoid.geo +8 -0
  302. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ellipticcyl.geo +10 -0
  303. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/extrusion.geo +99 -0
  304. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/fichera.geo +24 -0
  305. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/frame.step +11683 -0
  306. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/hinge.stl +8486 -0
  307. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/lshape3d.geo +26 -0
  308. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes.geo +26 -0
  309. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/manyholes2.geo +26 -0
  310. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/matrix.geo +27 -0
  311. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/ortho.geo +11 -0
  312. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/part1.stl +2662 -0
  313. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/period.geo +33 -0
  314. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/exportNeutral.py +26 -0
  315. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/mesh.py +19 -0
  316. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/py_tutorials/shaft.geo +65 -0
  317. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/revolution.geo +18 -0
  318. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/screw.step +1694 -0
  319. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sculpture.geo +13 -0
  320. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shaft.geo +65 -0
  321. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/shell.geo +10 -0
  322. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphere.geo +8 -0
  323. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/sphereincube.geo +17 -0
  324. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/square.in2d +35 -0
  325. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarecircle.in2d +48 -0
  326. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/squarehole.in2d +47 -0
  327. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/torus.geo +8 -0
  328. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/trafo.geo +57 -0
  329. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twobricks.geo +15 -0
  330. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocubes.geo +18 -0
  331. netgen_mesher-6.2.2506.post35.dev0.data/data/share/netgen/twocyl.geo +16 -0
  332. netgen_mesher-6.2.2506.post35.dev0.dist-info/METADATA +15 -0
  333. netgen_mesher-6.2.2506.post35.dev0.dist-info/RECORD +340 -0
  334. netgen_mesher-6.2.2506.post35.dev0.dist-info/WHEEL +5 -0
  335. netgen_mesher-6.2.2506.post35.dev0.dist-info/entry_points.txt +2 -0
  336. netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/AUTHORS +1 -0
  337. netgen_mesher-6.2.2506.post35.dev0.dist-info/licenses/LICENSE +504 -0
  338. netgen_mesher-6.2.2506.post35.dev0.dist-info/top_level.txt +2 -0
  339. pyngcore/__init__.py +1 -0
  340. 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