001/**
002 * Constant.java
003 * 
004 * Copyright (c) 2004-2012, Nicole C. Tedesco. All rights reserved.
005 * 
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007 * use this file except in compliance with the License. You may obtain a copy of
008 * the License at:
009 * 
010 * http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015 * License for the specific language governing permissions and limitations under
016 * the License.
017 */
018
019package net.sf.jaccumulator.primitives;
020
021import java.math.BigDecimal;
022import java.math.BigInteger;
023import java.text.NumberFormat;
024import java.text.ParseException;
025import java.util.Iterator;
026import java.util.Map;
027import java.util.TreeMap;
028import java.util.concurrent.atomic.AtomicBoolean;
029import java.util.concurrent.atomic.AtomicInteger;
030import java.util.concurrent.atomic.AtomicLong;
031
032import net.sf.jaccumulator.Domain;
033import net.sf.jaccumulator.StructureStrategy;
034import net.sf.jaccumulator.lex.To;
035import net.sf.jaccumulator.reals.Real;
036import net.sf.jaccumulator.reals.SealedReal;
037import net.sf.jaccumulator.scalars.NumericPrecision;
038import net.sf.jaccumulator.scalars.Scalar;
039import net.sf.jaccumulator.scalars.SealedScalar;
040import net.sf.jupperware.ScalarIndexedCache;
041
042/**
043 * Read-only {@link Primitive primitive}
044 * 
045 * @since JAccumulator 4.0
046 * @author Nicole Tedesco (<a
047 *         href="mailto:Nicole@NicoleTedesco.com">Nicole@NicoleTedesco.com</a>)
048 */
049public final class Constant
050    extends
051        AbstractConstant<Constant>
052{
053    private static final BigInteger LONG_MAX_BIT_POSITION = BigInteger.valueOf(Long.SIZE - 1);
054    private static final int MAX_CACHE_VALUE = Byte.MAX_VALUE;
055    private static final BigInteger MAX_CACHE_VALUE_UNLIMITED_INTEGER = BigInteger.valueOf(MAX_CACHE_VALUE);
056    private static final BigDecimal MAX_UNLIMITED_DECIMAL = new BigDecimal(
057        String.valueOf(Double.MAX_VALUE));
058    private static final BigInteger MAX_UNLIMITED_INTEGER = BigInteger.valueOf(Long.MAX_VALUE);
059    private static final int MIN_CACHE_VALUE = Byte.MIN_VALUE;
060    private static final BigInteger MIN_CACHE_VALUE_UNLIMITED_INTEGER = BigInteger.valueOf(MIN_CACHE_VALUE);
061    private static final BigDecimal MIN_UNLIMITED_DECIMAL = new BigDecimal(
062        String.valueOf(Double.MIN_VALUE));
063    private static final BigInteger MIN_UNLIMITED_INTEGER = BigInteger.valueOf(Long.MIN_VALUE);
064    private static final long serialVersionUID = 3047165988982562478L;
065    private static final ScalarIndexedCache<Constant> theByteCache = new ScalarIndexedCache<Constant>(
066        MIN_CACHE_VALUE_UNLIMITED_INTEGER, MAX_CACHE_VALUE_UNLIMITED_INTEGER,
067        Constant.class);
068    private static final ScalarIndexedCache<Constant> theCharacterCache = new ScalarIndexedCache<Constant>(
069        MIN_CACHE_VALUE_UNLIMITED_INTEGER, MAX_CACHE_VALUE_UNLIMITED_INTEGER,
070        Constant.class);
071    private static final ScalarIndexedCache<Constant> theIntegerCache = new ScalarIndexedCache<Constant>(
072        MIN_CACHE_VALUE_UNLIMITED_INTEGER, MAX_CACHE_VALUE_UNLIMITED_INTEGER,
073        Constant.class);
074    private static final ScalarIndexedCache<Constant> theLongCache = new ScalarIndexedCache<Constant>(
075        MIN_CACHE_VALUE_UNLIMITED_INTEGER, MAX_CACHE_VALUE_UNLIMITED_INTEGER,
076        Constant.class);
077    private static final Map<String,Constant> theLowerCaseMap = new TreeMap<String,Constant>();
078    private static final ScalarIndexedCache<Constant> theMaskCache = new ScalarIndexedCache<Constant>(
079        BigInteger.ZERO, LONG_MAX_BIT_POSITION, Constant.class);
080    private static final ScalarIndexedCache<Constant> theNotMaskCache = new ScalarIndexedCache<Constant>(
081        BigInteger.ZERO, LONG_MAX_BIT_POSITION, Constant.class);
082    private static final Map<String,Constant> theOriginalCaseMap = new TreeMap<String,Constant>();
083    private static final ScalarIndexedCache<Constant> theShortCache = new ScalarIndexedCache<Constant>(
084        MIN_CACHE_VALUE_UNLIMITED_INTEGER, MAX_CACHE_VALUE_UNLIMITED_INTEGER,
085        Constant.class);
086
087    /**
088     * ASCII "back slash" {@code 0x005C}
089     */
090    public static final Constant BACK_SLASH = registerCharacterConstant(new Constant(
091        '\\'));
092
093    /**
094     * ASCII "carriage return" {@code 0x0008}
095     */
096    public static final Constant BACK_SPACE = registerCharacterConstant(new Constant(
097        '\b'));;
098
099    /**
100     * ASCII "carriage return" {@code 0x000D}
101     */
102    public static final Constant CARRIAGE_RETURN = registerCharacterConstant(new Constant(
103        '\r'));
104    /**
105     * ASCII "delete" {@code 0x007F}
106     */
107    public static final Constant DELETE = registerCharacterConstant(new Constant(
108        '\u007f'));
109
110    /**
111     * ASCII double quote {@code 0x0022}
112     */
113    public static final Constant DOUBLE_QUOTE = registerCharacterConstant(new Constant(
114        '\"'));
115
116    /**
117     * Napier's (Euler's) constant
118     * 
119     * @see <a href="http://www.research.att.com/~njas/sequences/">The On-Line
120     *      Encyclopedia of Integer Sequences</a> (AT&T)
121     */
122    public static final Constant E = registerNamedConstant("e", new Constant(
123        NumericPrecision.DOUBLE, Math.E,
124        new BigDecimal(String.valueOf(Math.E)), String.valueOf(Math.E)));
125
126    /**
127     * Eight (8)
128     */
129    public static final Constant EIGHT = registerIntegerConstant(new Constant(8));
130
131    /**
132     * An empty string ("")
133     */
134    public static final Constant EMPTY = registerNamedConstant("".intern(),
135        new Constant("".intern()));
136
137    public static final String EMPTYS = "".intern();
138
139    /**
140     * ASCII "escape" {@code 0x001B}
141     */
142    public static final Constant ESCAPE = registerCharacterConstant(new Constant(
143        '\u001b'));
144
145    /**
146     * Boolean {@link Boolean#FALSE FALSE}
147     */
148    public static final Constant FALSE = registerNamedConstant(
149        String.valueOf(false), new Constant(false));
150
151    /**
152     * Five (5)
153     */
154    public static final Constant FIVE = registerIntegerConstant(new Constant(5));
155
156    /**
157     * ASCII "form feed" {@code 0x000C}
158     */
159    public static final Constant FORM_FEED = registerCharacterConstant(new Constant(
160        '\f'));
161
162    /**
163     * Four (4)
164     */
165    public static final Constant FOUR = registerIntegerConstant(new Constant(4));
166
167    /**
168     * IEEE Not-a-Number
169     * 
170     * @see Double#NaN
171     * @see Float#NaN
172     */
173    public static final Constant INVALID = registerNamedConstant(
174        String.valueOf(Double.NaN), new Constant(
175        /* aPrecision */NumericPrecision.DOUBLE,
176        /* aBoolean */false,
177        /* aBooleanObject */Boolean.FALSE,
178        /* aByte */(byte)0,
179        /* aCharacter */Character.MIN_VALUE,
180        /* aCharacterObject */Character.valueOf(Character.MIN_VALUE),
181        /* aDouble */Double.NaN,
182        /* aFloat */Float.NaN,
183        /* anInteger */0,
184        /* aLong */0L,
185        /* aNumber */Double.valueOf(Double.NaN),
186        /* aShort */(short)0,
187        /* aString */String.valueOf(Double.NaN),
188        /* anUnlimitedDecimal */BigDecimal.ZERO,
189        /* anUnlimitedInteger */BigInteger.ZERO,
190        /* aHashCode */Double.valueOf(Double.NaN).hashCode(),
191        /* aSignum */(int)Math.signum(Double.NaN),
192        /* isInfinity */false,
193        /* isInvalid */true,
194        /* isMinimum */false,
195        /* isMaximum */false,
196        /* isNegative */(int)Math.signum(Double.NaN) < 0,
197        /* isNegativeInfinity */false,
198        /* isPositive */0 < (int)Math.signum(Double.NaN),
199        /* isPositiveInfinity */false,
200        /* isUnity */false,
201        /* isZero */false));
202
203    /**
204     * ASCII "line feed" {@code 0x000A}
205     */
206    public static final Constant LINE_FEED = registerCharacterConstant(new Constant(
207        '\n'));
208
209    /**
210     * System-dependent line {@link System#lineSeparator() separator}
211     */
212    public static final Constant LINE_SEPARATOR = new Constant(
213        System.lineSeparator());
214
215    /**
216     * Maximum values
217     */
218    public static final Constant MAXIMUM = registerNamedConstant(
219        "maximum",
220        new Constant(
221            NumericPrecision.DOUBLE, true, Boolean.TRUE, Byte.MAX_VALUE,
222            Character.MAX_VALUE, Character.valueOf(Character.MAX_VALUE),
223            Double.MAX_VALUE, Float.MAX_VALUE, Integer.MAX_VALUE,
224            Long.MAX_VALUE, MAX_UNLIMITED_DECIMAL, Short.MAX_VALUE, "maximum",
225            MAX_UNLIMITED_DECIMAL, MAX_UNLIMITED_INTEGER,
226            MAX_UNLIMITED_DECIMAL.hashCode(), MAX_UNLIMITED_DECIMAL.signum(),
227            false, false, true, false, false, false, true, false, false, false));
228
229    /**
230     * Minimum values
231     */
232    public static final Constant MINIMUM = registerNamedConstant(
233        "minimum",
234        new Constant(
235            NumericPrecision.DOUBLE, false, Boolean.FALSE, Byte.MIN_VALUE,
236            Character.MIN_VALUE, Character.valueOf(Character.MIN_VALUE),
237            Double.MIN_VALUE, Float.MIN_VALUE, Integer.MIN_VALUE,
238            Long.MIN_VALUE, MIN_UNLIMITED_DECIMAL, Short.MIN_VALUE, "minimum",
239            MIN_UNLIMITED_DECIMAL, MIN_UNLIMITED_INTEGER,
240            MIN_UNLIMITED_DECIMAL.hashCode(), MIN_UNLIMITED_DECIMAL.signum(),
241            false, false, false, true, true, false, false, false, false, false));
242
243    /**
244     * Negative infinity
245     * 
246     * @see Double#NEGATIVE_INFINITY
247     * @see Float#NEGATIVE_INFINITY
248     */
249    public static final Constant NEGATIVE_INFINITY = registerNamedConstant(
250        String.valueOf(Double.NEGATIVE_INFINITY),
251        new Constant(
252            NumericPrecision.DOUBLE, false, Boolean.FALSE, Byte.MIN_VALUE,
253            Character.MIN_VALUE, Character.valueOf(Character.MIN_VALUE),
254            Double.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY,
255            Integer.MIN_VALUE, Long.MIN_VALUE,
256            Double.valueOf(Double.NEGATIVE_INFINITY), Short.MIN_VALUE,
257            String.valueOf(Double.NEGATIVE_INFINITY), MIN_UNLIMITED_DECIMAL,
258            MIN_UNLIMITED_INTEGER,
259            Double.valueOf(Double.NEGATIVE_INFINITY).hashCode(), -1, true,
260            false, false, false, true, true, false, false, false, false));
261
262    /**
263     * Negative One (-1)
264     */
265    public static final Constant NEGATIVE_ONE = registerIntegerConstant(new Constant(
266        -1));
267
268    /**
269     * Negative One (-1)
270     */
271    public static final Constant NEGATIVE_TWO = registerIntegerConstant(new Constant(
272        -2));
273
274    /**
275     * Nine (9)
276     */
277    public static final Constant NINE = registerIntegerConstant(new Constant(9));
278
279    /**
280     * Character NUL (zero)
281     */
282    public static final Constant NUL = registerCharacterConstant(new Constant(
283        '\0'));
284
285    /**
286     * {@link NumericPrecision#NULL Null}, the empty set, or {@code void}
287     */
288    public static final Constant NULL = registerNamedConstant(
289        String.valueOf((Object)null).intern(),
290        new Constant(
291            NumericPrecision.NULL, false, Boolean.FALSE, (byte)0,
292            Character.MIN_VALUE, Character.valueOf(Character.MIN_VALUE), 0.0D,
293            0.0F, 0, 0L, Double.valueOf(0.0D), (short)0, String.valueOf(
294                (Object)null).intern(), BigDecimal.ZERO, BigInteger.ZERO, 0, 0,
295            false, true, false, false, false, false, false, false, false, true));
296
297    public static final String NULL_STRING = String.valueOf((Object)null).intern();
298
299    /**
300     * One (1)
301     */
302    public static final Constant ONE = registerIntegerConstant(new Constant(1));
303
304    /**
305     * One Hundred (100)
306     */
307    public static final Constant ONE_HUNDRED = registerIntegerConstant(new Constant(
308        100));
309
310    /**
311     * Pi
312     * 
313     * @see <a href="http://www.research.att.com/~njas/sequences/">The On-Line
314     *      Encyclopedia of Integer Sequences</a> (AT&T)
315     */
316    public static final Constant PI = registerNamedConstant(
317        "pi",
318        new Constant(NumericPrecision.DOUBLE, Math.PI, new BigDecimal(
319            String.valueOf(Math.PI)), String.valueOf(Math.PI)));
320
321    /**
322     * Positive infinity
323     * 
324     * @see Double#POSITIVE_INFINITY
325     * @see Float#POSITIVE_INFINITY
326     */
327    public static final Constant POSITIVE_INFINITY = registerNamedConstant(
328        String.valueOf(Double.POSITIVE_INFINITY),
329        new Constant(
330            NumericPrecision.DOUBLE, true, Boolean.TRUE, Byte.MAX_VALUE,
331            Character.MAX_VALUE, Character.valueOf(Character.MAX_VALUE),
332            Double.POSITIVE_INFINITY, Float.POSITIVE_INFINITY,
333            Integer.MAX_VALUE, Long.MAX_VALUE,
334            Double.valueOf(Double.POSITIVE_INFINITY), Short.MAX_VALUE,
335            String.valueOf(Double.POSITIVE_INFINITY), MAX_UNLIMITED_DECIMAL,
336            MAX_UNLIMITED_INTEGER,
337            Double.valueOf(Double.POSITIVE_INFINITY).hashCode(), +1, true,
338            false, false, false, false, false, true, true, false, false));
339
340    /**
341     * Seven (7)
342     */
343    public static final Constant SEVEN = registerIntegerConstant(new Constant(7));
344
345    /**
346     * ASCII single quote {@code 0x0027}
347     */
348    public static final Constant SINGLE_QUOTE = registerCharacterConstant(new Constant(
349        '\''));
350
351    /**
352     * Size (6)
353     */
354    public static final Constant SIX = registerIntegerConstant(new Constant(6));
355
356    /**
357     * ASCII space {@code 0x0020}
358     */
359    public static final Constant SPACE = registerCharacterConstant(new Constant(
360        ' '));
361
362    /**
363     * ASCII tab {@code 0x0009}
364     */
365    public static final Constant TAB = registerCharacterConstant(new Constant(
366        '\t'));
367
368    /**
369     * Ten (10)
370     */
371    public static final Constant TEN = registerIntegerConstant(new Constant(10));
372
373    /**
374     * Three (3)
375     */
376    public static final Constant THREE = registerIntegerConstant(new Constant(3));
377
378    /**
379     * Boolean {@link Boolean#TRUE TRUE}
380     */
381    public static final Constant TRUE = registerNamedConstant(
382        String.valueOf(true), new Constant(true));
383
384    /**
385     * Two (2)
386     */
387    public static final Constant TWO = registerIntegerConstant(new Constant(2));
388
389    /**
390     * Unknown constant
391     */
392    public static final Constant UNKNOWN = registerNamedConstant(
393        "unknown".intern(), new Constant("unknown".intern()));
394
395    /**
396     * ASCII "vertical tab" {@code 0x000B}
397     */
398    public static final Constant VERTICAL_TAB = registerCharacterConstant(new Constant(
399        '\u000b'));
400
401    /**
402     * Zero (0)
403     */
404    public static final Constant ZERO = registerIntegerConstant(new Constant(0));
405
406    private final boolean _isEmpty;
407    private final boolean _isInfinity;
408    private final boolean _isInvalid;
409    private final boolean _isMaximum;
410    private final boolean _isMinimum;
411    private final boolean _isNegative;
412    private final boolean _isNegativeInfinity;
413    private final boolean _isPositive;
414    private final boolean _isPositiveInfinity;
415    private final boolean _isUnity;
416    private final boolean _isZero;
417    private final boolean _theBoolean;
418    private final Boolean _theBooleanObject;
419    private final byte _theByte;
420    private final char _theCharacter;
421    private final Character _theCharacterObject;
422    private final double _theDouble;
423    private final long _theDoubleLongBits;
424    private final Enum<?> _theEnumeration;
425    private final float _theFloat;
426    private final int _theFloatIntBits;
427    private final int _theHashCode;
428    private final int _theInteger;
429    private final long _theLong;
430    private final Number _theNumber;
431    private final short _theShort;
432    private final int _theSignum;
433    private final int _theSize;
434    private final String _theString;
435    private final StructureStrategy _theStructureStrategy;
436    private final BigDecimal _theUnlimitedDecimal;
437    private final BigInteger _theUnlimitedInteger;
438
439    protected Constant( final String aString, final SealedReal<?> aReal )
440    {
441        this(Domain.TEXT, NumericPrecision.UNKNOWN, aReal.booleanValue(),
442            aReal.toBoolean(), aReal.byteValue(), aReal.charValue(),
443            aReal.toCharacter(), aReal.doubleValue(), aReal.floatValue(),
444            aReal.intValue(), aReal.longValue(), aReal.toNumber(),
445            aReal.shortValue(), aString, aReal.toUnlimitedDecimal(),
446            aReal.toUnlimitedInteger(), aString.hashCode(), aReal.signum(),
447            aReal.isInfinity(), aReal.isInvalid(), aReal.isMaximum(),
448            aReal.isMinimum(), aReal.isNegative(), aReal.isNegativeInfinity(),
449            aReal.isPositive(), aReal.isPositiveInfinity(), aReal.isUnity(),
450            aReal.isZero());
451    }
452
453    public Constant( final BigDecimal ud )
454    {
455        this(NumericPrecision.UNLIMITED_DECIMAL, ud.signum() != 0,
456            Boolean.valueOf(ud.signum() != 0), ud.byteValue(),
457            (char)ud.intValue(), Character.valueOf((char)ud.intValue()),
458            ud.doubleValue(), ud.floatValue(), ud.intValue(), ud.longValue(),
459            ud, ud.shortValue(), ud.toString(), ud, ud.toBigInteger(),
460            ud.hashCode(), ud.signum(), false, false, false, false,
461            ud.signum() < 0, false, 0 < ud.signum(), false,
462            ud.compareTo(BigDecimal.ONE) == 0, ud.signum() == 0);
463    }
464
465    public Constant( final BigInteger ui )
466    {
467        this(NumericPrecision.UNLIMITED_INTEGER, ui.signum() != 0,
468            Boolean.valueOf(ui.signum() != 0), ui.byteValue(),
469            (char)ui.intValue(), Character.valueOf((char)ui.intValue()),
470            ui.doubleValue(), ui.floatValue(), ui.intValue(), ui.longValue(),
471            ui, ui.shortValue(), ui.toString(), new BigDecimal(ui), ui,
472            ui.hashCode(), ui.signum(), false, false, false, false,
473            ui.signum() < 0, false, 0 < ui.signum(), false,
474            ui.compareTo(BigInteger.ONE) == 0, ui.signum() == 0);
475    }
476
477    public Constant( final boolean aBoolean )
478    {
479        this(NumericPrecision.BIT, aBoolean, Boolean.valueOf(aBoolean),
480            aBoolean ? (byte)1 : (byte)0, aBoolean ? (char)1 : '\0',
481            Character.valueOf(aBoolean ? (char)1 : '\0'), aBoolean ? (double)1
482                    : (double)0, aBoolean ? (float)1 : (float)0, aBoolean ? 1
483                    : 0, aBoolean ? (long)1 : (long)0, aBoolean ? ONEI : ZEROI,
484            aBoolean ? (short)1 : (short)0, String.valueOf(aBoolean),
485            aBoolean ? BigDecimal.ONE : BigDecimal.ZERO,
486            aBoolean ? BigInteger.ONE : BigInteger.ZERO, Boolean.valueOf(
487                aBoolean).hashCode(), aBoolean ? +1 : 0, false, false,
488            aBoolean, !aBoolean, false, false, aBoolean, false, aBoolean,
489            !aBoolean);
490    }
491
492    public Constant( final byte aByte )
493    {
494        this(NumericPrecision.BYTE, aByte != (byte)0,
495            Boolean.valueOf(aByte != (byte)0), aByte, (char)aByte,
496            Character.valueOf((char)aByte), aByte, aByte, aByte, aByte,
497            Byte.valueOf(aByte), aByte, String.valueOf(aByte), new BigDecimal(
498                String.valueOf(aByte)), BigInteger.valueOf(aByte),
499            Byte.valueOf(aByte).hashCode(), Integer.signum(aByte), false,
500            false, aByte == Byte.MAX_VALUE, aByte == Byte.MIN_VALUE,
501            aByte < (byte)0, false, (byte)0 < aByte, false, aByte == (byte)1,
502            aByte == (byte)0);
503    }
504
505    public Constant( final char aCharacter )
506    {
507        this(NumericPrecision.CHARACTER, aCharacter != '\0',
508            Boolean.valueOf(aCharacter != '\0'), (byte)aCharacter, aCharacter,
509            Character.valueOf(aCharacter), aCharacter, aCharacter, aCharacter,
510            aCharacter, Integer.valueOf(aCharacter), (short)aCharacter,
511            String.valueOf(aCharacter), new BigDecimal(
512                BigInteger.valueOf(aCharacter)),
513            BigInteger.valueOf(aCharacter),
514            Character.valueOf(aCharacter).hashCode(),
515            Integer.signum(aCharacter), false, false,
516            aCharacter == Character.MAX_VALUE,
517            aCharacter == Character.MIN_VALUE, aCharacter < '\0', false,
518            '\0' < aCharacter, false, aCharacter == (char)1, aCharacter == '\0');
519    }
520
521    public Constant(
522        final Domain aDomain,
523        final NumericPrecision aPrecision,
524        final boolean aBoolean,
525        final Boolean aBooleanObject,
526        final byte aByte,
527        final char aCharacter,
528        final Character aCharacterObject,
529        final double aDouble,
530        final float aFloat,
531        final int anInteger,
532        final long aLong,
533        final Number aNumber,
534        final short aShort,
535        final String aString,
536        final BigDecimal anUnlimitedDecimal,
537        final BigInteger anUnlimitedInteger,
538        final int aHashCode,
539        final int aSignum,
540        final boolean isInfinity,
541        final boolean isInvalid,
542        final boolean isMaximum,
543        final boolean isMinimum,
544        final boolean isNegative,
545        final boolean isNegativeInfinity,
546        final boolean isPositive,
547        final boolean isPositiveInfinity,
548        final boolean isUnity,
549        final boolean isZero )
550    {
551        super(aDomain, aPrecision);
552
553        this._theBoolean = aBoolean;
554        this._theBooleanObject = aBooleanObject;
555        this._theByte = aByte;
556        this._theCharacter = aCharacter;
557        this._theCharacterObject = aCharacterObject;
558        this._theDouble = aDouble;
559        this._theDoubleLongBits = Double.doubleToLongBits(aDouble);
560        this._theFloat = aFloat;
561        this._theFloatIntBits = Float.floatToIntBits(aFloat);
562        this._theInteger = anInteger;
563        this._theLong = aLong;
564        this._theNumber = aNumber;
565        this._theShort = aShort;
566        this._theString = aString;
567        this._theUnlimitedDecimal = anUnlimitedDecimal;
568        this._theUnlimitedInteger = anUnlimitedInteger;
569        this._theHashCode = aHashCode;
570        this._theSignum = aSignum;
571        this._isInfinity = isInfinity;
572        this._isInvalid = isInvalid;
573        this._isMaximum = isMaximum;
574        this._isMinimum = isMinimum;
575        this._isNegative = isNegative;
576        this._isNegativeInfinity = isNegativeInfinity;
577        this._isPositive = isPositive;
578        this._isPositiveInfinity = isPositiveInfinity;
579        this._isUnity = isUnity;
580        this._isZero = isZero;
581        switch (aPrecision) {
582        case UNLIMITED_INTEGER:
583            this._theStructureStrategy = StructureStrategy.TUPLE;
584            this._theSize = anUnlimitedInteger.toByteArray().length;
585            break;
586        case UNLIMITED_DECIMAL:
587            this._theStructureStrategy = StructureStrategy.TUPLE;
588            this._theSize = anUnlimitedInteger.toByteArray().length;
589            break;
590        case UNKNOWN:
591            this._theStructureStrategy = StructureStrategy.TUPLE;
592            this._theSize = aString.length();
593            break;
594        case NULL:
595            this._theStructureStrategy = StructureStrategy.EMPTY;
596            this._theSize = 0;
597            break;
598        default:
599            this._theStructureStrategy = StructureStrategy.BITS;
600            this._theSize = aPrecision.size();
601            break;
602        }
603        this._isEmpty = this._theSize == 0;
604        this._theEnumeration = aPrecision;
605    }
606
607    public Constant( final double aDouble )
608    {
609        this(
610            NumericPrecision.DOUBLE,
611            Double.compare(aDouble, 0F) == 0,
612            Boolean.valueOf(Double.compare(aDouble, 0F) == 0),
613            (byte)aDouble,
614            (char)aDouble,
615            Character.valueOf((char)aDouble),
616            aDouble,
617            (float)aDouble,
618            (int)aDouble,
619            (long)aDouble,
620            Double.valueOf(aDouble),
621            (short)aDouble,
622            String.valueOf(aDouble),
623            new BigDecimal(String.valueOf(aDouble)),
624            new BigDecimal(String.valueOf(aDouble)).toBigInteger(),
625            Double.valueOf(aDouble).hashCode(),
626            (int)Math.signum(aDouble),
627            Double.isInfinite(aDouble),
628            Double.isNaN(aDouble),
629            Double.doubleToLongBits(aDouble) == Double.doubleToLongBits(Double.MAX_VALUE),
630            Double.doubleToLongBits(aDouble) == Double.doubleToLongBits(Double.MIN_VALUE),
631            Double.compare(aDouble, 0F) < 0,
632            aDouble == Double.NEGATIVE_INFINITY,
633            0 < Double.compare(aDouble, 0F),
634            aDouble == Double.POSITIVE_INFINITY,
635            Double.compare(aDouble, 1.0F) == 0,
636            Double.compare(aDouble, 0F) == 0);
637    }
638
639    public Constant( final Enum<?> anEnumeration )
640    {
641        this(anEnumeration, anEnumeration.toString());
642    }
643
644    public Constant( final Enum<?> anEnumeration, final String aDescription )
645    {
646        super(Domain.MODULO, NumericPrecision.INTEGER);
647
648        final Enum<?>[] values = anEnumeration.getDeclaringClass().getEnumConstants();
649
650        this._theEnumeration = anEnumeration;
651        this._theInteger = anEnumeration.ordinal();
652        this._isMaximum = anEnumeration.ordinal() == values.length - 1;
653        this._isMinimum = anEnumeration.ordinal() == 0;
654
655        this._theBoolean = 0 < this._theInteger;
656        this._theBooleanObject = this._theBoolean;
657        this._theByte = (byte)this._theInteger;
658        this._theCharacter = (char)this._theInteger;
659        this._theCharacterObject = this._theCharacter;
660        this._theDouble = this._theInteger;
661        this._theDoubleLongBits = Double.doubleToLongBits(this._theDouble);
662        this._theFloat = this._theInteger;
663        this._theFloatIntBits = Float.floatToIntBits(this._theFloat);
664        this._theLong = this._theInteger;
665        this._theNumber = this._theInteger;
666        this._theShort = (short)this._theInteger;
667        this._theString = aDescription;
668        this._theUnlimitedDecimal = toUnlimitedDecimal(this._theInteger);
669        this._theUnlimitedInteger = toUnlimitedInteger(this._theInteger);
670        this._theHashCode = anEnumeration.hashCode();
671        this._theSignum = Integer.signum(this._theInteger);
672        this._isInfinity = false;
673        this._isInvalid = false;
674        this._isNegative = false;
675        this._isNegativeInfinity = false;
676        this._isPositive = 0 < this._theInteger;
677        this._isPositiveInfinity = false;
678        this._isUnity = this._theInteger == 1;
679        this._isZero = this._theInteger == 0;
680        this._theStructureStrategy = StructureStrategy.SINGLETON;
681        this._theSize = NumericPrecision.INTEGER.size();
682        this._isEmpty = false;
683    }
684
685    public Constant( final float aFloat )
686    {
687        this(
688            NumericPrecision.FLOAT,
689            Float.compare(aFloat, 0F) == 0,
690            Boolean.valueOf(Float.compare(aFloat, 0F) == 0),
691            (byte)aFloat,
692            (char)aFloat,
693            Character.valueOf((char)aFloat),
694            aFloat,
695            aFloat,
696            (int)aFloat,
697            (long)aFloat,
698            Float.valueOf(aFloat),
699            (short)aFloat,
700            String.valueOf(aFloat),
701            new BigDecimal(String.valueOf(aFloat)),
702            new BigDecimal(String.valueOf(aFloat)).toBigInteger(),
703            Float.valueOf(aFloat).hashCode(),
704            (int)Math.signum(aFloat),
705            Float.isInfinite(aFloat),
706            Float.isNaN(aFloat),
707            Float.floatToIntBits(aFloat) == Float.floatToIntBits(Float.MAX_VALUE),
708            Float.floatToIntBits(aFloat) == Float.floatToIntBits(Float.MIN_VALUE),
709            Float.compare(aFloat, 0F) < 0, aFloat == Float.NEGATIVE_INFINITY,
710            0 < Float.compare(aFloat, 0F), aFloat == Float.POSITIVE_INFINITY,
711            Float.compare(aFloat, 1.0F) == 0, Float.compare(aFloat, 0F) == 0);
712    }
713
714    public Constant( final int anInteger )
715    {
716        this(NumericPrecision.INTEGER, anInteger != 0,
717            Boolean.valueOf(anInteger != 0), (byte)anInteger, (char)anInteger,
718            Character.valueOf((char)anInteger), anInteger, anInteger,
719            anInteger, anInteger, Integer.valueOf(anInteger), (short)anInteger,
720            String.valueOf(anInteger),
721            new BigDecimal(String.valueOf(anInteger)),
722            BigInteger.valueOf(anInteger),
723            Integer.valueOf(anInteger).hashCode(), Integer.signum(anInteger),
724            false, false, anInteger == Integer.MAX_VALUE,
725            anInteger == Integer.MIN_VALUE, anInteger < 0, false,
726            0 < anInteger, false, anInteger == 1, anInteger == 0);
727    }
728
729    public Constant( final long aLong )
730    {
731        this(NumericPrecision.LONG, aLong != 0L, Boolean.valueOf(aLong != 0L),
732            (byte)aLong, (char)aLong, Character.valueOf((char)aLong), aLong,
733            aLong, (int)aLong, aLong, Long.valueOf(aLong), (short)aLong,
734            String.valueOf(aLong), new BigDecimal(String.valueOf(aLong)),
735            BigInteger.valueOf(aLong), Long.valueOf(aLong).hashCode(),
736            Long.signum(aLong), false, false, aLong == Long.MAX_VALUE,
737            aLong == Long.MIN_VALUE, aLong < 0L, false, 0L < aLong, false,
738            aLong == 1L, aLong == 0L);
739    }
740
741    public Constant(
742        final NumericPrecision aPrecision,
743        final boolean aBoolean,
744        final Boolean aBooleanObject,
745        final byte aByte,
746        final char aCharacter,
747        final Character aCharacterObject,
748        final double aDouble,
749        final float aFloat,
750        final int anInteger,
751        final long aLong,
752        final Number aNumber,
753        final short aShort,
754        final String aString,
755        final BigDecimal anUnlimitedDecimal,
756        final BigInteger anUnlimitedInteger,
757        final int aHashCode,
758        final int aSignum,
759        final boolean isInfinity,
760        final boolean isInvalid,
761        final boolean isMaximum,
762        final boolean isMinimum,
763        final boolean isNegative,
764        final boolean isNegativeInfinity,
765        final boolean isPositive,
766        final boolean isPositiveInfinity,
767        final boolean isUnity,
768        final boolean isZero )
769    {
770        this(aPrecision == NumericPrecision.UNKNOWN ? Domain.TEXT
771                : aPrecision == NumericPrecision.NULL ? Domain.EMPTY
772                        : Domain.REAL, aPrecision, aBoolean, aBooleanObject,
773            aByte, aCharacter, aCharacterObject, aDouble, aFloat, anInteger,
774            aLong, aNumber, aShort, aString, anUnlimitedDecimal,
775            anUnlimitedInteger, aHashCode, aSignum, isInfinity, isInvalid,
776            isMaximum, isMinimum, isNegative, isNegativeInfinity, isPositive,
777            isPositiveInfinity, isUnity, isZero);
778    }
779
780    public Constant(
781        final NumericPrecision aPrecision,
782        final double aDouble,
783        final BigDecimal ud )
784    {
785        this(aPrecision, aDouble, (float)aDouble, ud, ud.toString());
786    }
787
788    public Constant(
789        final NumericPrecision aPrecision,
790        final double aDouble,
791        final BigDecimal ud,
792        final String aString )
793    {
794        this(aPrecision, aDouble, (float)aDouble, ud, aString);
795    }
796
797    public Constant(
798        final NumericPrecision aPrecision,
799        final double aDouble,
800        final float aFloat,
801        final BigDecimal ud,
802        final String aString )
803    {
804        this(
805            aPrecision,
806            ud.signum() != 0,
807            Boolean.valueOf(ud.signum() != 0),
808            ud.byteValue(),
809            (char)ud.intValue(),
810            Character.valueOf((char)ud.intValue()),
811            aDouble,
812            aFloat,
813            ud.intValue(),
814            ud.longValue(),
815            ud,
816            ud.shortValue(),
817            aString,
818            ud,
819            ud.toBigInteger(),
820            ud.hashCode(),
821            ud.signum(),
822            Double.isInfinite(aDouble),
823            Double.isNaN(aDouble),
824            Double.doubleToLongBits(aDouble) == Double.doubleToLongBits(Double.MAX_VALUE),
825            Double.doubleToLongBits(aDouble) == Double.doubleToLongBits(Double.MIN_VALUE),
826            ud.signum() < 0, aDouble == Double.NEGATIVE_INFINITY,
827            0 < ud.signum(), aDouble == Double.POSITIVE_INFINITY,
828            ud.compareTo(BigDecimal.ONE) == 0, ud.signum() == 0);
829    }
830
831    public Constant( final short aShort )
832    {
833        this(NumericPrecision.SHORT, aShort != (short)0,
834            Boolean.valueOf(aShort != (short)0), (byte)aShort, (char)aShort,
835            Character.valueOf((char)aShort), aShort, aShort, aShort, aShort,
836            Short.valueOf(aShort), aShort, String.valueOf(aShort),
837            new BigDecimal(String.valueOf(aShort)), BigInteger.valueOf(aShort),
838            Short.valueOf(aShort).hashCode(), Integer.signum(aShort), false,
839            false, aShort == Short.MAX_VALUE, aShort == Short.MIN_VALUE,
840            aShort < (short)0, false, (short)0 < aShort, false,
841            aShort == (short)1, aShort == (short)0);
842    }
843
844    public Constant( final String aString )
845    {
846        this(aString, toReal(aString));
847    }
848
849    @Override
850    public final boolean booleanValue()
851    {
852        return this._theBoolean;
853    }
854
855    @Override
856    public final byte byteValue()
857    {
858        return this._theByte;
859    }
860
861    @Override
862    public final char charAt( final int anIndex )
863    {
864        return this._theString.charAt(anIndex);
865    }
866
867    @Override
868    public final char charValue()
869    {
870        return this._theCharacter;
871    }
872
873    @Override
874    public final int codePointAt( final int index )
875    {
876        return this.toString().codePointAt(index);
877    }
878
879    @Override
880    public final int codePointBefore( final int index )
881    {
882        return this.toString().codePointBefore(index);
883    }
884
885    @Override
886    public final int codePointCount( final int beginIndex, final int endIndex )
887    {
888        return this.toString().codePointCount(beginIndex, endIndex);
889    }
890
891    @Override
892    public final Constant copyUsing( final BigDecimal aValue )
893    {
894        return valueOf(aValue);
895    }
896
897    @Override
898    public final Constant copyUsing( final BigInteger aValue )
899    {
900        return valueOf(aValue);
901    }
902
903    @Override
904    public final Constant copyUsing( final boolean aValue )
905    {
906        return valueOf(aValue);
907    }
908
909    @Override
910    public final Constant copyUsing( final byte aValue )
911    {
912        return valueOf(aValue);
913    }
914
915    @Override
916    public final Constant copyUsing( final char aValue )
917    {
918        return valueOf(aValue);
919    }
920
921    @Override
922    public final Constant copyUsing( final double aValue )
923    {
924        return valueOf(aValue);
925    }
926
927    @Override
928    public final Constant copyUsing( final float aValue )
929    {
930        return valueOf(aValue);
931    }
932
933    @Override
934    public final Constant copyUsing( final int aValue )
935    {
936        return valueOf(aValue);
937    }
938
939    @Override
940    public final Constant copyUsing( final long aValue )
941    {
942        return valueOf(aValue);
943    }
944
945    @Override
946    public final Constant copyUsing( final short aValue )
947    {
948        return valueOf(aValue);
949    }
950
951    @Override
952    public final Constant copyUsingPrimitive( final SealedPrimitive<?> aValue )
953    {
954        return valueOfPrimitive(aValue);
955    }
956
957    @Override
958    public final Constant copyUsingReal( final SealedReal<?> aValue )
959    {
960        return valueOfReal(aValue);
961    }
962
963    @Override
964    public final Constant copyUsingScalar( final SealedScalar<?> aValue )
965    {
966        return valueOfScalar(aValue);
967    }
968
969    @Override
970    public final Constant copyUsingText( final CharSequence aValue )
971    {
972        return valueOfText(String.valueOf(aValue));
973    }
974
975    public final long doubleLongBits()
976    {
977        return this._theDoubleLongBits;
978    }
979
980    @Override
981    public final double doubleValue()
982    {
983        return this._theDouble;
984    }
985
986    public final int floatIntBits()
987    {
988        return this._theFloatIntBits;
989    }
990
991    @Override
992    public final float floatValue()
993    {
994        return this._theFloat;
995    }
996
997    @Override
998    public final StructureStrategy getStructureStrategy()
999    {
1000        return this._theStructureStrategy;
1001    }
1002
1003    @Override
1004    public int hashCode()
1005    {
1006        return this._theHashCode;
1007    }
1008
1009    @Override
1010    public final int indexOfText( final CharSequence str )
1011    {
1012        return this._theString.indexOf(str.toString());
1013    }
1014
1015    @Override
1016    public final int indexOfText( final CharSequence str, final int beginIndex )
1017    {
1018        return this.toString().indexOf(str.toString(), beginIndex);
1019    }
1020
1021    @Override
1022    @SuppressWarnings( "unchecked" )
1023    public <R extends Real<?>> R induceRealMaximum( final R aTarget )
1024    {
1025        if (this.getDomain() == Domain.MODULO)
1026            return (R)aTarget.setScalar(this._theEnumeration.getDeclaringClass().getEnumConstants().length - 1);
1027        return super.induceRealMaximum(aTarget);
1028    }
1029
1030    @Override
1031    @SuppressWarnings( "unchecked" )
1032    public <R extends Real<?>> R induceRealMinimum( final R aTarget )
1033    {
1034        if (this.getDomain() == Domain.MODULO) return (R)aTarget.setZero();
1035        return super.induceRealMinimum(aTarget);
1036    }
1037
1038    @Override
1039    @SuppressWarnings( "unchecked" )
1040    public <S extends Scalar<?>> S induceScalarMaximum( final S aTarget )
1041    {
1042        if (this.getDomain() == Domain.MODULO)
1043            return (S)aTarget.setScalar(this._theEnumeration.getDeclaringClass().getEnumConstants().length - 1);
1044        return super.induceScalarMaximum(aTarget);
1045    }
1046
1047    @Override
1048    @SuppressWarnings( "unchecked" )
1049    public <S extends Scalar<?>> S induceScalarMinimum( final S aTarget )
1050    {
1051        if (this.getDomain() == Domain.MODULO) return (S)aTarget.setZero();
1052        return super.induceScalarMinimum(aTarget);
1053    }
1054
1055    @Override
1056    public final int intValue()
1057    {
1058        return this._theInteger;
1059    }
1060
1061    @Override
1062    public final boolean isEmpty()
1063    {
1064        return this._isEmpty;
1065    }
1066
1067    @Override
1068    public final boolean isInfinity()
1069    {
1070        return this._isInfinity;
1071    }
1072
1073    @Override
1074    public final boolean isInvalid()
1075    {
1076        return this._isInvalid;
1077    }
1078
1079    @Override
1080    public final boolean isMaximum()
1081    {
1082        return this._isMaximum;
1083    }
1084
1085    @Override
1086    public final boolean isMinimum()
1087    {
1088        return this._isMinimum;
1089    }
1090
1091    @Override
1092    public final boolean isNegative()
1093    {
1094        return this._isNegative;
1095    }
1096
1097    @Override
1098    public final boolean isNegativeInfinity()
1099    {
1100        return this._isNegativeInfinity;
1101    }
1102
1103    @Override
1104    public final boolean isPositive()
1105    {
1106        return this._isPositive;
1107    }
1108
1109    @Override
1110    public final boolean isPositiveInfinity()
1111    {
1112        return this._isPositiveInfinity;
1113    }
1114
1115    @Override
1116    public boolean isUnique()
1117    {
1118        return this.size() == 1;
1119    }
1120
1121    @Override
1122    public final boolean isUnity()
1123    {
1124        return this._isUnity;
1125    }
1126
1127    @Override
1128    public final boolean isZero()
1129    {
1130        return this._isZero;
1131    }
1132
1133    @Override
1134    public final int length()
1135    {
1136        return this._theString.length();
1137    }
1138
1139    @Override
1140    public final long longValue()
1141    {
1142        return this._theLong;
1143    }
1144
1145    @Override
1146    public final short shortValue()
1147    {
1148        return this._theShort;
1149    }
1150
1151    @Override
1152    public final int signum()
1153    {
1154        return this._theSignum;
1155    }
1156
1157    @Override
1158    public final int size()
1159    {
1160        return this._theSize;
1161    }
1162
1163    @Override
1164    public final CharSequence subSequence( final int start, final int end )
1165    {
1166        return this.toString().subSequence(start, end);
1167    }
1168
1169    @Override
1170    public final String substring( final int start )
1171    {
1172        return this.toString().substring(start);
1173    }
1174
1175    @Override
1176    public final String substring( final int start, final int end )
1177    {
1178        return this.toString().substring(start, end);
1179    }
1180
1181    @Override
1182    public Boolean toBoolean()
1183    {
1184        return this._theBooleanObject;
1185    }
1186
1187    @Override
1188    public final Character toCharacter()
1189    {
1190        return this._theCharacterObject;
1191    }
1192
1193    @Override
1194    public final Number toNumber()
1195    {
1196        return this._theNumber;
1197    }
1198
1199    @Override
1200    public final String toString()
1201    {
1202        return this._theString;
1203    }
1204
1205    @Override
1206    public final BigDecimal toUnlimitedDecimal()
1207    {
1208        return this._theUnlimitedDecimal;
1209    }
1210
1211    @Override
1212    public final BigInteger toUnlimitedInteger()
1213    {
1214        return this._theUnlimitedInteger;
1215    }
1216
1217    private static final Constant registerCharacterConstant(
1218        final Constant aConstant )
1219    {
1220        final int aScalar = aConstant.intValue();
1221        final Constant existingConstant = theCharacterCache.valueOf(aScalar,
1222            null);
1223        if (existingConstant != null) return existingConstant;
1224        theCharacterCache.setElement(aScalar, aConstant);
1225        return aConstant;
1226    }
1227
1228    private static final Constant registerIntegerConstant(
1229        final Constant aConstant )
1230    {
1231        final int aScalar = aConstant.intValue();
1232        final Constant existingConstant = theIntegerCache.valueOf(aScalar, null);
1233        if (existingConstant != null) return existingConstant;
1234        theIntegerCache.setElement(aScalar, aConstant);
1235        return aConstant;
1236    }
1237
1238    private static final Constant registerNamedConstant(
1239        final String aName,
1240        final Constant aConstant )
1241    {
1242        theLowerCaseMap.put(aName.toLowerCase(), aConstant);
1243        theOriginalCaseMap.put(aName, aConstant);
1244        return aConstant;
1245    }
1246
1247    private static final Real<?> toReal( final String aString )
1248    {
1249        final Variant aModel = new Variant();
1250        To.REAL.reactToText(aString, aModel);
1251        return aModel.getTarget();
1252    }
1253
1254    private static final Constant valueOfNumberOrText( final String aString )
1255    {
1256        try {
1257            final Number aNumber = NumberFormat.getNumberInstance().parse(
1258                aString);
1259            return valueOfNumber(aNumber);
1260        } catch (final ParseException ex) {
1261        }
1262        try {
1263            final BigDecimal aNumber = new BigDecimal(aString);
1264            return valueOf(aNumber);
1265        } catch (final NumberFormatException ex) {
1266        }
1267        return valueOfText(aString);
1268    }
1269
1270    public static final Constant getNamedConstant( final String aString )
1271    {
1272        final Constant aConstant = theOriginalCaseMap.get(aString);
1273        if (aConstant == null) return UNKNOWN;
1274        return aConstant;
1275    }
1276
1277    public static final Constant getNamedConstantIgnoreCase(
1278        final String aString )
1279    {
1280        final String lc = aString.toLowerCase();
1281        final Constant aConstant = theLowerCaseMap.get(lc);
1282        if (aConstant == null) return UNKNOWN;
1283        return aConstant;
1284    }
1285
1286    public static final boolean hasName( final String aName )
1287    {
1288        return theOriginalCaseMap.containsKey(aName);
1289    }
1290
1291    public static final boolean hasNameIgnoreCase( final String aName )
1292    {
1293        return theLowerCaseMap.containsKey(aName.toLowerCase());
1294    }
1295
1296    public static final Iterator<Constant> iterateNamedConstants()
1297    {
1298        return theOriginalCaseMap.values().iterator();
1299    }
1300
1301    public static final Iterator<String> iterateNames()
1302    {
1303        return theOriginalCaseMap.keySet().iterator();
1304    }
1305
1306    public static final Constant maskAt( final int aBitPosition )
1307    {
1308        final Constant aConstant = theMaskCache.valueOf(aBitPosition, null);
1309        if (aConstant != null) return aConstant;
1310        final BigInteger ui = BigInteger.ONE.shiftLeft(aBitPosition);
1311        return valueOf(ui);
1312    }
1313
1314    public static final Constant notMaskAt( final int aBitPosition )
1315    {
1316        final Constant aConstant = theNotMaskCache.valueOf(aBitPosition, null);
1317        if (aConstant != null) return aConstant;
1318        final BigInteger ui = BigInteger.valueOf(2).shiftLeft(aBitPosition).and(
1319            BigInteger.ONE);
1320        return valueOf(ui);
1321    }
1322
1323    public static final String toCamelCase( final String aString )
1324    {
1325        final String[] words = aString.split("_");
1326        final StringBuilder sb = new StringBuilder();
1327        for (final String aWord : words) {
1328            if (!aWord.isEmpty()) {
1329                final char first = Character.toUpperCase(aWord.charAt(0));
1330                sb.append(first);
1331                if (1 < aWord.length()) {
1332                    sb.append(aWord.substring(1).toLowerCase());
1333                }
1334            }
1335        }
1336        return sb.toString();
1337    }
1338
1339    public static final Primitive<?> toConstant( final Primitive<?> aPrimitive )
1340    {
1341        if (!aPrimitive.isMutable()) return aPrimitive;
1342        return valueOfPrimitive(aPrimitive);
1343    }
1344
1345    public static final BigDecimal toUnlimitedDecimal( final BigInteger aScalar )
1346    {
1347        final Constant aConstant = theLongCache.valueOf(aScalar, null);
1348        if (aConstant != null) return aConstant.toUnlimitedDecimal();
1349        return new BigDecimal(aScalar);
1350    }
1351
1352    public static final BigDecimal toUnlimitedDecimal( final boolean aScalar )
1353    {
1354        return aScalar ? TRUE.toUnlimitedDecimal() : FALSE.toUnlimitedDecimal();
1355    }
1356
1357    public static final BigDecimal toUnlimitedDecimal( final double aScalar )
1358    {
1359        return new BigDecimal(String.valueOf(aScalar));
1360    }
1361
1362    public static final BigDecimal toUnlimitedDecimal( final float aScalar )
1363    {
1364        return new BigDecimal(String.valueOf(aScalar));
1365    }
1366
1367    public static final BigDecimal toUnlimitedDecimal( final long aScalar )
1368    {
1369        final Constant aConstant = theLongCache.valueOf(aScalar, null);
1370        if (aConstant != null) return aConstant.toUnlimitedDecimal();
1371        return new BigDecimal(aScalar);
1372    }
1373
1374    public static final BigDecimal toUnlimitedDecimal( final String text )
1375    {
1376        return new BigDecimal(text);
1377    }
1378
1379    public static final BigInteger toUnlimitedInteger( final boolean aScalar )
1380    {
1381        return aScalar ? TRUE.toUnlimitedInteger() : FALSE.toUnlimitedInteger();
1382    }
1383
1384    public static final BigInteger toUnlimitedInteger( final long aScalar )
1385    {
1386        final Constant aConstant = theLongCache.valueOf(aScalar, null);
1387        if (aConstant != null) return aConstant.toUnlimitedInteger();
1388        return BigInteger.valueOf(aScalar);
1389    }
1390
1391    public static final Constant valueOf( final BigDecimal aScalar )
1392    {
1393        return new Constant(aScalar);
1394    }
1395
1396    public static final Constant valueOf( final BigInteger aScalar )
1397    {
1398        final Constant aConstant = theLongCache.valueOf(aScalar, null);
1399        if (aConstant != null) return aConstant;
1400        return new Constant(aScalar);
1401    }
1402
1403    public static final Constant valueOf( final boolean aScalar )
1404    {
1405        return aScalar ? TRUE : FALSE;
1406    }
1407
1408    public static final Constant valueOf( final byte aScalar )
1409    {
1410        final Constant aConstant = theByteCache.valueOf(aScalar, null);
1411        if (aConstant != null) return aConstant;
1412        return new Constant(aScalar);
1413    }
1414
1415    public static final Constant valueOf( final char aScalar )
1416    {
1417        final Constant aConstant = theCharacterCache.valueOf(aScalar, null);
1418        if (aConstant != null) return aConstant;
1419        return new Constant(aScalar);
1420    }
1421
1422    public static final Constant valueOf( final double aScalar )
1423    {
1424        if (Double.isNaN(aScalar)) return INVALID;
1425        if (aScalar == Double.POSITIVE_INFINITY) return POSITIVE_INFINITY;
1426        if (aScalar == Double.NEGATIVE_INFINITY) return NEGATIVE_INFINITY;
1427        return new Constant(aScalar);
1428    }
1429
1430    public static final Constant valueOf( final Enum<?> anEnumeration )
1431    {
1432        return new Constant(anEnumeration);
1433    }
1434
1435    public static final Constant valueOf(
1436        final Enum<?> anEnumeration,
1437        final String aDescription )
1438    {
1439        return new Constant(anEnumeration, aDescription);
1440    }
1441
1442    public static final Constant valueOf( final float aScalar )
1443    {
1444        if (Float.isNaN(aScalar)) return INVALID;
1445        if (aScalar == Float.POSITIVE_INFINITY) return POSITIVE_INFINITY;
1446        if (aScalar == Float.NEGATIVE_INFINITY) return NEGATIVE_INFINITY;
1447        return new Constant(aScalar);
1448    }
1449
1450    public static final Constant valueOf( final int aScalar )
1451    {
1452        final Constant aConstant = theIntegerCache.valueOf(aScalar, null);
1453        if (aConstant != null) return aConstant;
1454        return new Constant(aScalar);
1455    }
1456
1457    public static final Constant valueOf( final long aScalar )
1458    {
1459        final Constant aConstant = theLongCache.valueOf(aScalar, null);
1460        if (aConstant != null) return aConstant;
1461        return new Constant(aScalar);
1462    }
1463
1464    public static final Constant valueOf( final short aScalar )
1465    {
1466        final Constant aConstant = theShortCache.valueOf(aScalar, null);
1467        if (aConstant != null) return aConstant;
1468        return new Constant(aScalar);
1469    }
1470
1471    public static final Constant valueOfNumber( final Number aNumber )
1472    {
1473        final NumericPrecision prec = NumericPrecision.getPrecisionFor(aNumber);
1474        switch (prec) {
1475        case NULL:
1476            return NULL;
1477        case BIT:
1478            if (aNumber instanceof SealedScalar<?>)
1479                return valueOf(((SealedScalar<?>)aNumber).booleanValue());
1480            break;
1481        case BYTE:
1482            return valueOf(aNumber.byteValue());
1483        case CHARACTER:
1484            if (aNumber instanceof SealedScalar<?>)
1485                return valueOf(((SealedScalar<?>)aNumber).charValue());
1486            break;
1487        case SHORT:
1488            return valueOf(aNumber.shortValue());
1489        case INTEGER:
1490            return valueOf(aNumber.intValue());
1491        case LONG:
1492            return valueOf(aNumber.longValue());
1493        case FLOAT:
1494            return valueOf(aNumber.floatValue());
1495        case DOUBLE:
1496            return valueOf(aNumber.doubleValue());
1497        case UNLIMITED_INTEGER:
1498            if (aNumber instanceof SealedReal<?>) {
1499                final SealedReal<?> aPrimitive = (SealedReal<?>)aNumber;
1500                return valueOf(aPrimitive.toUnlimitedInteger());
1501            } else if (aNumber instanceof BigInteger) {
1502                final BigInteger big = (BigInteger)aNumber;
1503                return valueOf(big);
1504            } else {
1505                final BigInteger big = new BigInteger(aNumber.toString());
1506                return valueOf(big);
1507            }
1508        case UNLIMITED_DECIMAL:
1509            if (aNumber instanceof SealedReal<?>) {
1510                final SealedReal<?> aPrimitive = (SealedReal<?>)aNumber;
1511                return valueOf(aPrimitive.toUnlimitedDecimal());
1512            } else if (aNumber instanceof BigDecimal) {
1513                final BigDecimal big = (BigDecimal)aNumber;
1514                return valueOf(big);
1515            } else {
1516                final BigDecimal big = new BigDecimal(aNumber.toString());
1517                return valueOf(big);
1518            }
1519        }
1520        return valueOfTranslatedText(aNumber.toString());
1521    }
1522
1523    public static final Constant valueOfObject( final Object anObject )
1524    {
1525        if (anObject instanceof SealedScalar<?>) {
1526            final SealedScalar<?> aScalar = (SealedScalar<?>)anObject;
1527            if (aScalar instanceof Constant) return (Constant)aScalar;
1528            return valueOfScalar(aScalar);
1529        } else if (anObject instanceof Enum<?>) return valueOf((Enum<?>)anObject);
1530        else {
1531            final NumericPrecision prec = NumericPrecision.getPrecisionFor(anObject);
1532            switch (prec) {
1533            case NULL:
1534                return NULL;
1535            case BIT:
1536                if (anObject instanceof AtomicBoolean) {
1537                    final AtomicBoolean ab = (AtomicBoolean)anObject;
1538                    return valueOf(ab.get());
1539                }
1540                final Boolean b = (Boolean)anObject;
1541                return valueOf(b);
1542            case BYTE:
1543                final Byte by = (Byte)anObject;
1544                return valueOf(by);
1545            case SHORT:
1546                final Short sh = (Short)anObject;
1547                return valueOf(sh);
1548            case CHARACTER:
1549                final Character c = (Character)anObject;
1550                return valueOf(c);
1551            case INTEGER:
1552                if (anObject instanceof AtomicInteger) {
1553                    final AtomicInteger ai = (AtomicInteger)anObject;
1554                    return valueOf(ai.get());
1555                }
1556                final Integer i = (Integer)anObject;
1557                return valueOf(i);
1558            case LONG:
1559                if (anObject instanceof AtomicLong) {
1560                    final AtomicLong al = (AtomicLong)anObject;
1561                    return valueOf(al.get());
1562                }
1563                final Long l = (Long)anObject;
1564                return valueOf(l);
1565            case FLOAT:
1566                final Float f = (Float)anObject;
1567                return valueOf(f);
1568            case DOUBLE:
1569                final Double d = (Double)anObject;
1570                return valueOf(d);
1571            case UNLIMITED_INTEGER: {
1572                final BigInteger big = (BigInteger)anObject;
1573                return valueOf(big);
1574            }
1575            case UNLIMITED_DECIMAL: {
1576                final BigDecimal big = (BigDecimal)anObject;
1577                return valueOf(big);
1578            }
1579            }
1580        }
1581        final String aString = anObject.toString();
1582        return valueOfTranslatedText(aString);
1583    }
1584
1585    public static final Constant valueOfPrimitive(
1586        final SealedPrimitive<?> aPrimitive )
1587    {
1588        if (aPrimitive instanceof Constant) return (Constant)aPrimitive;
1589        final NumericPrecision prec = aPrimitive.getPrecision();
1590        switch (prec) {
1591        case NULL:
1592            return NULL;
1593        case BIT:
1594            return valueOf(aPrimitive.booleanValue());
1595        case BYTE:
1596            return valueOf(aPrimitive.byteValue());
1597        case SHORT:
1598            return valueOf(aPrimitive.shortValue());
1599        case CHARACTER:
1600            return valueOf(aPrimitive.charValue());
1601        case INTEGER:
1602            return valueOf(aPrimitive.intValue());
1603        case LONG:
1604            return valueOf(aPrimitive.longValue());
1605        case FLOAT:
1606            return valueOf(aPrimitive.floatValue());
1607        case DOUBLE:
1608            return valueOf(aPrimitive.doubleValue());
1609        case UNLIMITED_INTEGER:
1610            return valueOf(aPrimitive.toUnlimitedInteger());
1611        case UNLIMITED_DECIMAL:
1612            return valueOf(aPrimitive.toUnlimitedDecimal());
1613        }
1614        return valueOfText(aPrimitive.toString());
1615    }
1616
1617    public static final Constant valueOfReal( final SealedReal<?> aReal )
1618    {
1619        if (aReal instanceof Constant) return (Constant)aReal;
1620        final NumericPrecision prec = aReal.getPrecision();
1621        switch (prec) {
1622        case NULL:
1623            return NULL;
1624        case BIT:
1625            return valueOf(aReal.booleanValue());
1626        case BYTE:
1627            return valueOf(aReal.byteValue());
1628        case SHORT:
1629            return valueOf(aReal.shortValue());
1630        case CHARACTER:
1631            return valueOf(aReal.charValue());
1632        case INTEGER:
1633            return valueOf(aReal.intValue());
1634        case LONG:
1635            return valueOf(aReal.longValue());
1636        case FLOAT:
1637            return valueOf(aReal.floatValue());
1638        case DOUBLE:
1639            return valueOf(aReal.doubleValue());
1640        case UNLIMITED_INTEGER:
1641            return valueOf(aReal.toUnlimitedInteger());
1642        case UNLIMITED_DECIMAL:
1643            return valueOf(aReal.toUnlimitedDecimal());
1644        }
1645        return valueOfText(aReal.toString());
1646    }
1647
1648    public static final Constant valueOfScalar( final SealedScalar<?> aScalar )
1649    {
1650        if (aScalar instanceof Constant) return (Constant)aScalar;
1651        final NumericPrecision prec = aScalar.getPrecision();
1652        switch (prec) {
1653        case NULL:
1654            return NULL;
1655        case BIT:
1656            return valueOf(aScalar.booleanValue());
1657        case BYTE:
1658            return valueOf(aScalar.byteValue());
1659        case SHORT:
1660            return valueOf(aScalar.shortValue());
1661        case CHARACTER:
1662            return valueOf(aScalar.charValue());
1663        case INTEGER:
1664            return valueOf(aScalar.intValue());
1665        case UNLIMITED_INTEGER:
1666        case LONG:
1667            return valueOf(aScalar.longValue());
1668        case FLOAT:
1669            return valueOf(aScalar.floatValue());
1670        case UNLIMITED_DECIMAL:
1671        case DOUBLE:
1672            return valueOf(aScalar.doubleValue());
1673        }
1674        return valueOfText(aScalar.toString());
1675    }
1676
1677    public static final Constant valueOfText( final String aString )
1678    {
1679        return new Constant(aString);
1680    }
1681
1682    public static final Constant valueOfTranslatedText( final String aString )
1683    {
1684        final Constant aNamedConstant = getNamedConstantIgnoreCase(aString);
1685        if (aNamedConstant != null) return aNamedConstant;
1686        return valueOfNumberOrText(aString);
1687    }
1688}