@@ -104,10 +104,15 @@ sealed trait Tuple extends Product:
104104 inline def map [F [_]](f : [t] => t => F [t]): Map [this .type , F ] =
105105 runtime.Tuples .map(this , f).asInstanceOf [Map [this .type , F ]]
106106
107- /** A tuple consisting of all elements of this tuple that satisfy the predicate `p`. */
108- inline def filter [This >: this .type <: Tuple , P [_ <: Union [This ]] <: Boolean ]
109- (p : (x : Union [This ]) => P [x.type ]): Filter [This , P ] =
110- val arr = this .toArray.filter(x => p(x.asInstanceOf [Union [This ]]))
107+ /** A tuple consisting of all elements of this tuple that have types
108+ * for which the given type level predicate `P` reduces to the literal
109+ * constant `true`.
110+ */
111+ inline def filter [This >: this .type <: Tuple , P [_ <: Union [This ]] <: Boolean ]: Filter [This , P ] =
112+ val toInclude = constValueTuple[IndicesWhere [This , P ]].toArray
113+ val arr = new Array [Object ](toInclude.length)
114+ for i <- toInclude.indices do
115+ arr(i) = this .productElement(toInclude(i).asInstanceOf [Int ]).asInstanceOf [Object ]
111116 Tuple .fromArray(arr).asInstanceOf [Filter [This , P ]]
112117
113118 /** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
@@ -345,23 +350,14 @@ object Tuple:
345350 runtime.Tuples .fromProduct(product)
346351
347352 extension [X <: Tuple ](inline x : X )
348- // Note the two methods are not equivalent to using `constValue`,
349- // since they also allow cases unknown at compiletime.
350- // Also note it would be unsound to use a type parameter for `y` in the type level
351- // operations, since they are rightfully not covariant in their second parameter.
352353
353- /** The index (starting at 0) of the first occurrence of `y` in `x`
354- * or its size if no such element exists.
354+ /** The index (starting at 0) of the first occurrence of `y.type ` in the type `X` of `x`
355+ * or `Size[X]` if no such element exists.
355356 */
356- inline def indexOf (y : Any ): IndexOf [X , y.type ] =
357- val i = x.productIterator.indexOf(y)
358- (if i >= 0 then i else x.size).asInstanceOf [IndexOf [X , y.type ]]
359-
360- /** A boolean indicating whether `x` contains the element `y` */
361- inline def contains (y : Any ): Contains [X , y.type ] =
362- x.productIterator.contains(y).asInstanceOf [Contains [X , y.type ]]
357+ inline def indexOf (y : Any ): IndexOf [X , y.type ] = constValue[IndexOf [X , y.type ]]
363358
364- // TODO indexOfType & containsType ?
359+ /** A boolean indicating whether there is an element `y.type` in the type `X` of `x` */
360+ inline def contains (y : Any ): Contains [X , y.type ] = constValue[Contains [X , y.type ]]
365361
366362 end extension
367363
0 commit comments