@@ -104,10 +104,15 @@ sealed trait Tuple extends Product:
104
104
inline def map [F [_]](f : [t] => t => F [t]): Map [this .type , F ] =
105
105
runtime.Tuples .map(this , f).asInstanceOf [Map [this .type , F ]]
106
106
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 ]
111
116
Tuple .fromArray(arr).asInstanceOf [Filter [This , P ]]
112
117
113
118
/** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
@@ -345,23 +350,14 @@ object Tuple:
345
350
runtime.Tuples .fromProduct(product)
346
351
347
352
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.
352
353
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.
355
356
*/
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 ]]
363
358
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 ]]
365
361
366
362
end extension
367
363
0 commit comments