All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.common.function.Functions Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2017 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.wildfly.common.function;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.DoubleFunction;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.LongFunction;
import java.util.function.ObjDoubleConsumer;
import java.util.function.ObjIntConsumer;
import java.util.function.ObjLongConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleBiFunction;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntBiFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongBiFunction;
import java.util.function.ToLongFunction;

import org.jboss.logging.Logger;
import org.wildfly.common.Assert;

/**
 * A set of utility methods which return common functions.
 */
public final class Functions {
    private Functions() {}

    private static final Logger LOGGER = Logger.getLogger(Functions.class);

    private static final Consumer CLOSING_CONSUMER = quiet(AutoCloseable::close, exceptionLoggingConsumer());

    /**
     * Returns a consumer that quietly closes its argument, logging any exceptions.
     * @return a closing consumer
     */
    @SuppressWarnings("unchecked")
    public static  Consumer closingConsumer() {
        return (Consumer) CLOSING_CONSUMER;
    }

    private static final Consumer EXCEPTION_LOGGER = new Consumer() {
        @Override
        public void accept(Exception e) {
            LOGGER.warn(e.getLocalizedMessage(), e);
        }
    };

    /**
     * Returns a consumer that logs its exception parameter as a warning.
     * @param  the exception type
     * @return an exception consumer
     */
    @SuppressWarnings("unchecked")
    public static  Consumer exceptionLoggingConsumer() {
        return (Consumer) EXCEPTION_LOGGER;
    }

    /**
     * Returns a consumer that wraps and throws its exception parameter as a {@link RuntimeException}.
     * @param  the exception type
     * @return an exception consumer
     */
    public static  Consumer runtimeExceptionThrowingConsumer(Function runtimeExceptionWrapper) {
        return new Consumer() {
            @Override
            public void accept(E exception) {
                throw runtimeExceptionWrapper.apply(exception);
            }
        };
    }

    /**
     * Converts an {@link ExceptionConsumer} to a standard {@link Consumer} using the specified exception handler.
     * @param  the parameter type of the consumer
     * @param  the exception type
     * @param consumer an exception consumer
     * @param exceptionHandler an exception handler
     * @return a standard consumer
     */
    public static  Consumer quiet(ExceptionConsumer consumer, Consumer exceptionHandler) {
        return new Consumer() {
            @SuppressWarnings("unchecked")
            @Override
            public void accept(T value) {
                try {
                    consumer.accept(value);
                } catch (Exception e) {
                    exceptionHandler.accept((E) e);
                }
            }
        };
    }

    /**
     * Converts an {@link ExceptionBiConsumer} to a standard {@link BiConsumer} using the specified exception handler.
     * @param  the first parameter type of the consumer
     * @param  the second parameter type of the consumer
     * @param  the exception type
     * @param consumer a binary exception consumer
     * @param exceptionHandler an exception handler
     * @return a standard binary consumer
     */
    public static  BiConsumer quiet(ExceptionBiConsumer consumer, Consumer exceptionHandler) {
        return new BiConsumer() {
            @SuppressWarnings("unchecked")
            @Override
            public void accept(T value1, U value2) {
                try {
                    consumer.accept(value1, value2);
                } catch (Exception e) {
                    exceptionHandler.accept((E) e);
                }
            }
        };
    }

    /**
     * Converts an {@link ExceptionObjIntConsumer} to a standard {@link ObjIntConsumer} using the specified exception handler.
     * @param  the first parameter type of the consumer
     * @param  the exception type
     * @param consumer an object/int exception consumer
     * @param exceptionHandler an exception handler
     * @return a standard object/int consumer
     */
    public static  ObjIntConsumer quiet(ExceptionObjIntConsumer consumer, Consumer exceptionHandler) {
        return new ObjIntConsumer() {
            @SuppressWarnings("unchecked")
            @Override
            public void accept(T object, int i) {
                try {
                    consumer.accept(object, i);
                } catch (Exception e) {
                    exceptionHandler.accept((E) e);
                }
            }
        };
    }

