1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.util.function.pooled;
18 
19 import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire;
20 import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquireConstSupplier;
21 
22 import android.os.Message;
23 
24 import com.android.internal.util.function.HexConsumer;
25 import com.android.internal.util.function.HexFunction;
26 import com.android.internal.util.function.QuadConsumer;
27 import com.android.internal.util.function.QuadFunction;
28 import com.android.internal.util.function.QuintConsumer;
29 import com.android.internal.util.function.QuintFunction;
30 import com.android.internal.util.function.TriConsumer;
31 import com.android.internal.util.function.TriFunction;
32 import com.android.internal.util.function.pooled.PooledLambdaImpl.LambdaType.ReturnType;
33 
34 import java.util.function.BiConsumer;
35 import java.util.function.BiFunction;
36 import java.util.function.BiPredicate;
37 import java.util.function.Consumer;
38 import java.util.function.Function;
39 import java.util.function.Predicate;
40 import java.util.function.Supplier;
41 
42 /**
43  * A recyclable anonymous function.
44  * Allows obtaining {@link Function}s/{@link Runnable}s/{@link Supplier}s/etc. without allocating a
45  * new instance each time
46  *
47  * This exploits the mechanic that stateless lambdas (such as plain/non-bound method references)
48  * get translated into a singleton instance, making it possible to create a recyclable container
49  * ({@link PooledLambdaImpl}) holding a reference to such a singleton function, as well as
50  * (possibly partial) arguments required for its invocation.
51  *
52  * To obtain an instance, use one of the factory methods in this class.
53  *
54  * You can call {@link #recycleOnUse} to make the instance automatically recycled upon invocation,
55  * making if effectively <b>one-time use</b>.
56  * This is often the behavior you want, as it allows to not worry about manual recycling.
57  * Some notable examples: {@link android.os.Handler#post(Runnable)},
58  * {@link android.app.Activity#runOnUiThread(Runnable)}, {@link android.view.View#post(Runnable)}
59  *
60  * For factories of functions that take further arguments, the corresponding 'missing' argument's
61  * position is marked by an argument of type {@link ArgumentPlaceholder} with the type parameter
62  * corresponding to missing argument's type.
63  * You can fill the 'missing argument' spot with {@link #__()}
64  * (which is the factory function for {@link ArgumentPlaceholder})
65  *
66  * NOTE: It is highly recommended to <b>only</b> use {@code ClassName::methodName}
67  * (aka unbounded method references) as the 1st argument for any of the
68  * factories ({@code obtain*(...)}) to avoid unwanted allocations.
69  * This means <b>not</b> using:
70  * <ul>
71  *     <li>{@code someVar::methodName} or {@code this::methodName} as it captures the reference
72  *     on the left of {@code ::}, resulting in an allocation on each evaluation of such
73  *     bounded method references</li>
74  *
75  *     <li>A lambda expression, e.g. {@code () -> toString()} due to how easy it is to accidentally
76  *     capture state from outside. In the above lambda expression for example, no variable from
77  *     outer scope is explicitly mentioned, yet one is still captured due to {@code toString()}
78  *     being an equivalent of {@code this.toString()}</li>
79  * </ul>
80  *
81  * @hide
82  */
83 @SuppressWarnings({"unchecked", "unused", "WeakerAccess"})
84 public interface PooledLambda {
85 
86     /**
87      * Recycles this instance. No-op if already recycled.
88      */
recycle()89     void recycle();
90 
91     /**
92      * Makes this instance automatically {@link #recycle} itself after the first call.
93      *
94      * @return this instance for convenience
95      */
recycleOnUse()96     PooledLambda recycleOnUse();
97 
98 
99     // Factories
100 
101     /**
102      * @return {@link ArgumentPlaceholder} with the inferred type parameter value
103      */
__()104     static <R> ArgumentPlaceholder<R> __() {
105         return (ArgumentPlaceholder<R>) ArgumentPlaceholder.INSTANCE;
106     }
107 
108     /**
109      * @param typeHint the explicitly specified type of the missing argument
110      * @return {@link ArgumentPlaceholder} with the specified type parameter value
111      */
__(Class<R> typeHint)112     static <R> ArgumentPlaceholder<R> __(Class<R> typeHint) {
113         return __();
114     }
115 
116     /**
117      * Wraps the given value into a {@link PooledSupplier}
118      *
119      * @param value a value to wrap
120      * @return a pooled supplier of {@code value}
121      */
obtainSupplier(R value)122     static <R> PooledSupplier<R> obtainSupplier(R value) {
123         PooledLambdaImpl r = acquireConstSupplier(ReturnType.OBJECT);
124         r.mFunc = value;
125         return r;
126     }
127 
128     /**
129      * Wraps the given value into a {@link PooledSupplier}
130      *
131      * @param value a value to wrap
132      * @return a pooled supplier of {@code value}
133      */
obtainSupplier(int value)134     static PooledSupplier.OfInt obtainSupplier(int value) {
135         PooledLambdaImpl r = acquireConstSupplier(ReturnType.INT);
136         r.mConstValue = value;
137         return r;
138     }
139 
140     /**
141      * Wraps the given value into a {@link PooledSupplier}
142      *
143      * @param value a value to wrap
144      * @return a pooled supplier of {@code value}
145      */
obtainSupplier(long value)146     static PooledSupplier.OfLong obtainSupplier(long value) {
147         PooledLambdaImpl r = acquireConstSupplier(ReturnType.LONG);
148         r.mConstValue = value;
149         return r;
150     }
151 
152     /**
153      * Wraps the given value into a {@link PooledSupplier}
154      *
155      * @param value a value to wrap
156      * @return a pooled supplier of {@code value}
157      */
obtainSupplier(double value)158     static PooledSupplier.OfDouble obtainSupplier(double value) {
159         PooledLambdaImpl r = acquireConstSupplier(ReturnType.DOUBLE);
160         r.mConstValue = Double.doubleToRawLongBits(value);
161         return r;
162     }
163 
164     /**
165      * {@link PooledRunnable} factory
166      *
167      * @param function non-capturing lambda(typically an unbounded method reference)
168      *                 to be invoked on call
169      * @param arg1 parameter supplied to {@code function} on call
170      * @return a {@link PooledRunnable}, equivalent to lambda:
171      *         {@code () -> function(arg1) }
172      */
obtainRunnable( Consumer<? super A> function, A arg1)173     static <A> PooledRunnable obtainRunnable(
174             Consumer<? super A> function,
175             A arg1) {
176         return acquire(PooledLambdaImpl.sPool,
177                 function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null);
178     }
179 
180     /**
181      * {@link PooledSupplier} factory
182      *
183      * @param function non-capturing lambda(typically an unbounded method reference)
184      *                 to be invoked on call
185      * @param arg1 parameter supplied to {@code function} on call
186      * @return a {@link PooledSupplier}, equivalent to lambda:
187      *         {@code () -> function(arg1) }
188      */
obtainSupplier( Predicate<? super A> function, A arg1)189     static <A> PooledSupplier<Boolean> obtainSupplier(
190             Predicate<? super A> function,
191             A arg1) {
192         return acquire(PooledLambdaImpl.sPool,
193                 function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null);
194     }
195 
196     /**
197      * {@link PooledSupplier} factory
198      *
199      * @param function non-capturing lambda(typically an unbounded method reference)
200      *                 to be invoked on call
201      * @param arg1 parameter supplied to {@code function} on call
202      * @return a {@link PooledSupplier}, equivalent to lambda:
203      *         {@code () -> function(arg1) }
204      */
obtainSupplier( Function<? super A, ? extends R> function, A arg1)205     static <A, R> PooledSupplier<R> obtainSupplier(
206             Function<? super A, ? extends R> function,
207             A arg1) {
208         return acquire(PooledLambdaImpl.sPool,
209                 function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null);
210     }
211 
212     /**
213      * Factory of {@link Message}s that contain an
214      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
215      * {@link Message#getCallback internal callback}.
216      *
217      * The callback is equivalent to one obtainable via
218      * {@link #obtainRunnable(Consumer, Object)}
219      *
220      * Note that using this method with {@link android.os.Handler#handleMessage}
221      * is more efficient than the alternative of {@link android.os.Handler#post}
222      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
223      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
224      *
225      * You may optionally set a {@link Message#what} for the message if you want to be
226      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
227      * there's no need to do so
228      *
229      * @param function non-capturing lambda(typically an unbounded method reference)
230      *                 to be invoked on call
231      * @param arg1 parameter supplied to {@code function} on call
232      * @return a {@link Message} invoking {@code function(arg1) } when handled
233      */
obtainMessage( Consumer<? super A> function, A arg1)234     static <A> Message obtainMessage(
235             Consumer<? super A> function,
236             A arg1) {
237         synchronized (Message.sPoolSync) {
238             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
239                     function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null);
240             return Message.obtain().setCallback(callback.recycleOnUse());
241         }
242     }
243 
244     /**
245      * {@link PooledRunnable} factory
246      *
247      * @param function non-capturing lambda(typically an unbounded method reference)
248      *                 to be invoked on call
249      * @param arg1 parameter supplied to {@code function} on call
250      * @param arg2 parameter supplied to {@code function} on call
251      * @return a {@link PooledRunnable}, equivalent to lambda:
252      *         {@code () -> function(arg1, arg2) }
253      */
obtainRunnable( BiConsumer<? super A, ? super B> function, A arg1, B arg2)254     static <A, B> PooledRunnable obtainRunnable(
255             BiConsumer<? super A, ? super B> function,
256             A arg1, B arg2) {
257         return acquire(PooledLambdaImpl.sPool,
258                 function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null);
259     }
260 
261     /**
262      * {@link PooledSupplier} factory
263      *
264      * @param function non-capturing lambda(typically an unbounded method reference)
265      *                 to be invoked on call
266      * @param arg1 parameter supplied to {@code function} on call
267      * @param arg2 parameter supplied to {@code function} on call
268      * @return a {@link PooledSupplier}, equivalent to lambda:
269      *         {@code () -> function(arg1, arg2) }
270      */
obtainSupplier( BiPredicate<? super A, ? super B> function, A arg1, B arg2)271     static <A, B> PooledSupplier<Boolean> obtainSupplier(
272             BiPredicate<? super A, ? super B> function,
273             A arg1, B arg2) {
274         return acquire(PooledLambdaImpl.sPool,
275                 function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
276     }
277 
278     /**
279      * {@link PooledSupplier} factory
280      *
281      * @param function non-capturing lambda(typically an unbounded method reference)
282      *                 to be invoked on call
283      * @param arg1 parameter supplied to {@code function} on call
284      * @param arg2 parameter supplied to {@code function} on call
285      * @return a {@link PooledSupplier}, equivalent to lambda:
286      *         {@code () -> function(arg1, arg2) }
287      */
obtainSupplier( BiFunction<? super A, ? super B, ? extends R> function, A arg1, B arg2)288     static <A, B, R> PooledSupplier<R> obtainSupplier(
289             BiFunction<? super A, ? super B, ? extends R> function,
290             A arg1, B arg2) {
291         return acquire(PooledLambdaImpl.sPool,
292                 function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
293     }
294 
295     /**
296      * {@link PooledConsumer} factory
297      *
298      * @param function non-capturing lambda(typically an unbounded method reference)
299      *                 to be invoked on call
300      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
301      * @param arg2 parameter supplied to {@code function} on call
302      * @return a {@link PooledConsumer}, equivalent to lambda:
303      *         {@code (arg1) -> function(arg1, arg2) }
304      */
obtainConsumer( BiConsumer<? super A, ? super B> function, ArgumentPlaceholder<A> arg1, B arg2)305     static <A, B> PooledConsumer<A> obtainConsumer(
306             BiConsumer<? super A, ? super B> function,
307             ArgumentPlaceholder<A> arg1, B arg2) {
308         return acquire(PooledLambdaImpl.sPool,
309                 function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null);
310     }
311 
312     /**
313      * {@link PooledPredicate} factory
314      *
315      * @param function non-capturing lambda(typically an unbounded method reference)
316      *                 to be invoked on call
317      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
318      * @param arg2 parameter supplied to {@code function} on call
319      * @return a {@link PooledPredicate}, equivalent to lambda:
320      *         {@code (arg1) -> function(arg1, arg2) }
321      */
obtainPredicate( BiPredicate<? super A, ? super B> function, ArgumentPlaceholder<A> arg1, B arg2)322     static <A, B> PooledPredicate<A> obtainPredicate(
323             BiPredicate<? super A, ? super B> function,
324             ArgumentPlaceholder<A> arg1, B arg2) {
325         return acquire(PooledLambdaImpl.sPool,
326                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
327     }
328 
329     /**
330      * {@link PooledFunction} factory
331      *
332      * @param function non-capturing lambda(typically an unbounded method reference)
333      *                 to be invoked on call
334      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
335      * @param arg2 parameter supplied to {@code function} on call
336      * @return a {@link PooledFunction}, equivalent to lambda:
337      *         {@code (arg1) -> function(arg1, arg2) }
338      */
obtainFunction( BiFunction<? super A, ? super B, ? extends R> function, ArgumentPlaceholder<A> arg1, B arg2)339     static <A, B, R> PooledFunction<A, R> obtainFunction(
340             BiFunction<? super A, ? super B, ? extends R> function,
341             ArgumentPlaceholder<A> arg1, B arg2) {
342         return acquire(PooledLambdaImpl.sPool,
343                 function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
344     }
345 
346     /**
347      * {@link PooledConsumer} factory
348      *
349      * @param function non-capturing lambda(typically an unbounded method reference)
350      *                 to be invoked on call
351      * @param arg1 parameter supplied to {@code function} on call
352      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
353      * @return a {@link PooledConsumer}, equivalent to lambda:
354      *         {@code (arg2) -> function(arg1, arg2) }
355      */
obtainConsumer( BiConsumer<? super A, ? super B> function, A arg1, ArgumentPlaceholder<B> arg2)356     static <A, B> PooledConsumer<B> obtainConsumer(
357             BiConsumer<? super A, ? super B> function,
358             A arg1, ArgumentPlaceholder<B> arg2) {
359         return acquire(PooledLambdaImpl.sPool,
360                 function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null);
361     }
362 
363     /**
364      * {@link PooledPredicate} factory
365      *
366      * @param function non-capturing lambda(typically an unbounded method reference)
367      *                 to be invoked on call
368      * @param arg1 parameter supplied to {@code function} on call
369      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
370      * @return a {@link PooledPredicate}, equivalent to lambda:
371      *         {@code (arg2) -> function(arg1, arg2) }
372      */
obtainPredicate( BiPredicate<? super A, ? super B> function, A arg1, ArgumentPlaceholder<B> arg2)373     static <A, B> PooledPredicate<B> obtainPredicate(
374             BiPredicate<? super A, ? super B> function,
375             A arg1, ArgumentPlaceholder<B> arg2) {
376         return acquire(PooledLambdaImpl.sPool,
377                 function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
378     }
379 
380     /**
381      * {@link PooledFunction} factory
382      *
383      * @param function non-capturing lambda(typically an unbounded method reference)
384      *                 to be invoked on call
385      * @param arg1 parameter supplied to {@code function} on call
386      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
387      * @return a {@link PooledFunction}, equivalent to lambda:
388      *         {@code (arg2) -> function(arg1, arg2) }
389      */
obtainFunction( BiFunction<? super A, ? super B, ? extends R> function, A arg1, ArgumentPlaceholder<B> arg2)390     static <A, B, R> PooledFunction<B, R> obtainFunction(
391             BiFunction<? super A, ? super B, ? extends R> function,
392             A arg1, ArgumentPlaceholder<B> arg2) {
393         return acquire(PooledLambdaImpl.sPool,
394                 function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
395     }
396 
397     /**
398      * Factory of {@link Message}s that contain an
399      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
400      * {@link Message#getCallback internal callback}.
401      *
402      * The callback is equivalent to one obtainable via
403      * {@link #obtainRunnable(BiConsumer, Object, Object)}
404      *
405      * Note that using this method with {@link android.os.Handler#handleMessage}
406      * is more efficient than the alternative of {@link android.os.Handler#post}
407      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
408      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
409      *
410      * You may optionally set a {@link Message#what} for the message if you want to be
411      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
412      * there's no need to do so
413      *
414      * @param function non-capturing lambda(typically an unbounded method reference)
415      *                 to be invoked on call
416      * @param arg1 parameter supplied to {@code function} on call
417      * @param arg2 parameter supplied to {@code function} on call
418      * @return a {@link Message} invoking {@code function(arg1, arg2) } when handled
419      */
obtainMessage( BiConsumer<? super A, ? super B> function, A arg1, B arg2)420     static <A, B> Message obtainMessage(
421             BiConsumer<? super A, ? super B> function,
422             A arg1, B arg2) {
423         synchronized (Message.sPoolSync) {
424             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
425                     function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null);
426             return Message.obtain().setCallback(callback.recycleOnUse());
427         }
428     }
429 
430     /**
431      * {@link PooledRunnable} factory
432      *
433      * @param function non-capturing lambda(typically an unbounded method reference)
434      *                 to be invoked on call
435      * @param arg1 parameter supplied to {@code function} on call
436      * @param arg2 parameter supplied to {@code function} on call
437      * @param arg3 parameter supplied to {@code function} on call
438      * @return a {@link PooledRunnable}, equivalent to lambda:
439      *         {@code () -> function(arg1, arg2, arg3) }
440      */
obtainRunnable( TriConsumer<? super A, ? super B, ? super C> function, A arg1, B arg2, C arg3)441     static <A, B, C> PooledRunnable obtainRunnable(
442             TriConsumer<? super A, ? super B, ? super C> function,
443             A arg1, B arg2, C arg3) {
444         return acquire(PooledLambdaImpl.sPool,
445                 function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
446     }
447 
448     /**
449      * {@link PooledSupplier} factory
450      *
451      * @param function non-capturing lambda(typically an unbounded method reference)
452      *                 to be invoked on call
453      * @param arg1 parameter supplied to {@code function} on call
454      * @param arg2 parameter supplied to {@code function} on call
455      * @param arg3 parameter supplied to {@code function} on call
456      * @return a {@link PooledSupplier}, equivalent to lambda:
457      *         {@code () -> function(arg1, arg2, arg3) }
458      */
obtainSupplier( TriFunction<? super A, ? super B, ? super C, ? extends R> function, A arg1, B arg2, C arg3)459     static <A, B, C, R> PooledSupplier<R> obtainSupplier(
460             TriFunction<? super A, ? super B, ? super C, ? extends R> function,
461             A arg1, B arg2, C arg3) {
462         return acquire(PooledLambdaImpl.sPool,
463                 function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
464     }
465 
466     /**
467      * {@link PooledConsumer} factory
468      *
469      * @param function non-capturing lambda(typically an unbounded method reference)
470      *                 to be invoked on call
471      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
472      * @param arg2 parameter supplied to {@code function} on call
473      * @param arg3 parameter supplied to {@code function} on call
474      * @return a {@link PooledConsumer}, equivalent to lambda:
475      *         {@code (arg1) -> function(arg1, arg2, arg3) }
476      */
obtainConsumer( TriConsumer<? super A, ? super B, ? super C> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3)477     static <A, B, C> PooledConsumer<A> obtainConsumer(
478             TriConsumer<? super A, ? super B, ? super C> function,
479             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
480         return acquire(PooledLambdaImpl.sPool,
481                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
482     }
483 
484     /**
485      * {@link PooledFunction} factory
486      *
487      * @param function non-capturing lambda(typically an unbounded method reference)
488      *                 to be invoked on call
489      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
490      * @param arg2 parameter supplied to {@code function} on call
491      * @param arg3 parameter supplied to {@code function} on call
492      * @return a {@link PooledFunction}, equivalent to lambda:
493      *         {@code (arg1) -> function(arg1, arg2, arg3) }
494      */
obtainFunction( TriFunction<? super A, ? super B, ? super C, ? extends R> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3)495     static <A, B, C, R> PooledFunction<A, R> obtainFunction(
496             TriFunction<? super A, ? super B, ? super C, ? extends R> function,
497             ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
498         return acquire(PooledLambdaImpl.sPool,
499                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
500     }
501 
502     /**
503      * {@link PooledConsumer} factory
504      *
505      * @param function non-capturing lambda(typically an unbounded method reference)
506      *                 to be invoked on call
507      * @param arg1 parameter supplied to {@code function} on call
508      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
509      * @param arg3 parameter supplied to {@code function} on call
510      * @return a {@link PooledConsumer}, equivalent to lambda:
511      *         {@code (arg2) -> function(arg1, arg2, arg3) }
512      */
obtainConsumer( TriConsumer<? super A, ? super B, ? super C> function, A arg1, ArgumentPlaceholder<B> arg2, C arg3)513     static <A, B, C> PooledConsumer<B> obtainConsumer(
514             TriConsumer<? super A, ? super B, ? super C> function,
515             A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
516         return acquire(PooledLambdaImpl.sPool,
517                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
518     }
519 
520     /**
521      * {@link PooledFunction} factory
522      *
523      * @param function non-capturing lambda(typically an unbounded method reference)
524      *                 to be invoked on call
525      * @param arg1 parameter supplied to {@code function} on call
526      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
527      * @param arg3 parameter supplied to {@code function} on call
528      * @return a {@link PooledFunction}, equivalent to lambda:
529      *         {@code (arg2) -> function(arg1, arg2, arg3) }
530      */
obtainFunction( TriFunction<? super A, ? super B, ? super C, ? extends R> function, A arg1, ArgumentPlaceholder<B> arg2, C arg3)531     static <A, B, C, R> PooledFunction<B, R> obtainFunction(
532             TriFunction<? super A, ? super B, ? super C, ? extends R> function,
533             A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
534         return acquire(PooledLambdaImpl.sPool,
535                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
536     }
537 
538     /**
539      * {@link PooledConsumer} factory
540      *
541      * @param function non-capturing lambda(typically an unbounded method reference)
542      *                 to be invoked on call
543      * @param arg1 parameter supplied to {@code function} on call
544      * @param arg2 parameter supplied to {@code function} on call
545      * @param arg3 placeholder for a missing argument. Use {@link #__} to get one
546      * @return a {@link PooledConsumer}, equivalent to lambda:
547      *         {@code (arg3) -> function(arg1, arg2, arg3) }
548      */
obtainConsumer( TriConsumer<? super A, ? super B, ? super C> function, A arg1, B arg2, ArgumentPlaceholder<C> arg3)549     static <A, B, C> PooledConsumer<C> obtainConsumer(
550             TriConsumer<? super A, ? super B, ? super C> function,
551             A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
552         return acquire(PooledLambdaImpl.sPool,
553                 function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
554     }
555 
556     /**
557      * {@link PooledFunction} factory
558      *
559      * @param function non-capturing lambda(typically an unbounded method reference)
560      *                 to be invoked on call
561      * @param arg1 parameter supplied to {@code function} on call
562      * @param arg2 parameter supplied to {@code function} on call
563      * @param arg3 placeholder for a missing argument. Use {@link #__} to get one
564      * @return a {@link PooledFunction}, equivalent to lambda:
565      *         {@code (arg3) -> function(arg1, arg2, arg3) }
566      */
obtainFunction( TriFunction<? super A, ? super B, ? super C, ? extends R> function, A arg1, B arg2, ArgumentPlaceholder<C> arg3)567     static <A, B, C, R> PooledFunction<C, R> obtainFunction(
568             TriFunction<? super A, ? super B, ? super C, ? extends R> function,
569             A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
570         return acquire(PooledLambdaImpl.sPool,
571                 function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
572     }
573 
574     /**
575      * Factory of {@link Message}s that contain an
576      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
577      * {@link Message#getCallback internal callback}.
578      *
579      * The callback is equivalent to one obtainable via
580      * {@link #obtainRunnable(TriConsumer, Object, Object, Object)}
581      *
582      * Note that using this method with {@link android.os.Handler#handleMessage}
583      * is more efficient than the alternative of {@link android.os.Handler#post}
584      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
585      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
586      *
587      * You may optionally set a {@link Message#what} for the message if you want to be
588      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
589      * there's no need to do so
590      *
591      * @param function non-capturing lambda(typically an unbounded method reference)
592      *                 to be invoked on call
593      * @param arg1 parameter supplied to {@code function} on call
594      * @param arg2 parameter supplied to {@code function} on call
595      * @param arg3 parameter supplied to {@code function} on call
596      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3) } when handled
597      */
obtainMessage( TriConsumer<? super A, ? super B, ? super C> function, A arg1, B arg2, C arg3)598     static <A, B, C> Message obtainMessage(
599             TriConsumer<? super A, ? super B, ? super C> function,
600             A arg1, B arg2, C arg3) {
601         synchronized (Message.sPoolSync) {
602             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
603                     function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
604             return Message.obtain().setCallback(callback.recycleOnUse());
605         }
606     }
607 
608     /**
609      * {@link PooledRunnable} factory
610      *
611      * @param function non-capturing lambda(typically an unbounded method reference)
612      *                 to be invoked on call
613      * @param arg1 parameter supplied to {@code function} on call
614      * @param arg2 parameter supplied to {@code function} on call
615      * @param arg3 parameter supplied to {@code function} on call
616      * @param arg4 parameter supplied to {@code function} on call
617      * @return a {@link PooledRunnable}, equivalent to lambda:
618      *         {@code () -> function(arg1, arg2, arg3, arg4) }
619      */
obtainRunnable( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, C arg3, D arg4)620     static <A, B, C, D> PooledRunnable obtainRunnable(
621             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
622             A arg1, B arg2, C arg3, D arg4) {
623         return acquire(PooledLambdaImpl.sPool,
624                 function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
625     }
626 
627     /**
628      * {@link PooledSupplier} factory
629      *
630      * @param function non-capturing lambda(typically an unbounded method reference)
631      *                 to be invoked on call
632      * @param arg1 parameter supplied to {@code function} on call
633      * @param arg2 parameter supplied to {@code function} on call
634      * @param arg3 parameter supplied to {@code function} on call
635      * @param arg4 parameter supplied to {@code function} on call
636      * @return a {@link PooledSupplier}, equivalent to lambda:
637      *         {@code () -> function(arg1, arg2, arg3, arg4) }
638      */
obtainSupplier( QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function, A arg1, B arg2, C arg3, D arg4)639     static <A, B, C, D, R> PooledSupplier<R> obtainSupplier(
640             QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
641             A arg1, B arg2, C arg3, D arg4) {
642         return acquire(PooledLambdaImpl.sPool,
643                 function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
644     }
645 
646     /**
647      * {@link PooledConsumer} factory
648      *
649      * @param function non-capturing lambda(typically an unbounded method reference)
650      *                 to be invoked on call
651      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
652      * @param arg2 parameter supplied to {@code function} on call
653      * @param arg3 parameter supplied to {@code function} on call
654      * @param arg4 parameter supplied to {@code function} on call
655      * @return a {@link PooledConsumer}, equivalent to lambda:
656      *         {@code (arg1) -> function(arg1, arg2, arg3, arg4) }
657      */
obtainConsumer( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4)658     static <A, B, C, D> PooledConsumer<A> obtainConsumer(
659             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
660             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
661         return acquire(PooledLambdaImpl.sPool,
662                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
663     }
664 
665     /**
666      * {@link PooledFunction} factory
667      *
668      * @param function non-capturing lambda(typically an unbounded method reference)
669      *                 to be invoked on call
670      * @param arg1 placeholder for a missing argument. Use {@link #__} to get one
671      * @param arg2 parameter supplied to {@code function} on call
672      * @param arg3 parameter supplied to {@code function} on call
673      * @param arg4 parameter supplied to {@code function} on call
674      * @return a {@link PooledFunction}, equivalent to lambda:
675      *         {@code (arg1) -> function(arg1, arg2, arg3, arg4) }
676      */
obtainFunction( QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function, ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4)677     static <A, B, C, D, R> PooledFunction<A, R> obtainFunction(
678             QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
679             ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
680         return acquire(PooledLambdaImpl.sPool,
681                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
682     }
683 
684     /**
685      * {@link PooledConsumer} factory
686      *
687      * @param function non-capturing lambda(typically an unbounded method reference)
688      *                 to be invoked on call
689      * @param arg1 parameter supplied to {@code function} on call
690      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
691      * @param arg3 parameter supplied to {@code function} on call
692      * @param arg4 parameter supplied to {@code function} on call
693      * @return a {@link PooledConsumer}, equivalent to lambda:
694      *         {@code (arg2) -> function(arg1, arg2, arg3, arg4) }
695      */
obtainConsumer( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4)696     static <A, B, C, D> PooledConsumer<B> obtainConsumer(
697             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
698             A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
699         return acquire(PooledLambdaImpl.sPool,
700                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
701     }
702 
703     /**
704      * {@link PooledFunction} factory
705      *
706      * @param function non-capturing lambda(typically an unbounded method reference)
707      *                 to be invoked on call
708      * @param arg1 parameter supplied to {@code function} on call
709      * @param arg2 placeholder for a missing argument. Use {@link #__} to get one
710      * @param arg3 parameter supplied to {@code function} on call
711      * @param arg4 parameter supplied to {@code function} on call
712      * @return a {@link PooledFunction}, equivalent to lambda:
713      *         {@code (arg2) -> function(arg1, arg2, arg3, arg4) }
714      */
obtainFunction( QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function, A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4)715     static <A, B, C, D, R> PooledFunction<B, R> obtainFunction(
716             QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
717             A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
718         return acquire(PooledLambdaImpl.sPool,
719                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
720     }
721 
722     /**
723      * {@link PooledConsumer} factory
724      *
725      * @param function non-capturing lambda(typically an unbounded method reference)
726      *                 to be invoked on call
727      * @param arg1 parameter supplied to {@code function} on call
728      * @param arg2 parameter supplied to {@code function} on call
729      * @param arg3 placeholder for a missing argument. Use {@link #__} to get one
730      * @param arg4 parameter supplied to {@code function} on call
731      * @return a {@link PooledConsumer}, equivalent to lambda:
732      *         {@code (arg3) -> function(arg1, arg2, arg3, arg4) }
733      */
obtainConsumer( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4)734     static <A, B, C, D> PooledConsumer<C> obtainConsumer(
735             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
736             A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
737         return acquire(PooledLambdaImpl.sPool,
738                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
739     }
740 
741     /**
742      * {@link PooledFunction} factory
743      *
744      * @param function non-capturing lambda(typically an unbounded method reference)
745      *                 to be invoked on call
746      * @param arg1 parameter supplied to {@code function} on call
747      * @param arg2 parameter supplied to {@code function} on call
748      * @param arg3 placeholder for a missing argument. Use {@link #__} to get one
749      * @param arg4 parameter supplied to {@code function} on call
750      * @return a {@link PooledFunction}, equivalent to lambda:
751      *         {@code (arg3) -> function(arg1, arg2, arg3, arg4) }
752      */
obtainFunction( QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function, A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4)753     static <A, B, C, D, R> PooledFunction<C, R> obtainFunction(
754             QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
755             A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
756         return acquire(PooledLambdaImpl.sPool,
757                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
758     }
759 
760     /**
761      * {@link PooledConsumer} factory
762      *
763      * @param function non-capturing lambda(typically an unbounded method reference)
764      *                 to be invoked on call
765      * @param arg1 parameter supplied to {@code function} on call
766      * @param arg2 parameter supplied to {@code function} on call
767      * @param arg3 parameter supplied to {@code function} on call
768      * @param arg4 placeholder for a missing argument. Use {@link #__} to get one
769      * @return a {@link PooledConsumer}, equivalent to lambda:
770      *         {@code (arg4) -> function(arg1, arg2, arg3, arg4) }
771      */
obtainConsumer( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4)772     static <A, B, C, D> PooledConsumer<D> obtainConsumer(
773             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
774             A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
775         return acquire(PooledLambdaImpl.sPool,
776                 function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
777     }
778 
779     /**
780      * {@link PooledFunction} factory
781      *
782      * @param function non-capturing lambda(typically an unbounded method reference)
783      *                 to be invoked on call
784      * @param arg1 parameter supplied to {@code function} on call
785      * @param arg2 parameter supplied to {@code function} on call
786      * @param arg3 parameter supplied to {@code function} on call
787      * @param arg4 placeholder for a missing argument. Use {@link #__} to get one
788      * @return a {@link PooledFunction}, equivalent to lambda:
789      *         {@code (arg4) -> function(arg1, arg2, arg3, arg4) }
790      */
obtainFunction( QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function, A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4)791     static <A, B, C, D, R> PooledFunction<D, R> obtainFunction(
792             QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
793             A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
794         return acquire(PooledLambdaImpl.sPool,
795                 function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
796     }
797 
798     /**
799      * Factory of {@link Message}s that contain an
800      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
801      * {@link Message#getCallback internal callback}.
802      *
803      * The callback is equivalent to one obtainable via
804      * {@link #obtainRunnable(QuadConsumer, Object, Object, Object, Object)}
805      *
806      * Note that using this method with {@link android.os.Handler#handleMessage}
807      * is more efficient than the alternative of {@link android.os.Handler#post}
808      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
809      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
810      *
811      * You may optionally set a {@link Message#what} for the message if you want to be
812      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
813      * there's no need to do so
814      *
815      * @param function non-capturing lambda(typically an unbounded method reference)
816      *                 to be invoked on call
817      * @param arg1 parameter supplied to {@code function} on call
818      * @param arg2 parameter supplied to {@code function} on call
819      * @param arg3 parameter supplied to {@code function} on call
820      * @param arg4 parameter supplied to {@code function} on call
821      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4) } when handled
822      */
obtainMessage( QuadConsumer<? super A, ? super B, ? super C, ? super D> function, A arg1, B arg2, C arg3, D arg4)823     static <A, B, C, D> Message obtainMessage(
824             QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
825             A arg1, B arg2, C arg3, D arg4) {
826         synchronized (Message.sPoolSync) {
827             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
828                     function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
829             return Message.obtain().setCallback(callback.recycleOnUse());
830         }
831     }
832 
833     /**
834      * {@link PooledRunnable} factory
835      *
836      * @param function non-capturing lambda(typically an unbounded method reference)
837      *                 to be invoked on call
838      * @param arg1 parameter supplied to {@code function} on call
839      * @param arg2 parameter supplied to {@code function} on call
840      * @param arg3 parameter supplied to {@code function} on call
841      * @param arg4 parameter supplied to {@code function} on call
842      * @param arg5 parameter supplied to {@code function} on call
843      * @return a {@link PooledRunnable}, equivalent to lambda:
844      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5) }
845      */
obtainRunnable( QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function, A arg1, B arg2, C arg3, D arg4, E arg5)846     static <A, B, C, D, E> PooledRunnable obtainRunnable(
847             QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function,
848             A arg1, B arg2, C arg3, D arg4, E arg5) {
849         return acquire(PooledLambdaImpl.sPool,
850                 function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null);
851     }
852 
853     /**
854      * {@link PooledSupplier} factory
855      *
856      * @param function non-capturing lambda(typically an unbounded method reference)
857      *                 to be invoked on call
858      * @param arg1 parameter supplied to {@code function} on call
859      * @param arg2 parameter supplied to {@code function} on call
860      * @param arg3 parameter supplied to {@code function} on call
861      * @param arg4 parameter supplied to {@code function} on call
862      * @param arg5 parameter supplied to {@code function} on call
863      * @return a {@link PooledSupplier}, equivalent to lambda:
864      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5) }
865      */
obtainSupplier( QuintFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5)866     static <A, B, C, D, E, R> PooledSupplier<R> obtainSupplier(
867             QuintFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? extends R>
868                     function, A arg1, B arg2, C arg3, D arg4, E arg5) {
869         return acquire(PooledLambdaImpl.sPool,
870                 function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null);
871     }
872 
873     /**
874      * Factory of {@link Message}s that contain an
875      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
876      * {@link Message#getCallback internal callback}.
877      *
878      * The callback is equivalent to one obtainable via
879      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
880      *
881      * Note that using this method with {@link android.os.Handler#handleMessage}
882      * is more efficient than the alternative of {@link android.os.Handler#post}
883      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
884      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
885      *
886      * You may optionally set a {@link Message#what} for the message if you want to be
887      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
888      * there's no need to do so
889      *
890      * @param function non-capturing lambda(typically an unbounded method reference)
891      *                 to be invoked on call
892      * @param arg1 parameter supplied to {@code function} on call
893      * @param arg2 parameter supplied to {@code function} on call
894      * @param arg3 parameter supplied to {@code function} on call
895      * @param arg4 parameter supplied to {@code function} on call
896      * @param arg5 parameter supplied to {@code function} on call
897      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5) } when
898      *         handled
899      */
obtainMessage( QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function, A arg1, B arg2, C arg3, D arg4, E arg5)900     static <A, B, C, D, E> Message obtainMessage(
901             QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function,
902             A arg1, B arg2, C arg3, D arg4, E arg5) {
903         synchronized (Message.sPoolSync) {
904             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
905                     function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null);
906             return Message.obtain().setCallback(callback.recycleOnUse());
907         }
908     }
909 
910     /**
911      * {@link PooledRunnable} factory
912      *
913      * @param function non-capturing lambda(typically an unbounded method reference)
914      *                 to be invoked on call
915      * @param arg1 parameter supplied to {@code function} on call
916      * @param arg2 parameter supplied to {@code function} on call
917      * @param arg3 parameter supplied to {@code function} on call
918      * @param arg4 parameter supplied to {@code function} on call
919      * @param arg5 parameter supplied to {@code function} on call
920      * @param arg6 parameter supplied to {@code function} on call
921      * @return a {@link PooledRunnable}, equivalent to lambda:
922      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6) }
923      */
obtainRunnable( HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6)924     static <A, B, C, D, E, F> PooledRunnable obtainRunnable(
925             HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
926             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
927         return acquire(PooledLambdaImpl.sPool,
928                 function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6);
929     }
930 
931     /**
932      * {@link PooledSupplier} factory
933      *
934      * @param function non-capturing lambda(typically an unbounded method reference)
935      *                 to be invoked on call
936      * @param arg1 parameter supplied to {@code function} on call
937      * @param arg2 parameter supplied to {@code function} on call
938      * @param arg3 parameter supplied to {@code function} on call
939      * @param arg4 parameter supplied to {@code function} on call
940      * @param arg5 parameter supplied to {@code function} on call
941      * @param arg6 parameter supplied to {@code function} on call
942      * @return a {@link PooledSupplier}, equivalent to lambda:
943      *         {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6) }
944      */
obtainSupplier( HexFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6)945     static <A, B, C, D, E, F, R> PooledSupplier<R> obtainSupplier(
946             HexFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
947                     ? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
948         return acquire(PooledLambdaImpl.sPool,
949                 function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6);
950     }
951 
952     /**
953      * Factory of {@link Message}s that contain an
954      * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
955      * {@link Message#getCallback internal callback}.
956      *
957      * The callback is equivalent to one obtainable via
958      * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
959      *
960      * Note that using this method with {@link android.os.Handler#handleMessage}
961      * is more efficient than the alternative of {@link android.os.Handler#post}
962      * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
963      * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
964      *
965      * You may optionally set a {@link Message#what} for the message if you want to be
966      * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
967      * there's no need to do so
968      *
969      * @param function non-capturing lambda(typically an unbounded method reference)
970      *                 to be invoked on call
971      * @param arg1 parameter supplied to {@code function} on call
972      * @param arg2 parameter supplied to {@code function} on call
973      * @param arg3 parameter supplied to {@code function} on call
974      * @param arg4 parameter supplied to {@code function} on call
975      * @param arg5 parameter supplied to {@code function} on call
976      * @param arg6 parameter supplied to {@code function} on call
977      * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6) }
978      *         when handled
979      */
obtainMessage( HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6)980     static <A, B, C, D, E, F> Message obtainMessage(
981             HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
982             A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
983         synchronized (Message.sPoolSync) {
984             PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
985                     function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6);
986             return Message.obtain().setCallback(callback.recycleOnUse());
987         }
988     }
989 }
990