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,1760 @@
|
|
|
1
|
+
#ifndef NETGEN_CORE_ARRAY_HPP
|
|
2
|
+
#define NETGEN_CORE_ARRAY_HPP
|
|
3
|
+
|
|
4
|
+
/**************************************************************************/
|
|
5
|
+
/* File: array.hpp */
|
|
6
|
+
/* Author: Joachim Schoeberl */
|
|
7
|
+
/* Date: 01. Jun. 95 */
|
|
8
|
+
/**************************************************************************/
|
|
9
|
+
|
|
10
|
+
#include <cstring>
|
|
11
|
+
#include <array>
|
|
12
|
+
#include <type_traits>
|
|
13
|
+
|
|
14
|
+
#include "exception.hpp"
|
|
15
|
+
#include "logging.hpp" // for logger
|
|
16
|
+
#include "ngcore_api.hpp" // for NGCORE_API
|
|
17
|
+
#include "type_traits.hpp" // for all_of_tmpl
|
|
18
|
+
#include "localheap.hpp"
|
|
19
|
+
#include "memtracer.hpp"
|
|
20
|
+
#include "utils.hpp"
|
|
21
|
+
|
|
22
|
+
namespace ngcore
|
|
23
|
+
{
|
|
24
|
+
using std::ostream;
|
|
25
|
+
|
|
26
|
+
template <typename ... ARGS> class Tuple
|
|
27
|
+
{
|
|
28
|
+
public:
|
|
29
|
+
int Size() const { return 0; }
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
template <typename HEAD, typename ... TAIL>
|
|
33
|
+
class Tuple<HEAD, TAIL...> : Tuple<TAIL...>
|
|
34
|
+
{
|
|
35
|
+
typedef Tuple<TAIL...> BASE;
|
|
36
|
+
HEAD head;
|
|
37
|
+
public:
|
|
38
|
+
Tuple () { ; }
|
|
39
|
+
Tuple (HEAD h, TAIL ... t) : Tuple<TAIL...> (t...), head(h) { ; }
|
|
40
|
+
|
|
41
|
+
HEAD Head() const { return head; }
|
|
42
|
+
Tuple<TAIL...> Tail() const { return *this; }
|
|
43
|
+
|
|
44
|
+
int Size() const { return BASE::Size()+1; }
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
template <typename ... ARGS>
|
|
48
|
+
ostream & operator<< (ostream & ost, Tuple<ARGS...> /* tup */)
|
|
49
|
+
{
|
|
50
|
+
return ost;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
template <typename FIRST, typename ... ARGS>
|
|
54
|
+
ostream & operator<< (ostream & ost, Tuple<FIRST, ARGS...> tup)
|
|
55
|
+
{
|
|
56
|
+
ost << tup.Head() << ", " << tup.Tail();
|
|
57
|
+
return ost;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
template <typename ... ARGS>
|
|
62
|
+
Tuple<ARGS...> MakeTuple (ARGS ... args)
|
|
63
|
+
{
|
|
64
|
+
return Tuple<ARGS...> (args...);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
template <typename AO>
|
|
69
|
+
class AOWrapperIterator
|
|
70
|
+
{
|
|
71
|
+
const AO & ao;
|
|
72
|
+
size_t ind;
|
|
73
|
+
public:
|
|
74
|
+
NETGEN_INLINE AOWrapperIterator (const AO & aao, size_t ai)
|
|
75
|
+
: ao(aao), ind(ai) { ; }
|
|
76
|
+
NETGEN_INLINE AOWrapperIterator operator++ (int)
|
|
77
|
+
{ return AOWrapperIterator(ao, ind++); }
|
|
78
|
+
NETGEN_INLINE AOWrapperIterator& operator++ ()
|
|
79
|
+
{ ++ind; return *this; }
|
|
80
|
+
NETGEN_INLINE auto operator*() const -> decltype(ao[ind]) { return ao[ind]; }
|
|
81
|
+
NETGEN_INLINE auto operator*() -> decltype(ao[ind]) { return ao[ind]; }
|
|
82
|
+
NETGEN_INLINE bool operator != (AOWrapperIterator d2) { return ind != d2.ind; }
|
|
83
|
+
NETGEN_INLINE bool operator == (AOWrapperIterator d2) { return ind == d2.ind; }
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
/*
|
|
90
|
+
Some class which can be treated as array
|
|
91
|
+
*/
|
|
92
|
+
template <typename T> // , typename TA = T>
|
|
93
|
+
class BaseArrayObject
|
|
94
|
+
{
|
|
95
|
+
public:
|
|
96
|
+
NETGEN_INLINE BaseArrayObject() { ; }
|
|
97
|
+
|
|
98
|
+
NETGEN_INLINE const T & Spec() const { return static_cast<const T&> (*this); }
|
|
99
|
+
NETGEN_INLINE size_t Size() const { return Spec().Size(); }
|
|
100
|
+
template <typename T2>
|
|
101
|
+
NETGEN_INLINE bool Contains(const T2 & el) const
|
|
102
|
+
{
|
|
103
|
+
for (size_t i = 0; i < Size(); i++)
|
|
104
|
+
if (Spec()[i] == el)
|
|
105
|
+
return true;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static constexpr size_t ILLEGAL_POSITION = size_t(-1);
|
|
110
|
+
template <typename T2>
|
|
111
|
+
NETGEN_INLINE size_t Pos(const T2 & el) const
|
|
112
|
+
{
|
|
113
|
+
for (size_t i = 0; i < Size(); i++)
|
|
114
|
+
if (Spec()[i] == el)
|
|
115
|
+
return i;
|
|
116
|
+
return ILLEGAL_POSITION;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
template <typename T2>
|
|
120
|
+
NETGEN_INLINE size_t PosSure(const T2 & el) const
|
|
121
|
+
{
|
|
122
|
+
for (size_t i = 0; ; i++)
|
|
123
|
+
if (Spec()[i] == el)
|
|
124
|
+
return i;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// NETGEN_INLINE auto & operator[] (size_t i) { return Spec()[i]; }
|
|
128
|
+
NETGEN_INLINE auto operator[] (size_t i) const { return Spec()[i]; }
|
|
129
|
+
// NETGEN_INLINE auto begin() const { return Spec().begin(); }
|
|
130
|
+
// NETGEN_INLINE auto end() const { return Spec().end(); }
|
|
131
|
+
NETGEN_INLINE auto begin () const { return AOWrapperIterator<BaseArrayObject> (*this, 0); }
|
|
132
|
+
NETGEN_INLINE auto end () const { return AOWrapperIterator<BaseArrayObject> (*this, Size()); }
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
template <typename T>
|
|
138
|
+
class AOWrapper : public BaseArrayObject<AOWrapper<T>>
|
|
139
|
+
{
|
|
140
|
+
T ar;
|
|
141
|
+
public:
|
|
142
|
+
NETGEN_INLINE AOWrapper (T aar) : ar(aar) { ; }
|
|
143
|
+
NETGEN_INLINE operator T () const { return ar; }
|
|
144
|
+
NETGEN_INLINE size_t Size() const { return ar.Size(); }
|
|
145
|
+
NETGEN_INLINE auto operator[] (size_t i) { return ar[i]; }
|
|
146
|
+
NETGEN_INLINE auto operator[] (size_t i) const { return ar[i]; }
|
|
147
|
+
NETGEN_INLINE AOWrapperIterator<AOWrapper> begin () const { return AOWrapperIterator<AOWrapper> (*this, 0); }
|
|
148
|
+
NETGEN_INLINE AOWrapperIterator<AOWrapper> end () const { return AOWrapperIterator<AOWrapper> (*this, Size()); }
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
template <typename T>
|
|
152
|
+
NETGEN_INLINE AOWrapper<const T&> ArrayObject (const T & ar)
|
|
153
|
+
{
|
|
154
|
+
return AOWrapper<const T&> (ar);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
template <typename T>
|
|
158
|
+
NETGEN_INLINE AOWrapper<T> ArrayObject (T && ar)
|
|
159
|
+
{
|
|
160
|
+
return AOWrapper<T> (ar);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
template <typename FUNC>
|
|
164
|
+
auto ArrayObject (size_t s, FUNC f)
|
|
165
|
+
{
|
|
166
|
+
class Dummy
|
|
167
|
+
{
|
|
168
|
+
size_t s;
|
|
169
|
+
FUNC f;
|
|
170
|
+
public:
|
|
171
|
+
Dummy (size_t _s, FUNC _f) : s(_s), f(_f) { ; }
|
|
172
|
+
size_t Size() const { return s; }
|
|
173
|
+
auto operator[] (size_t i) const { return f(i); }
|
|
174
|
+
};
|
|
175
|
+
return ArrayObject(Dummy(s,f));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
template <typename T, typename FUNC>
|
|
179
|
+
auto Substitute (const BaseArrayObject<T> & ao, FUNC f)
|
|
180
|
+
{
|
|
181
|
+
return ArrayObject(ao.Size(),
|
|
182
|
+
[&ao,f] (size_t i) { return f(ao[i]); });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
nothing more but a new type for a C array.
|
|
190
|
+
return value for Addr - operator of array
|
|
191
|
+
*/
|
|
192
|
+
template <class T>
|
|
193
|
+
class CArray
|
|
194
|
+
{
|
|
195
|
+
protected:
|
|
196
|
+
/// the data
|
|
197
|
+
T * data;
|
|
198
|
+
public:
|
|
199
|
+
|
|
200
|
+
/// initialize array
|
|
201
|
+
NETGEN_INLINE CArray () { data = 0; }
|
|
202
|
+
|
|
203
|
+
/// provide size and memory
|
|
204
|
+
NETGEN_INLINE CArray (T * adata)
|
|
205
|
+
: data(adata) { ; }
|
|
206
|
+
|
|
207
|
+
/// Access array
|
|
208
|
+
NETGEN_INLINE T & operator[] (size_t i) const
|
|
209
|
+
{
|
|
210
|
+
return data[i];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
NETGEN_INLINE operator T* () const { return data; }
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
template <typename T>
|
|
218
|
+
constexpr T IndexBASE () { return T(0); }
|
|
219
|
+
|
|
220
|
+
template <typename T>
|
|
221
|
+
constexpr T IndexBASE (T ind) { return IndexBASE<T>(); }
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class IndexFromEnd
|
|
226
|
+
{
|
|
227
|
+
ptrdiff_t i;
|
|
228
|
+
public:
|
|
229
|
+
constexpr IndexFromEnd (ptrdiff_t ai) : i(ai) { }
|
|
230
|
+
IndexFromEnd operator+ (ptrdiff_t inc) const { return i+inc; }
|
|
231
|
+
IndexFromEnd operator- (ptrdiff_t dec) const { return i-dec; }
|
|
232
|
+
// operator ptrdiff_t () const { return i; }
|
|
233
|
+
ptrdiff_t Value() const { return i; }
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
constexpr IndexFromEnd END(0);
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
template <class T, class IndexType = size_t> class FlatArray;
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
template <typename TELEM, typename IndexType>
|
|
243
|
+
class ArrayIterator
|
|
244
|
+
{
|
|
245
|
+
FlatArray<TELEM, IndexType> ar;
|
|
246
|
+
IndexType ind;
|
|
247
|
+
public:
|
|
248
|
+
NETGEN_INLINE ArrayIterator (FlatArray<TELEM, IndexType> aar, IndexType ai)
|
|
249
|
+
: ar(aar), ind(ai) { ; }
|
|
250
|
+
NETGEN_INLINE ArrayIterator operator++ (int)
|
|
251
|
+
{ return ArrayIterator(ar, ind++); }
|
|
252
|
+
NETGEN_INLINE ArrayIterator operator++ ()
|
|
253
|
+
{ return ArrayIterator(ar, ++ind); }
|
|
254
|
+
// NETGEN_INLINE const TELEM & operator*() const { return ar[ind]; }
|
|
255
|
+
// NETGEN_INLINE TELEM & operator*() { return ar[ind]; }
|
|
256
|
+
NETGEN_INLINE auto operator*() const -> decltype(ar[ind]) { return ar[ind]; }
|
|
257
|
+
NETGEN_INLINE auto operator*() -> decltype(ar[ind]) { return ar[ind]; }
|
|
258
|
+
NETGEN_INLINE bool operator != (ArrayIterator d2) { return ind != d2.ind; }
|
|
259
|
+
NETGEN_INLINE bool operator == (ArrayIterator d2) { return ind == d2.ind; }
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
template <typename TSIZE>
|
|
265
|
+
class ArrayRangeIterator
|
|
266
|
+
{
|
|
267
|
+
TSIZE ind;
|
|
268
|
+
public:
|
|
269
|
+
NETGEN_INLINE ArrayRangeIterator (TSIZE ai) : ind(ai) { ; }
|
|
270
|
+
NETGEN_INLINE ArrayRangeIterator operator++ (int) { return ind++; }
|
|
271
|
+
NETGEN_INLINE ArrayRangeIterator operator++ () { return ++ind; }
|
|
272
|
+
NETGEN_INLINE TSIZE operator*() const { return ind; }
|
|
273
|
+
NETGEN_INLINE TSIZE Index() { return ind; }
|
|
274
|
+
NETGEN_INLINE operator TSIZE () const { return ind; }
|
|
275
|
+
NETGEN_INLINE bool operator != (ArrayRangeIterator d2) { return ind != d2.ind; }
|
|
276
|
+
NETGEN_INLINE bool operator == (ArrayRangeIterator d2) { return ind == d2.ind; }
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/// a range of integers
|
|
280
|
+
template <typename T>
|
|
281
|
+
class T_Range : public BaseArrayObject <T_Range<T>>
|
|
282
|
+
{
|
|
283
|
+
T first, next;
|
|
284
|
+
public:
|
|
285
|
+
NETGEN_INLINE T_Range () { ; }
|
|
286
|
+
// NETGEN_INLINE T_Range (T n) : first(0), next(n) {;}
|
|
287
|
+
NETGEN_INLINE explicit T_Range (size_t n) : first(IndexBASE<T>()), next(IndexBASE<T>()+n) {;}
|
|
288
|
+
NETGEN_INLINE T_Range (T f, T n) : first(f), next(n) {;}
|
|
289
|
+
template <typename T2>
|
|
290
|
+
NETGEN_INLINE T_Range(T_Range<T2> r2) : first(r2.First()), next(r2.Next()) { ; }
|
|
291
|
+
NETGEN_INLINE T First() const { return first; }
|
|
292
|
+
NETGEN_INLINE T Next() const { return next; }
|
|
293
|
+
NETGEN_INLINE T & First() { return first; }
|
|
294
|
+
NETGEN_INLINE T & Next() { return next; }
|
|
295
|
+
NETGEN_INLINE auto Size() const { return next-first; }
|
|
296
|
+
NETGEN_INLINE T operator[] (size_t i) const { return first+i; }
|
|
297
|
+
NETGEN_INLINE bool Contains (T i) const { return ((i >= first) && (i < next)); }
|
|
298
|
+
NETGEN_INLINE T_Range Modify(int inc_beg, int inc_end) const
|
|
299
|
+
{ return T_Range(first+inc_beg, next+inc_end); }
|
|
300
|
+
NETGEN_INLINE ArrayRangeIterator<T> begin() const { return first; }
|
|
301
|
+
NETGEN_INLINE ArrayRangeIterator<T> end() const { return next; }
|
|
302
|
+
|
|
303
|
+
NETGEN_INLINE T_Range Split (size_t nr, int tot) const
|
|
304
|
+
{
|
|
305
|
+
auto diff = next-first;
|
|
306
|
+
return T_Range (first + nr * diff / tot,
|
|
307
|
+
first + (nr+1) * diff / tot);
|
|
308
|
+
}
|
|
309
|
+
// NETGEN_INLINE operator IntRange () const { return IntRange(first,next); }
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
using IntRange = T_Range<size_t>;
|
|
313
|
+
|
|
314
|
+
template <typename T>
|
|
315
|
+
NETGEN_INLINE T_Range<T> Range (T a, T b)
|
|
316
|
+
{
|
|
317
|
+
return T_Range<T>(a,b);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
template<typename T>
|
|
321
|
+
NETGEN_INLINE auto Range (const T& ao)
|
|
322
|
+
-> typename std::enable_if<has_range<T>, decltype(std::declval<T>().Range())>::type
|
|
323
|
+
{ return ao.Range(); }
|
|
324
|
+
|
|
325
|
+
template <typename T>
|
|
326
|
+
NETGEN_INLINE T_Range<T> Range_impl (T n, std::true_type)
|
|
327
|
+
{
|
|
328
|
+
return T_Range<T> (0, n);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
template <typename TA>
|
|
332
|
+
NETGEN_INLINE auto Range_impl (const TA & ao, std::false_type)
|
|
333
|
+
-> T_Range<index_type<TA>>
|
|
334
|
+
{
|
|
335
|
+
return T_Range<index_type<TA>> (IndexBASE<index_type<TA>>(),
|
|
336
|
+
IndexBASE<index_type<TA>>() + index_type<TA>(ao.Size()));
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
Range(obj) will create a range in using the following steps:
|
|
341
|
+
|
|
342
|
+
* if obj is an integral type it will create T_Range<type(obj)>(0, obj)
|
|
343
|
+
* if obj has a function Range() it will return obj.Range()
|
|
344
|
+
* if obj has a typedef index_type it will return
|
|
345
|
+
T_Range<index_type>(IndexBASE<index_type>(), IndexBASE<index_type>() + index_type(obj.Size()))
|
|
346
|
+
* else it will return T_Range<size_t> (0, obj.Size())
|
|
347
|
+
|
|
348
|
+
*/
|
|
349
|
+
template <typename T>
|
|
350
|
+
auto Range(const T & x)
|
|
351
|
+
-> typename std::enable_if<std::is_integral_v<T> || !has_range<T>,
|
|
352
|
+
decltype(Range_impl(x, std::is_integral<T>()))>::type {
|
|
353
|
+
return Range_impl(x, std::is_integral<T>());
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
NETGEN_INLINE IntRange operator+ (const IntRange & range, int shift)
|
|
358
|
+
{
|
|
359
|
+
return IntRange (range.First()+shift, range.Next()+shift);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
NETGEN_INLINE IntRange operator+ (int shift, const IntRange & range)
|
|
363
|
+
{
|
|
364
|
+
return IntRange (range.First()+shift, range.Next()+shift);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
NETGEN_INLINE IntRange operator* (int scale, const IntRange & range)
|
|
368
|
+
{
|
|
369
|
+
return IntRange (scale*range.First(), scale*range.Next());
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
NETGEN_INLINE IntRange operator* (const IntRange & range, int scale)
|
|
373
|
+
{
|
|
374
|
+
return IntRange (scale*range.First(), scale*range.Next());
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
template <typename TI>
|
|
378
|
+
inline ostream & operator<< (ostream & s, T_Range<TI> ir)
|
|
379
|
+
{
|
|
380
|
+
s << "[" << ir.First() << "," << ir.Next() << ")";
|
|
381
|
+
return s;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
template <typename ... ARGS>
|
|
385
|
+
ostream & operator<< (ostream & ost, Tuple<IntRange, ARGS...> tup)
|
|
386
|
+
{
|
|
387
|
+
ost << tup.Head() << ", " << tup.Tail();
|
|
388
|
+
return ost;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
template <typename T>
|
|
393
|
+
inline ostream & operator<< (ostream & ost, const BaseArrayObject<T> & array)
|
|
394
|
+
{
|
|
395
|
+
for (auto i : Range(array.Size()))
|
|
396
|
+
ost << i << ":" << array[i] << std::endl;
|
|
397
|
+
return ost;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
template <typename T, typename TI, typename INDEX_ARRAY>
|
|
402
|
+
class IndirectArray : public BaseArrayObject<IndirectArray<T, TI, INDEX_ARRAY> >
|
|
403
|
+
{
|
|
404
|
+
FlatArray<T,TI> ba;
|
|
405
|
+
const INDEX_ARRAY & ia;
|
|
406
|
+
|
|
407
|
+
public:
|
|
408
|
+
NETGEN_INLINE IndirectArray (FlatArray<T,TI> aba,
|
|
409
|
+
const INDEX_ARRAY & aia)
|
|
410
|
+
: ba(aba), ia(aia) { ; }
|
|
411
|
+
|
|
412
|
+
NETGEN_INLINE size_t Size() const { return ia.Size(); }
|
|
413
|
+
NETGEN_INLINE T & operator[] (size_t i) const { return ba[ia[i]]; }
|
|
414
|
+
// NETGEN_INLINE T & operator[] (size_t i) { return ba[ia[i]]; }
|
|
415
|
+
|
|
416
|
+
NETGEN_INLINE IndirectArray operator= (const T & val)
|
|
417
|
+
{
|
|
418
|
+
for (auto i : Range(Size()))
|
|
419
|
+
(*this)[i] = val;
|
|
420
|
+
return IndirectArray (ba, ia);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
template <typename T2>
|
|
424
|
+
NETGEN_INLINE IndirectArray operator= (const BaseArrayObject<T2> & a2)
|
|
425
|
+
{
|
|
426
|
+
for (auto i : Range(Size()))
|
|
427
|
+
(*this)[i] = a2[i];
|
|
428
|
+
return IndirectArray (ba, ia);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
NETGEN_INLINE AOWrapperIterator<IndirectArray> begin() const { return { *this, 0 }; }
|
|
432
|
+
NETGEN_INLINE AOWrapperIterator<IndirectArray> end() const { return { *this, Size() }; }
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
A simple array container.
|
|
438
|
+
Array represented by size and data-pointer.
|
|
439
|
+
No memory allocation and deallocation, must be provided by user.
|
|
440
|
+
Helper functions for printing.
|
|
441
|
+
Optional range check by macro NETGEN_CHECK_RANGE
|
|
442
|
+
*/
|
|
443
|
+
template <class T, class IndexType>
|
|
444
|
+
class FlatArray : public BaseArrayObject<FlatArray<T,IndexType> >
|
|
445
|
+
{
|
|
446
|
+
protected:
|
|
447
|
+
static constexpr IndexType BASE = IndexBASE<IndexType>();
|
|
448
|
+
/// the size
|
|
449
|
+
size_t size = 0;
|
|
450
|
+
/// the data
|
|
451
|
+
T * __restrict data = nullptr;
|
|
452
|
+
public:
|
|
453
|
+
typedef T value_type;
|
|
454
|
+
typedef IndexType index_type;
|
|
455
|
+
using BaseArrayObject<FlatArray>::ILLEGAL_POSITION;
|
|
456
|
+
|
|
457
|
+
/// initialize array
|
|
458
|
+
NETGEN_INLINE FlatArray () = default;
|
|
459
|
+
// { ; } // size = 0; data = 0; }
|
|
460
|
+
|
|
461
|
+
/// copy constructor allows size-type conversion
|
|
462
|
+
NETGEN_INLINE FlatArray (const FlatArray & a2) = default;
|
|
463
|
+
// : size(a2.Size()), data(a2.data) { ; }
|
|
464
|
+
|
|
465
|
+
/// provide size and memory
|
|
466
|
+
NETGEN_INLINE FlatArray (size_t asize, T * adata)
|
|
467
|
+
: size(asize), data(adata) { ; }
|
|
468
|
+
|
|
469
|
+
/// memory from local heap
|
|
470
|
+
NETGEN_INLINE FlatArray(size_t asize, Allocator & lh)
|
|
471
|
+
: size(asize), data(new (lh) T[asize])
|
|
472
|
+
{ ; }
|
|
473
|
+
|
|
474
|
+
NETGEN_INLINE FlatArray(size_t asize, LocalHeap & lh)
|
|
475
|
+
: size(asize), data (lh.Alloc<T> (asize))
|
|
476
|
+
{ ; }
|
|
477
|
+
|
|
478
|
+
template <size_t N>
|
|
479
|
+
NETGEN_INLINE FlatArray(std::array<T,N> & a)
|
|
480
|
+
: size(N), data(&a[0]) { }
|
|
481
|
+
|
|
482
|
+
/// the size
|
|
483
|
+
NETGEN_INLINE size_t Size() const { return size; }
|
|
484
|
+
|
|
485
|
+
/// the data
|
|
486
|
+
NETGEN_INLINE T* Data() const { return data; }
|
|
487
|
+
|
|
488
|
+
/// Fill array with value val
|
|
489
|
+
NETGEN_INLINE const FlatArray & operator= (const T & val) const
|
|
490
|
+
{
|
|
491
|
+
size_t hsize = size;
|
|
492
|
+
T * hdata = data;
|
|
493
|
+
for (size_t i = 0; i < hsize; i++)
|
|
494
|
+
hdata[i] = val;
|
|
495
|
+
return *this;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/// copies array
|
|
499
|
+
NETGEN_INLINE const FlatArray & operator= (const FlatArray & a2) const
|
|
500
|
+
{
|
|
501
|
+
size_t hsize = size;
|
|
502
|
+
T * hdata = data;
|
|
503
|
+
for (size_t i = 0; i < hsize; i++) hdata[i] = a2.data[i];
|
|
504
|
+
return *this;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
template <typename T2>
|
|
508
|
+
NETGEN_INLINE const FlatArray & operator= (const BaseArrayObject<T2> & a2) const
|
|
509
|
+
{
|
|
510
|
+
size_t hsize = size;
|
|
511
|
+
T * hdata = data;
|
|
512
|
+
auto p2 = a2.begin();
|
|
513
|
+
for (size_t i = 0; i < hsize; i++, p2++) hdata[i] = *p2;
|
|
514
|
+
return *this;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
template <typename T2, std::enable_if_t<std::is_function<T2>::value>>
|
|
518
|
+
NETGEN_INLINE const FlatArray & operator= (const T2 & func) const
|
|
519
|
+
{
|
|
520
|
+
for (size_t i = 0; i < size; i++)
|
|
521
|
+
data[i] = func(i+BASE);
|
|
522
|
+
return *this;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// template <typename T2>
|
|
526
|
+
// const FlatArray operator= (ParallelValue<T2> val);
|
|
527
|
+
// template <typename T2>
|
|
528
|
+
// const FlatArray operator= (ParallelFunction<T2> val);
|
|
529
|
+
|
|
530
|
+
/// copies pointers
|
|
531
|
+
NETGEN_INLINE const FlatArray & Assign (const FlatArray & a2)
|
|
532
|
+
{
|
|
533
|
+
size = a2.size;
|
|
534
|
+
data = a2.data;
|
|
535
|
+
return *this;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/// assigns memory from local heap
|
|
539
|
+
NETGEN_INLINE const FlatArray & Assign (size_t asize, LocalHeap & lh)
|
|
540
|
+
{
|
|
541
|
+
size = asize;
|
|
542
|
+
data = lh.Alloc<T> (asize);
|
|
543
|
+
return *this;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/// Access array. range check by macro NETGEN_CHECK_RANGE
|
|
547
|
+
NETGEN_INLINE T & operator[] (IndexType i) const
|
|
548
|
+
{
|
|
549
|
+
NETGEN_CHECK_RANGE(i,BASE,size+BASE);
|
|
550
|
+
return data[i-BASE];
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
NETGEN_INLINE T_Range<index_type> Range () const
|
|
554
|
+
{
|
|
555
|
+
return T_Range<index_type> (BASE, size+BASE);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
NETGEN_INLINE const CArray<T> Addr (size_t pos) const
|
|
559
|
+
{
|
|
560
|
+
return CArray<T> (data+pos-BASE);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// const CArray<T> operator+ (int pos)
|
|
564
|
+
// { return CArray<T> (data+pos); }
|
|
565
|
+
NETGEN_INLINE T * operator+ (size_t pos) const { return data+pos; }
|
|
566
|
+
|
|
567
|
+
/// access first element. check by macro NETGEN_CHECK_RANGE
|
|
568
|
+
T & First () const
|
|
569
|
+
{
|
|
570
|
+
NETGEN_CHECK_RANGE(0,0,size);
|
|
571
|
+
return data[0];
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/// access last element. check by macro NETGEN_CHECK_RANGE
|
|
575
|
+
T & Last () const
|
|
576
|
+
{
|
|
577
|
+
NETGEN_CHECK_RANGE(size-1,0,size);
|
|
578
|
+
return data[size-1];
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/// takes sub-array starting from position pos
|
|
582
|
+
NETGEN_INLINE const FlatArray<T> Part (size_t pos)
|
|
583
|
+
{
|
|
584
|
+
return FlatArray<T> (size-pos, data+pos);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/// takes subsize elements starting from position pos
|
|
588
|
+
NETGEN_INLINE const FlatArray<T> Part (size_t pos, size_t subsize)
|
|
589
|
+
{
|
|
590
|
+
return FlatArray<T> (subsize, data+pos);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/// takes range starting from position start of end-start elements
|
|
594
|
+
NETGEN_INLINE FlatArray<T> Range (size_t start, size_t end) const
|
|
595
|
+
{
|
|
596
|
+
return FlatArray<T> (end-start, data+start);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/// takes range starting from position start of end-start elements
|
|
600
|
+
NETGEN_INLINE FlatArray<T> Range (size_t start, IndexFromEnd indend) const
|
|
601
|
+
{
|
|
602
|
+
return this->Range(start, size_t(Size()+indend.Value()));
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/// takes range starting from position start of end-start elements
|
|
606
|
+
NETGEN_INLINE FlatArray<T> Range (T_Range<size_t> range) const
|
|
607
|
+
{
|
|
608
|
+
return FlatArray<T> (range.Size(), data+range.First());
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/// takes range starting from position start of end-start elements
|
|
612
|
+
NETGEN_INLINE const FlatArray<T> operator[] (T_Range<IndexType> range) const
|
|
613
|
+
{
|
|
614
|
+
return FlatArray<T> (range.Size(), data+range.First());
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
template <typename TI1>
|
|
618
|
+
auto operator[] (const BaseArrayObject<TI1> & ind_array) const
|
|
619
|
+
{
|
|
620
|
+
return IndirectArray<T, IndexType, BaseArrayObject<TI1> > (*this, ind_array);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/// first position of element elem, returns -1 if element not contained in array
|
|
624
|
+
NETGEN_INLINE size_t Pos(const T & el) const
|
|
625
|
+
{
|
|
626
|
+
for (size_t i = 0; i < Size(); i++)
|
|
627
|
+
if (data[i] == el)
|
|
628
|
+
return i;
|
|
629
|
+
return ILLEGAL_POSITION;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/// does the array contain element elem ?
|
|
633
|
+
NETGEN_INLINE bool Contains(const T & elem) const
|
|
634
|
+
{
|
|
635
|
+
return Pos(elem) != ILLEGAL_POSITION;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
//auto begin() const { return ArrayIterator<T,IndexType> (*this, BASE); }
|
|
639
|
+
// auto end() const { return ArrayIterator<T,IndexType> (*this, size+BASE); }
|
|
640
|
+
NETGEN_INLINE auto begin() const { return data; }
|
|
641
|
+
NETGEN_INLINE auto end() const { return data+Size(); }
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
template <typename T>
|
|
645
|
+
FlatArray<T> View (FlatArray<T> fa) { return fa; }
|
|
646
|
+
|
|
647
|
+
template <typename T, typename TI>
|
|
648
|
+
auto Max (FlatArray<T,TI> array, typename std::remove_const<T>::type max = std::numeric_limits<T>::min()) -> T
|
|
649
|
+
{
|
|
650
|
+
for (auto & v : array)
|
|
651
|
+
if (v > max) max = v;
|
|
652
|
+
return max;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
template <typename T, typename TI>
|
|
656
|
+
auto Min (FlatArray<T,TI> array, typename std::remove_const<T>::type min = std::numeric_limits<T>::max()) -> T
|
|
657
|
+
{
|
|
658
|
+
for (auto & v : array)
|
|
659
|
+
if (v < min) min = v;
|
|
660
|
+
return min;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/// print array
|
|
664
|
+
template <class T, class TIND>
|
|
665
|
+
inline ostream & operator<< (ostream & s, const FlatArray<T, TIND> & a)
|
|
666
|
+
{
|
|
667
|
+
for (auto i : a.Range())
|
|
668
|
+
s << i << ": " << a[i] << "\n";
|
|
669
|
+
return s;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/// have arrays the same contents ?
|
|
673
|
+
template <class T1, class T2>
|
|
674
|
+
inline bool operator== (const FlatArray<T1> & a1,
|
|
675
|
+
const FlatArray<T2> & a2)
|
|
676
|
+
{
|
|
677
|
+
if (a1.Size () != a2.Size()) return 0;
|
|
678
|
+
for (size_t i = 0; i < a1.Size(); i++)
|
|
679
|
+
if (a1[i] != a2[i]) return false;
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
template <class T1, class T2>
|
|
684
|
+
inline bool operator!= (const FlatArray<T1> & a1,
|
|
685
|
+
const FlatArray<T2> & a2)
|
|
686
|
+
{
|
|
687
|
+
return !(a1==a2);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
Dynamic array container.
|
|
693
|
+
|
|
694
|
+
Array<T> is an automatically increasing array container.
|
|
695
|
+
The allocated memory doubles on overflow.
|
|
696
|
+
Either the container takes care of memory allocation and deallocation,
|
|
697
|
+
or the user provides one block of data.
|
|
698
|
+
*/
|
|
699
|
+
template <class T, class IndexType = size_t>
|
|
700
|
+
class Array : public FlatArray<T, IndexType>
|
|
701
|
+
{
|
|
702
|
+
protected:
|
|
703
|
+
/// physical size of array
|
|
704
|
+
size_t allocsize;
|
|
705
|
+
/// that's the data we have to delete, nullptr for not owning the memory
|
|
706
|
+
T * mem_to_delete;
|
|
707
|
+
MemoryTracer mt;
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
using FlatArray<T,IndexType>::size;
|
|
711
|
+
using FlatArray<T,IndexType>::data;
|
|
712
|
+
using FlatArray<T,IndexType>::BASE;
|
|
713
|
+
|
|
714
|
+
public:
|
|
715
|
+
using index_type = typename FlatArray<T, IndexType>::index_type;
|
|
716
|
+
/// Generate array of logical and physical size asize
|
|
717
|
+
NETGEN_INLINE explicit Array()
|
|
718
|
+
: FlatArray<T,IndexType> (0, nullptr)
|
|
719
|
+
{
|
|
720
|
+
allocsize = 0;
|
|
721
|
+
mem_to_delete = nullptr;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
NETGEN_INLINE explicit Array(size_t asize)
|
|
725
|
+
: FlatArray<T,IndexType> (asize, new T[asize])
|
|
726
|
+
{
|
|
727
|
+
allocsize = asize;
|
|
728
|
+
mem_to_delete = data;
|
|
729
|
+
mt.Alloc(sizeof(T)*asize);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
/// Generate array in user data
|
|
734
|
+
NETGEN_INLINE Array(size_t asize, T* adata, bool ownMemory = false)
|
|
735
|
+
: FlatArray<T> (asize, adata)
|
|
736
|
+
{
|
|
737
|
+
allocsize = asize;
|
|
738
|
+
if(ownMemory)
|
|
739
|
+
{
|
|
740
|
+
mem_to_delete = adata;
|
|
741
|
+
mt.Alloc(sizeof(T)*asize);
|
|
742
|
+
}
|
|
743
|
+
else
|
|
744
|
+
mem_to_delete = nullptr;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/// Generate array in user data
|
|
748
|
+
template <typename ALLOCATOR>
|
|
749
|
+
NETGEN_INLINE Array(size_t asize, ALLOCATOR & lh)
|
|
750
|
+
: FlatArray<T> (asize, lh)
|
|
751
|
+
{
|
|
752
|
+
allocsize = asize;
|
|
753
|
+
mem_to_delete = nullptr;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
NETGEN_INLINE Array (Array && a2)
|
|
757
|
+
{
|
|
758
|
+
mt = std::move(a2.mt);
|
|
759
|
+
size = a2.size;
|
|
760
|
+
data = a2.data;
|
|
761
|
+
allocsize = a2.allocsize;
|
|
762
|
+
mem_to_delete = a2.mem_to_delete;
|
|
763
|
+
a2.size = 0;
|
|
764
|
+
a2.allocsize = 0;
|
|
765
|
+
a2.data = nullptr;
|
|
766
|
+
a2.mem_to_delete = nullptr;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/// array copy
|
|
770
|
+
NETGEN_INLINE explicit Array (const Array & a2)
|
|
771
|
+
: FlatArray<T,IndexType> (a2.Size(), a2.Size() ? new T[a2.Size()] : nullptr)
|
|
772
|
+
{
|
|
773
|
+
if constexpr (std::is_copy_assignable<T>::value)
|
|
774
|
+
{
|
|
775
|
+
allocsize = size;
|
|
776
|
+
mem_to_delete = data;
|
|
777
|
+
mt.Alloc(sizeof(T)*size);
|
|
778
|
+
for (size_t i = 0; i < size; i++)
|
|
779
|
+
data[i] = a2.data[i];
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// #ifdef __cpp_exceptions
|
|
783
|
+
#ifndef __CUDA_ARCH__
|
|
784
|
+
else
|
|
785
|
+
throw Exception(std::string("cannot copy-construct Array of type ") + typeid(T).name());
|
|
786
|
+
#endif
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
template <typename TA>
|
|
791
|
+
explicit Array (const BaseArrayObject<TA> & a2)
|
|
792
|
+
: FlatArray<T,IndexType> (a2.Size(),
|
|
793
|
+
a2.Size() ? new T[a2.Size()] : nullptr)
|
|
794
|
+
{
|
|
795
|
+
allocsize = size;
|
|
796
|
+
mem_to_delete = data;
|
|
797
|
+
mt.Alloc(sizeof(T)*size);
|
|
798
|
+
/*
|
|
799
|
+
for (size_t i = 0; i < size; i++)
|
|
800
|
+
data[i] = a2[i];
|
|
801
|
+
*/
|
|
802
|
+
auto p2 = a2.begin();
|
|
803
|
+
for (size_t i = 0; i < size; i++, p2++)
|
|
804
|
+
data[i] = *p2;
|
|
805
|
+
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
Array (std::initializer_list<T> list)
|
|
809
|
+
: FlatArray<T> (list.size(),
|
|
810
|
+
list.size() ? new T[list.size()] : NULL)
|
|
811
|
+
{
|
|
812
|
+
allocsize = size;
|
|
813
|
+
mem_to_delete = data;
|
|
814
|
+
mt.Alloc(sizeof(T)*size);
|
|
815
|
+
size_t cnt = 0;
|
|
816
|
+
for (auto val : list)
|
|
817
|
+
data[cnt++] = val;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/// array merge-copy
|
|
821
|
+
explicit Array (const Array<T> & a2, const Array<T> & a3)
|
|
822
|
+
: FlatArray<T> (a2.Size()+a3.Size(),
|
|
823
|
+
a2.Size()+a3.Size() ? new T[a2.Size()+a3.Size()] : 0)
|
|
824
|
+
{
|
|
825
|
+
allocsize = size;
|
|
826
|
+
mem_to_delete = data;
|
|
827
|
+
mt.Alloc(sizeof(T)*size);
|
|
828
|
+
for(size_t i = 0; i < a2.Size(); i++)
|
|
829
|
+
data[i] = a2[i];
|
|
830
|
+
for (size_t i = a2.Size(), j=0; i < size; i++,j++)
|
|
831
|
+
data[i] = a3[j];
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/// if responsible, deletes memory
|
|
835
|
+
NETGEN_INLINE ~Array()
|
|
836
|
+
{
|
|
837
|
+
if(mem_to_delete)
|
|
838
|
+
mt.Free(sizeof(T)*allocsize);
|
|
839
|
+
delete [] mem_to_delete;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// Only provide this function if T is archivable
|
|
843
|
+
template<typename ARCHIVE>
|
|
844
|
+
auto DoArchive(ARCHIVE& archive)
|
|
845
|
+
-> typename std::enable_if_t<ARCHIVE::template is_archivable<T>, void>
|
|
846
|
+
{
|
|
847
|
+
if(archive.Output())
|
|
848
|
+
archive << size;
|
|
849
|
+
else
|
|
850
|
+
{
|
|
851
|
+
size_t s;
|
|
852
|
+
archive & s;
|
|
853
|
+
SetSize(s);
|
|
854
|
+
}
|
|
855
|
+
archive.Do(data, size);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/// we tell the compiler that there is no need for deleting the array ..
|
|
859
|
+
NETGEN_INLINE void NothingToDelete ()
|
|
860
|
+
{
|
|
861
|
+
mem_to_delete = nullptr;
|
|
862
|
+
|
|
863
|
+
// this memory is not managed by the Array anymore, so set the memory usage to 0
|
|
864
|
+
mt.Free(sizeof(T)*allocsize);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/// Change logical size. If necessary, do reallocation. Keeps contents.
|
|
868
|
+
NETGEN_INLINE void SetSize(size_t nsize)
|
|
869
|
+
{
|
|
870
|
+
if (nsize > allocsize) ReSize (nsize);
|
|
871
|
+
size = nsize;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
///
|
|
875
|
+
NETGEN_INLINE void SetSize0()
|
|
876
|
+
{
|
|
877
|
+
size = 0;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/// Change physical size. Keeps logical size. Keeps contents.
|
|
881
|
+
NETGEN_INLINE void SetAllocSize (size_t nallocsize)
|
|
882
|
+
{
|
|
883
|
+
if (nallocsize > allocsize)
|
|
884
|
+
ReSize (nallocsize);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/// Change physical size. Keeps logical size. Keeps contents.
|
|
888
|
+
NETGEN_INLINE size_t AllocSize () const
|
|
889
|
+
{
|
|
890
|
+
return allocsize;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
/// assigns memory from local heap
|
|
895
|
+
NETGEN_INLINE const Array & Assign (size_t asize, LocalHeap & lh)
|
|
896
|
+
{
|
|
897
|
+
if(mem_to_delete)
|
|
898
|
+
mt.Free(sizeof(T)*allocsize);
|
|
899
|
+
delete [] mem_to_delete;
|
|
900
|
+
size = allocsize = asize;
|
|
901
|
+
data = lh.Alloc<T> (asize);
|
|
902
|
+
mem_to_delete = nullptr;
|
|
903
|
+
return *this;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/// Add element at end of array. reallocation if necessary.
|
|
907
|
+
/// Returns index of new element.
|
|
908
|
+
NETGEN_INLINE index_type Append (const T & el)
|
|
909
|
+
{
|
|
910
|
+
if (size == allocsize)
|
|
911
|
+
ReSize (size+1);
|
|
912
|
+
data[size] = el;
|
|
913
|
+
return BASE + size++;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/// Add element at end of array. reallocation not necessary.
|
|
917
|
+
/// Returns index of new element.
|
|
918
|
+
NETGEN_INLINE index_type AppendHaveMem (const T & el)
|
|
919
|
+
{
|
|
920
|
+
NETGEN_CHECK_RANGE(size, 0, allocsize);
|
|
921
|
+
data[size] = el;
|
|
922
|
+
return BASE + size++;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
/// Add element at end of array. reallocation if necessary.
|
|
927
|
+
/// Returns index of new element.
|
|
928
|
+
NETGEN_INLINE index_type Append (T && el)
|
|
929
|
+
{
|
|
930
|
+
if (size == allocsize)
|
|
931
|
+
ReSize (size+1);
|
|
932
|
+
data[size] = std::move(el);
|
|
933
|
+
return BASE + size++;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// Add elements of initializer list to end of array. Reallocation if necessary.
|
|
937
|
+
NETGEN_INLINE void Append(std::initializer_list<T> lst)
|
|
938
|
+
{
|
|
939
|
+
if(allocsize < size + lst.size())
|
|
940
|
+
ReSize(size+lst.size());
|
|
941
|
+
for(auto val : lst)
|
|
942
|
+
data[size++] = val;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/// Add element at end of array. reallocation if necessary.
|
|
946
|
+
NETGEN_INLINE void Insert (size_t pos, const T & el)
|
|
947
|
+
{
|
|
948
|
+
if (size == allocsize)
|
|
949
|
+
ReSize (size+1);
|
|
950
|
+
for (size_t i = size; i > pos; i--)
|
|
951
|
+
data[i] = data[i-1];
|
|
952
|
+
data[pos] = el;
|
|
953
|
+
size++;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
NETGEN_INLINE Array & operator += (const T & el)
|
|
957
|
+
{
|
|
958
|
+
Append (el);
|
|
959
|
+
return *this;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
/// Append array at end of array. reallocation if necessary.
|
|
964
|
+
NETGEN_INLINE void Append (FlatArray<T> source)
|
|
965
|
+
{
|
|
966
|
+
if(size + source.Size() >= allocsize)
|
|
967
|
+
ReSize (size + source.Size() + 1);
|
|
968
|
+
|
|
969
|
+
for(size_t i = size, j=0; j<source.Size(); i++, j++)
|
|
970
|
+
data[i] = source[j];
|
|
971
|
+
|
|
972
|
+
size += source.Size();
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
/// Delete element i. Move last element to position i.
|
|
978
|
+
NETGEN_INLINE void DeleteElement (IndexType i)
|
|
979
|
+
{
|
|
980
|
+
NETGEN_CHECK_RANGE(i,BASE,BASE+size);
|
|
981
|
+
data[i-BASE] = std::move(data[size-1]);
|
|
982
|
+
size--;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
/// Delete element i. Move all remaining elements forward
|
|
987
|
+
NETGEN_INLINE void RemoveElement (IndexType i)
|
|
988
|
+
{
|
|
989
|
+
NETGEN_CHECK_RANGE(i, BASE, BASE+size);
|
|
990
|
+
for(size_t j = i-BASE; j+1 < this->size; j++)
|
|
991
|
+
this->data[j] = this->data[j+1];
|
|
992
|
+
this->size--;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
/// Delete last element.
|
|
997
|
+
NETGEN_INLINE void DeleteLast ()
|
|
998
|
+
{
|
|
999
|
+
NETGEN_CHECK_RANGE(size-1,0,size);
|
|
1000
|
+
size--;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/// Deallocate memory
|
|
1004
|
+
NETGEN_INLINE void DeleteAll ()
|
|
1005
|
+
{
|
|
1006
|
+
if(mem_to_delete)
|
|
1007
|
+
mt.Free(sizeof(T)*allocsize);
|
|
1008
|
+
delete [] mem_to_delete;
|
|
1009
|
+
mem_to_delete = NULL;
|
|
1010
|
+
data = 0;
|
|
1011
|
+
size = allocsize = 0;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/// Fill array with val
|
|
1015
|
+
NETGEN_INLINE Array & operator= (const T & val)
|
|
1016
|
+
{
|
|
1017
|
+
FlatArray<T,IndexType>::operator= (val);
|
|
1018
|
+
return *this;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/// array copy
|
|
1022
|
+
NETGEN_INLINE Array & operator= (const Array & a2)
|
|
1023
|
+
{
|
|
1024
|
+
if constexpr (std::is_copy_assignable<T>::value)
|
|
1025
|
+
{
|
|
1026
|
+
SetSize0 ();
|
|
1027
|
+
SetSize (a2.Size());
|
|
1028
|
+
for (size_t i = 0; i < size; i++)
|
|
1029
|
+
data[i] = a2.data[i];
|
|
1030
|
+
return *this;
|
|
1031
|
+
}
|
|
1032
|
+
#ifndef __CUDA_ARCH__
|
|
1033
|
+
else
|
|
1034
|
+
throw Exception(std::string("cannot copy Array of type ") + typeid(T).name());
|
|
1035
|
+
#endif
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
/// steal array
|
|
1040
|
+
NETGEN_INLINE Array & operator= (Array && a2)
|
|
1041
|
+
{
|
|
1042
|
+
mt = std::move(a2.mt);
|
|
1043
|
+
ngcore::Swap (size, a2.size);
|
|
1044
|
+
ngcore::Swap (data, a2.data);
|
|
1045
|
+
ngcore::Swap (allocsize, a2.allocsize);
|
|
1046
|
+
ngcore::Swap (mem_to_delete, a2.mem_to_delete);
|
|
1047
|
+
return *this;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
/// array copy
|
|
1052
|
+
NETGEN_INLINE Array & operator= (const FlatArray<T> & a2)
|
|
1053
|
+
{
|
|
1054
|
+
SetSize (a2.Size());
|
|
1055
|
+
for (size_t i = 0; i < size; i++)
|
|
1056
|
+
data[i] = a2[i];
|
|
1057
|
+
return *this;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/*
|
|
1061
|
+
/// fill array with first, first+1, ...
|
|
1062
|
+
Array & operator= (const IntRange & range)
|
|
1063
|
+
{
|
|
1064
|
+
SetSize (range.Size());
|
|
1065
|
+
for (int i = 0; i < size; i++)
|
|
1066
|
+
(*this)[i] = range.First()+i;
|
|
1067
|
+
return *this;
|
|
1068
|
+
}
|
|
1069
|
+
*/
|
|
1070
|
+
template <typename T2>
|
|
1071
|
+
Array & operator= (const BaseArrayObject<T2> & a2)
|
|
1072
|
+
{
|
|
1073
|
+
size_t newsize = a2.Spec().Size();
|
|
1074
|
+
SetSize0 ();
|
|
1075
|
+
SetSize (newsize);
|
|
1076
|
+
// for (size_t i = 0; i < newsize; i++)
|
|
1077
|
+
// (*this)[i] = a2.Spec()[i];
|
|
1078
|
+
size_t i = 0;
|
|
1079
|
+
for (auto val : a2.Spec())
|
|
1080
|
+
(*this)[i++] = val;
|
|
1081
|
+
|
|
1082
|
+
return *this;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
template <typename ...ARGS>
|
|
1086
|
+
Array & operator= (Tuple<ARGS...> tup)
|
|
1087
|
+
{
|
|
1088
|
+
SetSize (ArraySize (tup));
|
|
1089
|
+
StoreToArray (*this, tup);
|
|
1090
|
+
return *this;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
Array & operator= (std::initializer_list<T> list)
|
|
1094
|
+
{
|
|
1095
|
+
*this = Array<T> (list);
|
|
1096
|
+
return *this;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
// template <typename T2>
|
|
1101
|
+
// Array & operator= (ParallelValue<T2> val)
|
|
1102
|
+
// {
|
|
1103
|
+
// FlatArray<T>::operator= (val);
|
|
1104
|
+
// return *this;
|
|
1105
|
+
// }
|
|
1106
|
+
// template <typename T2>
|
|
1107
|
+
// Array & operator= (ParallelFunction<T2> val)
|
|
1108
|
+
// {
|
|
1109
|
+
// FlatArray<T>::operator= (val);
|
|
1110
|
+
// return *this;
|
|
1111
|
+
// }
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
NETGEN_INLINE void Swap (Array & b)
|
|
1115
|
+
{
|
|
1116
|
+
mt = std::move(b.mt);
|
|
1117
|
+
ngcore::Swap (size, b.size);
|
|
1118
|
+
ngcore::Swap (data, b.data);
|
|
1119
|
+
ngcore::Swap (allocsize, b.allocsize);
|
|
1120
|
+
ngcore::Swap (mem_to_delete, b.mem_to_delete);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
NETGEN_INLINE void StartMemoryTracing () const
|
|
1124
|
+
{
|
|
1125
|
+
if(mem_to_delete)
|
|
1126
|
+
mt.Alloc(sizeof(T) * allocsize);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
const MemoryTracer& GetMemoryTracer() const { return mt; }
|
|
1130
|
+
|
|
1131
|
+
private:
|
|
1132
|
+
|
|
1133
|
+
/// resize array, at least to size minsize. copy contents
|
|
1134
|
+
NETGEN_INLINE void ReSize (size_t minsize);
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
/// resize array, at least to size minsize. copy contents
|
|
1139
|
+
template <class T, class IndexType>
|
|
1140
|
+
NETGEN_INLINE void Array<T, IndexType> :: ReSize (size_t minsize)
|
|
1141
|
+
{
|
|
1142
|
+
size_t nsize = 2 * allocsize;
|
|
1143
|
+
if (nsize < minsize) nsize = minsize;
|
|
1144
|
+
|
|
1145
|
+
T * hdata = data;
|
|
1146
|
+
data = new T[nsize];
|
|
1147
|
+
mt.Alloc(sizeof(T) * nsize);
|
|
1148
|
+
|
|
1149
|
+
if (hdata)
|
|
1150
|
+
{
|
|
1151
|
+
size_t mins = (nsize < size) ? nsize : size;
|
|
1152
|
+
#if defined(__GNUG__) && __GNUC__ < 5 && !defined(__clang__)
|
|
1153
|
+
for (size_t i = 0; i < mins; i++) data[i] = std::move(hdata[i]);
|
|
1154
|
+
#else
|
|
1155
|
+
if (std::is_trivially_copyable<T>::value)
|
|
1156
|
+
memcpy ((void*)data, hdata, sizeof(T)*mins);
|
|
1157
|
+
else
|
|
1158
|
+
for (size_t i = 0; i < mins; i++) data[i] = std::move(hdata[i]);
|
|
1159
|
+
#endif
|
|
1160
|
+
if(mem_to_delete)
|
|
1161
|
+
mt.Free(sizeof(T) * allocsize);
|
|
1162
|
+
delete [] mem_to_delete;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
mem_to_delete = data;
|
|
1166
|
+
allocsize = nsize;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
//extern template class Array<int,int>;
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
/**
|
|
1173
|
+
Array with static and dynamic memory management.
|
|
1174
|
+
Declares a static array which size is given by the template parameter.
|
|
1175
|
+
If the dynamic size fits into the static size, use static memory,
|
|
1176
|
+
otherwise perform dynamic allocation
|
|
1177
|
+
*/
|
|
1178
|
+
template <class T, int S>
|
|
1179
|
+
class ArrayMem : public Array<T>
|
|
1180
|
+
{
|
|
1181
|
+
T mem[S];
|
|
1182
|
+
|
|
1183
|
+
using Array<T>::size;
|
|
1184
|
+
using Array<T>::allocsize;
|
|
1185
|
+
using Array<T>::data;
|
|
1186
|
+
using Array<T>::mem_to_delete;
|
|
1187
|
+
using Array<T>::mt;
|
|
1188
|
+
// using Array<T>::ownmem;
|
|
1189
|
+
|
|
1190
|
+
public:
|
|
1191
|
+
/// Generate array of logical and physical size asize
|
|
1192
|
+
explicit ArrayMem(size_t asize = 0)
|
|
1193
|
+
: Array<T> (S, mem)
|
|
1194
|
+
{
|
|
1195
|
+
size = asize;
|
|
1196
|
+
if (asize > S)
|
|
1197
|
+
{
|
|
1198
|
+
data = new T[asize];
|
|
1199
|
+
allocsize = size;
|
|
1200
|
+
mem_to_delete = data;
|
|
1201
|
+
mt.Alloc(sizeof(T)*asize);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/// copies from Array a2
|
|
1206
|
+
explicit ArrayMem(const Array<T> & a2)
|
|
1207
|
+
: Array<T> (S, (T*)mem)
|
|
1208
|
+
{
|
|
1209
|
+
Array<T>::operator= (a2);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
/// copies from ArrayMem a2
|
|
1213
|
+
explicit ArrayMem(const ArrayMem & a2)
|
|
1214
|
+
: Array<T> (S, (T*)mem)
|
|
1215
|
+
{
|
|
1216
|
+
Array<T>::operator= (a2);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
ArrayMem(ArrayMem && a2)
|
|
1220
|
+
: Array<T> (a2.Size(), (T*)mem)
|
|
1221
|
+
{
|
|
1222
|
+
mt = std::move(a2.mt);
|
|
1223
|
+
if (a2.mem_to_delete)
|
|
1224
|
+
{
|
|
1225
|
+
mem_to_delete = a2.mem_to_delete;
|
|
1226
|
+
data = a2.data;
|
|
1227
|
+
allocsize = a2.allocsize;
|
|
1228
|
+
a2.mem_to_delete = nullptr;
|
|
1229
|
+
a2.data = nullptr;
|
|
1230
|
+
a2.size = 0;
|
|
1231
|
+
}
|
|
1232
|
+
else
|
|
1233
|
+
{
|
|
1234
|
+
allocsize = S;
|
|
1235
|
+
for (auto i : ngcore::Range(size))
|
|
1236
|
+
mem[i] = a2.mem[i];
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
ArrayMem (std::initializer_list<T> list)
|
|
1241
|
+
: ArrayMem (list.size())
|
|
1242
|
+
{
|
|
1243
|
+
size_t cnt = 0;
|
|
1244
|
+
for (auto val : list)
|
|
1245
|
+
data[cnt++] = val;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
template <typename T2>
|
|
1249
|
+
ArrayMem (const BaseArrayObject<T2> & a2)
|
|
1250
|
+
: ArrayMem (a2.Size())
|
|
1251
|
+
{
|
|
1252
|
+
for (size_t i : ngcore::Range(size))
|
|
1253
|
+
data[i] = a2[i];
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
ArrayMem & operator= (const T & val)
|
|
1258
|
+
{
|
|
1259
|
+
FlatArray<T>::operator= (val);
|
|
1260
|
+
return *this;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
ArrayMem & operator= (ArrayMem && a2)
|
|
1264
|
+
{
|
|
1265
|
+
mt = std::move(a2.mt);
|
|
1266
|
+
ngcore::Swap (mem_to_delete, a2.mem_to_delete);
|
|
1267
|
+
ngcore::Swap (allocsize, a2.allocsize);
|
|
1268
|
+
ngcore::Swap (size, a2.size);
|
|
1269
|
+
|
|
1270
|
+
if (mem_to_delete==nullptr)
|
|
1271
|
+
{
|
|
1272
|
+
for (auto i : ngcore::Range(size))
|
|
1273
|
+
mem[i] = std::move(a2.mem[i]);
|
|
1274
|
+
data = mem;
|
|
1275
|
+
}
|
|
1276
|
+
else
|
|
1277
|
+
ngcore::Swap (data, a2.data);
|
|
1278
|
+
|
|
1279
|
+
return *this;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
/// array copy
|
|
1284
|
+
ArrayMem & operator= (const FlatArray<T> & a2)
|
|
1285
|
+
{
|
|
1286
|
+
this->SetSize (a2.Size());
|
|
1287
|
+
for (size_t i = 0; i < size; i++)
|
|
1288
|
+
(*this)[i] = a2[i];
|
|
1289
|
+
return *this;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
template <typename T2>
|
|
1294
|
+
ArrayMem & operator= (const BaseArrayObject<T2> & a2)
|
|
1295
|
+
{
|
|
1296
|
+
this->SetSize (a2.Spec().Size());
|
|
1297
|
+
|
|
1298
|
+
size_t i = 0;
|
|
1299
|
+
for (auto val : a2.Spec())
|
|
1300
|
+
(*this)[i++] = val;
|
|
1301
|
+
|
|
1302
|
+
return *this;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
};
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
template <typename ... ARGS>
|
|
1312
|
+
size_t ArraySize (Tuple<ARGS...> /* tup */)
|
|
1313
|
+
{ return 0;}
|
|
1314
|
+
|
|
1315
|
+
template <typename ... ARGS>
|
|
1316
|
+
size_t ArraySize (Tuple<int,ARGS...> tup)
|
|
1317
|
+
{ return 1+ArraySize(tup.Tail()); }
|
|
1318
|
+
|
|
1319
|
+
template <typename ... ARGS>
|
|
1320
|
+
size_t ArraySize (Tuple<IntRange,ARGS...> tup)
|
|
1321
|
+
{ return tup.Head().Size()+ArraySize(tup.Tail()); }
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
template <typename T, typename ... ARGS>
|
|
1325
|
+
void StoreToArray (FlatArray<T> /* a */, Tuple<ARGS...> /* tup */) { ; }
|
|
1326
|
+
|
|
1327
|
+
template <typename T, typename ... ARGS>
|
|
1328
|
+
void StoreToArray (FlatArray<T> a, Tuple<int,ARGS...> tup)
|
|
1329
|
+
{
|
|
1330
|
+
a[0] = tup.Head();
|
|
1331
|
+
StoreToArray (a.Range(1, a.Size()), tup.Tail());
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
template <typename T, typename ... ARGS>
|
|
1335
|
+
void StoreToArray (FlatArray<T> a, Tuple<IntRange,ARGS...> tup)
|
|
1336
|
+
{
|
|
1337
|
+
IntRange r = tup.Head();
|
|
1338
|
+
a.Range(0,r.Size()) = r;
|
|
1339
|
+
StoreToArray (a.Range(r.Size(), a.Size()), tup.Tail());
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/*
|
|
1343
|
+
template <typename T> template <typename ...ARGS>
|
|
1344
|
+
NETGEN_INLINE Array<T> & Array<T> :: operator= (Tuple<ARGS...> tup)
|
|
1345
|
+
{
|
|
1346
|
+
SetSize (ArraySize (tup));
|
|
1347
|
+
StoreToArray (*this, tup);
|
|
1348
|
+
}
|
|
1349
|
+
*/
|
|
1350
|
+
|
|
1351
|
+
/*
|
|
1352
|
+
/// append integers to array
|
|
1353
|
+
inline Array<int> & operator+= (Array<int> & array, const IntRange & range)
|
|
1354
|
+
{
|
|
1355
|
+
int oldsize = array.Size();
|
|
1356
|
+
int s = range.Next() - range.First();
|
|
1357
|
+
|
|
1358
|
+
array.SetSize (oldsize+s);
|
|
1359
|
+
|
|
1360
|
+
for (int i = 0; i < s; i++)
|
|
1361
|
+
array[oldsize+i] = range.First()+i;
|
|
1362
|
+
|
|
1363
|
+
return array;
|
|
1364
|
+
}
|
|
1365
|
+
*/
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
/*
|
|
1369
|
+
template <typename T, typename T2>
|
|
1370
|
+
inline Array<T> & operator+= (Array<T> & array, const BaseArrayObject<T2> & a2)
|
|
1371
|
+
{
|
|
1372
|
+
size_t oldsize = array.Size();
|
|
1373
|
+
size_t s = a2.Spec().Size();
|
|
1374
|
+
|
|
1375
|
+
array.SetSize (oldsize+s);
|
|
1376
|
+
|
|
1377
|
+
for (size_t i = 0; i < s; i++)
|
|
1378
|
+
array[oldsize+i] = a2.Spec()[i];
|
|
1379
|
+
|
|
1380
|
+
return array;
|
|
1381
|
+
}
|
|
1382
|
+
*/
|
|
1383
|
+
|
|
1384
|
+
template <typename T, typename T2>
|
|
1385
|
+
inline Array<T> & operator+= (Array<T> & array, const BaseArrayObject<T2> & a2)
|
|
1386
|
+
{
|
|
1387
|
+
auto oldsize = array.Size();
|
|
1388
|
+
auto s = a2.Spec().Size();
|
|
1389
|
+
|
|
1390
|
+
array.SetSize (oldsize+s);
|
|
1391
|
+
|
|
1392
|
+
for (auto val : a2.Spec())
|
|
1393
|
+
array[oldsize++] = val;
|
|
1394
|
+
|
|
1395
|
+
return array;
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
template <typename T, typename T2>
|
|
1399
|
+
inline Array<T> operator+= (Array<T> && array, const BaseArrayObject<T2> & a2)
|
|
1400
|
+
{
|
|
1401
|
+
array += a2;
|
|
1402
|
+
return std::move(array);
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
/// bubble sort array
|
|
1407
|
+
template <class T>
|
|
1408
|
+
inline void BubbleSort (FlatArray<T> data)
|
|
1409
|
+
{
|
|
1410
|
+
T hv;
|
|
1411
|
+
for (size_t i = 0; i < data.Size(); i++)
|
|
1412
|
+
for (size_t j = i+1; j < data.Size(); j++)
|
|
1413
|
+
if (data[i] > data[j])
|
|
1414
|
+
{
|
|
1415
|
+
hv = data[i];
|
|
1416
|
+
data[i] = data[j];
|
|
1417
|
+
data[j] = hv;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/// bubble sort array
|
|
1422
|
+
template <class T, class S>
|
|
1423
|
+
inline void BubbleSort (FlatArray<T> data, FlatArray<S> index)
|
|
1424
|
+
{
|
|
1425
|
+
for (size_t i = 0; i < data.Size(); i++)
|
|
1426
|
+
for (size_t j = i+1; j < data.Size(); j++)
|
|
1427
|
+
if (data[i] > data[j])
|
|
1428
|
+
{
|
|
1429
|
+
T hv = data[i];
|
|
1430
|
+
data[i] = data[j];
|
|
1431
|
+
data[j] = hv;
|
|
1432
|
+
|
|
1433
|
+
S hvs = index[i];
|
|
1434
|
+
index[i] = index[j];
|
|
1435
|
+
index[j] = hvs;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
template <class T, typename TLESS>
|
|
1443
|
+
void QuickSort (FlatArray<T> data, TLESS less)
|
|
1444
|
+
{
|
|
1445
|
+
constexpr size_t INSERTION_SORT_THRESHOLD = 16;
|
|
1446
|
+
|
|
1447
|
+
if (data.Size() <= INSERTION_SORT_THRESHOLD) {
|
|
1448
|
+
// insertion sort
|
|
1449
|
+
for (ptrdiff_t k = 1; k < data.Size(); ++k)
|
|
1450
|
+
{
|
|
1451
|
+
auto newval = data[k];
|
|
1452
|
+
ptrdiff_t l = k;
|
|
1453
|
+
for ( ; l > 0 && less(newval, data[l-1]); --l)
|
|
1454
|
+
data[l] = data[l-1];
|
|
1455
|
+
data[l] = newval;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
// if (data.Size() <= 1) return;
|
|
1462
|
+
|
|
1463
|
+
ptrdiff_t i = 0;
|
|
1464
|
+
ptrdiff_t j = data.Size()-1;
|
|
1465
|
+
|
|
1466
|
+
T midval = data[ (i+j)/2 ];
|
|
1467
|
+
|
|
1468
|
+
do
|
|
1469
|
+
{
|
|
1470
|
+
while (less (data[i], midval)) i++;
|
|
1471
|
+
while (less (midval, data[j])) j--;
|
|
1472
|
+
|
|
1473
|
+
if (i <= j)
|
|
1474
|
+
{
|
|
1475
|
+
Swap (data[i], data[j]);
|
|
1476
|
+
i++; j--;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
while (i <= j);
|
|
1480
|
+
|
|
1481
|
+
QuickSort (data.Range (0, j+1), less);
|
|
1482
|
+
QuickSort (data.Range (i, data.Size()), less);
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
template <typename T>
|
|
1486
|
+
NETGEN_INLINE bool DefaultLess (const T & a, const T & b)
|
|
1487
|
+
{
|
|
1488
|
+
return a < b;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
template <typename T>
|
|
1492
|
+
class DefaultLessCl
|
|
1493
|
+
{
|
|
1494
|
+
public:
|
|
1495
|
+
bool operator() (const T & a, const T & b) const
|
|
1496
|
+
{
|
|
1497
|
+
return a < b;
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
template <class T>
|
|
1504
|
+
NETGEN_INLINE void QuickSort (FlatArray<T> data)
|
|
1505
|
+
{
|
|
1506
|
+
QuickSort (data, DefaultLessCl<T>());
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
template <class T, typename TLESS>
|
|
1512
|
+
void QuickSortI (FlatArray<T> data, FlatArray<int> index, TLESS less)
|
|
1513
|
+
{
|
|
1514
|
+
if (index.Size() <= 1) return;
|
|
1515
|
+
|
|
1516
|
+
ptrdiff_t i = 0;
|
|
1517
|
+
ptrdiff_t j = index.Size()-1;
|
|
1518
|
+
|
|
1519
|
+
int midval = index[ (i+j)/2 ];
|
|
1520
|
+
|
|
1521
|
+
do
|
|
1522
|
+
{
|
|
1523
|
+
while (less (data[index[i]],data[midval]) ) i++;
|
|
1524
|
+
while (less (data[midval], data[index[j]])) j--;
|
|
1525
|
+
|
|
1526
|
+
if (i <= j)
|
|
1527
|
+
{
|
|
1528
|
+
Swap (index[i], index[j]);
|
|
1529
|
+
i++; j--;
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
while (i <= j);
|
|
1533
|
+
|
|
1534
|
+
QuickSortI (data, index.Range (0, j+1), less);
|
|
1535
|
+
QuickSortI (data, index.Range (i, index.Size()), less);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
template <class T>
|
|
1540
|
+
NETGEN_INLINE void QuickSortI (FlatArray<T> data, FlatArray<int> index)
|
|
1541
|
+
{
|
|
1542
|
+
QuickSortI (data, index, DefaultLessCl<T>());
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
template <typename T>
|
|
1550
|
+
NETGEN_INLINE T xxxRemoveRef (const T & x)
|
|
1551
|
+
{
|
|
1552
|
+
return x;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
template <class TA1, class TA2>
|
|
1556
|
+
class SumArray : public BaseArrayObject<SumArray<TA1,TA2>>
|
|
1557
|
+
{
|
|
1558
|
+
const TA1 & a1;
|
|
1559
|
+
const TA2 & a2;
|
|
1560
|
+
public:
|
|
1561
|
+
SumArray (const TA1 & aa1, const TA2 & aa2) : a1(aa1), a2(aa2) { ; }
|
|
1562
|
+
size_t Size() const { return a1.Size()+a2.Size(); }
|
|
1563
|
+
auto operator[] (size_t i) const -> decltype (xxxRemoveRef (a1[0]))
|
|
1564
|
+
{
|
|
1565
|
+
return (i < a1.Size()) ? a1[i] : a2[i-a1.Size()];
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
|
|
1569
|
+
template <class TA1, class TA2>
|
|
1570
|
+
SumArray<TA1,TA2> operator+ (const BaseArrayObject<TA1> & a1,
|
|
1571
|
+
const BaseArrayObject<TA2> & a2)
|
|
1572
|
+
{
|
|
1573
|
+
return SumArray<TA1,TA2> (a1.Spec(), a2.Spec());
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
struct HTAHelp { };
|
|
1578
|
+
|
|
1579
|
+
// head-tail array
|
|
1580
|
+
template <size_t S, typename T>
|
|
1581
|
+
class HTArray
|
|
1582
|
+
{
|
|
1583
|
+
HTArray<S-1,T> tail;
|
|
1584
|
+
T head;
|
|
1585
|
+
public:
|
|
1586
|
+
constexpr HTArray () = default;
|
|
1587
|
+
constexpr HTArray (const HTArray &) = default;
|
|
1588
|
+
template <typename T2>
|
|
1589
|
+
constexpr HTArray (const HTArray<S,T2> & a2) : tail(a2.Tail()), head(a2.Head()) { ; }
|
|
1590
|
+
|
|
1591
|
+
constexpr HTArray (T v) : tail(v), head(v) { } // all the same
|
|
1592
|
+
|
|
1593
|
+
template <class... T2,
|
|
1594
|
+
std::enable_if_t<S==1+sizeof...(T2),bool> = true>
|
|
1595
|
+
constexpr HTArray (const T &v, T2... rest)
|
|
1596
|
+
: tail{HTAHelp(), v,rest...}, head(std::get<S-2>(std::tuple(rest...))) { }
|
|
1597
|
+
|
|
1598
|
+
template <class... T2>
|
|
1599
|
+
constexpr HTArray (HTAHelp h, const T &v, T2... rest)
|
|
1600
|
+
: tail{h, v,rest...}, head(std::get<S-2>(std::tuple(rest...))) { }
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
HTArray & operator= (const HTArray &) = default;
|
|
1604
|
+
|
|
1605
|
+
T * Ptr () { return tail.Ptr(); }
|
|
1606
|
+
T & operator[] (size_t i) { return Ptr()[i]; }
|
|
1607
|
+
|
|
1608
|
+
const T * Ptr () const { return tail.Ptr(); }
|
|
1609
|
+
const T & operator[] (size_t i) const { return Ptr()[i]; }
|
|
1610
|
+
template <int NR>
|
|
1611
|
+
T & Elem() { return (NR==S-1) ? head : tail.template Elem<NR>(); }
|
|
1612
|
+
|
|
1613
|
+
auto Tail() const { return tail; }
|
|
1614
|
+
auto Head() const { return head; }
|
|
1615
|
+
};
|
|
1616
|
+
|
|
1617
|
+
template <typename T>
|
|
1618
|
+
class HTArray<1,T>
|
|
1619
|
+
{
|
|
1620
|
+
T head;
|
|
1621
|
+
public:
|
|
1622
|
+
constexpr HTArray () = default;
|
|
1623
|
+
constexpr HTArray (const HTArray &) = default;
|
|
1624
|
+
template <typename T2>
|
|
1625
|
+
constexpr HTArray (const HTArray<1,T2> & a2) : head(a2.Head()) { ; }
|
|
1626
|
+
constexpr HTArray (T v) : head(v) { } // all the same
|
|
1627
|
+
template <class... T2>
|
|
1628
|
+
constexpr HTArray (HTAHelp h, const T &v, T2... rest)
|
|
1629
|
+
: head(v) { }
|
|
1630
|
+
|
|
1631
|
+
|
|
1632
|
+
HTArray & operator= (const HTArray &) = default;
|
|
1633
|
+
|
|
1634
|
+
T * Ptr () { return &head; }
|
|
1635
|
+
T & operator[] (size_t i) { return Ptr()[i]; }
|
|
1636
|
+
|
|
1637
|
+
const T * Ptr () const { return &head; }
|
|
1638
|
+
const T & operator[] (size_t i) const { return Ptr()[i]; }
|
|
1639
|
+
template <int NR>
|
|
1640
|
+
T & Elem()
|
|
1641
|
+
{
|
|
1642
|
+
// assert(NR==0, "HTArray index error");
|
|
1643
|
+
return head;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
auto Head() const { return head; }
|
|
1647
|
+
};
|
|
1648
|
+
|
|
1649
|
+
template <typename T>
|
|
1650
|
+
class HTArray<0,T>
|
|
1651
|
+
{
|
|
1652
|
+
// T head; // dummy variable
|
|
1653
|
+
public:
|
|
1654
|
+
HTArray () = default;
|
|
1655
|
+
HTArray (const HTArray &) = default;
|
|
1656
|
+
template <typename T2>
|
|
1657
|
+
HTArray (const HTArray<0,T2> & a2) { ; }
|
|
1658
|
+
constexpr HTArray (T v) { } // all the same
|
|
1659
|
+
HTArray & operator= (const HTArray &) = default;
|
|
1660
|
+
|
|
1661
|
+
/*
|
|
1662
|
+
T * Ptr () { return &head; }
|
|
1663
|
+
T & operator[] (size_t i) { return Ptr()[i]; }
|
|
1664
|
+
|
|
1665
|
+
const T * Ptr () const { return &head; }
|
|
1666
|
+
const T & operator[] (size_t i) const { return Ptr()[i]; }
|
|
1667
|
+
template <int NR>
|
|
1668
|
+
T & Elem()
|
|
1669
|
+
{
|
|
1670
|
+
// assert(false, "HTArray index error");
|
|
1671
|
+
return head;
|
|
1672
|
+
}
|
|
1673
|
+
*/
|
|
1674
|
+
// T * Ptr () { return (T*)(void*)&head; }
|
|
1675
|
+
T * Ptr () { return (T*)(void*)this; }
|
|
1676
|
+
T & operator[] (size_t i) { return Ptr()[i]; }
|
|
1677
|
+
// const T * Ptr () const { return (const T*)(const void*)&head; }
|
|
1678
|
+
const T * Ptr () const { return (const T*)(const void*)this; }
|
|
1679
|
+
const T & operator[] (size_t i) const { return Ptr()[i]; }
|
|
1680
|
+
template <int NR>
|
|
1681
|
+
T & Elem()
|
|
1682
|
+
{
|
|
1683
|
+
throw Exception("illegal HTArray<0>::Elem<0>");
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
};
|
|
1687
|
+
|
|
1688
|
+
template<size_t S, typename T>
|
|
1689
|
+
const T * operator+ (const HTArray<S,T> & ar, size_t i)
|
|
1690
|
+
{
|
|
1691
|
+
return ar.Ptr()+i;
|
|
1692
|
+
}
|
|
1693
|
+
template<size_t S, typename T>
|
|
1694
|
+
T * operator+ (HTArray<S,T> & ar, size_t i)
|
|
1695
|
+
{
|
|
1696
|
+
return ar.Ptr()+i;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
|
|
1705
|
+
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
template <typename TIA, typename TIB>
|
|
1709
|
+
class IteratorPair
|
|
1710
|
+
{
|
|
1711
|
+
TIA a;
|
|
1712
|
+
TIB b;
|
|
1713
|
+
public:
|
|
1714
|
+
IteratorPair (TIA _a, TIB _b) : a(_a), b(_b) { ; }
|
|
1715
|
+
|
|
1716
|
+
IteratorPair & operator++() { ++a; ++b; return *this; }
|
|
1717
|
+
bool operator!= (const IteratorPair & it2) { return a != it2.a; }
|
|
1718
|
+
|
|
1719
|
+
auto operator*()
|
|
1720
|
+
{
|
|
1721
|
+
// return pair(*a,*b);
|
|
1722
|
+
return std::pair<decltype(*a), decltype(*b)> (*a, *b); // keep reference
|
|
1723
|
+
}
|
|
1724
|
+
};
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
template <typename TA, typename TB>
|
|
1728
|
+
class Zip
|
|
1729
|
+
{
|
|
1730
|
+
const TA & a;
|
|
1731
|
+
const TB & b;
|
|
1732
|
+
public:
|
|
1733
|
+
Zip(const TA & _a, const TB & _b) : a(_a), b(_b) { ; }
|
|
1734
|
+
auto begin() const { return IteratorPair(a.begin(), b.begin()); }
|
|
1735
|
+
auto end() const { return IteratorPair(a.end(), b.end()); }
|
|
1736
|
+
};
|
|
1737
|
+
|
|
1738
|
+
template <typename T>
|
|
1739
|
+
inline size_t size (const BaseArrayObject<T> & ao) { return ao.Size(); }
|
|
1740
|
+
|
|
1741
|
+
template <typename TA>
|
|
1742
|
+
class Enumerate
|
|
1743
|
+
{
|
|
1744
|
+
IntRange r;
|
|
1745
|
+
const TA & a;
|
|
1746
|
+
public:
|
|
1747
|
+
Enumerate(const TA & _a) : r(size(_a)), a(_a) { ; }
|
|
1748
|
+
auto begin() const { return IteratorPair(r.begin(), a.begin()); }
|
|
1749
|
+
auto end() const { return IteratorPair(r.end(), a.end()); }
|
|
1750
|
+
};
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
#endif // NETGEN_CORE_ARRAY_HPP
|
|
1760
|
+
|