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.ConstantDescs; 019import java.lang.constant.DynamicConstantDesc; 020import java.lang.constant.MethodHandleDesc; 021import java.lang.constant.MethodTypeDesc; 022 023import java.util.Optional; 024 025import static java.lang.constant.ConstantDescs.BSM_INVOKE; 026import static java.lang.constant.ConstantDescs.CD_boolean; 027import static java.lang.constant.DirectMethodHandleDesc.Kind.STATIC; 028 029/** 030 * A {@link Value} whose value is a {@code boolean}. 031 * 032 * @param value the value 033 * 034 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a> 035 */ 036public final record BooleanValue(boolean value) implements Value<BooleanValue> { 037 038 /** 039 * The {@link BooleanValue} representing {@code true}. 040 */ 041 public static final BooleanValue TRUE = new BooleanValue(true); 042 043 /** 044 * The {@link BooleanValue} representing {@code false}. 045 */ 046 public static final BooleanValue FALSE = new BooleanValue(false); 047 048 @Override // Comparable<Value> 049 public final int compareTo(BooleanValue other) { 050 if (other == null) { 051 return -1; 052 } else if (this.equals(other)) { 053 return 0; 054 } else if (this.value()) { 055 return 1; // false comes first 056 } else { 057 return -1; 058 } 059 } 060 061 @Override // Constable 062 public final Optional<DynamicConstantDesc<BooleanValue>> describeConstable() { 063 final ClassDesc cd = ClassDesc.of(this.getClass().getName()); 064 return 065 Optional.of(DynamicConstantDesc.of(BSM_INVOKE, 066 MethodHandleDesc.ofMethod(STATIC, 067 cd, 068 "of", 069 MethodTypeDesc.of(cd, 070 CD_boolean)), 071 this.value() ? ConstantDescs.TRUE : ConstantDescs.FALSE)); 072 } 073 074 @Override // Record 075 public final boolean equals(final Object other) { 076 return 077 other == this || 078 // Follow java.lang.annotation.Annotation requirements 079 other != null && other.getClass() == this.getClass() && this.value() == ((BooleanValue)other).value(); 080 } 081 082 @Override // Record 083 public final int hashCode() { 084 // Follow java.lang.annotation.Annotation requirements. 085 return Boolean.valueOf(this.value()).hashCode(); 086 } 087 088 @Override // Record 089 public final String toString() { 090 return String.valueOf(this.value()); 091 } 092 093 /** 094 * Returns a {@link BooleanValue} suitable for the supplied arguments. 095 * 096 * @param b a {@code boolean} 097 * 098 * @return {@link TRUE} if {@code b} is {@code true}; {@link FALSE} otherwise 099 */ 100 public static final BooleanValue of(final boolean b) { 101 return b ? TRUE : FALSE; 102 } 103 104}