PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sys/java/fan/sys/Range.java

https://bitbucket.org/bedlaczech/fan-1.0
Java | 273 lines | 217 code | 34 blank | 22 comment | 55 complexity | 6329345396493045517c923003ed759d MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //
  2. // Copyright (c) 2006, Brian Frank and Andy Frank
  3. // Licensed under the Academic Free License version 3.0
  4. //
  5. // History:
  6. // 11 Dec 05 Brian Frank Creation
  7. //
  8. package fan.sys;
  9. /**
  10. * Range
  11. */
  12. public final class Range
  13. extends FanObj
  14. {
  15. //////////////////////////////////////////////////////////////////////////
  16. // Constructors
  17. //////////////////////////////////////////////////////////////////////////
  18. public static Range makeInclusive(long start, long end)
  19. {
  20. return new Range(start, end, false);
  21. }
  22. public static Range makeExclusive(long start, long end)
  23. {
  24. return new Range(start, end, true);
  25. }
  26. public static Range make(long start, long end, boolean exclusive)
  27. {
  28. return new Range(start, end, exclusive);
  29. }
  30. public static Range fromStr(String s) { return fromStr(s, true); }
  31. public static Range fromStr(String s, boolean checked)
  32. {
  33. try
  34. {
  35. int dot = s.indexOf('.');
  36. if (s.charAt(dot+1) != '.') throw new Exception();
  37. boolean exclusive = s.charAt(dot+2) == '<';
  38. long start = Long.parseLong(s.substring(0, dot));
  39. long end = Long.parseLong(s.substring(dot + (exclusive?3:2)));
  40. return new Range(start, end, exclusive);
  41. }
  42. catch (Exception e) {}
  43. if (!checked) return null;
  44. throw ParseErr.make("Range", s);
  45. }
  46. private Range(long start, long end, boolean exclusive)
  47. {
  48. this.start = start;
  49. this.end = end;
  50. this.exclusive = exclusive;
  51. }
  52. //////////////////////////////////////////////////////////////////////////
  53. // Range
  54. //////////////////////////////////////////////////////////////////////////
  55. public final long start()
  56. {
  57. return start;
  58. }
  59. public final long end()
  60. {
  61. return end;
  62. }
  63. public final boolean inclusive()
  64. {
  65. return !exclusive;
  66. }
  67. public final boolean exclusive()
  68. {
  69. return exclusive;
  70. }
  71. public final boolean isEmpty()
  72. {
  73. return exclusive && start == end;
  74. }
  75. public final Long min()
  76. {
  77. if (isEmpty()) return null;
  78. if (end < start) return Long.valueOf(exclusive ? end+1 : end);
  79. return Long.valueOf(start);
  80. }
  81. public final Long max()
  82. {
  83. if (isEmpty()) return null;
  84. if (end < start) return Long.valueOf(start);
  85. return Long.valueOf(exclusive ? end-1 : end);
  86. }
  87. public final Long first()
  88. {
  89. if (isEmpty()) return null;
  90. return Long.valueOf(start);
  91. }
  92. public final Long last()
  93. {
  94. if (isEmpty()) return null;
  95. if (!exclusive) return Long.valueOf(end);
  96. if (start < end) return Long.valueOf(end-1);
  97. return Long.valueOf(end+1);
  98. }
  99. public final boolean contains(long i)
  100. {
  101. if (start < end)
  102. {
  103. if (exclusive)
  104. return start <= i && i < end;
  105. else
  106. return start <= i && i <= end;
  107. }
  108. else
  109. {
  110. if (exclusive)
  111. return end < i && i <= start;
  112. else
  113. return end <= i && i <= start;
  114. }
  115. }
  116. public final Range offset(long offset)
  117. {
  118. if (offset == 0) return this;
  119. return new Range(start+offset, end+offset, exclusive);
  120. }
  121. public final void each(Func f)
  122. {
  123. long start = this.start;
  124. long end = this.end;
  125. if (start < end)
  126. {
  127. if (exclusive) --end;
  128. for (long i=start; i<=end; ++i) f.call(Long.valueOf(i));
  129. }
  130. else
  131. {
  132. if (exclusive) ++end;
  133. for (long i=start; i>=end; --i) f.call(Long.valueOf(i));
  134. }
  135. }
  136. public final List map(Func f)
  137. {
  138. long start = this.start;
  139. long end = this.end;
  140. Type r = f.returns();
  141. if (r == Sys.VoidType) r = Sys.ObjType.toNullable();
  142. List acc = new List(r);
  143. if (start < end)
  144. {
  145. if (exclusive) --end;
  146. for (long i=start; i<=end; ++i) acc.add(f.call(Long.valueOf(i)));
  147. }
  148. else
  149. {
  150. if (exclusive) ++end;
  151. for (long i=start; i>=end; --i) acc.add(f.call(Long.valueOf(i)));
  152. }
  153. return acc;
  154. }
  155. public final List toList()
  156. {
  157. long start = this.start;
  158. long end = this.end;
  159. List acc = new List(Sys.IntType);
  160. if (start < end)
  161. {
  162. if (exclusive) --end;
  163. acc.capacity(Long.valueOf(end-start+1));
  164. for (long i=start; i<=end; ++i) acc.add(Long.valueOf(i));
  165. }
  166. else
  167. {
  168. if (exclusive) ++end;
  169. acc.capacity(Long.valueOf(start-end+1));
  170. for (long i=start; i>=end; --i) acc.add(Long.valueOf(i));
  171. }
  172. return acc;
  173. }
  174. public final long random()
  175. {
  176. return FanInt.random(this);
  177. }
  178. public final boolean equals(Object object)
  179. {
  180. if (object instanceof Range)
  181. {
  182. Range that = (Range)object;
  183. return this.start == that.start &&
  184. this.end == that.end &&
  185. this.exclusive == that.exclusive;
  186. }
  187. return false;
  188. }
  189. public final long hash()
  190. {
  191. return (start << 24) ^ end;
  192. }
  193. public String toStr()
  194. {
  195. if (exclusive)
  196. return start + "..<" + end;
  197. else
  198. return start + ".." + end;
  199. }
  200. public Type typeof() { return Sys.RangeType; }
  201. //////////////////////////////////////////////////////////////////////////
  202. // Slice Utils
  203. //////////////////////////////////////////////////////////////////////////
  204. public final int startIndex(int size)
  205. {
  206. int x = (int)start;
  207. if (x < 0) x = size + x;
  208. if (x > size) throw IndexErr.make(this);
  209. return x;
  210. }
  211. public final long startIndex(long size)
  212. {
  213. long x = start;
  214. if (x < 0) x = size + x;
  215. if (x > size) throw IndexErr.make(this);
  216. return x;
  217. }
  218. public final int endIndex(int size)
  219. {
  220. int x = (int)end;
  221. if (x < 0) x = size + x;
  222. if (exclusive) x--;
  223. if (x >= size) throw IndexErr.make(this);
  224. return x;
  225. }
  226. public final long endIndex(long size)
  227. {
  228. long x = end;
  229. if (x < 0) x = size + x;
  230. if (exclusive) x--;
  231. if (x >= size) throw IndexErr.make(this);
  232. return x;
  233. }
  234. //////////////////////////////////////////////////////////////////////////
  235. // Fields
  236. //////////////////////////////////////////////////////////////////////////
  237. private final long start, end;
  238. private final boolean exclusive;
  239. }