package com.impossibl.postgres.data;

public class Range<T> {
	
	public static class Flags {
		
		byte value;
	
		private static final byte RANGE_EMPTY 	= 0x01;	/* range is empty */
		private static final byte RANGE_LB_INC 	= 0x02;	/* lower bound is inclusive */
		private static final byte RANGE_UB_INC 	= 0x04;	/* upper bound is inclusive */
		private static final byte RANGE_LB_INF 	= 0x08;	/* lower bound is -infinity */
		private static final byte RANGE_UB_INF 	= 0x10;	/* upper bound is +infinity */
		
		public Flags(byte value) {
			super();
			this.value = value;
		}
		
		public byte getValue() {
			return value;
		}

		public boolean isEmpty() {
			return (value & RANGE_EMPTY) != 0;
		}
		
		public boolean hasLowerBound() {
			return (value & RANGE_LB_INC) != 0;
		}
		
		public boolean isLowerBoundInfinity() {
			return (value & RANGE_LB_INF) != 0;
		}

		public boolean hasUpperBound() {
			return (value & RANGE_UB_INC) != 0;
		}

		public boolean isUpperBoundInfinity() {
			return (value & RANGE_UB_INF) != 0;
		}

	}

	Flags flags;
	Object[] values;
	
	public Range(Flags flags, Object[] values) {
		this.flags = flags;
		this.values = values.clone();
	}
	
	public Flags getFlags() {
		return flags;
	}
	
	public boolean isEmpty() {
		return flags.isEmpty();
	}
	
	public boolean hasLowerBound() {
		return flags.hasLowerBound();
	}
	
	@SuppressWarnings("unchecked")
	public T getLowerBound() {
		return (T) values[0];
	}
	
	public boolean isLowerBoundInfinity() {
		return flags.isLowerBoundInfinity();
	}

	public boolean hasUpperBound() {
		return flags.hasUpperBound();
	}

	@SuppressWarnings("unchecked")
	public T getUpperBound() {
		return (T) values[1];
	}
	
	public boolean isUpperBoundInfinity() {
		return flags.isUpperBoundInfinity();
	}

}

@@ -499,19 +499,171 @@
 nity */%0A
+%09%09private static final byte RANGE_LB_NULL%09= 0x20;%09/* lower bound is null */%0A%09%09private static final byte RANGE_UB_NULL = 0x40;%09/* upper bound is null */%0A
 %09%09%0A
-
 %09%09public
@@ -875,32 +875,151 @@
 sLowerBound() %7B%0A
+%09%09%09return (value & (RANGE_EMPTY %7C RANGE_LB_NULL %7C RANGE_LB_INF)) != 0;%0A%09%09%7D%0A%0A%09%09public boolean isLowerBoundInclusive() %7B%0A
 %09%09%09return (value
@@ -1161,32 +1161,151 @@
 sUpperBound() %7B%0A
+%09%09%09return (value & (RANGE_EMPTY %7C RANGE_UB_NULL %7C RANGE_UB_INF)) != 0;%0A%09%09%7D%0A%0A%09%09public boolean isUpperBoundInclusive() %7B%0A
 %09%09%09return (value
@@ -1417,17 +1417,19 @@
  0;%0A%09%09%7D%0A
+%09%09
 %0A
-
 %09%7D%0A%0A%09Fla
@@ -1822,32 +1822,217 @@
 values%5B0%5D;%0A%09%7D%0A%09%0A
+%09public void setLowerBound(T val) %7B%0A%09%09values%5B0%5D = val;%0A%09%09if(val == null) %7B%0A%09%09%09flags.value %7C= Flags.RANGE_LB_NULL;%0A%09%09%09if(!hasUpperBound())%0A%09%09%09%09flags.value %7C= Flags.RANGE_EMPTY;%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09public boolean 
@@ -2221,32 +2221,32 @@
 tUpperBound() %7B%0A
-
 %09%09return (T) val
@@ -2250,32 +2250,217 @@
 values%5B1%5D;%0A%09%7D%0A%09%0A
+%09public void setUpperBound(T val) %7B%0A%09%09values%5B1%5D = val;%0A%09%09if(val == null) %7B%0A%09%09%09flags.value %7C= Flags.RANGE_UB_NULL;%0A%09%09%09if(!hasLowerBound())%0A%09%09%09%09flags.value %7C= Flags.RANGE_EMPTY;%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09public boolean 

Fix range flags interpretation