1 /*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15 package org.apache.commons.functor.generator.util;
16
17 import org.apache.commons.functor.UnaryProcedure;
18 import org.apache.commons.functor.generator.BaseGenerator;
19
20 /**
21 * A generator for the range <i>from</i> (inclusive) to <i>to</i> (exclusive).
22 *
23 * @since 1.0
24 * @version $Revision: 1345136 $ $Date: 2012-06-01 08:47:06 -0400 (Fri, 01 Jun 2012) $
25 */
26 public final class LongRange extends BaseGenerator<Long> {
27 // attributes
28 //---------------------------------------------------------------
29
30 /**
31 * The start index.
32 */
33 private final long from;
34
35 /**
36 * The end index.
37 */
38 private final long to;
39
40 /**
41 * The increment counter.
42 */
43 private final long step;
44
45 // constructors
46 //---------------------------------------------------------------
47 /**
48 * Create a new LongRange.
49 * @param from start
50 * @param to end
51 */
52 public LongRange(Number from, Number to) {
53 this(from.longValue(), to.longValue());
54 }
55
56 /**
57 * Create a new LongRange.
58 * @param from start
59 * @param to end
60 * @param step increment
61 */
62 public LongRange(Number from, Number to, Number step) {
63 this(from.longValue(), to.longValue(), step.longValue());
64 }
65
66 /**
67 * Create a new LongRange.
68 * @param from start
69 * @param to end
70 */
71 public LongRange(long from, long to) {
72 this(from, to, defaultStep(from, to));
73 }
74
75 /**
76 * Create a new LongRange.
77 * @param from start
78 * @param to end
79 * @param step increment
80 */
81 public LongRange(long from, long to, long step) {
82 if (from != to && signOf(step) != signOf(to - from)) {
83 throw new IllegalArgumentException("Will never reach " + to + " from " + from + " using step " + step);
84 }
85 this.from = from;
86 this.to = to;
87 this.step = step;
88 }
89
90 // methods
91 //---------------------------------------------------------------
92 /**
93 * {@inheritDoc}
94 */
95 public void run(UnaryProcedure<? super Long> proc) {
96 if (signOf(step) == -1L) {
97 for (long i = from; i > to; i += step) {
98 proc.run(Long.valueOf(i));
99 }
100 } else {
101 for (long i = from; i < to; i += step) {
102 proc.run(Long.valueOf(i));
103 }
104 }
105 }
106
107 /**
108 * {@inheritDoc}
109 */
110 @Override
111 public String toString() {
112 return "LongRange<" + from + "," + to + "," + step + ">";
113 }
114
115 /**
116 * {@inheritDoc}
117 */
118 @Override
119 public boolean equals(Object obj) {
120 if (obj == this) {
121 return true;
122 }
123 if (!(obj instanceof LongRange)) {
124 return false;
125 }
126 LongRange that = (LongRange) obj;
127 return this.from == that.from && this.to == that.to && this.step == that.step;
128 }
129
130 /**
131 * {@inheritDoc}
132 */
133 @Override
134 public int hashCode() {
135 int hash = "LongRange".hashCode();
136 hash <<= 2;
137 hash ^= from;
138 hash <<= 2;
139 hash ^= to;
140 hash <<= 2;
141 hash ^= step;
142 return hash;
143 }
144
145 // private methods
146 //---------------------------------------------------------------
147 /**
148 * Get <code>value/|value|</code> (0L when value == 0L).
149 * @param value to test
150 * @return long
151 */
152 private static long signOf(long value) {
153 return value < 0L ? -1L : value > 0L ? 1L : 0L;
154 }
155
156 /**
157 * Calculate default step to get from <code>from</code> to <code>to</code>.
158 * @param from start
159 * @param to end
160 * @return long
161 */
162 private static long defaultStep(long from, long to) {
163 return from > to ? -1L : 1L;
164 }
165
166 }