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

com.speedment.runtime.compute.internal.expression.PlusUtil Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

The newest version!
/*
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * 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 com.speedment.runtime.compute.internal.expression;

import com.speedment.runtime.compute.ToByte;
import com.speedment.runtime.compute.ToDouble;
import com.speedment.runtime.compute.ToFloat;
import com.speedment.runtime.compute.ToInt;
import com.speedment.runtime.compute.ToLong;
import com.speedment.runtime.compute.ToShort;
import com.speedment.runtime.compute.expression.BinaryExpression;
import com.speedment.runtime.compute.expression.BinaryObjExpression;
import com.speedment.runtime.compute.expression.Expression;

import java.util.Objects;

import static java.util.Objects.requireNonNull;

/**
 * Utility class used to construct expression that gives the sum of two
 * expressions.
 *
 * @author Emil Forslund
 * @since  3.1.0
 */
public final class PlusUtil {

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToShort bytePlusByte(ToByte first, byte second) {
        class BytePlusByte extends AbstractPlusByte> implements ToShort {
            private BytePlusByte(ToByte first, byte second) {
                super(first, second);
            }

            @Override
            public short applyAsShort(T object) {
                return (short) (firstInner.applyAsByte(object) + secondInner);
            }
        }

        return new BytePlusByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt bytePlusInt(ToByte first, int second) {
        class BytePlusInt extends AbstractPlusInt> implements ToInt {
            private BytePlusInt(ToByte first, int second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsByte(object) + secondInner;
            }
        }

        return new BytePlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong bytePlusLong(ToByte first, long second) {
        class BytePlusLong extends AbstractPlusLong> implements ToLong {
            private BytePlusLong(ToByte first, long second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsByte(object) + secondInner;
            }
        }

        return new BytePlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToShort bytePlusByte(ToByte first, ToByte second) {
        class BytePlusByte extends AbstractPlus, ToByte> implements ToShort {
            private BytePlusByte(ToByte first, ToByte second) {
                super(first, second);
            }

            @Override
            public short applyAsShort(T object) {
                return (short) (firstInner.applyAsByte(object)
                    + secondInner.applyAsByte(object));
            }
        }

        return new BytePlusByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt shortPlusByte(ToShort first, byte second) {
        class ShortPlusShort extends AbstractPlusByte> implements ToInt {
            private ShortPlusShort(ToShort first, byte second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsShort(object) + secondInner;
            }
        }

        return new ShortPlusShort(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt shortPlusInt(ToShort first, int second) {
        class ShortPlusInt extends AbstractPlusInt> implements ToInt {
            private ShortPlusInt(ToShort first, int second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsShort(object) + secondInner;
            }
        }

        return new ShortPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong shortPlusLong(ToShort first, long second) {
        class ShortPlusLong extends AbstractPlusLong> implements ToLong {
            private ShortPlusLong(ToShort first, long second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsShort(object) + secondInner;
            }
        }

        return new ShortPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToShort shortPlusShort(ToShort first, ToShort second) {
        class ShortPlusShort extends AbstractPlus, ToShort> implements ToShort {
            private ShortPlusShort(ToShort first, ToShort second) {
                super(first, second);
            }

            @Override
            public short applyAsShort(T object) {
                return (short) (firstInner.applyAsShort(object)
                    + secondInner.applyAsShort(object));
            }
        }

        return new ShortPlusShort(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intPlusByte(ToInt first, byte second) {
        class IntPlusByte extends AbstractPlusByte> implements ToInt {
            private IntPlusByte(ToInt first, byte second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsInt(object) + secondInner;
            }
        }

        return new IntPlusByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intPlusInt(ToInt first, int second) {
        class IntPlusInt extends AbstractPlusInt> implements ToInt {
            private IntPlusInt(ToInt first, int second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsInt(object) + secondInner;
            }
        }

        return new IntPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong intPlusLong(ToInt first, long second) {
        class IntPlusLong extends AbstractPlusLong> implements ToLong {
            private IntPlusLong(ToInt first, long second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsInt(object) + secondInner;
            }
        }

        return new IntPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intPlusByte(ToInt first, ToByte second) {
        class IntPlusByte extends AbstractPlus, ToByte> implements ToInt {
            private IntPlusByte(ToInt first, ToByte second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsInt(object) +
                    secondInner.applyAsByte(object);
            }
        }

        return new IntPlusByte(first, second);
    }


    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intPlusInt(ToInt first, ToInt second) {
        class IntPlusInt extends AbstractPlus, ToInt> implements ToInt {
            private IntPlusInt(ToInt first, ToInt second) {
                super(first, second);
            }

            @Override
            public int applyAsInt(T object) {
                return firstInner.applyAsInt(object) +
                    secondInner.applyAsInt(object);
            }
        }

        return new IntPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longPlusByte(ToLong first, byte second) {
        class LongPlusLong extends AbstractPlusByte> implements ToLong {
            private LongPlusLong(ToLong first, byte second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsLong(object) + secondInner;
            }
        }

        return new LongPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longPlusInt(ToLong first, int second) {
        class LongPlusInt extends AbstractPlusInt> implements ToLong {
            private LongPlusInt(ToLong first, int second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsLong(object) + secondInner;
            }
        }

        return new LongPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longPlusLong(ToLong first, long second) {
        class LongPlusLong extends AbstractPlusLong> implements ToLong {
            private LongPlusLong(ToLong first, long second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsLong(object) + secondInner;
            }
        }

        return new LongPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longPlusInt(ToLong first, ToInt second) {
        class LongPlusInt extends AbstractPlus, ToInt> implements ToLong {
            private LongPlusInt(ToLong first, ToInt second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsLong(object)
                    + secondInner.applyAsInt(object);
            }
        }

        return new LongPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longPlusLong(ToLong first, ToLong second) {
        class LongPlusLong extends AbstractPlus, ToLong> implements ToLong {
            private LongPlusLong(ToLong first, ToLong second) {
                super(first, second);
            }

            @Override
            public long applyAsLong(T object) {
                return firstInner.applyAsLong(object)
                    + secondInner.applyAsLong(object);
            }
        }

        return new LongPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatPlusInt(ToFloat first, int second) {
        class FloatPlusInt extends AbstractPlusInt> implements ToFloat {
            private FloatPlusInt(ToFloat first, int second) {
                super(first, second);
            }

            @Override
            public float applyAsFloat(T object) {
                return firstInner.applyAsFloat(object) + secondInner;
            }
        }

        return new FloatPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble floatPlusLong(ToFloat first, long second) {
        class FloatPlusLong extends AbstractPlusLong> implements ToDouble {
            private FloatPlusLong(ToFloat first, long second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsFloat(object) + secondInner;
            }
        }

        return new FloatPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatPlusFloat(ToFloat first, float second) {
        class FloatPlusFloat extends AbstractPlusFloat> implements ToFloat {
            private FloatPlusFloat(ToFloat first, float second) {
                super(first, second);
            }

            @Override
            public float applyAsFloat(T object) {
                return firstInner.applyAsFloat(object) + secondInner;
            }
        }

        return new FloatPlusFloat(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatPlusInt(ToFloat first, ToInt second) {
        class FloatPlusInt extends AbstractPlus, ToInt> implements ToFloat {
            private FloatPlusInt(ToFloat first, ToInt second) {
                super(first, second);
            }

            @Override
            public float applyAsFloat(T object) {
                return firstInner.applyAsFloat(object)
                    + secondInner.applyAsInt(object);
            }
        }

        return new FloatPlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble floatPlusLong(ToFloat first, ToLong second) {
        class FloatPlusLong extends AbstractPlus, ToLong> implements ToDouble {
            private FloatPlusLong(ToFloat first, ToLong second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsFloat(object)
                    + secondInner.applyAsLong(object);
            }
        }

        return new FloatPlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatPlusFloat(ToFloat first, ToFloat second) {
        class FloatPlusFloat extends AbstractPlus, ToFloat> implements ToFloat {
            private FloatPlusFloat(ToFloat first, ToFloat second) {
                super(first, second);
            }

            @Override
            public float applyAsFloat(T object) {
                return firstInner.applyAsFloat(object)
                    + secondInner.applyAsFloat(object);
            }
        }

        return new FloatPlusFloat(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusInt(ToDouble first, int second) {
        class DoublePlusInt extends AbstractPlusInt> implements ToDouble {
            private DoublePlusInt(ToDouble first, int second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object) + secondInner;
            }
        }

        return new DoublePlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusLong(ToDouble first, long second) {
        class DoublePlusLong extends AbstractPlusLong> implements ToDouble {
            private DoublePlusLong(ToDouble first, long second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object) + secondInner;
            }
        }

        return new DoublePlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and adds a constant to it.
     *
     * @param first   the first input expression
     * @param second  the second input constant
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusDouble(ToDouble first, double second) {
        class DoublePlusDouble extends AbstractPlusDouble> implements ToDouble {
            private DoublePlusDouble(ToDouble first, double second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object) + secondInner;
            }
        }

        return new DoublePlusDouble(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusInt(ToDouble first, ToInt second) {
        class DoublePlusInt extends AbstractPlus, ToInt> implements ToDouble {
            private DoublePlusInt(ToDouble first, ToInt second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object)
                    + secondInner.applyAsInt(object);
            }
        }

        return new DoublePlusInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusLong(ToDouble first, ToLong second) {
        class DoublePlusLong extends AbstractPlus, ToLong> implements ToDouble {
            private DoublePlusLong(ToDouble first, ToLong second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object)
                    + secondInner.applyAsLong(object);
            }
        }

        return new DoublePlusLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and add them together.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doublePlusDouble(ToDouble first, ToDouble second) {
        class DoublePlusDouble extends AbstractPlus, ToDouble> implements ToDouble {
            private DoublePlusDouble(ToDouble first, ToDouble second) {
                super(first, second);
            }

            @Override
            public double applyAsDouble(T object) {
                return firstInner.applyAsDouble(object)
                    + secondInner.applyAsDouble(object);
            }
        }

        return new DoublePlusDouble(first, second);
    }

    /**
     * Abstract base for a plus operation.
     *
     * @param        the input entity type
     * @param    the first operand expression type
     * @param   the second operand expression type
     */
    private static abstract class AbstractPlus, SECOND extends Expression>
    implements BinaryExpression {

        final FIRST firstInner;
        final SECOND secondInner;

        private AbstractPlus(FIRST first, SECOND second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = requireNonNull(second);
        }

        @Override
        public final FIRST first() {
            return firstInner;
        }

        @Override
        public final SECOND second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryExpression)) return false;
            final BinaryExpression that = (BinaryExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Abstract base for a plus operation that takes a {@code byte} as the
     * second operand.
     *
     * @param       the input entity type
     * @param   the first operand expression type
     */
    private static abstract class AbstractPlusByte>
    implements BinaryObjExpression {

        final INNER firstInner;
        final byte secondInner;

        private AbstractPlusByte(INNER first, byte second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = second;
        }

        @Override
        public final INNER first() {
            return firstInner;
        }

        @Override
        public final Byte second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryObjExpression)) return false;
            final BinaryObjExpression that = (BinaryObjExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Abstract base for a plus operation that takes an {@code int} as the
     * second operand.
     *
     * @param       the input entity type
     * @param   the first operand expression type
     */
    private static abstract class AbstractPlusInt>
    implements BinaryObjExpression {

        final INNER firstInner;
        final int secondInner;

        private AbstractPlusInt(INNER first, int second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = second;
        }

        @Override
        public final INNER first() {
            return firstInner;
        }

        @Override
        public final Integer second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryObjExpression)) return false;
            final BinaryObjExpression that = (BinaryObjExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Abstract base for a plus operation that takes a {@code long} as the
     * second operand.
     *
     * @param       the input entity type
     * @param   the first operand expression type
     */
    private static abstract class AbstractPlusLong>
    implements BinaryObjExpression {

        final INNER firstInner;
        final long secondInner;

        private AbstractPlusLong(INNER first, long second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = second;
        }

        @Override
        public final INNER first() {
            return firstInner;
        }

        @Override
        public final Long second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryObjExpression)) return false;
            final BinaryObjExpression that = (BinaryObjExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Abstract base for a plus operation that takes a {@code float} as the
     * second operand.
     *
     * @param       the input entity type
     * @param   the first operand expression type
     */
    private static abstract class AbstractPlusFloat>
    implements BinaryObjExpression {

        final INNER firstInner;
        final float secondInner;

        private AbstractPlusFloat(INNER first, float second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = second;
        }

        @Override
        public final INNER first() {
            return firstInner;
        }

        @Override
        public final Float second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryObjExpression)) return false;
            final BinaryObjExpression that = (BinaryObjExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Abstract base for a plus operation that takes a {@code double} as the
     * second operand.
     *
     * @param       the input type
     * @param   the first operand expression type
     */
    private static abstract class AbstractPlusDouble>
    implements BinaryObjExpression {

        final INNER firstInner;
        final double secondInner;

        private AbstractPlusDouble(INNER first, double second) {
            this.firstInner  = requireNonNull(first);
            this.secondInner = second;
        }

        @Override
        public final INNER first() {
            return firstInner;
        }

        @Override
        public final Double second() {
            return secondInner;
        }

        @Override
        public final Operator operator() {
            return Operator.PLUS;
        }

        @Override
        public final boolean equals(Object o) {
            if (o == null) return false;
            else if (this == o) return true;
            else if (!(o instanceof BinaryObjExpression)) return false;
            final BinaryObjExpression that = (BinaryObjExpression) o;
            return Objects.equals(firstInner, that.first()) &&
                Objects.equals(secondInner, that.second()) &&
                Objects.equals(operator(), that.operator());
        }

        @Override
        public final int hashCode() {
            return Objects.hash(firstInner, secondInner, operator());
        }
    }

    /**
     * Utility classes should not be instantiated.
     */
    private PlusUtil() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy