Skip to main content

Mojo struct

VariadicPack

@register_passable struct VariadicPack[elt_is_mutable: Bool, //, is_owned: Bool, origin: Origin[elt_is_mutable], element_trait: AnyTrait[AnyType], *element_types: element_trait]

A utility class to access heterogeneous variadic function arguments.

VariadicPack is used when you need to accept variadic arguments where each argument can have a different type, but all types conform to a common trait. Unlike VariadicList (which is homogeneous), VariadicPack allows each element to have a different concrete type.

VariadicPack is essentially a heterogeneous tuple that gets lowered to a struct at runtime. Because VariadicPack is a heterogeneous tuple (not an array), each element can have a different size and memory layout, which means the compiler needs to know the exact type of each element at compile time to generate the correct memory layout and access code.

Therefore, indexing into VariadicPack requires compile-time indices using @parameter for loops, whereas indexing into VariadicList uses runtime indices.

For example, in the following function signature, *args: *ArgTypes creates a VariadicPack because it uses a variadic type parameter *ArgTypes instead of a single type. The * before ArgTypes indicates that ArgTypes is a variadic type parameter, which means that the function can accept any number of arguments, and each argument can have a different type. This allows each argument to have a different type while all types must conform to the Intable trait.

fn count_many_things[*ArgTypes: Intable](*args: *ArgTypes) -> Int:
var total = 0

# Must use @parameter for loop because args is a VariadicPack
@parameter
for i in range(args.__len__()):
# Each args[i] has a different concrete type from *ArgTypes
# The compiler generates specific code for each iteration
total += Int(args[i])

return total

def main():
print(count_many_things(5, 11.7, 12)) # Prints: 28
fn count_many_things[*ArgTypes: Intable](*args: *ArgTypes) -> Int:
var total = 0

# Must use @parameter for loop because args is a VariadicPack
@parameter
for i in range(args.__len__()):
# Each args[i] has a different concrete type from *ArgTypes
# The compiler generates specific code for each iteration
total += Int(args[i])

return total

def main():
print(count_many_things(5, 11.7, 12)) # Prints: 28

Parameters

  • elt_is_mutable (Bool): True if the elements of the list are mutable for an mut or owned argument pack.
  • is_owned (Bool): Whether the elements are owned by the pack. If so, the pack will release the elements when it is destroyed.
  • origin (Origin[elt_is_mutable]): The origin of the underlying elements.
  • element_trait (AnyTrait[AnyType]): The trait that each element of the pack conforms to.
  • *element_types (element_trait): The list of types held by the argument pack.

Implemented traits

AnyType, Sized, UnknownDestructibility

Methods

__del__

__del__(var self)

Destructor that releases elements if owned.

__getitem__

__getitem__[index: Int](self) -> ref [origin] element_types[index.value]

Return a reference to an element of the pack.

Parameters:

  • index (Int): The element of the pack to return.

Returns:

A reference to the element. The Pointer's mutability follows the mutability of the pack argument convention.

__len__

static __len__() -> Int

Return the VariadicPack length.

Returns:

The number of elements in the variadic pack.

__len__(self) -> Int

Return the VariadicPack length.

Returns:

The number of elements in the variadic pack.

Was this page helpful?