blob: 627ee792f4703ce51ccf776aec8107ad626d0192 [file] [log] [blame]
// 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;
}
}