001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2025 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
012 * specific language governing permissions and limitations under the License.
013 */
014package org.microbean.attributes;
015
016import java.lang.constant.ClassDesc;
017import java.lang.constant.ConstantDesc;
018import java.lang.constant.DynamicConstantDesc;
019import java.lang.constant.MethodHandleDesc;
020import java.lang.constant.MethodTypeDesc;
021
022import java.util.Optional;
023
024import static java.lang.constant.ConstantDescs.BSM_INVOKE;
025import static java.lang.constant.ConstantDescs.CD_double;
026import static java.lang.constant.DirectMethodHandleDesc.Kind.STATIC;
027
028/**
029 * A {@link Value} whose value is a {@code double}.
030 *
031 * @param value the value
032 *
033 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a>
034 */
035public final record DoubleValue(double value) implements Value<DoubleValue> {
036
037  @Override // Comparable<DoubleValue>
038  public final int compareTo(final DoubleValue other) {
039    if (other == null) {
040      return -1;
041    } else if (this.equals(other)) {
042      return 0;
043    }
044    return this.value() > other.value() ? 1 : -1;
045  }
046
047  @Override // Constable
048  public final Optional<DynamicConstantDesc<DoubleValue>> describeConstable() {
049    final ClassDesc cd = ClassDesc.of(this.getClass().getName());
050    return
051      Optional.of(DynamicConstantDesc.of(BSM_INVOKE,
052                                         MethodHandleDesc.ofMethod(STATIC,
053                                                                   cd,
054                                                                   "of",
055                                                                   MethodTypeDesc.of(cd,
056                                                                                     CD_double)),
057                                         Double.valueOf(this.value())));
058  }
059
060  @Override // Record
061  public final boolean equals(final Object other) {
062    return
063      other == this ||
064      // Follow java.lang.annotation.Annotation requirements.
065      other != null && other.getClass() == this.getClass() && Double.valueOf(this.value()).equals(Double.valueOf(((DoubleValue)other).value()));
066  }
067
068  @Override // Record
069  public final int hashCode() {
070    // Follow java.lang.annotation.Annotation requirements.
071    return Double.valueOf(this.value()).hashCode();
072  }
073
074  @Override // Record
075  public final String toString() {
076    return String.valueOf(this.value());
077  }
078
079  /**
080   * Returns a {@link DoubleValue} suitable for the supplied arguments.
081   *
082   * @param d a {@code double}
083   *
084   * @return a non-{@code null} {@link DoubleValue}
085   */
086  public static final DoubleValue of(final double d) {
087    return new DoubleValue(d);
088  }
089
090}