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

com.speedment.runtime.compute.internal.expression.MultiplyUtil 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 MultiplyUtil {

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 byteMultiplyByte(ToByte first, byte second) {
        class ByteMultiplyByte extends AbstractMultiplyByte> implements ToInt {
            private ByteMultiplyByte(ToByte first, byte second) {
                super(first, second);
            }

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

        return new ByteMultiplyByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 byteMultiplyInt(ToByte first, int second) {
        class ByteMultiplyInt extends AbstractMultiplyInt> implements ToInt {
            private ByteMultiplyInt(ToByte first, int second) {
                super(first, second);
            }

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

        return new ByteMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 byteMultiplyLong(ToByte first, long second) {
        class ByteMultiplyLong extends AbstractMultiplyLong> implements ToLong {
            private ByteMultiplyLong(ToByte first, long second) {
                super(first, second);
            }

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

        return new ByteMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt byteMultiplyByte(ToByte first, ToByte second) {
        class ByteMultiplyByte extends AbstractMultiply, ToByte> implements ToInt {
            private ByteMultiplyByte(ToByte first, ToByte second) {
                super(first, second);
            }

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

        return new ByteMultiplyByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 shortMultiplyByte(ToShort first, byte second) {
        class ShortMultiplyShort extends AbstractMultiplyByte> implements ToInt {
            private ShortMultiplyShort(ToShort first, byte second) {
                super(first, second);
            }

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

        return new ShortMultiplyShort(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 shortMultiplyInt(ToShort first, int second) {
        class ShortMultiplyInt extends AbstractMultiplyInt> implements ToInt {
            private ShortMultiplyInt(ToShort first, int second) {
                super(first, second);
            }

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

        return new ShortMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 shortMultiplyLong(ToShort first, long second) {
        class ShortMultiplyLong extends AbstractMultiplyLong> implements ToLong {
            private ShortMultiplyLong(ToShort first, long second) {
                super(first, second);
            }

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

        return new ShortMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt shortMultiplyShort(ToShort first, ToShort second) {
        class ShortMultiplyShort extends AbstractMultiply, ToShort> implements ToInt {
            private ShortMultiplyShort(ToShort first, ToShort second) {
                super(first, second);
            }

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

        return new ShortMultiplyShort(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 intMultiplyByte(ToInt first, byte second) {
        class IntMultiplyByte extends AbstractMultiplyByte> implements ToInt {
            private IntMultiplyByte(ToInt first, byte second) {
                super(first, second);
            }

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

        return new IntMultiplyByte(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 intMultiplyInt(ToInt first, int second) {
        class IntMultiplyInt extends AbstractMultiplyInt> implements ToInt {
            private IntMultiplyInt(ToInt first, int second) {
                super(first, second);
            }

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

        return new IntMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 intMultiplyLong(ToInt first, long second) {
        class IntMultiplyLong extends AbstractMultiplyLong> implements ToLong {
            private IntMultiplyLong(ToInt first, long second) {
                super(first, second);
            }

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

        return new IntMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intMultiplyByte(ToInt first, ToByte second) {
        class IntMultiplyByte extends AbstractMultiply, ToByte> implements ToInt {
            private IntMultiplyByte(ToInt first, ToByte second) {
                super(first, second);
            }

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

        return new IntMultiplyByte(first, second);
    }


    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToInt intMultiplyInt(ToInt first, ToInt second) {
        class IntMultiplyInt extends AbstractMultiply, ToInt> implements ToInt {
            private IntMultiplyInt(ToInt first, ToInt second) {
                super(first, second);
            }

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

        return new IntMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 longMultiplyByte(ToLong first, byte second) {
        class LongMultiplyLong extends AbstractMultiplyByte> implements ToLong {
            private LongMultiplyLong(ToLong first, byte second) {
                super(first, second);
            }

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

        return new LongMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 longMultiplyInt(ToLong first, int second) {
        class LongMultiplyInt extends AbstractMultiplyInt> implements ToLong {
            private LongMultiplyInt(ToLong first, int second) {
                super(first, second);
            }

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

        return new LongMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 longMultiplyLong(ToLong first, long second) {
        class LongMultiplyLong extends AbstractMultiplyLong> implements ToLong {
            private LongMultiplyLong(ToLong first, long second) {
                super(first, second);
            }

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

        return new LongMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longMultiplyInt(ToLong first, ToInt second) {
        class LongMultiplyInt extends AbstractMultiply, ToInt> implements ToLong {
            private LongMultiplyInt(ToLong first, ToInt second) {
                super(first, second);
            }

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

        return new LongMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToLong longMultiplyLong(ToLong first, ToLong second) {
        class LongMultiplyLong extends AbstractMultiply, ToLong> implements ToLong {
            private LongMultiplyLong(ToLong first, ToLong second) {
                super(first, second);
            }

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

        return new LongMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 floatMultiplyInt(ToFloat first, int second) {
        class FloatMultiplyInt extends AbstractMultiplyInt> implements ToFloat {
            private FloatMultiplyInt(ToFloat first, int second) {
                super(first, second);
            }

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

        return new FloatMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 floatMultiplyLong(ToFloat first, long second) {
        class FloatMultiplyLong extends AbstractMultiplyLong> implements ToDouble {
            private FloatMultiplyLong(ToFloat first, long second) {
                super(first, second);
            }

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

        return new FloatMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 floatMultiplyFloat(ToFloat first, float second) {
        class FloatMultiplyFloat extends AbstractMultiplyFloat> implements ToFloat {
            private FloatMultiplyFloat(ToFloat first, float second) {
                super(first, second);
            }

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

        return new FloatMultiplyFloat(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatMultiplyInt(ToFloat first, ToInt second) {
        class FloatMultiplyInt extends AbstractMultiply, ToInt> implements ToFloat {
            private FloatMultiplyInt(ToFloat first, ToInt second) {
                super(first, second);
            }

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

        return new FloatMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble floatMultiplyLong(ToFloat first, ToLong second) {
        class FloatMultiplyLong extends AbstractMultiply, ToLong> implements ToDouble {
            private FloatMultiplyLong(ToFloat first, ToLong second) {
                super(first, second);
            }

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

        return new FloatMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToFloat floatMultiplyFloat(ToFloat first, ToFloat second) {
        class FloatMultiplyFloat extends AbstractMultiply, ToFloat> implements ToFloat {
            private FloatMultiplyFloat(ToFloat first, ToFloat second) {
                super(first, second);
            }

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

        return new FloatMultiplyFloat(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 doubleMultiplyInt(ToDouble first, int second) {
        class DoubleMultiplyInt extends AbstractMultiplyInt> implements ToDouble {
            private DoubleMultiplyInt(ToDouble first, int second) {
                super(first, second);
            }

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

        return new DoubleMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 doubleMultiplyLong(ToDouble first, long second) {
        class DoubleMultiplyLong extends AbstractMultiplyLong> implements ToDouble {
            private DoubleMultiplyLong(ToDouble first, long second) {
                super(first, second);
            }

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

        return new DoubleMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the expression
     * and multiplies 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 doubleMultiplyDouble(ToDouble first, double second) {
        class DoubleMultiplyDouble extends AbstractMultiplyDouble> implements ToDouble {
            private DoubleMultiplyDouble(ToDouble first, double second) {
                super(first, second);
            }

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

        return new DoubleMultiplyDouble(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doubleMultiplyInt(ToDouble first, ToInt second) {
        class DoubleMultiplyInt extends AbstractMultiply, ToInt> implements ToDouble {
            private DoubleMultiplyInt(ToDouble first, ToInt second) {
                super(first, second);
            }

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

        return new DoubleMultiplyInt(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doubleMultiplyLong(ToDouble first, ToLong second) {
        class DoubleMultiplyLong extends AbstractMultiply, ToLong> implements ToDouble {
            private DoubleMultiplyLong(ToDouble first, ToLong second) {
                super(first, second);
            }

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

        return new DoubleMultiplyLong(first, second);
    }

    /**
     * Creates and returns an expression that takes the result of the two
     * expressions and multiplies them to get the product.
     *
     * @param first   the first input expression
     * @param second  the second input expression
     * @param      the input type
     * @return        the new expression
     */
    public static  ToDouble doubleMultiplyDouble(ToDouble first, ToDouble second) {
        class DoubleMultiplyDouble extends AbstractMultiply, ToDouble> implements ToDouble {
            private DoubleMultiplyDouble(ToDouble first, ToDouble second) {
                super(first, second);
            }

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

        return new DoubleMultiplyDouble(first, second);
    }

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

        final FIRST firstInner;
        final SECOND secondInner;

        private AbstractMultiply(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.MULTIPLY;
        }

        @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 multiply operation that takes a {@code byte} as the
     * second operand.
     *
     * @param   the first operand expression type
     */
    private static abstract class AbstractMultiplyByte>
    implements BinaryObjExpression {

        final INNER firstInner;
        final byte secondInner;

        private AbstractMultiplyByte(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.MULTIPLY;
        }

        @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 multiply operation that takes an {@code int} as the
     * second operand.
     *
     * @param       the input type
     * @param   the first operand expression type
     */
    private static abstract class AbstractMultiplyInt>
    implements BinaryObjExpression {

        final INNER firstInner;
        final int secondInner;

        private AbstractMultiplyInt(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.MULTIPLY;
        }

        @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 multiply operation that takes a {@code long} as the
     * second operand.
     *
     * @param       the input type
     * @param   the first operand expression type
     */
    private static abstract class AbstractMultiplyLong>
    implements BinaryObjExpression {

        final INNER firstInner;
        final long secondInner;

        private AbstractMultiplyLong(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.MULTIPLY;
        }

        @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 multiply operation that takes a {@code float} as the
     * second operand.
     *
     * @param       the input type
     * @param   the first operand expression type
     */
    private static abstract class AbstractMultiplyFloat>
    implements BinaryObjExpression {

        final INNER firstInner;
        final float secondInner;

        private AbstractMultiplyFloat(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.MULTIPLY;
        }

        @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 multiply operation that takes a {@code double} as the
     * second operand.
     *
     * @param       the input type
     * @param   the first operand expression type
     */
    private static abstract class AbstractMultiplyDouble>
    implements BinaryObjExpression {

        final INNER firstInner;
        final double secondInner;

        private AbstractMultiplyDouble(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.MULTIPLY;
        }

        @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 MultiplyUtil() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy