Numeric Properties

A Numeric Properties contains a numeric value.

Idea 1: we mainly need numeric values only defined in some field (for example, [3,18] for the sum of 3 dices).

Idea 2: the field could be defined with intervals, sets or regular expressions.

The value of a Numeric Property is always limited to some field. We couldn't find useful examples for using sets or regular expressions (moreover the last ones are complex to implement and to use). So we'll only use intervals. We couldn't find useful examples for using intersections, unions or exclusions of intervals to define the field. So we'll only use one interval. The interval should contain one or more numbers.

If no interval is given, the interval with the min and max values for this value type are used.

If a interval is given (a min and a max values), both values should be legal (not 'NaN' for a real, for example), and correctly put in order.

We'll need at least some Properties both for integers and real values. To start, we'll defined Properties with 'long' and 'double' values.

Implementation:
class LongProperty extends Property
{
  LongProperty( String name, long value) throws IllegalArgument;
  // IllegalArgument if null name
  // field defaulted to [Long.MIN_VALUE, Long.MAX_VALUE]

  LongProperty( String name, long value, long min, long max)
  throws IllegalArgument;
  // IllegalArgument if null name or max < min

  long getLongValue();
  long getMinValue();
  long getMaxValue();
 
  void applyModifier( AbsoluteModifier modifier);
  void applyModifier( RelativeModifier modifier);
  void removeModifier( AbsoluteModifier modifier);
  void removeModifier( RelativeModifier modifier);
}

class DoubleProperty extends Property
{
  DoubleProperty( String name, double value) throws IllegalArgument;
  // IllegalArgument if null name or NaN value
  // field defaulted to [Double.MIN_VALUE, Double.MAX_VALUE]

  DoubleProperty( String name, double value, double min, double max)
  throws IllegalArgument
  // IllegalArgument if null name or NaN value, min or max, or max < min

  double getDoubleValue();
  double getMinValue();
  double getMaxValue();
 
  void applyModifier( AbsoluteModifier modifier);
  void applyModifier( RelativeModifier modifier);
  void removeModifier( AbsoluteModifier modifier);
  void removeModifier( RelativeModifier modifier);
}

Note

for implementation, min and max values can be stored in a memory-friendly way. They aren't stored as two long or double values but as a special immutable Interval object (in fact a reference to this object). A hashtable links (min, max) couples to IntervalManager objects, so for a given interval, only one Interval exists.

Old solution's memory requirements: two values * number of such Properties.

New solution's memory requirements: a reference * number of such Properties + Interval object with two values (+ hashtable)

Implementation:
final class LongInterval
{
  LongInterval( long min, long max); // no control here
  long getMin();
  long getMax();
  boolean isInInterval( long value);
  // return (min <= value && value <= max)
  long boundedValue( long value);
  // min if value < min, max if value > max, otherwise value
}

final class DoubleInterval
{
  DoubleInterval( double min, double max); // no control here
  double getMin();
  double getMax();
  boolean isInInterval( double value);
  // return (min <= value && value <= max)
  double boundedValue( long value);
  // min if value < min, max if value > max, otherwise value
}