001/**
002 * The MIT License (MIT)
003 *
004 * Copyright (c) 2015-2016 decimal4j (tools4j), Marco Terzer
005 *
006 * Permission is hereby granted, free of charge, to any person obtaining a copy
007 * of this software and associated documentation files (the "Software"), to deal
008 * in the Software without restriction, including without limitation the rights
009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010 * copies of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 *
013 * The above copyright notice and this permission notice shall be included in all
014 * copies or substantial portions of the Software.
015 *
016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022 * SOFTWARE.
023 */
024package org.decimal4j.factory;
025
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029
030import org.decimal4j.scale.ScaleMetrics;
031import org.decimal4j.factory.Factory0f;
032import org.decimal4j.factory.Factory10f;
033import org.decimal4j.factory.Factory11f;
034import org.decimal4j.factory.Factory12f;
035import org.decimal4j.factory.Factory13f;
036import org.decimal4j.factory.Factory14f;
037import org.decimal4j.factory.Factory15f;
038import org.decimal4j.factory.Factory16f;
039import org.decimal4j.factory.Factory17f;
040import org.decimal4j.factory.Factory18f;
041import org.decimal4j.factory.Factory1f;
042import org.decimal4j.factory.Factory2f;
043import org.decimal4j.factory.Factory3f;
044import org.decimal4j.factory.Factory4f;
045import org.decimal4j.factory.Factory5f;
046import org.decimal4j.factory.Factory6f;
047import org.decimal4j.factory.Factory7f;
048import org.decimal4j.factory.Factory8f;
049import org.decimal4j.factory.Factory9f;
050import org.decimal4j.generic.GenericDecimalFactory;
051
052/**
053 * Utility class with static methods to access {@link DecimalFactory} instances.
054 */
055public final class Factories {
056
057        //@formatter:off
058        private static final DecimalFactory<?>[] FACTORIES = {
059                Factory0f.INSTANCE,
060                Factory1f.INSTANCE,
061                Factory2f.INSTANCE,
062                Factory3f.INSTANCE,
063                Factory4f.INSTANCE,
064                Factory5f.INSTANCE,
065                Factory6f.INSTANCE,
066                Factory7f.INSTANCE,
067                Factory8f.INSTANCE,
068                Factory9f.INSTANCE,
069                Factory10f.INSTANCE,
070                Factory11f.INSTANCE,
071                Factory12f.INSTANCE,
072                Factory13f.INSTANCE,
073                Factory14f.INSTANCE,
074                Factory15f.INSTANCE,
075                Factory16f.INSTANCE,
076                Factory17f.INSTANCE,
077                Factory18f.INSTANCE
078        };
079        //@formatter:on
080        
081        private static final GenericDecimalFactory<?>[] GENERIC_FACTORIES = initGenericFactories();
082
083        private static final GenericDecimalFactory<?>[] initGenericFactories() {
084                final GenericDecimalFactory<?>[] genericFactories = new GenericDecimalFactory<?>[FACTORIES.length];
085                for (int i = 0; i < FACTORIES.length; i++) {
086                        genericFactories[i] = new GenericDecimalFactory<ScaleMetrics>(FACTORIES[i].getScaleMetrics());
087                }
088                return genericFactories;
089        }
090
091        /**
092         * All decimal factory constants in an immutable ordered list:
093         * <br>
094         * {@code VALUES=[Factory0f.INSTANCE, Factory1f.INSTANCE, ..., Factory18f.INSTANCE]}
095         */
096        public static final List<DecimalFactory<?>> VALUES = Collections.unmodifiableList(Arrays.asList(FACTORIES));
097
098        /**
099         * Returns the {@code DecimalFactory} constant based on a given scale.
100         * 
101         * @param scale
102         *            the scale value; must be in {@code [0,18]} both ends inclusive
103         * @return the factory constant corresponding to {@code scale}
104         * @throws IllegalArgumentException
105         *             if scale is not in {@code [0, 18]}
106         */
107        public static final DecimalFactory<?> getDecimalFactory(int scale) {
108                if (0 <= scale & scale <= 18) {
109                        return FACTORIES[scale];
110                }
111                throw new IllegalArgumentException("Illegal scale, must be in [0,18] but was: " + scale);
112        }
113
114        /**
115         * Returns the {@code DecimalFactory} for the given scale metrics.
116         * 
117         * @param scaleMetrics
118         *            the scale metrics
119         * @param <S> the generic type for {@code scaleMetrics}
120         * @return the factory constant corresponding to {@code scaleMetrics}
121         */
122        public static final <S extends ScaleMetrics> DecimalFactory<S> getDecimalFactory(S scaleMetrics) {
123                @SuppressWarnings("unchecked")
124                final DecimalFactory<S> factory = (DecimalFactory<S>)getDecimalFactory(scaleMetrics.getScale());
125                return factory;
126        }
127
128        /**
129         * Returns the {@code GenericDecimalFactory} based on a given scale.
130         * 
131         * @param scale
132         *            the scale value; must be in {@code [0,18]} both ends inclusive
133         * @return the generic factory corresponding to {@code scale}
134         * @throws IllegalArgumentException
135         *             if scale is not in {@code [0, 18]}
136         */
137        public static final GenericDecimalFactory<?> getGenericDecimalFactory(int scale) {
138                if (0 <= scale & scale <= 18) {
139                        return GENERIC_FACTORIES[scale];
140                }
141                throw new IllegalArgumentException("Illegal scale, must be in [0,18] but was: " + scale);
142        }
143
144        /**
145         * Returns the {@code GenericDecimalFactory} for the given scale metrics.
146         * 
147         * @param scaleMetrics
148         *            the scale metrics
149         * @param <S> the generic type for {@code scaleMetrics}
150         * @return the generic factory corresponding to {@code scaleMetrics}
151         */
152        public static final <S extends ScaleMetrics> GenericDecimalFactory<S> getGenericDecimalFactory(S scaleMetrics) {
153                @SuppressWarnings("unchecked")
154                final GenericDecimalFactory<S> factory = (GenericDecimalFactory<S>)getGenericDecimalFactory(scaleMetrics.getScale());
155                return factory;
156        }
157
158        //no instances
159        private Factories() {
160                super();
161        }
162}