@@ -30,7 +30,7 @@ import kotlinx.coroutines.flow.internal.unsafeFlow as flow
30
30
*/
31
31
@JvmName(" flowCombine" )
32
32
public fun <T1 , T2 , R > Flow<T1>.combine (flow : Flow <T2 >, transform : suspend (a: T1 , b: T2 ) -> R ): Flow <R > = flow {
33
- combineInternal(arrayOf(this @combine, flow), { arrayOfNulls( 2 ) } , { emit(transform(it[0 ] as T1 , it[1 ] as T2 )) })
33
+ combineInternal(arrayOf(this @combine, flow), nullArrayFactory() , { emit(transform(it[0 ] as T1 , it[1 ] as T2 )) })
34
34
}
35
35
36
36
/* *
@@ -72,7 +72,7 @@ public fun <T1, T2, R> combine(flow: Flow<T1>, flow2: Flow<T2>, transform: suspe
72
72
public fun <T1 , T2 , R > Flow<T1>.combineTransform (
73
73
flow : Flow <T2 >,
74
74
@BuilderInference transform : suspend FlowCollector <R >.(a: T1 , b: T2 ) -> Unit
75
- ): Flow <R > = combineTransform (this , flow) { args: Array <* > ->
75
+ ): Flow <R > = combineTransformUnsafe (this , flow) { args: Array <* > ->
76
76
transform(
77
77
args[0 ] as T1 ,
78
78
args[1 ] as T2
@@ -100,7 +100,7 @@ public fun <T1, T2, R> combineTransform(
100
100
flow : Flow <T1 >,
101
101
flow2 : Flow <T2 >,
102
102
@BuilderInference transform : suspend FlowCollector <R >.(a: T1 , b: T2 ) -> Unit
103
- ): Flow <R > = combineTransform (flow, flow2) { args: Array <* > ->
103
+ ): Flow <R > = combineTransformUnsafe (flow, flow2) { args: Array <* > ->
104
104
transform(
105
105
args[0 ] as T1 ,
106
106
args[1 ] as T2
@@ -111,12 +111,12 @@ public fun <T1, T2, R> combineTransform(
111
111
* Returns a [Flow] whose values are generated with [transform] function by combining
112
112
* the most recently emitted values by each flow.
113
113
*/
114
- public inline fun <T1 , T2 , T3 , R > combine (
114
+ public fun <T1 , T2 , T3 , R > combine (
115
115
flow : Flow <T1 >,
116
116
flow2 : Flow <T2 >,
117
117
flow3 : Flow <T3 >,
118
- @BuilderInference crossinline transform : suspend (T1 , T2 , T3 ) -> R
119
- ): Flow <R > = combine (flow, flow2, flow3) { args: Array <* > ->
118
+ @BuilderInference transform : suspend (T1 , T2 , T3 ) -> R
119
+ ): Flow <R > = combineUnsafe (flow, flow2, flow3) { args: Array <* > ->
120
120
transform(
121
121
args[0 ] as T1 ,
122
122
args[1 ] as T2 ,
@@ -130,12 +130,12 @@ public inline fun <T1, T2, T3, R> combine(
130
130
* The receiver of the [transform] is [FlowCollector] and thus `transform` is a
131
131
* generic function that may transform emitted element, skip it or emit it multiple times.
132
132
*/
133
- public inline fun <T1 , T2 , T3 , R > combineTransform (
133
+ public fun <T1 , T2 , T3 , R > combineTransform (
134
134
flow : Flow <T1 >,
135
135
flow2 : Flow <T2 >,
136
136
flow3 : Flow <T3 >,
137
- @BuilderInference crossinline transform : suspend FlowCollector <R >.(T1 , T2 , T3 ) -> Unit
138
- ): Flow <R > = combineTransform (flow, flow2, flow3) { args: Array <* > ->
137
+ @BuilderInference transform : suspend FlowCollector <R >.(T1 , T2 , T3 ) -> Unit
138
+ ): Flow <R > = combineTransformUnsafe (flow, flow2, flow3) { args: Array <* > ->
139
139
transform(
140
140
args[0 ] as T1 ,
141
141
args[1 ] as T2 ,
@@ -147,12 +147,12 @@ public inline fun <T1, T2, T3, R> combineTransform(
147
147
* Returns a [Flow] whose values are generated with [transform] function by combining
148
148
* the most recently emitted values by each flow.
149
149
*/
150
- public inline fun <T1 , T2 , T3 , T4 , R > combine (
150
+ public fun <T1 , T2 , T3 , T4 , R > combine (
151
151
flow : Flow <T1 >,
152
152
flow2 : Flow <T2 >,
153
153
flow3 : Flow <T3 >,
154
154
flow4 : Flow <T4 >,
155
- crossinline transform : suspend (T1 , T2 , T3 , T4 ) -> R
155
+ transform : suspend (T1 , T2 , T3 , T4 ) -> R
156
156
): Flow <R > = combine(flow, flow2, flow3, flow4) { args: Array <* > ->
157
157
transform(
158
158
args[0 ] as T1 ,
@@ -168,13 +168,13 @@ public inline fun <T1, T2, T3, T4, R> combine(
168
168
* The receiver of the [transform] is [FlowCollector] and thus `transform` is a
169
169
* generic function that may transform emitted element, skip it or emit it multiple times.
170
170
*/
171
- public inline fun <T1 , T2 , T3 , T4 , R > combineTransform (
171
+ public fun <T1 , T2 , T3 , T4 , R > combineTransform (
172
172
flow : Flow <T1 >,
173
173
flow2 : Flow <T2 >,
174
174
flow3 : Flow <T3 >,
175
175
flow4 : Flow <T4 >,
176
- @BuilderInference crossinline transform : suspend FlowCollector <R >.(T1 , T2 , T3 , T4 ) -> Unit
177
- ): Flow <R > = combineTransform (flow, flow2, flow3, flow4) { args: Array <* > ->
176
+ @BuilderInference transform : suspend FlowCollector <R >.(T1 , T2 , T3 , T4 ) -> Unit
177
+ ): Flow <R > = combineTransformUnsafe (flow, flow2, flow3, flow4) { args: Array <* > ->
178
178
transform(
179
179
args[0 ] as T1 ,
180
180
args[1 ] as T2 ,
@@ -187,14 +187,14 @@ public inline fun <T1, T2, T3, T4, R> combineTransform(
187
187
* Returns a [Flow] whose values are generated with [transform] function by combining
188
188
* the most recently emitted values by each flow.
189
189
*/
190
- public inline fun <T1 , T2 , T3 , T4 , T5 , R > combine (
190
+ public fun <T1 , T2 , T3 , T4 , T5 , R > combine (
191
191
flow : Flow <T1 >,
192
192
flow2 : Flow <T2 >,
193
193
flow3 : Flow <T3 >,
194
194
flow4 : Flow <T4 >,
195
195
flow5 : Flow <T5 >,
196
- crossinline transform : suspend (T1 , T2 , T3 , T4 , T5 ) -> R
197
- ): Flow <R > = combine (flow, flow2, flow3, flow4, flow5) { args: Array <* > ->
196
+ transform : suspend (T1 , T2 , T3 , T4 , T5 ) -> R
197
+ ): Flow <R > = combineUnsafe (flow, flow2, flow3, flow4, flow5) { args: Array <* > ->
198
198
transform(
199
199
args[0 ] as T1 ,
200
200
args[1 ] as T2 ,
@@ -210,14 +210,14 @@ public inline fun <T1, T2, T3, T4, T5, R> combine(
210
210
* The receiver of the [transform] is [FlowCollector] and thus `transform` is a
211
211
* generic function that may transform emitted element, skip it or emit it multiple times.
212
212
*/
213
- public inline fun <T1 , T2 , T3 , T4 , T5 , R > combineTransform (
213
+ public fun <T1 , T2 , T3 , T4 , T5 , R > combineTransform (
214
214
flow : Flow <T1 >,
215
215
flow2 : Flow <T2 >,
216
216
flow3 : Flow <T3 >,
217
217
flow4 : Flow <T4 >,
218
218
flow5 : Flow <T5 >,
219
- @BuilderInference crossinline transform : suspend FlowCollector <R >.(T1 , T2 , T3 , T4 , T5 ) -> Unit
220
- ): Flow <R > = combineTransform (flow, flow2, flow3, flow4, flow5) { args: Array <* > ->
219
+ @BuilderInference transform : suspend FlowCollector <R >.(T1 , T2 , T3 , T4 , T5 ) -> Unit
220
+ ): Flow <R > = combineTransformUnsafe (flow, flow2, flow3, flow4, flow5) { args: Array <* > ->
221
221
transform(
222
222
args[0 ] as T1 ,
223
223
args[1 ] as T2 ,
@@ -251,6 +251,31 @@ public inline fun <reified T, R> combineTransform(
251
251
combineInternal(flows, { arrayOfNulls(flows.size) }, { transform(it) })
252
252
}
253
253
254
+ /*
255
+ * Same as combine, but does not copy array each time, deconstructing existing
256
+ * array each time. Used in overloads that accept FunctionN instead of Function<Array<R>>
257
+ */
258
+ private inline fun <reified T , R > combineUnsafe (
259
+ vararg flows : Flow <T >,
260
+ crossinline transform : suspend (Array <T >) -> R
261
+ ): Flow <R > = flow {
262
+ combineInternal(flows, nullArrayFactory(), { emit(transform(it)) })
263
+ }
264
+
265
+ /*
266
+ * Same as combineTransform, but does not copy array each time, deconstructing existing
267
+ * array each time. Used in overloads that accept FunctionN instead of Function<Array<R>>
268
+ */
269
+ private inline fun <reified T , R > combineTransformUnsafe (
270
+ vararg flows : Flow <T >,
271
+ @BuilderInference crossinline transform : suspend FlowCollector <R >.(Array <T >) -> Unit
272
+ ): Flow <R > = safeFlow {
273
+ combineInternal(flows, nullArrayFactory(), { transform(it) })
274
+ }
275
+
276
+ // Saves bunch of anonymous classes
277
+ private fun <T > nullArrayFactory (): () -> Array <T >? = { null }
278
+
254
279
/* *
255
280
* Returns a [Flow] whose values are generated with [transform] function by combining
256
281
* the most recently emitted values by each flow.
0 commit comments