    /**
     * Converts an {@link ExceptionObjLongConsumer} to a standard {@link ObjLongConsumer} using the specified exception handler.
     * @param  the first parameter type of the consumer
     * @param  the exception type
     * @param consumer an object/long exception consumer
     * @param exceptionHandler an exception handler
     * @return a standard object/long consumer
     */
    public static  ObjLongConsumer quiet(ExceptionObjLongConsumer consumer, Consumer exceptionHandler) {
        return new ObjLongConsumer() {
            @SuppressWarnings("unchecked")
            @Override
            public void accept(T object, long i) {
                try {
                    consumer.accept(object, i);
                } catch (Exception e) {
                    exceptionHandler.accept((E) e);
                }
            }
        };
    }

    /**
     * Get the singleton consumer which accepts and runs runnable instances.
     *
     * @return the runnable consumer
     */
    public static Consumer runnableConsumer() {
        return RunnableConsumer.INSTANCE;
    }

    /**
     * Get the singleton exception consumer which accepts and runs exception runnable instances.
     *
     * @param  the exception type
     * @return the runnable consumer
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionConsumer, E> exceptionRunnableConsumer() {
        return ExceptionRunnableConsumer.INSTANCE;
    }

    /**
     * Get the singleton exception consumer which accepts and runs runnable instances.
     *
     * @return the runnable consumer
     */
    public static ExceptionConsumer runnableExceptionConsumer() {
        return RunnableExceptionConsumer.INSTANCE;
    }

    /**
     * Get the singleton consumer which accepts a consumer and an argument to hand to it.
     *
     * @param  the argument type
     * @return the consumer
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  BiConsumer, T> consumerBiConsumer() {
        return ConsumerBiConsumer.INSTANCE;
    }

    /**
     * Get the singleton consumer which accepts a consumer and an argument to hand to it.
     *
     * @param  the argument type
     * @param  the exception type
     * @return the consumer
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionBiConsumer, T, E> exceptionConsumerBiConsumer() {
        return ExceptionConsumerBiConsumer.INSTANCE;
    }

    /**
     * Get the singleton consumer which accepts a consumer and an argument to hand to it.
     *
     * @param  the argument type
     * @return the consumer
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionBiConsumer, T, RuntimeException> consumerExceptionBiConsumer() {
        return ConsumerExceptionBiConsumer.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a supplier and returns the result of the supplier.
     *
     * @param  the result type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  Function, R> supplierFunction() {
        return SupplierFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a supplier and returns the result of the supplier.
     *
     * @param  the result type
     * @param  the exception type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionFunction, R, E> exceptionSupplierFunction() {
        return ExceptionSupplierFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a supplier and returns the result of the supplier.
     *
     * @param  the result type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionFunction, R, RuntimeException> supplierExceptionFunction() {
        return SupplierExceptionFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a function which accepts a supplier, all of which return the result
     * of the supplier.
     *
     * @param  the result type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  BiFunction, R>, Supplier, R> supplierFunctionBiFunction() {
        return FunctionSupplierBiFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a function which accepts a supplier, all of which return the result
     * of the supplier.
     *
     * @param  the result type
     * @param  the exception type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionBiFunction, R, E>, ExceptionSupplier, R, E> exceptionSupplierFunctionBiFunction() {
        return ExceptionFunctionSupplierBiFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a function and a parameter to pass to the function, and returns the
     * result of the function.
     *
     * @param  the argument type
     * @param  the result type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  BiFunction, T, R> functionBiFunction() {
        return FunctionBiFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a function and a parameter to pass to the function, and returns the
     * result of the function.
     *
     * @param  the argument type
     * @param  the result type
     * @param  the exception type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionBiFunction, T, R, E> exceptionFunctionBiFunction() {
        return ExceptionFunctionBiFunction.INSTANCE;
    }

    /**
     * Get the singleton function which accepts a function and a parameter to pass to the function, and returns the
     * result of the function.
     *
     * @param  the argument type
     * @param  the result type
     * @return the function
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionBiFunction, T, R, RuntimeException> functionExceptionBiFunction() {
        return FunctionExceptionBiFunction.INSTANCE;
    }

    /**
     * Get a supplier which always returns the same value.
     *
     * @param value the value to return
     * @param  the value type
     * @return the value supplier
     */
    @SuppressWarnings("unchecked")
    public static  Supplier constantSupplier(T value) {
        return value == null ? ConstantSupplier.NULL : new ConstantSupplier<>(value);
    }

