Construct a vec from an arbitrary iterable.
(
builder: IRBuilder,
vec_type: RVec,
iterable: Expression,
line: int,
*,
capacity: Value | None = None,
)
| 619 | |
| 620 | |
| 621 | def vec_from_iterable( |
| 622 | builder: IRBuilder, |
| 623 | vec_type: RVec, |
| 624 | iterable: Expression, |
| 625 | line: int, |
| 626 | *, |
| 627 | capacity: Value | None = None, |
| 628 | ) -> Value: |
| 629 | """Construct a vec from an arbitrary iterable.""" |
| 630 | item_type = vec_type.item_type |
| 631 | api_name = vec_api_by_item_type.get(item_type) |
| 632 | iterable_rtype = builder.node_type(iterable) |
| 633 | use_c_from_iterable = ( |
| 634 | is_object_rprimitive(iterable_rtype) |
| 635 | or is_list_rprimitive(iterable_rtype) |
| 636 | or is_tuple_rprimitive(iterable_rtype) |
| 637 | ) |
| 638 | if api_name is not None and ( |
| 639 | use_c_from_iterable |
| 640 | or is_bytes_rprimitive(iterable_rtype) |
| 641 | or is_bytearray_rprimitive(iterable_rtype) |
| 642 | ): |
| 643 | # For generic iterables (typed as object) and bytes/bytearray |
| 644 | # (which support the buffer protocol for fast memcpy), call the |
| 645 | # C-level from_iterable. For concrete types like range, list, |
| 646 | # vec, etc., the for-loop desugaring below produces better IR. |
| 647 | name = f"{api_name}.from_iterable" |
| 648 | extra_args: list[Value] = [] |
| 649 | elif api_name is None and vec_type.depth() == 0 and use_c_from_iterable: |
| 650 | name = "VecTApi.from_iterable" |
| 651 | extra_args = [vec_item_type(builder.builder, item_type, line)] |
| 652 | else: |
| 653 | name = None |
| 654 | if name is not None: |
| 655 | iterable_val = builder.accept(iterable) |
| 656 | cap = ( |
| 657 | as_platform_int(builder.builder, capacity, line) |
| 658 | if capacity is not None |
| 659 | else Integer(0, int64_rprimitive) |
| 660 | ) |
| 661 | args = extra_args + [iterable_val, cap] |
| 662 | call = CallC( |
| 663 | name, |
| 664 | args, |
| 665 | vec_type, |
| 666 | steals=[False] * len(args), |
| 667 | is_borrowed=False, |
| 668 | error_kind=ERR_MAGIC, |
| 669 | line=line, |
| 670 | ) |
| 671 | return builder.add(call) |
| 672 | |
| 673 | # Use a for loop with vec_append. The comprehension helper |
| 674 | # special-cases range, list, vec, etc. for efficient iteration. |
| 675 | vec = Register(vec_type) |
| 676 | builder.assign(vec, vec_create(builder.builder, vec_type, 0, line, capacity=capacity), line) |
| 677 | name = f"___tmp_{line}" |
| 678 | var = Var(name) |
no test coverage detected
searching dependent graphs…