001/*
002 * Units of Measurement Reference Implementation
003 * Copyright (c) 2005-2021, Jean-Marie Dautelle, Werner Keil, Otavio Santana.
004 *
005 * All rights reserved.
006 *
007 * Redistribution and use in source and binary forms, with or without modification,
008 * are permitted provided that the following conditions are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright notice,
011 *    this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
014 *    and the following disclaimer in the documentation and/or other materials provided with the distribution.
015 *
016 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products
017 *    derived from this software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package tech.units.indriya.quantity;
031
032import static javax.measure.Quantity.Scale.ABSOLUTE;
033
034import javax.measure.Quantity;
035import javax.measure.Unit;
036
037import tech.units.indriya.AbstractQuantity;
038import tech.units.indriya.ComparableQuantity;
039import tech.units.indriya.internal.function.Calculator;
040import tech.units.indriya.internal.function.ScaleHelper;
041
042/**
043 * Implementation of {@link ComparableQuantity} that holds a Java {@link Number}, 
044 * which represented this quantity's amount.
045 * <p> 
046 * This object is immutable.
047 * <p>
048 *
049 * @see AbstractQuantity
050 * @see Quantity
051 * @see ComparableQuantity
052 * @param <Q>
053 *          The type of the quantity.
054 * @author Andi Huber
055 * @author Werner Keil
056 * @version 2.1, Feb 16, 2021
057 * @since 1.0
058 * 
059 */
060public final class NumberQuantity<Q extends Quantity<Q>> extends AbstractQuantity<Q> {
061
062    private static final long serialVersionUID = -6494337491031528402L;
063    
064    private final Number value;
065
066    /**
067     * @since 2.0
068     */
069    protected NumberQuantity(Number number, Unit<Q> unit, Scale sc) {
070      super(unit, sc);
071      value = Calculator.of(number).peek(); // takes care of invalid number values (infinity, ...)
072    }
073    
074    protected NumberQuantity(Number number, Unit<Q> unit) {
075        this(number, unit, ABSOLUTE); 
076    }
077
078    @Override
079    public ComparableQuantity<Q> add(Quantity<Q> that) {
080        return ScaleHelper.addition(this, that, 
081                (thisValue, thatValue) -> Calculator.of(thisValue).add(thatValue).peek());
082    }
083
084    @Override
085    public ComparableQuantity<Q> subtract(Quantity<Q> that) {
086        return ScaleHelper.addition(this, that, 
087                (thisValue, thatValue) -> Calculator.of(thisValue).subtract(thatValue).peek());
088    }
089
090    @Override
091    public ComparableQuantity<?> divide(Quantity<?> that) {
092        return ScaleHelper.multiplication(this, that, 
093                (thisValue, thatValue) -> Calculator.of(thisValue).divide(thatValue).peek(),
094                (thisUnit, thatUnit) -> thisUnit.divide(thatUnit));
095    }
096
097    @Override
098    public ComparableQuantity<Q> divide(Number divisor) {
099        return ScaleHelper.scalarMultiplication(this, thisValue -> 
100                Calculator.of(thisValue).divide(divisor).peek());
101    }
102
103    @Override
104    public ComparableQuantity<?> multiply(Quantity<?> that) {
105        return ScaleHelper.multiplication(this, that, 
106                (thisValue, thatValue) -> Calculator.of(thisValue).multiply(thatValue).peek(),
107                (thisUnit, thatUnit) -> thisUnit.multiply(thatUnit));
108    }
109
110    @Override
111    public ComparableQuantity<Q> multiply(Number factor) {
112        return ScaleHelper.scalarMultiplication(this, thisValue -> 
113                Calculator.of(thisValue).multiply(factor).peek());
114    }
115
116    @Override
117    public ComparableQuantity<?> inverse() {
118        final Number resultValueInThisUnit = Calculator
119                .of(getValue())
120                .reciprocal()
121                .peek();
122        return Quantities.getQuantity(resultValueInThisUnit, getUnit().inverse(), getScale());
123    }
124
125    @Override
126    public Quantity<Q> negate() {
127        final Number resultValueInThisUnit = Calculator
128                .of(getValue())
129                .negate()
130                .peek();
131        return Quantities.getQuantity(resultValueInThisUnit, getUnit(), getScale());
132    }
133
134    @Override
135    public Number getValue() {
136        return value;
137    }
138    
139    
140
141}