    /**
     * Get a supplier which always returns the same value.
     *
     * @param value the value to return
     * @param  the value type
     * @param  the exception type
     * @return the value supplier
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static  ExceptionSupplier constantExceptionSupplier(T value) {
        return value == null ? ConstantSupplier.NULL : new ConstantSupplier(value);
    }

    /**
     * Get a runnable which executes the given consumer with captured values.
     *
     * @param consumer the consumer to run (must not be {@code null})
     * @param param1 the first parameter to pass
     * @param param2 the second parameter to pass
     * @param  the first parameter type
     * @param  the second parameter type
     * @return the capturing runnable
     */
    public static  Runnable capturingRunnable(BiConsumer consumer, T param1, U param2) {
        Assert.checkNotNullParam("consumer", consumer);
        return new BiConsumerRunnable(consumer, param1, param2);
    }

    /**
     * Get a runnable which executes the given consumer with captured values.
     *
     * @param consumer the consumer to run (must not be {@code null})
     * @param param the parameter to pass
     * @param  the parameter type
     * @return the capturing runnable
     */
    public static  Runnable capturingRunnable(Consumer consumer, T param) {
        Assert.checkNotNullParam("consumer", consumer);
        return new ConsumerRunnable(consumer, param);
    }

    /**
     * Get a runnable which executes the given consumer with captured values.
     *
     * @param consumer the consumer to run (must not be {@code null})
     * @param param1 the first parameter to pass
     * @param param2 the second parameter to pass
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @return the capturing runnable
     */
    public static  ExceptionRunnable exceptionCapturingRunnable(ExceptionBiConsumer consumer, T param1, U param2) {
        Assert.checkNotNullParam("consumer", consumer);
        return new ExceptionBiConsumerRunnable(consumer, param1, param2);
    }

    /**
     * Get a runnable which executes the given consumer with captured values.
     *
     * @param consumer the consumer to run (must not be {@code null})
     * @param param the parameter to pass
     * @param  the parameter type
     * @param  the exception type
     * @return the capturing runnable
     */
    public static  ExceptionRunnable exceptionCapturingRunnable(ExceptionConsumer consumer, T param) {
        Assert.checkNotNullParam("consumer", consumer);
        return new ExceptionConsumerRunnable(consumer, param);
    }

    /**
     * Get a consumer which discards the values it is given.
     *
     * @param  the parameter type
     * @return the discarding consumer
     */
    @SuppressWarnings("unchecked")
    public static  Consumer discardingConsumer() {
        return DiscardingConsumer.INSTANCE;
    }

    /**
     * Get a consumer which discards the values it is given.
     *
     * @param  the parameter type
     * @param  the exception type
     * @return the discarding consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionConsumer discardingExceptionConsumer() {
        return DiscardingConsumer.INSTANCE;
    }

    /**
     * Get a consumer which discards the values it is given.
     *
     * @param  the first parameter type
     * @param  the second parameter type
     * @return the discarding consumer
     */
    @SuppressWarnings("unchecked")
    public static  BiConsumer discardingBiConsumer() {
        return DiscardingBiConsumer.INSTANCE;
    }

    /**
     * Get a consumer which discards the values it is given.
     *
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @return the discarding consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionBiConsumer discardingExceptionBiConsumer() {
        return DiscardingBiConsumer.INSTANCE;
    }

    /**
     * Returns a {@link Consumer} with identical behavior to the specified {@link Consumer} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  Consumer cast(Consumer consumer) {
        return (Consumer) consumer;
    }

    /**
     * Returns a {@link Predicate} with identical behavior to the specified {@link Predicate} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param predicate a predicate
     * @return a functionally equivalent predicate
     */
    @SuppressWarnings("unchecked")
    public static  Predicate cast(Predicate predicate) {
        return (Predicate) predicate;
    }

    /**
     * Returns a {@link Supplier} with identical behavior to the specified {@link Supplier} but with relaxed return type.
     * @param  the return type
     * @param  the relaxed return type
     * @param supplier a supplier
     * @return a functionally equivalent supplier
     */
    @SuppressWarnings("unchecked")
    public static  Supplier cast(Supplier supplier) {
        return (Supplier) supplier;
    }

