-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[stdlib] Parameterize __getitem__ and __setitem__ in stdlib types #2384
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -59,7 +59,12 @@ trait Boolable: | |||||
@value | ||||||
@register_passable("trivial") | ||||||
struct Bool( | ||||||
Stringable, CollectionElement, Boolable, EqualityComparable, Intable | ||||||
Stringable, | ||||||
CollectionElement, | ||||||
Boolable, | ||||||
EqualityComparable, | ||||||
Intable, | ||||||
Indexer, | ||||||
): | ||||||
"""The primitive Bool scalar value used in Mojo.""" | ||||||
|
||||||
|
@@ -324,6 +329,15 @@ struct Bool( | |||||
""" | ||||||
return __mlir_op.`index.casts`[_type = __mlir_type.index](self.value) | ||||||
|
||||||
@always_inline("nodebug") | ||||||
fn __index__(self) -> Int: | ||||||
bgreni marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
"""Convert this Bool to an integer for indexing purposes | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit
Suggested change
|
||||||
|
||||||
Returns: | ||||||
Bool as Int | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide a more details description here, e.g. " |
||||||
""" | ||||||
return self.__int__() | ||||||
|
||||||
|
||||||
# ===----------------------------------------------------------------------=== # | ||||||
# bool | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -146,16 +146,19 @@ struct VariadicList[type: AnyRegType](Sized): | |||||
return __mlir_op.`pop.variadic.size`(self.value) | ||||||
|
||||||
@always_inline | ||||||
fn __getitem__(self, index: Int) -> type: | ||||||
fn __getitem__[indexer: Indexer](self, idx: indexer) -> type: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: here and elsewhere: we try to make type parameters PascalCase, could you please change these?
Suggested change
If you want, I'm also okay with calling these just |
||||||
"""Gets a single element on the variadic list. | ||||||
|
||||||
Parameters: | ||||||
indexer: The type of the indexing value. | ||||||
|
||||||
Args: | ||||||
index: The index of the element to access on the list. | ||||||
idx: The index of the element to access on the list. | ||||||
|
||||||
Returns: | ||||||
The element on the list corresponding to the given index. | ||||||
""" | ||||||
return __mlir_op.`pop.variadic.get`(self.value, index.value) | ||||||
return __mlir_op.`pop.variadic.get`(self.value, index(idx).value) | ||||||
|
||||||
@always_inline | ||||||
fn __iter__(self) -> Self.IterType: | ||||||
|
@@ -358,18 +361,21 @@ struct VariadicListMem[ | |||||
# TODO: Fix for loops + _VariadicListIter to support a __nextref__ protocol | ||||||
# allowing us to get rid of this and make foreach iteration clean. | ||||||
@always_inline | ||||||
fn __getitem__(self, index: Int) -> Self.reference_type: | ||||||
fn __getitem__[indexer: Indexer](self, idx: indexer) -> Self.reference_type: | ||||||
"""Gets a single element on the variadic list. | ||||||
|
||||||
Parameters: | ||||||
indexer: The type of the indexing value. | ||||||
|
||||||
Args: | ||||||
index: The index of the element to access on the list. | ||||||
idx: The index of the element to access on the list. | ||||||
|
||||||
Returns: | ||||||
A low-level pointer to the element on the list corresponding to the | ||||||
given index. | ||||||
""" | ||||||
return Self.reference_type( | ||||||
__mlir_op.`pop.variadic.get`(self.value, index.value) | ||||||
__mlir_op.`pop.variadic.get`(self.value, index(idx).value) | ||||||
) | ||||||
|
||||||
@always_inline | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -139,6 +139,7 @@ struct SIMD[type: DType, size: Int = simdwidthof[type]()]( | |||||
Sized, | ||||||
Stringable, | ||||||
Truncable, | ||||||
Indexer, | ||||||
): | ||||||
"""Represents a small vector that is backed by a hardware vector element. | ||||||
|
||||||
|
@@ -483,6 +484,22 @@ struct SIMD[type: DType, size: Int = simdwidthof[type]()]( | |||||
rebind[Scalar[type]](self).value | ||||||
) | ||||||
|
||||||
@always_inline("nodebug") | ||||||
fn __index__(self) -> Int: | ||||||
"""Returns the value as an int if it is an integral value | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit here and below: missing periods
Suggested change
|
||||||
|
||||||
Contraints: | ||||||
Must be an integral value | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It also needs to be a scalar, could you please add that here? |
||||||
|
||||||
Returns: | ||||||
The value as an integer | ||||||
""" | ||||||
constrained[ | ||||||
type.is_integral() or type.is_bool(), | ||||||
"expected integral or bool type", | ||||||
]() | ||||||
return self.__int__() | ||||||
|
||||||
@always_inline | ||||||
fn __str__(self) -> String: | ||||||
"""Get the SIMD as a string. | ||||||
|
@@ -1731,9 +1748,12 @@ struct SIMD[type: DType, size: Int = simdwidthof[type]()]( | |||||
# ===-------------------------------------------------------------------===# | ||||||
|
||||||
@always_inline("nodebug") | ||||||
fn __getitem__(self, idx: Int) -> Scalar[type]: | ||||||
fn __getitem__[indexer: Indexer](self, idx: indexer) -> Scalar[type]: | ||||||
"""Gets an element from the vector. | ||||||
|
||||||
Parameters: | ||||||
indexer: The type of the indexing value. | ||||||
|
||||||
Args: | ||||||
idx: The element index. | ||||||
|
||||||
|
@@ -1742,32 +1762,44 @@ struct SIMD[type: DType, size: Int = simdwidthof[type]()]( | |||||
""" | ||||||
return __mlir_op.`pop.simd.extractelement`[ | ||||||
_type = __mlir_type[`!pop.scalar<`, type.value, `>`] | ||||||
](self.value, idx.value) | ||||||
](self.value, index(idx).value) | ||||||
|
||||||
@always_inline("nodebug") | ||||||
fn __setitem__(inout self, idx: Int, val: Scalar[type]): | ||||||
fn __setitem__[ | ||||||
indexer: Indexer | ||||||
](inout self, idx: indexer, val: Scalar[type]): | ||||||
"""Sets an element in the vector. | ||||||
|
||||||
Parameters: | ||||||
indexer: The type of the indexing value. | ||||||
|
||||||
Args: | ||||||
idx: The index to set. | ||||||
val: The value to set. | ||||||
""" | ||||||
self.value = __mlir_op.`pop.simd.insertelement`( | ||||||
self.value, val.value, idx.value | ||||||
self.value, val.value, index(idx).value | ||||||
) | ||||||
|
||||||
@always_inline("nodebug") | ||||||
fn __setitem__( | ||||||
inout self, idx: Int, val: __mlir_type[`!pop.scalar<`, type.value, `>`] | ||||||
fn __setitem__[ | ||||||
indexer: Indexer | ||||||
]( | ||||||
inout self, | ||||||
idx: indexer, | ||||||
val: __mlir_type[`!pop.scalar<`, type.value, `>`], | ||||||
): | ||||||
"""Sets an element in the vector. | ||||||
|
||||||
Parameters: | ||||||
indexer: The type of the indexing value. | ||||||
|
||||||
Args: | ||||||
idx: The index to set. | ||||||
val: The value to set. | ||||||
""" | ||||||
self.value = __mlir_op.`pop.simd.insertelement`( | ||||||
self.value, val, idx.value | ||||||
self.value, val, index(idx).value | ||||||
) | ||||||
|
||||||
fn __hash__(self) -> Int: | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -203,3 +203,37 @@ trait BoolableKeyElement(Boolable, KeyElement): | |
""" | ||
|
||
pass | ||
|
||
|
||
trait Indexer: | ||
bgreni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""This trait denotes a type that can be used to index a container that | ||
handles integral index values. | ||
|
||
This solves the issue of being able to index data structures such as `List` with the various | ||
integral types without being too broad and allowing types that should not be used such as float point | ||
values. | ||
Comment on lines
+212
to
+214
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style nit: please wrap lines to 80 char |
||
""" | ||
|
||
fn __index__(self) -> Int: | ||
"""Return the index value | ||
|
||
Returns: | ||
The index value of the object | ||
""" | ||
Comment on lines
+218
to
+222
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JoeLoser Do we have styleguide recommendations on documentating method declarations in traits? And do they even generate docs correctly? |
||
... | ||
|
||
|
||
@always_inline("nodebug") | ||
fn index[indexer: Indexer](idx: indexer) -> Int: | ||
"""Returns the value of `__index__` for the given value. | ||
|
||
Parameters: | ||
indexer: The type of the given value. | ||
|
||
Args: | ||
idx: The value. | ||
|
||
Returns: | ||
An int respresenting the index value. | ||
""" | ||
return idx.__index__() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test for this (we test these implementations directly using explicit calls to
__index__
instead of through the free functions).