funktionsklempner 1.0.0__py3-none-any.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 (70) hide show
  1. funktionsklempner/__init__.py +0 -0
  2. funktionsklempner/generate/__init__.py +26 -0
  3. funktionsklempner/generate/boilerplate.py +92 -0
  4. funktionsklempner/generate/cpp.py +86 -0
  5. funktionsklempner/generate/python.py +119 -0
  6. funktionsklempner/language/__init__.py +22 -0
  7. funktionsklempner/language/abstract.py +177 -0
  8. funktionsklempner/language/arrays.py +82 -0
  9. funktionsklempner/language/conversion.py +229 -0
  10. funktionsklempner/language/cpp.py +89 -0
  11. funktionsklempner/language/fundamental.py +167 -0
  12. funktionsklempner/language/python.py +139 -0
  13. funktionsklempner/language/strings.py +86 -0
  14. funktionsklempner/parse/__init__.py +24 -0
  15. funktionsklempner/parse/function.py +142 -0
  16. funktionsklempner/parse/library.py +153 -0
  17. funktionsklempner/parse/macros.py +29 -0
  18. funktionsklempner/parse/parse.py +434 -0
  19. funktionsklempner/parse/sizecontrol.py +54 -0
  20. funktionsklempner/parse/spdx.py +157 -0
  21. funktionsklempner/parse/struct.py +74 -0
  22. funktionsklempner/parse/usertypes.py +49 -0
  23. funktionsklempner/parse/variable.py +298 -0
  24. funktionsklempner/py.typed +0 -0
  25. funktionsklempner/repo/__init__.py +30 -0
  26. funktionsklempner/repo/paths.py +219 -0
  27. funktionsklempner/repo/repository.py +47 -0
  28. funktionsklempner/repo/tomllib.py +172 -0
  29. funktionsklempner/scripts/__init__.py +827 -0
  30. funktionsklempner/scripts/pre-commit +18 -0
  31. funktionsklempner/subprojectfiles/boost-1.90.0.wrap +4 -0
  32. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/call.hpp +85 -0
  33. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/cdecl.hpp +61 -0
  34. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/default_units.hpp +320 -0
  35. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/fixedmap.hpp +95 -0
  36. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/funktionsklempner.hpp +52 -0
  37. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/math.hpp +160 -0
  38. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/ndarray.hpp +132 -0
  39. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/numpytypes.hpp +202 -0
  40. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/quantityarray.hpp +526 -0
  41. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/scalar.hpp +110 -0
  42. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/strings.cpp +118 -0
  43. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/strings.hpp +83 -0
  44. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/tartanllama/expected.hpp +2475 -0
  45. funktionsklempner/subprojectfiles/funktionsklempner/funktionsklempner/units.hpp +696 -0
  46. funktionsklempner/subprojectfiles/funktionsklempner/meson.build +82 -0
  47. funktionsklempner/subprojectfiles/gcem.wrap +6 -0
  48. funktionsklempner/subprojectfiles/objektbuch.wrap +3 -0
  49. funktionsklempner/subprojectfiles/packagefiles/boost/meson.build.1 +8 -0
  50. funktionsklempner/subprojectfiles/packagefiles/boost-1.90.0_units.tar.gz +0 -0
  51. funktionsklempner/subprojectfiles/packagefiles/gcem/meson.build.0 +7 -0
  52. funktionsklempner/templates/quantityarray.py +57 -0
  53. funktionsklempner/templates/wrapper.py +165 -0
  54. funktionsklempner/tools/__init__.py +27 -0
  55. funktionsklempner/tools/views.py +100 -0
  56. funktionsklempner/wrap/__init__.py +22 -0
  57. funktionsklempner/wrap/array.py +607 -0
  58. funktionsklempner/wrap/function.py +421 -0
  59. funktionsklempner/wrap/input.py +174 -0
  60. funktionsklempner/wrap/library.py +69 -0
  61. funktionsklempner/wrap/out.py +124 -0
  62. funktionsklempner/wrap/paralist.py +105 -0
  63. funktionsklempner/wrap/parameter.py +477 -0
  64. funktionsklempner/wrap/string.py +220 -0
  65. funktionsklempner/wrap/variablegraph.py +291 -0
  66. funktionsklempner-1.0.0.dist-info/METADATA +296 -0
  67. funktionsklempner-1.0.0.dist-info/RECORD +70 -0
  68. funktionsklempner-1.0.0.dist-info/WHEEL +4 -0
  69. funktionsklempner-1.0.0.dist-info/entry_points.txt +3 -0
  70. funktionsklempner-1.0.0.dist-info/licenses/LICENSE +287 -0