    /**
     * Returns a {@link Function} with identical behavior to the specified {@link Function} but with restricted parameter type and relaxed return type.
     * @param  the parameter type
     * @param  the return type
     * @param  the restricted parameter type
     * @param  the relaxed return type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  Function cast(Function function) {
        return (Function) function;
    }

    /**
     * Returns a {@link DoubleFunction} with identical behavior to the specified {@link DoubleFunction} but with relaxed return type.
     * @param  the return type
     * @param  the relaxed return type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  DoubleFunction cast(DoubleFunction function) {
        return (DoubleFunction) function;
    }

    /**
     * Returns a {@link IntFunction} with identical behavior to the specified {@link IntFunction} but with relaxed return type.
     * @param  the return type
     * @param  the relaxed return type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  IntFunction cast(IntFunction function) {
        return (IntFunction) function;
    }

    /**
     * Returns a {@link LongFunction} with identical behavior to the specified {@link LongFunction} but with relaxed return type.
     * @param  the return type
     * @param  the relaxed return type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  LongFunction cast(LongFunction function) {
        return (LongFunction) function;
    }

    /**
     * Returns a {@link ToDoubleFunction} with identical behavior to the specified {@link ToDoubleFunction} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToDoubleFunction cast(ToDoubleFunction function) {
        return (ToDoubleFunction) function;
    }

    /**
     * Returns a {@link ToIntFunction} with identical behavior to the specified {@link ToIntFunction} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToIntFunction cast(ToIntFunction function) {
        return (ToIntFunction) function;
    }

    /**
     * Returns a {@link ToLongFunction} with identical behavior to the specified {@link ToLongFunction} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToLongFunction cast(ToLongFunction function) {
        return (ToLongFunction) function;
    }

    /**
     * Returns a {@link BiConsumer} with identical behavior to the specified {@link BiConsumer} but with restricted parameter types.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  BiConsumer cast(BiConsumer consumer) {
        return (BiConsumer) consumer;
    }

    /**
     * Returns a {@link ObjDoubleConsumer} with identical behavior to the specified {@link ObjDoubleConsumer} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ObjDoubleConsumer cast(ObjDoubleConsumer consumer) {
        return (ObjDoubleConsumer) consumer;
    }

    /**
     * Returns a {@link ObjIntConsumer} with identical behavior to the specified {@link ObjIntConsumer} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ObjIntConsumer cast(ObjIntConsumer consumer) {
        return (ObjIntConsumer) consumer;
    }

    /**
     * Returns a {@link ObjLongConsumer} with identical behavior to the specified {@link ObjLongConsumer} but with restricted parameter type.
     * @param  the parameter type
     * @param  the restricted parameter type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ObjLongConsumer cast(ObjLongConsumer consumer) {
        return (ObjLongConsumer) consumer;
    }

    /**
     * Returns a {@link BiPredicate} with identical behavior to the specified {@link BiPredicate} but with restricted parameter types.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param predicate a predicate
     * @return a functionally equivalent predicate
     */
    @SuppressWarnings("unchecked")
    public static  BiPredicate cast(BiPredicate predicate) {
        return (BiPredicate) predicate;
    }

