Val.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-7.1.0).
003  * Copyright (c) 2007-2022 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.prog.op;
021 
022 import static java.lang.Double.doubleToLongBits;
023 import static java.lang.Float.floatToIntBits;
024 
025 import java.math.BigDecimal;
026 import java.math.BigInteger;
027 import java.util.Objects;
028 
029 /**
030  * This is the <em>sealed</em> base class for unmodifiable values. The only
031  * subclasses of this type are {@link Const} and {@link EphemeralConst}.
032  *
033  @see Const
034  @see EphemeralConst
035  *
036  @param <T> the type of the constant value
037  *
038  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
039  @version 7.0
040  @since 5.0
041  */
042 public abstract sealed class Val<T>
043     implements Op<T>
044     permits Const, EphemeralConst
045 {
046 
047     private final String _name;
048 
049     Val(final String name) {
050         _name = name;
051     }
052 
053     @Override
054     public final String name() {
055         return _name;
056     }
057 
058     /**
059      * Return the constant value.
060      *
061      @return the constant value
062      */
063     public abstract T value();
064 
065     /**
066      * The apply method will always return the {@link #value()}.
067      *
068      @param value the input parameters will be ignored
069      @return always {@link #value()}
070      */
071     @Override
072     public final T apply(final T[] value) {
073         return value();
074     }
075 
076     /**
077      * The arity of {@code Val} objects is always zero.
078      *
079      @return always zero
080      */
081     @Override
082     public final int arity() {
083         return 0;
084     }
085 
086     @Override
087     public final int hashCode() {
088         return Objects.hashCode(value());
089     }
090 
091     @Override
092     public final boolean equals(final Object obj) {
093         return obj == this ||
094             obj instanceof Val<?> other &&
095             equals(other.value(), value());
096     }
097 
098     private static boolean equals(final Object a, final Object b) {
099         if (instanceof Double aa && b instanceof Double bb) {
100             return doubleToLongBits(aa== doubleToLongBits(bb);
101         else if (instanceof Float aa && b instanceof Float bb) {
102             return floatToIntBits(aa== floatToIntBits(bb);
103         else if (instanceof BigDecimal aa && b instanceof BigDecimal bb) {
104             return aa.compareTo(bb== 0;
105         else if (instanceof BigInteger aa && b instanceof BigInteger bb) {
106             return aa.compareTo(bb== 0;
107         }
108 
109         return Objects.equals(a, b);
110     }
111 
112 }