File without changes
@@ -0,0 +1,26 @@
1
+ # The Funktionsklempner wrapper code generation module.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2026 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2026 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from .python import generate_python_source as generate_python_source
25
+ from .cpp import (generate_cpp_source as generate_cpp_source,
26
+ generate_cpp_header as generate_cpp_header)
@@ -0,0 +1,92 @@
1
+ # Write C++ and Python boilerplate code.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from typing import Iterable, Literal
25
+ from ..wrap.library import WrappedLibrary
26
+ from itertools import islice
27
+
28
+
29
+ def generate_boilerplate(
30
+ lib: WrappedLibrary,
31
+ ncols: int,
32
+ language: Literal["C++","Python"]
33
+ ) -> Iterable[str]:
34
+ """
35
+ Generate the license boilerplate code.
36
+ """
37
+ if language == "C++":
38
+ yield f"/*\n"
39
+ indent = " *"
40
+ else:
41
+ indent = "#"
42
+ n_indent = len(indent)
43
+ yield indent
44
+ yield " Autogenerated shared library wrapper for "
45
+ module = ".".join(lib.module())
46
+ if len(module) > ncols - 41 - len(indent):
47
+ # Exceeding maximum column width 'ncols'.
48
+ yield f"\n{indent} {module}\n{indent}\n{indent} Authors: "
49
+ else:
50
+ yield f"{lib.module}\n{indent}\n{indent} Authors: "
51
+ authors = lib.authors()
52
+ if len(authors) == 0:
53
+ raise RuntimeError("No authors declared.")
54
+ yield f"{authors[0][0]} ({authors[0][1]})\n"
55
+ for author, email in islice(authors, 1, None):
56
+ yield f"{indent} {author} ({email})\n"
57
+ yield from (
58
+ f"{indent}\n{indent} SPDX-FileCopyrightText: {cr}\n"
59
+ for cr in lib.copyright()
60
+ )
61
+
62
+ # Assemble the license boilerplate into the column width:
63
+ license_boilerplate = lib.license_boilerplate()
64
+ if license_boilerplate is not None:
65
+ yield f"{indent}\n"
66
+ words = license_boilerplate.split()
67
+ line: list[str] = [indent]
68
+ line_length = n_indent
69
+ for word in words:
70
+ nw = len(word)
71
+ if line_length + nw + 1 > ncols:
72
+ # Start a new line. However, if there's only one long word,
73
+ # write it out here:
74
+ if len(line) == 1:
75
+ yield f"{indent} {word}\n"
76
+ else:
77
+ yield " ".join(line)
78
+ yield "\n"
79
+ line.clear()
80
+ line.append(indent)
81
+ line.append(word)
82
+ line_length = n_indent + 1 + nw
83
+ else:
84
+ line_length += nw + 1
85
+ line.append(word)
86
+
87
+ if len(line) > 1:
88
+ yield " ".join(line)
89
+ yield "\n"
90
+
91
+ if language == "C++":
92
+ yield "*/\n"
@@ -0,0 +1,86 @@
1
+ # Generate C++ wrapper codes.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025-2026 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from typing import Iterable
25
+ from ..wrap.library import WrappedLibrary
26
+ from .boilerplate import generate_boilerplate
27
+ from ..repo import include_statement
28
+
29
+
30
+ def generate_cpp_source(
31
+ lib: WrappedLibrary
32
+ ) -> Iterable[str]:
33
+ """
34
+ Writes the C++ source.
35
+ """
36
+ # Boilerplate:
37
+ yield from generate_boilerplate(lib, 80, 'C++')
38
+
39
+ yield (
40
+ "/* For error handling: */\n"
41
+ "#include <funktionsklempner/strings.hpp>\n\n"
42
+ "#include <funktionsklempner/call.hpp>\n\n"
43
+ f"{include_statement(lib.wrapper_include(), delimiter='""')}\n\n"
44
+ )
45
+
46
+ for f in lib.functions:
47
+ yield from f.compose_cpp_body()
48
+
49
+
50
+ def generate_cpp_header(
51
+ lib: WrappedLibrary
52
+ ) -> Iterable[str]:
53
+ """
54
+ Writes the C++ header.
55
+ """
56
+ # Boilerplate:
57
+ yield from generate_boilerplate(lib, 80, 'C++')
58
+ yield "\n"
59
+
60
+ includeguard = (
61
+ f"{"_".join(lib.module()).upper()}_HPP"
62
+ )
63
+ yield (
64
+ f"#ifndef {includeguard}\n#define {includeguard}\n\n"
65
+ "/* For uint64_t and the like: */\n"
66
+ "#include <cstdint>\n\n"
67
+ "\n"
68
+ "\n"
69
+ f"{include_statement(lib.header_include(), '""')}\n"
70
+ "\n"
71
+ 'extern "C" {\n'
72
+ "\n"
73
+ "\n"
74
+ )
75
+
76
+ for f in lib.functions:
77
+ yield from f.compose_cpp_head(True)
78
+ yield "\n"
79
+
80
+ yield (
81
+ "\n"
82
+ "\n"
83
+ "}\n"
84
+ "\n"
85
+ "#endif\n"
86
+ )
@@ -0,0 +1,119 @@
1
+ # Generate Python wrapper code.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from importlib import resources
25
+ from typing import Iterable
26
+ from itertools import islice
27
+ from ..wrap.library import WrappedLibrary
28
+ from ..language.strings import type_string
29
+ from ..language.arrays import NDArray
30
+ from .boilerplate import generate_boilerplate
31
+ from ..tools.views import join
32
+
33
+
34
+ with resources.open_text(
35
+ 'funktionsklempner.templates','wrapper.py', encoding='utf-8'
36
+ ) as f:
37
+ WRAPPER_PY: str = f.read()
38
+
39
+
40
+ CDLL_NAME = "_cdll"
41
+
42
+
43
+
44
+ def generate_python_source(
45
+ lib: WrappedLibrary
46
+ ) -> Iterable[str]:
47
+ """
48
+
49
+ """
50
+ # Boilerplate:
51
+ yield from generate_boilerplate(lib, 80, 'Python')
52
+
53
+ # Define the package and the shared library name for finding them
54
+ # among the package resources:
55
+ yield "\n\nANCHOR = '"
56
+ module = lib.module()
57
+ yield from join(islice(module, 0, len(module)-1), ".")
58
+ yield f"'\nSHARED_LIBRARY = '"
59
+ yield lib.shared_library_name()
60
+ yield "'\nPACKAGE = '"
61
+ yield lib.module()[0]
62
+ yield "'\n\n"
63
+
64
+ # Include the boilerplate glue code:
65
+ yield WRAPPER_PY
66
+
67
+ # Import the quantity array. Use a relative import going up to the
68
+ # root of this package and then back down to _funktionsklempner.
69
+ yield (
70
+ f"\n\nfrom {"." * (len(lib.module()) - 2)}"
71
+ "._funktionsklempner.quantityarray import QuantityArray\n\n"
72
+ )
73
+
74
+ # Import NumPy if we encountered any arrays:
75
+ if lib.requires_numpy():
76
+ yield "\nimport numpy as np\nfrom typing import Iterable\n"
77
+
78
+ # Structures:
79
+ structs = lib.structs()
80
+ if len(structs) > 0:
81
+ yield "\n"
82
+ for s in structs:
83
+ yield f"class {s.name}(Structure):\n"
84
+ if len(s.members) == 0:
85
+ yield " _fields_ = []\n\n"
86
+ else:
87
+ yield " _fields_ = [\n"
88
+ yield from (
89
+ f" ('{m[1]}', {type_string(m[0])}),\n"
90
+ for m in s.members
91
+ )
92
+ yield " ]\n\n"
93
+
94
+ # Functions:
95
+ yield "# Shared library functions:\n"
96
+ # Keep track of whether any NumPy array occurs. This allows us to
97
+ # only conditionally include the NumPy types and keep NumPy an
98
+ # optional dependency.
99
+ has_np_array: bool = False
100
+ for f in lib.functions:
101
+ yield from f.compose_ctypes_function(CDLL_NAME)
102
+ if any(isinstance(p.dtype.val, NDArray) for p in f.python_input):
103
+ has_np_array = True
104
+ if any(isinstance(p.dtype.val, NDArray) for p in f.python_output):
105
+ has_np_array = True
106
+
107
+
108
+ yield "# Python interface:\n"
109
+ if has_np_array:
110
+ yield (
111
+ "from typing import TYPE_CHECKING\n"
112
+ "if TYPE_CHECKING:\n"
113
+ " from numpy.typing import NDArray\n"
114
+ " import numpy as np\n\n"
115
+ )
116
+
117
+ yield from (
118
+ body for f in lib.functions for body in f.compose_python_body()
119
+ )
@@ -0,0 +1,22 @@
1
+ # Funktionsklempner types module.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
@@ -0,0 +1,177 @@
1
+ # Funktionsklempner abstract types.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025-2026 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025-2026 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from typing import Any, Iterable, TypeVar, Generic
25
+
26
+ T0 = TypeVar("T0", covariant=True)
27
+
28
+ class Pointer(Generic[T0]):
29
+ val: T0
30
+
31
+ def __init__(self, val: T0):
32
+ self.val = val
33
+
34
+ def __repr__(self):
35
+ return f"POINTER({self.val.__repr__()})"
36
+
37
+ def __eq__(self, other: Any) -> bool:
38
+ if isinstance(other, Pointer):
39
+ return self.val == other.val # pyright: ignore
40
+ return False
41
+
42
+
43
+ T1 = TypeVar("T1", covariant=True)
44
+
45
+ class Const(Generic[T1]):
46
+ val: T1
47
+
48
+ def __init__(self, val: T1):
49
+ self.val = val
50
+
51
+ def __repr__(self):
52
+ return f"CONST({self.val.__repr__()})"
53
+
54
+ def __eq__(self, other: Any) -> bool:
55
+ if isinstance(other, Const):
56
+ return self.val == other.val # pyright: ignore
57
+ return False
58
+
59
+ T2 = TypeVar("T2", covariant=True)
60
+
61
+ class Struct(Generic[T2]):
62
+ name: str
63
+ members: tuple[tuple[T2, str], ...]
64
+
65
+ def __init__(self, name: str, members: Iterable[tuple[T2, str]]):
66
+ self.name = name
67
+ self.members = tuple(members)
68
+
69
+ def __repr__(self) -> str:
70
+ repr = f"struct {self.name} {{"
71
+ for i,m in enumerate(self.members):
72
+ if i > 0:
73
+ repr += ", "
74
+ repr += f"{m[0].__repr__()} {m[1]}"
75
+ return repr + "}"
76
+
77
+ def __eq__(self, other: Any):
78
+ return isinstance(other, Struct) and self.name == other.name
79
+
80
+
81
+ T3 = TypeVar("T3", covariant=True)
82
+
83
+ class Input(Generic[T3]):
84
+ """
85
+ Input that is automatically converted into a corresponding fundamental
86
+ Python type, if possible.
87
+ """
88
+ val: T3
89
+
90
+ def __init__(self, val: T3):
91
+ self.val = val
92
+
93
+ def __repr__(self):
94
+ return f"INPUT({self.val.__repr__()})"
95
+
96
+ def __eq__(self, other: Any) -> bool:
97
+ if type(other) == Input:
98
+ return self.val == other.val # pyright: ignore
99
+ return False
100
+
101
+
102
+ T4 = TypeVar("T4", covariant=True)
103
+
104
+ class PureInput(Input[T4]):
105
+ """
106
+ Input that is not auto-converted into a corresponding fundamental
107
+ Python type.
108
+ """
109
+ def __repr__(self):
110
+ return f"PURE_INPUT({self.val.__repr__()})"
111
+
112
+ def __eq__(self, other: Any) -> bool:
113
+ if type(other) == PureInput:
114
+ return self.val == other.val # pyright: ignore
115
+ return False
116
+
117
+
118
+
119
+ T5 = TypeVar("T5", covariant=True)
120
+
121
+ class Output(Generic[T5]):
122
+ """
123
+ Output that is automatically converted into a corresponding fundamental
124
+ Python type, if possible.
125
+ """
126
+ val: T5
127
+
128
+ def __init__(self, val: T5):
129
+ if isinstance(val, Const):
130
+ raise RuntimeError(
131
+ "Output arguments need to be non-const types."
132
+ )
133
+ self.val = val
134
+
135
+ def __repr__(self):
136
+ return f"OUTPUT({self.val.__repr__()})"
137
+
138
+ def __eq__(self, other: Any) -> bool:
139
+ if isinstance(other, Output):
140
+ return self.val == other.val # pyright: ignore
141
+ return False
142
+
143
+ T6 = TypeVar("T6", covariant=True)
144
+
145
+ class PureOutput(Output[T6]):
146
+ """
147
+ Output that is not auto-converted into a corresponding fundamental
148
+ Python type.
149
+ """
150
+ def __repr__(self):
151
+ return f"PURE_OUTPUT({self.val.__repr__()})"
152
+
153
+ def __eq__(self, other: Any) -> bool:
154
+ if isinstance(other, Output):
155
+ return self.val == other.val # pyright: ignore
156
+ return False
157
+
158
+
159
+
160
+ T7 = TypeVar("T7", covariant=True)
161
+
162
+ class Temporary(Generic[T7]):
163
+ """
164
+ TemporaryType.
165
+ """
166
+ val: T7
167
+
168
+ def __init__(self, val: T7):
169
+ self.val = val
170
+
171
+ def __repr__(self):
172
+ return f"Temporary({self.val.__repr__()})"
173
+
174
+ def __eq__(self, other: Any) -> bool:
175
+ if type(other) == Input:
176
+ return self.val == other.val # pyright: ignore
177
+ return False
@@ -0,0 +1,82 @@
1
+ # Funktionsklempner array types.
2
+ #
3
+ # Author: Malte J. Ziebarth (malte.ziebarth@tum.de)
4
+ #
5
+ # Copyright (C) 2025-2026 Technische Universität München
6
+ #
7
+ # Licensed under the EUPL, Version 1.2 or – as soon they will be approved by
8
+ # the European Commission - subsequent versions of the EUPL (the "Licence");
9
+ # You may not use this work except in compliance with the Licence.
10
+ # You may obtain a copy of the Licence at:
11
+ #
12
+ # https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the Licence is distributed on an "AS IS" basis,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the Licence for the specific language governing permissions and
18
+ # limitations under the Licence.
19
+ #
20
+ # SPDX-FileCopyrightText: 2025-2026 Technical University of Munich
21
+ # SPDX-License-Identifier: EUPL-1.2
22
+ # SPDX-FileContributor: Malte J. Ziebarth <malte.ziebarth@tum.de>
23
+
24
+ from typing import Any
25
+ from .fundamental import FundamentalBaseType, CTypeBaseType
26
+ from .conversion import TYPE_MAP
27
+ from .abstract import Const
28
+
29
+
30
+ class NDArray:
31
+ dtype: FundamentalBaseType | Const[FundamentalBaseType]
32
+ size_control: "NDArray | QuantityArray | None"
33
+
34
+ def __init__(self,
35
+ dtype: FundamentalBaseType | Const[FundamentalBaseType]
36
+ ):
37
+ self.dtype = dtype
38
+ self.size_control = None
39
+
40
+ def __repr__(self):
41
+ return "NDArray(" + self.dtype.__repr__() + ")"
42
+
43
+ def __eq__(self, other: Any) -> bool:
44
+ if isinstance(other, NDArray):
45
+ return self.dtype == other.dtype # pyright: ignore
46
+ return False
47
+
48
+ def ctypes_type(self) -> CTypeBaseType:
49
+ if isinstance(self.dtype, Const):
50
+ return TYPE_MAP[self.dtype.val]
51
+ return TYPE_MAP[self.dtype]
52
+
53
+
54
+
55
+ class QuantityArray:
56
+ dtype: FundamentalBaseType | Const[FundamentalBaseType]
57
+ boost_unit: str
58
+ size_control: "NDArray | QuantityArray | None"
59
+
60
+ def __init__(self,
61
+ dtype: FundamentalBaseType | Const[FundamentalBaseType],
62
+ boost_unit: str
63
+ ):
64
+ self.dtype = dtype
65
+ self.boost_unit = boost_unit
66
+ self.size_control = None
67
+
68
+ def __repr__(self):
69
+ return f"QuantityArray({self.dtype.__repr__()}, {self.boost_unit})"
70
+
71
+ def __eq__(self, other: Any) -> bool:
72
+ if isinstance(other, QuantityArray):
73
+ return (
74
+ self.dtype == other.dtype # pyright: ignore
75
+ and self.boost_unit == other.boost_unit
76
+ )
77
+ return False
78
+
79
+ def ctypes_type(self) -> CTypeBaseType:
80
+ if isinstance(self.dtype, Const):
81
+ return TYPE_MAP[self.dtype.val]
82
+ return TYPE_MAP[self.dtype]