    /**
     * Returns a {@link BiFunction} with identical behavior to the specified {@link BiFunction} but with restricted parameter types and relaxed return type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the return type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed return type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  BiFunction cast(BiFunction function) {
        return (BiFunction) function;
    }

    /**
     * Returns a {@link ToDoubleBiFunction} with identical behavior to the specified {@link ToDoubleBiFunction} but with restricted parameter types.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToDoubleBiFunction cast(ToDoubleBiFunction function) {
        return (ToDoubleBiFunction) function;
    }

    /**
     * Returns a {@link ToIntBiFunction} with identical behavior to the specified {@link ToIntBiFunction} but with restricted parameter types.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToIntBiFunction cast(ToIntBiFunction function) {
        return (ToIntBiFunction) function;
    }

    /**
     * Returns a {@link ToLongBiFunction} with identical behavior to the specified {@link ToLongBiFunction} but with restricted parameter types.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ToLongBiFunction cast(ToLongBiFunction function) {
        return (ToLongBiFunction) function;
    }

    /**
     * Returns a {@link ExceptionConsumer} with identical behavior to the specified {@link ExceptionConsumer} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionConsumer cast(ExceptionConsumer consumer) {
        return (ExceptionConsumer) consumer;
    }

    /**
     * Returns a {@link ExceptionPredicate} with identical behavior to the specified {@link ExceptionPredicate} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param predicate a predicate
     * @return a functionally equivalent predicate
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionPredicate cast(ExceptionPredicate consumer) {
        return (ExceptionPredicate) consumer;
    }

    /**
     * Returns a {@link ExceptionSupplier} with identical behavior to the specified {@link ExceptionSupplier} but with relaxed return type and relaxed exception type.
     * @param  the return type
     * @param  the exception type
     * @param  the relaxed return type
     * @param  the relaxed exception type
     * @param supplier a supplier
     * @return a functionally equivalent supplier
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionSupplier cast(ExceptionSupplier supplier) {
        return (ExceptionSupplier) supplier;
    }

    /**
     * Returns a {@link ExceptionFunction} with identical behavior to the specified {@link ExceptionFunction} but with restricted parameter type, relaxed return type, and relaxed exception type.
     * @param  the parameter type
     * @param  the return type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed return type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionFunction cast(ExceptionFunction function) {
        return (ExceptionFunction) function;
    }

    /**
     * Returns a {@link ExceptionIntFunction} with identical behavior to the specified {@link ExceptionFunction} but with relaxed return type and relaxed exception type.
     * @param  the return type
     * @param  the exception type
     * @param  the relaxed return type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionIntFunction cast(ExceptionIntFunction function) {
        return (ExceptionIntFunction) function;
    }

    /**
     * Returns a {@link ExceptionLongFunction} with identical behavior to the specified {@link ExceptionLongFunction} but with relaxed return type and relaxed exception type.
     * @param  the return type
     * @param  the exception type
     * @param  the relaxed return type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionLongFunction cast(ExceptionLongFunction function) {
        return (ExceptionLongFunction) function;
    }

    /**
     * Returns a {@link ExceptionToIntFunction} with identical behavior to the specified {@link ExceptionToIntFunction} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionToIntFunction cast(ExceptionToIntFunction function) {
        return (ExceptionToIntFunction) function;
    }

    /**
     * Returns a {@link ExceptionToLongFunction} with identical behavior to the specified {@link ExceptionToLongFunction} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionToLongFunction cast(ExceptionToLongFunction function) {
        return (ExceptionToLongFunction) function;
    }

    /**
     * Returns a {@link ExceptionBiConsumer} with identical behavior to the specified {@link ExceptionBiConsumer} but with restricted parameter types and relaxed exception type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed exception type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionBiConsumer cast(ExceptionBiConsumer consumer) {
        return (ExceptionBiConsumer) consumer;
    }

    /**
     * Returns a {@link ExceptionObjIntConsumer} with identical behavior to the specified {@link ExceptionObjIntConsumer} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionObjIntConsumer cast(ExceptionObjIntConsumer consumer) {
        return (ExceptionObjIntConsumer) consumer;
    }

    /**
     * Returns a {@link ExceptionObjLongConsumer} with identical behavior to the specified {@link ExceptionObjLongConsumer} but with restricted parameter type and relaxed exception type.
     * @param  the parameter type
     * @param  the exception type
     * @param  the restricted parameter type
     * @param  the relaxed exception type
     * @param consumer a consumer
     * @return a functionally equivalent consumer
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionObjLongConsumer cast(ExceptionObjLongConsumer consumer) {
        return (ExceptionObjLongConsumer) consumer;
    }

    /**
     * Returns a {@link ExceptionBiPredicate} with identical behavior to the specified {@link ExceptionBiPredicate} but with restricted parameter types and relaxed exception type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed exception type
     * @param predicate a predicate
     * @return a functionally equivalent predicate
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionBiPredicate cast(ExceptionBiPredicate predicate) {
        return (ExceptionBiPredicate) predicate;
    }

    /**
     * Returns a {@link ExceptionBiFunction} with identical behavior to the specified {@link ExceptionBiFunction} but with restricted parameter types, relaxed return type, and relaxed exception type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the return type
     * @param  the exception type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed return type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionBiFunction cast(ExceptionBiFunction function) {
        return (ExceptionBiFunction) function;
    }

    /**
     * Returns a {@link ExceptionToIntBiFunction} with identical behavior to the specified {@link ExceptionToIntBiFunction} but with restricted parameter types and relaxed exception type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionToIntBiFunction cast(ExceptionToIntBiFunction function) {
        return (ExceptionToIntBiFunction) function;
    }

    /**
     * Returns a {@link ExceptionToLongBiFunction} with identical behavior to the specified {@link ExceptionToLongBiFunction} but with restricted parameter types and relaxed exception type.
     * @param  the first parameter type
     * @param  the second parameter type
     * @param  the exception type
     * @param  the restricted first parameter type
     * @param  the restricted second parameter type
     * @param  the relaxed exception type
     * @param function a function
     * @return a functionally equivalent function
     */
    @SuppressWarnings("unchecked")
    public static  ExceptionToLongBiFunction cast(ExceptionToLongBiFunction function) {
        return (ExceptionToLongBiFunction) function;
    }

