You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Generate code that converts a C++ value to a Python value.
137
+
138
+
Parameters:
139
+
cpp_type (CppType): The C++ type of the value to convert.
140
+
input_cpp_var (str): Name of the C++ variable holding the value to be converted.
141
+
output_py_var (str): Name of the Python variable that should receive the converted value.
142
+
143
+
Returns:
144
+
A code snippet (as `Code` or `str`) that assigns or produces a Python representation of `input_cpp_var` into `output_py_var`, or `None` if no conversion is necessary.
145
+
"""
135
146
raiseNotImplementedError()
136
147
137
148
defsupports_delegation(self) ->bool:
138
149
"""
139
-
Return True if this converter should be invoked when the type
140
-
is an element inside a container (e.g., std::vector).
141
-
142
-
By default, Cython handles conversion of standard types inside
143
-
containers automatically. When this returns True, container
144
-
converters will delegate to this converter instead.
150
+
Indicates whether this converter should be used for elements contained within container types.
151
+
152
+
When `True`, container converters (for example, std::vector) will delegate per-element conversion to this converter instead of relying on the container's default/automatic conversion handling.
153
+
154
+
Returns:
155
+
bool: `True` if elements should be delegated to this converter, `False` otherwise.
Code for new object instantiation from iterator (double deref for iterator-ptr)
152
-
153
-
Note that if cpp_type is a pointer and the iterator therefore refers to
154
-
an STL object of std::vector< _FooObject* >, then we need the base type
155
-
to instantiate a new object and dereference twice.
156
-
157
-
Example output:
158
-
shared_ptr[ _FooObject ] (new _FooObject (*foo_iter) )
159
-
shared_ptr[ _FooObject ] (new _FooObject (**foo_iter_ptr) )
162
+
Create C++ expression code that constructs a shared_ptr to a new instance created from an iterator.
163
+
164
+
Parameters:
165
+
cpp_type (CppType): The target C++ type to instantiate. If `cpp_type` is a reference, its base type is used; if it is a pointer, the iterator is assumed to yield pointers and the generated expression will dereference twice.
166
+
it (str): Expression referring to the iterator value (as a string) to be dereferenced when constructing the new object.
167
+
168
+
Returns:
169
+
str: A C++ code snippet that calls `new` and wraps the result in `shared_ptr[...]`, using `deref(it)` or `deref(deref(it))` as appropriate.
160
170
"""
161
171
162
172
ifcpp_type.is_ref:
@@ -1562,6 +1572,34 @@ def _perform_recursion(
1562
1572
*a,
1563
1573
**kw
1564
1574
):
1575
+
"""
1576
+
Recursively generates and assembles code snippets for converting nested containers (typically nested std::vector) from Python to C++.
1577
+
1578
+
This helper performs a single level of recursion for nested container element conversion: it invokes the appropriate element converter for the inner element type, incorporates that converter's pre-call (topmost) and post-call (bottommost/cleanup) code into the caller's code blocks, and appends the necessary loop and push_back mechanics to build the outer container from inner results. It mutates the provided Code objects to accumulate pre-call code (code/topmost_code) and post-call cleanup code (cleanup_code/bottommost_code) for the overall conversion and does not return a value.
1579
+
1580
+
Parameters:
1581
+
cpp_type: CppType
1582
+
The full CppType of the container being converted (used to decide reference/const semantics for post-call behavior).
1583
+
tt: CppType
1584
+
The element CppType for this recursion level (the type to be handled by the invoked converter).
1585
+
arg_num: str
1586
+
Base argument identifier (used to name temporaries for this recursion level).
1587
+
item: str
1588
+
Name of the Python-side iteration variable for the current recursion level; becomes the argument passed to the inner converter.
1589
+
topmost_code: Code or None
1590
+
Code block that should receive top-level (pre-call) snippets. If None, this function treats itself as the topmost recursion and writes into `code`.
1591
+
bottommost_code: Code or None
1592
+
Code block that should receive bottom-level (post-call) snippets. If None, this function treats itself as the outermost recursion for cleanup placement.
1593
+
code: Code
1594
+
Code block used to accumulate the main pre-call construction (e.g., outer loop and inner loop bodies).
1595
+
cleanup_code: Code
1596
+
Code block used to accumulate post-call cleanup and any result-copying logic.
1597
+
recursion_cnt: int
1598
+
Current recursion depth (0 for outermost). Used to name intermediate temporaries used for multi-level replacement and cleanup.
1599
+
*a, **kw:
1600
+
Formatting/templating context forwarded to Code.add calls (contains mapping keys such as argument_var, temp_var, it, etc.).
"""Check if element type has a converter that supports delegation."""
1721
+
"""
1722
+
Determine whether the registered converter for the given element type opts into delegation.
1723
+
1724
+
Parameters:
1725
+
element_type (CppType): The C++ type to look up in the converter registry.
1726
+
1727
+
Returns:
1728
+
bool: `True` if a converter is registered for `element_type` and its `supports_delegation()` returns `True`, `False` otherwise.
1729
+
"""
1684
1730
ifnothasattr(self, "cr"):
1685
1731
returnFalse
1686
1732
try:
@@ -1698,13 +1744,30 @@ def input_conversion(
1698
1744
bottommost_code: Optional[Code] =None,
1699
1745
recursion_cnt: int=0,
1700
1746
) ->Tuple[Code, str, Code]:
1701
-
"""Do the input conversion for a std::vector<T>
1702
-
1703
-
In this case, the template argument is tt (or "inner").
1704
-
1705
-
It is possible to nest or recurse multiple vectors (like in
1706
-
std::vector< std::vector< T > > which is detected since the template
1707
-
argument of tt itself is not None).
1747
+
"""
1748
+
Convert a Python sequence argument into a C++ libcpp_vector suitable for passing to C++.
1749
+
1750
+
This generates the Cython pre-call code, the expression to use in the C++ call, and the post-call cleanup for converting a Python iterable (argument_var) into a temporary libcpp_vector corresponding to cpp_type (a std::vector<T>). The method handles:
1751
+
- element types that are enums, wrapped C++ classes, shared_ptr<T>, nested std::vector<T> recursion, and element converters that support delegation;
1752
+
- producing top-level declarations when recursion requires them;
1753
+
- producing a cleanup step that writes back to the original Python container when the parameter is a non-const reference.
1754
+
1755
+
Parameters:
1756
+
cpp_type (CppType): The std::vector type to convert (template argument T is inspected).
1757
+
argument_var (str): Name of the Python variable containing the input sequence.
1758
+
arg_num (int): Numerical index used to create unique temporary/local identifiers.
1759
+
topmost_code (Optional[Code]): Optional Code object to which declarations that must appear at function top-level are appended when recursing.
1760
+
bottommost_code (Optional[Code]): Optional Code object used to append cleanup code at the bottom-level when recursing.
1761
+
recursion_cnt (int): Current recursion depth for nested vector conversion; 0 for the top level.
1762
+
1763
+
Returns:
1764
+
Tuple[Code, str, Code]: A 3-tuple of (pre-call code, call-expression, cleanup code):
1765
+
- pre-call Code: Cython code that prepares and fills a temporary libcpp_vector corresponding to cpp_type.
1766
+
- call-expression (str): Expression to pass to the generated C++ call (typically the temp vector or deref(temp)).
1767
+
- cleanup Code: Code to run after the call to perform any necessary write-back or cleanup (e.g., replace original Python contents for non-const ref parameters, or delete temporaries).
1768
+
1769
+
Raises:
1770
+
Exception: If recursion for the given nested template structure is not implemented or required resources are missing (for example, when nested recursion is requested but a ConverterRegistry instance is not available on self).
1708
1771
"""
1709
1772
# If we are inside a recursion, we expect the top-most and bottom most code to be present...
0 commit comments