| // Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.utils; | |
| import static com.android.tools.r8.utils.FunctionUtils.ignoreArgument; | |
| import java.util.Map; | |
| import java.util.Map.Entry; | |
| import java.util.function.BiFunction; | |
| import java.util.function.Consumer; | |
| import java.util.function.Function; | |
| public class TraversalUtils { | |
| public static <BT, CT> BT getFirst( | |
| Function<Function<BT, TraversalContinuation<BT, CT>>, TraversalContinuation<BT, CT>> | |
| traversal) { | |
| return traversal.apply(TraversalContinuation::doBreak).asBreak().getValue(); | |
| } | |
| public static <BT, CT> boolean hasNext( | |
| Consumer<Function<CT, TraversalContinuation<BT, CT>>> traversal) { | |
| return !isEmpty(traversal); | |
| } | |
| public static <BT, CT> boolean isEmpty( | |
| Consumer<Function<CT, TraversalContinuation<BT, CT>>> traversal) { | |
| return isSizeExactly(traversal, 0); | |
| } | |
| public static <BT, CT> boolean isSingleton( | |
| Consumer<Function<CT, TraversalContinuation<BT, CT>>> traversal) { | |
| return isSizeExactly(traversal, 1); | |
| } | |
| public static <BT, CT> boolean isSizeExactly( | |
| Consumer<Function<CT, TraversalContinuation<BT, CT>>> traversal, int value) { | |
| IntBox counter = new IntBox(); | |
| traversal.accept( | |
| ignoreArgument(() -> TraversalContinuation.breakIf(counter.incrementAndGet() > value))); | |
| return counter.get() == value; | |
| } | |
| public static <BT, CT> boolean isSizeGreaterThan( | |
| Consumer<Function<CT, TraversalContinuation<BT, CT>>> traversal, int value) { | |
| IntBox counter = new IntBox(); | |
| traversal.accept( | |
| ignoreArgument(() -> TraversalContinuation.breakIf(counter.incrementAndGet() > value))); | |
| return counter.get() > value; | |
| } | |
| public static <S, BT, CT> TraversalContinuation<BT, CT> traverseIterable( | |
| Iterable<S> iterable, | |
| BiFunction<? super S, ? super CT, TraversalContinuation<BT, CT>> fn, | |
| CT initialValue) { | |
| TraversalContinuation<BT, CT> traversalContinuation = | |
| TraversalContinuation.doContinue(initialValue); | |
| for (S element : iterable) { | |
| traversalContinuation = | |
| fn.apply(element, traversalContinuation.asContinue().getValueOrDefault(null)); | |
| if (traversalContinuation.isBreak()) { | |
| break; | |
| } | |
| } | |
| return traversalContinuation; | |
| } | |
| public static <S, T, BT, CT> TraversalContinuation<BT, CT> traverseMap( | |
| Map<S, T> map, | |
| TriFunction<? super S, ? super T, ? super CT, TraversalContinuation<BT, CT>> fn, | |
| CT initialValue) { | |
| TraversalContinuation<BT, CT> traversalContinuation = | |
| TraversalContinuation.doContinue(initialValue); | |
| for (Entry<S, T> entry : map.entrySet()) { | |
| traversalContinuation = | |
| fn.apply( | |
| entry.getKey(), | |
| entry.getValue(), | |
| traversalContinuation.asContinue().getValueOrDefault(null)); | |
| if (traversalContinuation.isBreak()) { | |
| break; | |
| } | |
| } | |
| return traversalContinuation; | |
| } | |
| } |