    static class RunnableConsumer implements Consumer {
        static final Consumer INSTANCE = new RunnableConsumer();

        private RunnableConsumer() {}

        public void accept(final Runnable runnable) {
            runnable.run();
        }
    }

    static class ExceptionRunnableConsumer implements ExceptionConsumer, E> {
        static final ExceptionConsumer INSTANCE = new ExceptionRunnableConsumer<>();

        private ExceptionRunnableConsumer() {}

        public void accept(final ExceptionRunnable ExceptionRunnable) throws E {
            ExceptionRunnable.run();
        }
    }

    static class RunnableExceptionConsumer implements ExceptionConsumer {
        static final RunnableExceptionConsumer INSTANCE = new RunnableExceptionConsumer();

        private RunnableExceptionConsumer() {}

        public void accept(final Runnable runnable) throws RuntimeException {
            runnable.run();
        }
    }

    static class ConsumerBiConsumer implements BiConsumer, Object> {
        static final BiConsumer INSTANCE = new ConsumerBiConsumer();

        private ConsumerBiConsumer() {}

        public void accept(final Consumer consumer, final Object o) {
            consumer.accept(o);
        }
    }

    static class ExceptionConsumerBiConsumer implements ExceptionBiConsumer, Object, E> {
        static final ExceptionBiConsumer INSTANCE = new ExceptionConsumerBiConsumer<>();

        private ExceptionConsumerBiConsumer() {}

        public void accept(final ExceptionConsumer consumer, final Object o) throws E {
            consumer.accept(o);
        }
    }

    static class ConsumerExceptionBiConsumer implements ExceptionBiConsumer, T, RuntimeException> {
        static final ExceptionBiConsumer INSTANCE = new ConsumerExceptionBiConsumer();

        private ConsumerExceptionBiConsumer() {}

        public void accept(final Consumer consumer, final T t) throws RuntimeException {
            consumer.accept(t);
        }
    }

    static class SupplierFunction implements Function, Object> {
        static final Function INSTANCE = new SupplierFunction();

        private SupplierFunction() {}

        public Object apply(final Supplier supplier) {
            return supplier.get();
        }
    }

    static class ExceptionSupplierFunction implements ExceptionFunction, Object, E> {
        static final ExceptionFunction INSTANCE = new ExceptionSupplierFunction<>();

        private ExceptionSupplierFunction() {}

        public Object apply(final ExceptionSupplier supplier) throws E {
            return supplier.get();
        }
    }

    static class SupplierExceptionFunction implements ExceptionFunction, R, RuntimeException> {
        static final SupplierExceptionFunction INSTANCE = new SupplierExceptionFunction();

        private SupplierExceptionFunction() {}

        public R apply(final Supplier supplier) throws RuntimeException {
            return supplier.get();
        }
    }

    static class FunctionSupplierBiFunction implements BiFunction, Object>, Supplier, Object> {
        static final BiFunction INSTANCE = new FunctionSupplierBiFunction();

        private FunctionSupplierBiFunction() {}

