190 // otherwise round up to step |
190 // otherwise round up to step |
191 return bisection > step ? bisection - bisection % step : step; |
191 return bisection > step ? bisection - bisection % step : step; |
192 } |
192 } |
193 } |
193 } |
194 |
194 |
195 /** |
|
196 * A {@code double} range spliterator. |
|
197 * |
|
198 * <p>The traversing and splitting logic is equivalent to that of |
|
199 * {@code RangeLongSpliterator} for increasing values with a {@code step} of |
|
200 * {@code 1}. |
|
201 * |
|
202 * <p>A {@code double} value is calculated from the function |
|
203 * {@code start + i * step} where {@code i} is the absolute position of the |
|
204 * value when traversing an instance of this class that has not been split. |
|
205 * This ensures the same values are produced at the same absolute positions |
|
206 * regardless of how an instance of this class is split or traversed. |
|
207 */ |
|
208 static final class RangeDoubleSpliterator implements Spliterator.OfDouble { |
|
209 private final double from; |
|
210 private final double upTo; |
|
211 private final double step; |
|
212 |
|
213 private long lFrom; |
|
214 private final long lUpTo; |
|
215 |
|
216 RangeDoubleSpliterator(double from, double upTo, double step, long lFrom, long lUpTo) { |
|
217 this.from = from; |
|
218 this.upTo = upTo; |
|
219 this.step = step; |
|
220 this.lFrom = lFrom; |
|
221 this.lUpTo = lUpTo; |
|
222 } |
|
223 |
|
224 @Override |
|
225 public boolean tryAdvance(DoubleConsumer consumer) { |
|
226 boolean hasNext = lFrom < lUpTo; |
|
227 if (hasNext) { |
|
228 consumer.accept(from + lFrom * step); |
|
229 lFrom++; |
|
230 } |
|
231 return hasNext; |
|
232 } |
|
233 |
|
234 @Override |
|
235 public void forEachRemaining(DoubleConsumer consumer) { |
|
236 double hOrigin = from; |
|
237 double hStep = step; |
|
238 long hLUpTo = lUpTo; |
|
239 long i = lFrom; |
|
240 for (; i < hLUpTo; i++) { |
|
241 consumer.accept(hOrigin + i * hStep); |
|
242 } |
|
243 lFrom = i; |
|
244 } |
|
245 |
|
246 @Override |
|
247 public long estimateSize() { |
|
248 return lUpTo - lFrom; |
|
249 } |
|
250 |
|
251 @Override |
|
252 public int characteristics() { |
|
253 return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | |
|
254 Spliterator.IMMUTABLE | Spliterator.NONNULL | |
|
255 Spliterator.DISTINCT | Spliterator.SORTED; |
|
256 } |
|
257 |
|
258 @Override |
|
259 public Comparator<? super Double> getComparator() { |
|
260 return null; |
|
261 } |
|
262 |
|
263 @Override |
|
264 public Spliterator.OfDouble trySplit() { |
|
265 return estimateSize() <= 1 |
|
266 ? null |
|
267 : new RangeDoubleSpliterator(from, upTo, step, lFrom, lFrom = lFrom + midPoint()); |
|
268 } |
|
269 |
|
270 private long midPoint() { |
|
271 // Size is known to be >= 2 |
|
272 return (lUpTo - lFrom) / 2; |
|
273 } |
|
274 } |
|
275 |
|
276 private static abstract class AbstractStreamBuilderImpl<T, S extends Spliterator<T>> implements Spliterator<T> { |
195 private static abstract class AbstractStreamBuilderImpl<T, S extends Spliterator<T>> implements Spliterator<T> { |
277 // >= 0 when building, < 0 when built |
196 // >= 0 when building, < 0 when built |
278 // -1 == no elements |
197 // -1 == no elements |
279 // -2 == one element, held by first |
198 // -2 == one element, held by first |
280 // -3 == two or more elements, held by buffer |
199 // -3 == two or more elements, held by buffer |