        public Object apply(final Function, Object> function, final Supplier supplier) {
            return function.apply(supplier);
        }
    }

    static class ExceptionFunctionSupplierBiFunction implements ExceptionBiFunction, Object, E>, ExceptionSupplier, Object, E> {
        static final ExceptionBiFunction INSTANCE = new ExceptionFunctionSupplierBiFunction();

        private ExceptionFunctionSupplierBiFunction() {}

        public Object apply(final ExceptionFunction, Object, E> function, final ExceptionSupplier supplier) throws E {
            return function.apply(supplier);
        }
    }

    static class FunctionExceptionBiFunction implements ExceptionBiFunction, T, R, RuntimeException> {
        static final FunctionExceptionBiFunction INSTANCE = new FunctionExceptionBiFunction();

        private FunctionExceptionBiFunction() {}

        public R apply(final Function function, final T t) throws RuntimeException {
            return function.apply(t);
        }
    }

    static class FunctionBiFunction implements BiFunction, T, R> {
        static final BiFunction INSTANCE = new FunctionBiFunction();

        private FunctionBiFunction() {
        }

        public R apply(final Function function, final T t) {
            return function.apply(t);
        }
    }

    static class ExceptionFunctionBiFunction implements ExceptionBiFunction, T, R, E> {
        static final ExceptionBiFunction INSTANCE = new ExceptionFunctionBiFunction();

        private ExceptionFunctionBiFunction() {
        }

        public R apply(final ExceptionFunction function, final T t) throws E {
            return function.apply(t);
        }
    }

    static class ConstantSupplier implements Supplier, ExceptionSupplier {
        static final ConstantSupplier NULL = new ConstantSupplier<>(null);

        private final T arg1;

        ConstantSupplier(final T arg1) {
            this.arg1 = arg1;
        }

        public T get() {
            return arg1;
        }

        public String toString() {
            return String.format("supplier(%s)", arg1);
        }
    }

    static class BiConsumerRunnable implements Runnable {
        private final BiConsumer consumer;
        private final T param1;
        private final U param2;

        BiConsumerRunnable(final BiConsumer consumer, final T param1, final U param2) {
            this.consumer = consumer;
            this.param1 = param1;
            this.param2 = param2;
        }

        public void run() {
            consumer.accept(param1, param2);
        }

        public String toString() {
            return String.format("%s(%s,%s)", consumer, param1, param2);
        }
    }

    static class ConsumerRunnable implements Runnable {
        private final Consumer consumer;
        private final T param;

        ConsumerRunnable(final Consumer consumer, final T param) {
            this.consumer = consumer;
            this.param = param;
        }

        public void run() {
            consumer.accept(param);
        }

        public String toString() {
            return String.format("%s(%s)", consumer, param);
        }
    }

    static class ExceptionBiConsumerRunnable implements ExceptionRunnable {
        private final ExceptionBiConsumer consumer;
        private final T param1;
        private final U param2;

        ExceptionBiConsumerRunnable(final ExceptionBiConsumer consumer, final T param1, final U param2) {
            this.consumer = consumer;
            this.param1 = param1;
            this.param2 = param2;
        }

        public void run() throws E {
            consumer.accept(param1, param2);
        }

        public String toString() {
            return String.format("%s(%s,%s)", consumer, param1, param2);
        }
    }

    static class ExceptionConsumerRunnable implements ExceptionRunnable {
        private final ExceptionConsumer consumer;
        private final T param;

        ExceptionConsumerRunnable(final ExceptionConsumer consumer, final T param) {
            this.consumer = consumer;
            this.param = param;
        }

        public void run() throws E {
            consumer.accept(param);
        }

        public String toString() {
            return String.format("%s(%s)", consumer, param);
        }
    }

    static class DiscardingConsumer implements Consumer, ExceptionConsumer {
        static final DiscardingConsumer INSTANCE = new DiscardingConsumer();

        private DiscardingConsumer() {
        }

        public void accept(final T t) {
        }
    }

    static class DiscardingBiConsumer implements BiConsumer, ExceptionBiConsumer {
        static final DiscardingBiConsumer INSTANCE = new DiscardingBiConsumer();

        private DiscardingBiConsumer() {
        }

        public void accept(final T t, final U u) {
        }
    }
}